diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-05-27 23:03:38 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-05-27 23:03:38 +0200 |
commit | 8f9642a5148f44771dd7c9e029885bb9cf45a303 (patch) | |
tree | 22bd7c65ff36a48d897943d4dbc5452627457aa4 /sys/src/boot | |
parent | 5da4f0fc0f55b43815adbdbc8f2e0e26eaac84e6 (diff) |
9boot: detect SYSLINUX "memdisk" and pass to kernel via ramdisk0= parameter
this makes virtual "memdisk" from SYSLINUX accessible to
the kernel, allowing the iso to be loaded via TFTP and
started without any ethernet or disk drivers available.
Diffstat (limited to 'sys/src/boot')
-rw-r--r-- | sys/src/boot/pc/sub.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/sys/src/boot/pc/sub.c b/sys/src/boot/pc/sub.c index 514a54e4d..caa919d98 100644 --- a/sys/src/boot/pc/sub.c +++ b/sys/src/boot/pc/sub.c @@ -187,6 +187,7 @@ char *confend; static void apmconf(int); static void e820conf(void); +static void ramdiskconf(int); static void uartconf(char*); static char* @@ -249,6 +250,7 @@ Clear: memset(confend, 0, BOOTARGSLEN); e820conf(); + ramdiskconf(0); } nowait = 1; inblock = 0; @@ -418,6 +420,78 @@ e820conf(void) print(s); } +static int +checksum(void *v, int n) +{ + uchar *p, s; + + s = 0; + p = v; + while(n-- > 0) + s += *p++; + return s; +} + +static void +ramdiskconf(int id) +{ + struct { + /* ACPI header */ + char sig[4]; + u32int len; + uchar revision; + uchar csum; + char oem_id[6]; + char oem_table_id[8]; + u32int oem_revision; + char asl_compiler_id[4]; + u32int asl_compiler_revision; + + u32int safe_hook; + + /* MDI structure */ + u16int bytes; + uchar version_minor; + uchar version_major; + u32int diskbuf; + u32int disksize; + u32int cmdline; + u32int oldint13; + u32int oldint15; + u16int olddosmem; + uchar bootloaderid; + uchar sector_shift; + u16int dpt_ptr; + } *mbft; + int shift; + char *s; + +#define BDA ((uchar*)0x400) + mbft = (void*)((((BDA[0x14]<<8) | BDA[0x13])<<10) - 1024); + for(; (ulong)&mbft->sector_shift < 0xA0000; mbft = (void*)((ulong)mbft + 16)){ + if(memcmp("mBFT", mbft, 4) == 0 + && mbft->len < 1024 && (uchar*)mbft + mbft->len > &mbft->sector_shift + && checksum(mbft, mbft->len) == 0) + goto Found; + } + return; +Found: + shift = mbft->sector_shift; + if(shift == 0) + shift = 9; + + s = confend; + addconfx("ramdisk", 1, id); + addconfx("=0x", 8, mbft->diskbuf); + addconfx(" 0x", 8, mbft->disksize<<shift); + addconfx(" 0x", 8, 1UL<<shift); + + *confend++ = '\n'; + *confend = 0; + + print(s); +} + static void uartconf(char *s) { |