summaryrefslogtreecommitdiff
path: root/memdisk/setup.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2006-10-17 14:50:47 -0700
committerH. Peter Anvin <hpa@zytor.com>2006-10-17 14:50:47 -0700
commitaf9cc4b2abe87db7ef0680e52393a24d550cc31d (patch)
tree887a89278126e514d4ebde6f47922c3ca71899de /memdisk/setup.c
parent3748de36714958902ebaf0669e004ae4113204db (diff)
downloadsyslinux-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.c39
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;
}