Skip to content

Conversation

@losfair
Copy link

@losfair losfair commented Mar 26, 2025

This patch adds support for using the kernel ramdisk as read-only block storage.

$ qemu-system-x86_64 -enable-kvm -kernel nanos/output/platform/pc/bin/kernel.img \
  -smp 2 -m 512 -display none -serial stdio \
  -initrd  $HOME/.ops/images/myapp
[0.254580] RAMDISK: 269197824 bytes at 0xffff800300000000
...

return irangel(e->base, e->length);
}
return irange(INVALID_PHYSICAL, INVALID_PHYSICAL);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having this function defined in all architectures, it's better to pass the ramdisk range directly to init_ramdisk() as a function argument, and call init_ramdisk() only when there is an actual ramdisk.

token = runtime_strtok_r(&input, delim, &rest);
while (!sstring_is_null(token)) {
if(runtime_strcmp(token, ss("verbose")) == 0) {
cmdline_verbose_logging = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the cmdline_verbose_logging variable, and keep logging confined to when INIT_DEBUG is #defined; after all, these logging messages are useful mostly when debugging, and I would rather avoid carrying this debug stuff in production kernels.

storage, st, boolean, write,
void *buf, range blocks, status_handler sh);

typedef struct storage
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to avoid such a generic name, I would add a ramdisk-related prefix, e.g. something like struct ramdisk_storage

{
closure_struct(storage_simple_req_handler, req_handler);
closure_struct(ramdisk_io, read);
closure_struct(ramdisk_io, write);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary to define the ramdisk_io closure struct, you can use closure_struct(block_io) instead, for both read and write. Then, you can have 2 separate functions (defined with closure_func_basic) for read and write: for reading, you would retrieve the ramdisk_storage struct pointer via struct_from_closure(); for writing, you don't need any pointer and just apply the status handler with the error status.

u64 end_byte_offset = blocks.end * SECTOR_SIZE;
if (start_byte_offset > end_byte_offset || end_byte_offset > st->ramdisk_size)
{
apply(sh, timm("result", "read out of bounds"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use range_valid(blocks); also, instead of applying an error status to the status handler, I would just use assert(), since an out-of-bounds range would indicate a kernel bug bad enough to warrant taking down the VM.

return;
}
u64 ramdisk_size = range_span(ramdisk_phys);
u64 v = allocate_u64((heap)heap_virtual_huge(kh), ramdisk_size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert(v != INVALID_PHYSICAL);

map(v, ramdisk_phys.start, ramdisk_size, pageflags_memory());

heap h = heap_locked(kh);
storage st = allocate(h, sizeof(struct storage));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert(st != INVALID_ADDRESS);

init_closure(&st->read, ramdisk_io, st, false),
init_closure(&st->write, ramdisk_io, st, true)),
ramdisk_size, -1);
msg_print("RAMDISK: %u bytes at %p", st->ramdisk_size, st->ramdisk);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to use msg_info(). For most things the kernel is quiet during boot, unless explicitly told to be more verbose. (I know, right now LOG_INFO messages cannot be enabled this early during boot, but hopefully we will add this capability in the future.)

.end:

_start:
xor edx, edx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be xor rdx, rdx, so that all 64 bits are zeroed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants