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,8 +67,17 @@ 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
79+ boolean cmdline_verbose_logging = false;
80+
6981range kern_get_elf (void )
7082{
7183 for_regions (e ) {
@@ -75,6 +87,15 @@ range kern_get_elf(void)
7587 return irange (INVALID_PHYSICAL , INVALID_PHYSICAL );
7688}
7789
90+ range kern_get_ramdisk (void )
91+ {
92+ for_regions (e ) {
93+ if (e -> type == REGION_RAMDISK )
94+ return irangel (e -> base , e -> length );
95+ }
96+ return irange (INVALID_PHYSICAL , INVALID_PHYSICAL );
97+ }
98+
7899BSS_RO_AFTER_INIT static boolean have_rdseed ;
79100BSS_RO_AFTER_INIT static boolean have_rdrand ;
80101
@@ -292,20 +313,21 @@ void init_physical_heap(void)
292313 }
293314
294315 boolean found = false;
295- early_init_debug ("physical memory:" );
316+ if (cmdline_verbose_logging )
317+ early_debug ("Physical memory: \n" );
296318 for_regions (e ) {
297319 if (e -> type == REGION_PHYSICAL ) {
298320 u64 base = e -> base ;
299321 u64 length = e -> length ;
300322 if (length == 0 )
301323 continue ;
302- #ifdef INIT_DEBUG
303- early_debug ("INIT: [" );
304- early_debug_u64 (base );
305- early_debug (", " );
306- early_debug_u64 (base + length );
307- early_debug (")\n" );
308- #endif
324+ if ( cmdline_verbose_logging ) {
325+ early_debug ("\t [" );
326+ early_debug_u64 (base );
327+ early_debug (", " );
328+ early_debug_u64 (base + length );
329+ early_debug (")\n" );
330+ }
309331 if (!pageheap_add_range (base , length ))
310332 halt (" - id_heap_add_range failed\n" );
311333 found = true;
@@ -319,19 +341,59 @@ void init_physical_heap(void)
319341static void setup_initmap (void )
320342{
321343 u64 kernel_size = u64_from_pointer (& END ) - KERNEL_BASE_PHYS ;
344+ create_region (KERNEL_BASE_PHYS , kernel_size , REGION_KERN_LOAD );
345+
322346 region page_region = 0 ;
323347 for_regions (r ) {
324- if ((r -> type == REGION_PHYSICAL ) && (r -> base <= KERNEL_BASE_PHYS ) &&
325- (r -> base + r -> length > KERNEL_BASE_PHYS )) {
326- /* This is the memory region where the kernel has been loaded: adjust the region
327- * boundaries so that the memory occupied by the kernel code does not appear as free
328- * memory, and possibly and make a new memory region. */
329- if (r -> base < KERNEL_BASE_PHYS )
330- create_region (r -> base , KERNEL_BASE_PHYS - r -> base , r -> type );
331- region_resize (r , r -> base - pad (KERNEL_BASE_PHYS + kernel_size , PAGESIZE ));
332-
333- page_region = r ;
334- break ;
348+ if (r -> type == REGION_PHYSICAL ) {
349+ for_regions (s ) {
350+ if (s -> type != REGION_PHYSICAL &&
351+ s -> length != 0 &&
352+ r -> base <= s -> base &&
353+ r -> base + r -> length > s -> base ) {
354+ u64 inner_start = s -> base ;
355+ u64 inner_end = s -> base + s -> length ;
356+
357+ if (inner_end > r -> base + r -> length ) {
358+ inner_end = r -> base + r -> length ;
359+ }
360+ if (cmdline_verbose_logging ) {
361+ early_debug ("Reserving region: [" );
362+ early_debug_u64 (r -> base );
363+ early_debug (" - " );
364+ early_debug_u64 (r -> base + r -> length );
365+ early_debug ("] (physmem), [" );
366+ early_debug_u64 (inner_start );
367+ early_debug (" - " );
368+ early_debug_u64 (inner_end );
369+ early_debug ("] (" );
370+ early_debug_u64 (s -> type );
371+ early_debug (")\n" );
372+ }
373+ if (r -> base < inner_start ) {
374+ create_region (r -> base , inner_start - r -> base , r -> type );
375+ if (cmdline_verbose_logging ) {
376+ early_debug ("\tcreate: " );
377+ early_debug_u64 (r -> base );
378+ early_debug (" - " );
379+ early_debug_u64 (inner_start );
380+ early_debug ("\n" );
381+ }
382+ }
383+ region_resize (r , r -> base - pad (inner_end , PAGESIZE ));
384+ if (cmdline_verbose_logging ) {
385+ early_debug ("\tshrink: " );
386+ early_debug_u64 (r -> base );
387+ early_debug (" - " );
388+ early_debug_u64 (r -> base + r -> length );
389+ early_debug ("\n" );
390+ }
391+ if (s -> type == REGION_KERN_LOAD ) {
392+ assert (!page_region );
393+ page_region = r ;
394+ }
395+ }
396+ }
335397 }
336398 }
337399 assert (page_region );
@@ -366,11 +428,13 @@ static void setup_initmap(void)
366428}
367429
368430// init linker set
369- void init_service (u64 rdi , u64 rsi )
431+ void init_service (u64 rdi , u64 rsi , hvm_start_info start_info )
370432{
371433 u8 * params = pointer_from_u64 (rsi );
372434 const char * cmdline = 0 ;
373435 u32 cmdline_size ;
436+ void * ramdisk = 0 ;
437+ u32 ramdisk_size ;
374438
375439 if (params && (* (u16 * )(params + BOOT_PARAM_OFFSET_BOOT_FLAG ) == 0xAA55 ) &&
376440 (* (u32 * )(params + BOOT_PARAM_OFFSET_HEADER ) == 0x53726448 )) {
@@ -389,9 +453,51 @@ void init_service(u64 rdi, u64 rsi)
389453 BOOT_PARAM_OFFSET_CMD_LINE_PTR )));
390454 cmdline_size = * ((u32 * )(params + BOOT_PARAM_OFFSET_CMDLINE_SIZE ));
391455
392- setup_initmap ();
456+ ramdisk = pointer_from_u64 ((u64 )* ((u32 * )(params +
457+ BOOT_PARAM_OFFSET_RAMDISK_IMAGE )));
458+ ramdisk_size = * ((u32 * )(params + BOOT_PARAM_OFFSET_RAMDISK_SIZE ));
459+ } else if (start_info )
460+ {
461+ cmdline = pointer_from_u64 (start_info -> cmdline_paddr );
462+ cmdline_size = 0 ;
463+ const char * cmdline_p = cmdline ;
464+ while (* cmdline_p )
465+ {
466+ cmdline_size ++ ;
467+ cmdline_p ++ ;
468+ }
469+
470+ if (start_info -> nr_modules )
471+ {
472+ hvm_modlist_entry ramdisk_entry = pointer_from_u64 (start_info -> modlist_paddr );
473+ ramdisk = pointer_from_u64 (ramdisk_entry -> paddr );
474+ ramdisk_size = ramdisk_entry -> size ;
475+ }
476+ }
477+
478+ if (cmdline ) {
479+ create_region (u64_from_pointer (cmdline ), cmdline_size , REGION_CMDLINE );
480+ sstring input = sstring_from_cstring (cmdline , cmdline_size );
481+ sstring token , rest ;
482+ sstring delim = ss (" " );
483+ token = runtime_strtok_r (& input , delim , & rest );
484+ while (!sstring_is_null (token )) {
485+ if (runtime_strcmp (token , ss ("verbose" )) == 0 ) {
486+ cmdline_verbose_logging = true;
487+ }
488+ token = runtime_strtok_r (0 , delim , & rest );
489+ }
393490 }
394491
492+ if (ramdisk )
493+ create_region (u64_from_pointer (ramdisk ), ramdisk_size , REGION_RAMDISK );
494+
495+ #ifdef INIT_DEBUG
496+ cmdline_verbose_logging = true;
497+ #endif
498+
499+ setup_initmap ();
500+
395501 serial_init ();
396502 early_init_debug ("init_service" );
397503
@@ -402,8 +508,6 @@ void init_service(u64 rdi, u64 rsi)
402508 init_hwrand ();
403509 kaslr ();
404510 init_kernel_heaps ();
405- if (cmdline )
406- create_region (u64_from_pointer (cmdline ), cmdline_size , REGION_CMDLINE );
407511 u64 stack_size = 32 * PAGESIZE ;
408512 u64 stack_location = allocate_u64 ((heap )heap_page_backed (get_kernel_heaps ()), stack_size );
409513 stack_location += stack_size - STACK_ALIGNMENT ;
@@ -421,8 +525,7 @@ void pvh_start(hvm_start_info start_info)
421525 if (mem_table [i ].type == HVM_MEMMAP_TYPE_RAM )
422526 create_region (mem_table [i ].addr , mem_table [i ].size , REGION_PHYSICAL );
423527 }
424- setup_initmap ();
425- init_service (0 , 0 );
528+ init_service (0 , 0 , start_info );
426529}
427530
428531RO_AFTER_INIT static struct console_driver serial_console_driver = {
@@ -499,6 +602,7 @@ void detect_devices(kernel_heaps kh, storage_attach sa)
499602 init_pvscsi (kh , sa );
500603 init_nvme (kh , sa );
501604 init_ata_pci (kh , sa );
605+ init_ramdisk (kh , sa );
502606
503607 init_virtio_9p (kh );
504608 init_virtio_socket (kh );
0 commit comments