diff options
author | H. Peter Anvin <hpa@zytor.com> | 2006-10-17 14:50:47 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2006-10-17 14:50:47 -0700 |
commit | af9cc4b2abe87db7ef0680e52393a24d550cc31d (patch) | |
tree | 887a89278126e514d4ebde6f47922c3ca71899de /memdisk/setup.c | |
parent | 3748de36714958902ebaf0669e004ae4113204db (diff) | |
download | syslinux-af9cc4b2abe87db7ef0680e52393a24d550cc31d.tar.gz |
[memdisk] Make ES:DI point to the $PnP structure on entry
ES:DI is supposed to point to the $PnP structure on entry, make it sew.
Diffstat (limited to 'memdisk/setup.c')
-rw-r--r-- | memdisk/setup.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/memdisk/setup.c b/memdisk/setup.c index 2f41a4d9..fe8023b1 100644 --- a/memdisk/setup.c +++ b/memdisk/setup.c @@ -498,6 +498,33 @@ void __attribute__((noreturn)) die(void) asm volatile("hlt"); } +/* + * Find a $PnP installation check structure; return (ES << 16) + DI value + */ +static uint32_t pnp_install_check(void) +{ + uint32_t *seg; + unsigned char *p, csum; + int i; + + for (seg = (uint32_t *)0xf0000; seg < (uint32_t *)0x100000; seg += 4) { + if (*seg == ('$'+('P' << 8)+('n' << 16)+('P' << 24))) { + p = (unsigned char *)seg; + if (p[2] < 0x21) + continue; + csum = 0; + for (i = p[2]; i; i--) + csum += *p++; + if (csum != 0) + continue; + + return (0xf000 << 16) + (uint16_t)(unsigned long)seg; + } + } + + return 0; +} + #define STACK_NEEDED 512 /* Number of bytes of stack */ /* @@ -508,7 +535,12 @@ void __attribute__((noreturn)) die(void) syscall_t syscall; void *sys_bounce; -uint32_t setup(syscall_t cs_syscall, void *cs_bounce) +struct setup_return { + uint32_t es; /* ES:DI -> $PnP structure */ + uint32_t dx; /* DL -> boot device */ +}; + +struct setup_return setup(syscall_t cs_syscall, void *cs_bounce) { unsigned int bin_size = (int) &_binary_memdisk_bin_size; struct memdisk_header *hptr; @@ -521,6 +553,7 @@ uint32_t setup(syscall_t cs_syscall, void *cs_bounce) int total_size, cmdlinelen; com32sys_t regs; uint32_t ramdisk_image, ramdisk_size; + struct setup_return sr; /* Set up global variables */ syscall = cs_syscall; @@ -776,5 +809,7 @@ uint32_t setup(syscall_t cs_syscall, void *cs_bounce) puts("booting...\n"); /* On return the assembly code will jump to the boot vector */ - return geometry->driveno; + sr.esdi = pnp_install_check(); + sr.dx = geometry->driveno; + return sr; } |