summaryrefslogtreecommitdiff
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
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.
-rw-r--r--memdisk/memdisk16.asm12
-rw-r--r--memdisk/setup.c39
2 files changed, 44 insertions, 7 deletions
diff --git a/memdisk/memdisk16.asm b/memdisk/memdisk16.asm
index 37e85967..ebcfe7e8 100644
--- a/memdisk/memdisk16.asm
+++ b/memdisk/memdisk16.asm
@@ -133,20 +133,22 @@ copy_cmdline:
; When init32 returns, we have been set up, the new boot sector loaded,
; and we should go and and run the newly loaded boot sector
;
-; The setup function returns (in AL) the drive number which should be
-; put into DL
+; The setup function returns (in DX) the drive number, and
+; the value for ES:DI in AX
;
- mov dx,ax
+ movzx edi,ax
+ shr eax,16
+ mov es,ax
cli
xor esi,esi ; No partition table involved
mov ds,si ; Make all the segments consistent
- mov es,si
mov fs,si
mov gs,si
mov ss,si
mov esp,0x7C00 ; Good place for SP to start out
- jmp 0:0x7C00
+ call 0:0x7C00
+ int 18h ; A far return -> INT 18h
;
; We enter protected mode, set up a flat 32-bit environment, run rep movsd
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;
}