diff options
author | hpa <hpa> | 2001-12-09 07:18:37 +0000 |
---|---|---|
committer | hpa <hpa> | 2001-12-09 07:18:37 +0000 |
commit | d6406ffa95891bed7b5148c7c2b0ad540f764f87 (patch) | |
tree | 8a2f3cabe548d6cdb611b05c8cfab6679aeac445 | |
parent | 8b77853436b60b3d4297d5eefd80f3d7a88d1e0c (diff) | |
download | syslinux-d6406ffa95891bed7b5148c7c2b0ad540f764f87.tar.gz |
More work at patching and setup; load the boot sector when done
-rw-r--r-- | memdisk/msetup.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/memdisk/msetup.c b/memdisk/msetup.c index 907d8d3c..713f368f 100644 --- a/memdisk/msetup.c +++ b/memdisk/msetup.c @@ -251,14 +251,20 @@ rdz_32(uint32_t addr) } /* Addresses in the zero page */ -#define BIOS_BASEMEM 0x413 /* Amount of DOS memory */ +#define BIOS_INT13 (0x13*4) /* INT 13h vector */ +#define BIOS_INT15 (0x15*4) /* INT 13h vector */ +#define BIOS_BASEMEM 0x413 /* Amount of DOS memory */ void setup(void) { unsigned int size = (int) &_binary_memdisk_bin_size; struct memdisk_header *hptr; struct patch_area *pptr; - uint32_t old_dos_mem; + uint16_t driverseg; + uint32_t driverptr, driveraddr; + uint8_t driveno = 0; + uint8_t status; + uint16_t exitcode; /* Point %fs to the zero page */ asm volatile("movw %0,%%fs" :: "r" (0)); @@ -274,13 +280,13 @@ void setup(void) /* Badness... */ } - old_dos_mem = dos_mem; + pptr->olddosmem = rdz_16(BIOS_BASEMEM); - dos_mem -= hptr->total_size; - dos_mem &= ~0x3FF; + driveraddr = dos_mem - hptr->total_size; + driveraddr &= ~0x3FF; /* Reserve this range of memory */ - insertrange(dos_mem, old_dos_mem-dos_mem, 2); + insertrange(driveraddr, dos_mem-driveraddr, 2); parse_mem(); pptr->mem1mb = low_mem >> 10; @@ -288,18 +294,47 @@ void setup(void) pptr->memint1588 = (low_mem == 0xf00000) ? ((high_mem > 0x30ffc00) ? 0xffff : (high_mem >> 10)+0x3c00) : (low_mem >> 10); - pptr->olddosmem = rdz_16(BIOS_BASEMEM); - wrz_16(BIOS_BASEMEM, dos_mem >> 10); - /* ... patch other things ... */ + driverseg = driveraddr >> 4; + driverptr = driverseg << 16; + + pptr->oldint13 = rdz_32(BIOS_INT13); + pptr->oldint15 = rdz_32(BIOS_INT15); + + /* Claim the memory and copy the driver into place */ + wrz_16(BIOS_BASEMEM, dos_mem >> 10); - /* Copy the driver into place */ asm volatile("pushw %%es ; " "movw %0,%%es ; " "rep ; movsl %%ds:(%%si), %%es:(%%di) ; " "popw %%es" - :: "r" ((uint16_t)(dos_mem >> 4)), + :: "r" (driverseg), "c" (size >> 2), "S" (&_binary_memdisk_bin_start), "D" (0)); + + /* Install the interrupt handlers */ + wrz_32(BIOS_INT13, driverptr+hptr->int13_offs); + wrz_32(BIOS_INT15, driverptr+hptr->int15_offs); + + /* Reboot into the new "disk" */ + asm volatile("pushw %%es ; " + "xorw %%cx,%%cx ; " + "movw %%cx,%%es ; " + "incw %%cx ; " + "movw $0x0201,%%ax ; " + "movw $0x7c00,%%bx ; " + "int $0x13 ; " + "setc %0 ; " + "popw %%es" + : "=r" (status), "=a" (exitcode) + : "d" ((uint16_t)driveno) + : "ebx", "ecx", "edx", "esi", "edi", "ebp"); + + if ( status ) { + /* Badness... */ + } + + /* On return the assembly code will jump to the boot vector */ } + |