Skip to content

Commit d58aaa5

Browse files
committed
drivers: add ramdisk storage driver
1 parent 34904cc commit d58aaa5

9 files changed

Lines changed: 130 additions & 2 deletions

File tree

platform/pc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ SRCS-kernel.elf= \
2222
$(SRCDIR)/drivers/gve.c \
2323
$(SRCDIR)/drivers/nvme.c \
2424
$(SRCDIR)/drivers/netconsole.c \
25+
$(SRCDIR)/drivers/ramdisk.c \
2526
$(SRCDIR)/drivers/vga.c \
2627
$(SRCDIR)/gdb/gdbstub.c \
2728
$(SRCDIR)/gdb/gdbtcp.c \

platform/pc/service.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
#include <pci.h>
1919
#include <xen_platform.h>
2020
#include <virtio/virtio.h>
21+
#include <drivers/ramdisk.h>
2122
#include <vmware/vmware.h>
2223
#include "serial.h"
2324

2425
#define BOOT_PARAM_OFFSET_E820_ENTRIES 0x01E8
2526
#define BOOT_PARAM_OFFSET_BOOT_FLAG 0x01FE
2627
#define BOOT_PARAM_OFFSET_HEADER 0x0202
28+
#define BOOT_PARAM_OFFSET_RAMDISK_IMAGE 0x0218
29+
#define BOOT_PARAM_OFFSET_RAMDISK_SIZE 0x021C
2730
#define BOOT_PARAM_OFFSET_CMD_LINE_PTR 0x0228
2831
#define BOOT_PARAM_OFFSET_CMDLINE_SIZE 0x0238
2932
#define BOOT_PARAM_OFFSET_E820_TABLE 0x02D0
@@ -64,6 +67,13 @@ typedef struct hvm_memmap_entry {
6467
u32 reserved;
6568
} *hvm_memmap_entry;
6669

70+
typedef struct hvm_modlist_entry {
71+
u64 paddr;
72+
u64 size;
73+
u64 cmdline_paddr;
74+
u64 reserved;
75+
} *hvm_modlist_entry;
76+
6777
extern u8 START, END;
6878

6979
range kern_get_elf(void)
@@ -75,6 +85,15 @@ range kern_get_elf(void)
7585
return irange(INVALID_PHYSICAL, INVALID_PHYSICAL);
7686
}
7787

88+
range kern_get_ramdisk(void)
89+
{
90+
for_regions(e) {
91+
if (e->type == REGION_RAMDISK)
92+
return irangel(e->base, e->length);
93+
}
94+
return irange(INVALID_PHYSICAL, INVALID_PHYSICAL);
95+
}
96+
7897
BSS_RO_AFTER_INIT static boolean have_rdseed;
7998
BSS_RO_AFTER_INIT static boolean have_rdrand;
8099

@@ -366,11 +385,13 @@ static void setup_initmap(void)
366385
}
367386

368387
// init linker set
369-
void init_service(u64 rdi, u64 rsi)
388+
void init_service(u64 rdi, u64 rsi, hvm_start_info start_info)
370389
{
371390
u8 *params = pointer_from_u64(rsi);
372391
const char *cmdline = 0;
373392
u32 cmdline_size;
393+
void *ramdisk = 0;
394+
u32 ramdisk_size;
374395

375396
if (params && (*(u16 *)(params + BOOT_PARAM_OFFSET_BOOT_FLAG) == 0xAA55) &&
376397
(*(u32 *)(params + BOOT_PARAM_OFFSET_HEADER) == 0x53726448)) {
@@ -389,7 +410,28 @@ void init_service(u64 rdi, u64 rsi)
389410
BOOT_PARAM_OFFSET_CMD_LINE_PTR)));
390411
cmdline_size = *((u32 *)(params + BOOT_PARAM_OFFSET_CMDLINE_SIZE));
391412

413+
ramdisk = pointer_from_u64((u64)*((u32 *)(params +
414+
BOOT_PARAM_OFFSET_RAMDISK_IMAGE)));
415+
ramdisk_size = *((u32 *)(params + BOOT_PARAM_OFFSET_RAMDISK_SIZE));
416+
392417
setup_initmap();
418+
} else if (start_info)
419+
{
420+
cmdline = pointer_from_u64(start_info->cmdline_paddr);
421+
cmdline_size = 0;
422+
const char *cmdline_p = cmdline;
423+
while (*cmdline_p)
424+
{
425+
cmdline_size++;
426+
cmdline_p++;
427+
}
428+
429+
if (start_info->nr_modules)
430+
{
431+
hvm_modlist_entry ramdisk_entry = pointer_from_u64(start_info->modlist_paddr);
432+
ramdisk = pointer_from_u64(ramdisk_entry->paddr);
433+
ramdisk_size = ramdisk_entry->size;
434+
}
393435
}
394436

395437
serial_init();
@@ -404,6 +446,8 @@ void init_service(u64 rdi, u64 rsi)
404446
init_kernel_heaps();
405447
if (cmdline)
406448
create_region(u64_from_pointer(cmdline), cmdline_size, REGION_CMDLINE);
449+
if (ramdisk)
450+
create_region(u64_from_pointer(ramdisk), ramdisk_size, REGION_RAMDISK);
407451
u64 stack_size = 32*PAGESIZE;
408452
u64 stack_location = allocate_u64((heap)heap_page_backed(get_kernel_heaps()), stack_size);
409453
stack_location += stack_size - STACK_ALIGNMENT;
@@ -422,7 +466,7 @@ void pvh_start(hvm_start_info start_info)
422466
create_region(mem_table[i].addr, mem_table[i].size, REGION_PHYSICAL);
423467
}
424468
setup_initmap();
425-
init_service(0, 0);
469+
init_service(0, 0, start_info);
426470
}
427471

428472
RO_AFTER_INIT static struct console_driver serial_console_driver = {
@@ -499,6 +543,7 @@ void detect_devices(kernel_heaps kh, storage_attach sa)
499543
init_pvscsi(kh, sa);
500544
init_nvme(kh, sa);
501545
init_ata_pci(kh, sa);
546+
init_ramdisk(kh, sa);
502547

503548
init_virtio_9p(kh);
504549
init_virtio_socket(kh);

platform/riscv-virt/service.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ range kern_get_elf(void)
6363
return irange(INVALID_PHYSICAL, INVALID_PHYSICAL);
6464
}
6565

66+
range kern_get_ramdisk(void)
67+
{
68+
return irange(INVALID_PHYSICAL, INVALID_PHYSICAL);
69+
}
70+
6671
void reclaim_regions(void)
6772
{
6873
/* mmu init complete; unmap temporary identity map */

platform/virt/service.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ range kern_get_elf(void)
194194
return irange(INVALID_PHYSICAL, INVALID_PHYSICAL);
195195
}
196196

197+
range kern_get_ramdisk(void)
198+
{
199+
return irange(INVALID_PHYSICAL, INVALID_PHYSICAL);
200+
}
201+
197202
void reclaim_regions(void)
198203
{
199204
}

src/drivers/ramdisk.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <kernel.h>
2+
#include <storage.h>
3+
4+
#include "ramdisk.h"
5+
6+
typedef struct storage *storage;
7+
8+
declare_closure_struct(2, 3, void, ramdisk_io,
9+
storage, st, boolean, write,
10+
void *buf, range blocks, status_handler sh);
11+
12+
typedef struct storage
13+
{
14+
closure_struct(storage_simple_req_handler, req_handler);
15+
closure_struct(ramdisk_io, read);
16+
closure_struct(ramdisk_io, write);
17+
void *ramdisk;
18+
u64 ramdisk_size;
19+
} *storage;
20+
21+
define_closure_function(2, 3, void, ramdisk_io,
22+
storage, st, boolean, write,
23+
void *buf, range blocks, status_handler sh)
24+
{
25+
storage st = bound(st);
26+
boolean write = bound(write);
27+
28+
if (write)
29+
{
30+
apply(sh, timm("result", "read-only device"));
31+
return;
32+
}
33+
34+
u64 start_byte_offset = blocks.start * SECTOR_SIZE;
35+
u64 end_byte_offset = blocks.end * SECTOR_SIZE;
36+
if (start_byte_offset > end_byte_offset || end_byte_offset > st->ramdisk_size)
37+
{
38+
apply(sh, timm("result", "read out of bounds"));
39+
return;
40+
}
41+
42+
runtime_memcpy(buf, st->ramdisk + start_byte_offset, end_byte_offset - start_byte_offset);
43+
apply(sh, STATUS_OK);
44+
}
45+
46+
void init_ramdisk(kernel_heaps kh, storage_attach a)
47+
{
48+
range ramdisk_phys = kern_get_ramdisk();
49+
if (ramdisk_phys.start == INVALID_PHYSICAL)
50+
{
51+
msg_print("RAMDISK: not detected");
52+
return;
53+
}
54+
u64 ramdisk_size = range_span(ramdisk_phys);
55+
u64 v = allocate_u64((heap)heap_virtual_huge(kh), ramdisk_size);
56+
map(v, ramdisk_phys.start, ramdisk_size, pageflags_memory());
57+
58+
heap h = heap_locked(kh);
59+
storage st = allocate(h, sizeof(struct storage));
60+
st->ramdisk = pointer_from_u64(v);
61+
st->ramdisk_size = ramdisk_size;
62+
apply(a,
63+
storage_init_req_handler(&st->req_handler,
64+
init_closure(&st->read, ramdisk_io, st, false),
65+
init_closure(&st->write, ramdisk_io, st, true)),
66+
ramdisk_size, -1);
67+
msg_print("RAMDISK: %u bytes at %p", st->ramdisk_size, st->ramdisk);
68+
}

src/drivers/ramdisk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
void init_ramdisk(kernel_heaps kh, storage_attach a);

src/kernel/kernel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ void init_platform_devices(kernel_heaps kh);
602602
void init_cpuinfo_machine(cpuinfo ci, heap backed);
603603
void kernel_runtime_init(kernel_heaps kh);
604604
range kern_get_elf(void);
605+
range kern_get_ramdisk(void);
605606
void reclaim_regions(void);
606607

607608
extern u64 kernel_phys_offset;

src/kernel/region.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef struct region *region;
1919
#define REGION_RECLAIM 14 /* areas to be unmapped and reclaimed in stage3 (only stage2 stack presently) */
2020
#define REGION_SMBIOS 15 /* SMBIOS entry point */
2121
#define REGION_RSDP 16 /* location of the ACPI RSDP */
22+
#define REGION_RAMDISK 17 /* kernel ramdisk */
2223

2324

2425
static inline region create_region(u64 base, u64 length, int type)

src/x86_64/crt0.s

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ write_xmsr:
396396
.end:
397397

398398
_start:
399+
xor edx, edx
399400
call init_service
400401
hlt
401402
.end:

0 commit comments

Comments
 (0)