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+
6777extern u8 START , END ;
6878
6979range 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+
7897BSS_RO_AFTER_INIT static boolean have_rdseed ;
7998BSS_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
428472RO_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 );
0 commit comments