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 | |
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.
-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) { |