Convert to using a 32-bit installer framework, in preparation for
authorhpa <hpa>
Thu, 10 Apr 2003 06:28:08 +0000 (06:28 +0000)
committerhpa <hpa>
Thu, 10 Apr 2003 06:28:08 +0000 (06:28 +0000)
supporting gzip compressed images

memdisk/Makefile
memdisk/conio.c
memdisk/e820test.c
memdisk/init.S16
memdisk/memdisk.h
memdisk/msetup.c
memdisk/postprocess.pl
memdisk/setup.c

index 13e87ce..220e8fb 100644 (file)
 VERSION := $(shell cat ../version)
 
 CC       = gcc
-CFLAGS   = -Wall -O2 -fomit-frame-pointer -march=i386 \
+CFLAGS   = -g -Wall -O2 -fomit-frame-pointer -march=i386 \
           -malign-functions=0 -malign-jumps=0 -malign-loops=0 \
+         -I../com32/include \
           -DVERSION='"$(VERSION)"' -DDATE='"$(DATE)"'
-LDFLAGS  = 
+LDFLAGS  = -g
 INCLUDE  =
 AS       = as
 LD      = ld
-NASM     = nasm
+NASM     = nasm -O99
 NINCLUDE = 
 OBJCOPY  = objcopy
 PERL     = perl
 
 # Important: init.o16 must be first!!
-OBJS     = init.o16 setup.o16 msetup.o16 e820func.o16 conio.o16 memdisk.o
+OBJS16   = init.o16 init32.o
+OBJS32   = start32.o setup.o msetup.o e820func.o conio.o memcpy.o memdisk.o
 
 CSRC     = setup.c msetup.c e820func.c conio.c
 SSRC     = init.S16
-NASMSRC  = memdisk.asm
+NASMSRC  = memdisk.asm jmp32.asm
 
 all: memdisk e820test
 
@@ -45,9 +47,15 @@ clean: tidy
 spotless: clean
        rm -f memdisk .depend
 
+%.o: %.asm
+       $(NASM) -f elf -l $*.lst -o $@ $<
+
 %.o16: %.s16
        $(AS) -o $@ $<
 
+%.o: %.c
+       $(CC) $(INCLUDE) $(CFLAGS) -c -o $@ $<
+
 %.s16: %.s
        echo '.code16gcc' | cat - $< > $@
 
@@ -69,12 +77,17 @@ spotless: clean
 %.bin: %.asm
        $(NASM) -f bin $(NINCLUDE) -o $@ -l $*.lst $<
 
-memdisk.elf: $(OBJS)
+memdisk16.elf: $(OBJS16)
        $(LD) -Ttext 0 -o $@ $^
 
-memdisk: memdisk.elf postprocess.pl
+memdisk32.elf: $(OBJS32)
+       $(LD) -Ttext 0x100000 -o $@ $^
+
+%.bin: %.elf
        $(OBJCOPY) -O binary $< $@
-       $(PERL) postprocess.pl $@
+
+memdisk: memdisk16.bin memdisk32.bin postprocess.pl
+       $(PERL) postprocess.pl $@ memdisk16.bin memdisk32.bin
 
 e820test: e820func.o msetup.o e820test.o memdisk.o
        $(CC) $(LDFLAGS) -o $@ $^
index 1efe724..34a75b3 100644 (file)
  */
 
 #include <stdint.h>
+#include "memdisk.h"
 #include "conio.h"
 
 int putchar(int ch)
 {
+  com32sys_t regs;
+
   if ( ch == '\n' ) {
     /* \n -> \r\n */
-    asm volatile("movw $0x0e0d,%%ax ; "
-                "movw $0x0007,%%bx ; "
-                "int $0x10"
-                ::: "eax", "ebx", "ecx", "edx",
-                "esi", "edi", "ebp");
+    putchar('\r');
   }
   
-  {
-    uint16_t ax = 0x0e00|(ch&0xff);
-    asm volatile("movw $0x0007,%%bx ; "
-                "int $0x10"
-                : "+a" (ax)
-                :: "ebx", "ecx", "edx", "esi", "edi", "ebp");
-  }
+  regs.eax.w[0] = 0x0e00|(ch&0xff);
+  syscall(0x10, &regs, NULL);
 
   return ch;
 }
index 2d10a35..813893c 100644 (file)
@@ -1,7 +1,7 @@
 #ident "$Id$"
 /* ----------------------------------------------------------------------- *
  *   
- *   Copyright 2001 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2001-2003 H. Peter Anvin - All Rights Reserved
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -22,6 +22,8 @@
 #include <inttypes.h>
 #include "e820.h"
 
+void *sys_bounce;              /* Dummy */
+
 extern void parse_mem(void);
 extern uint32_t dos_mem, low_mem, high_mem;
 
index d4332d7..a70f08d 100644 (file)
@@ -19,6 +19,8 @@
  * This module *MUST* get linked first into the image
  */
 
+#include "version.h"
+
                .text
                .code16
 
@@ -159,15 +161,15 @@ endcmd:
                xorb %al,%al
                stosb %al,%es:(%di)
 /*
- * Jump to C code
+ * Jump to 32-bit code
  */
-               sti                     # Maybe not?
-               calll setup             # Call the C code
+               sti
+               call init32             # Call the 32-bit code
                # The setup function returns the drive number,
                # which should be returned in %dl
                movw %ax,%dx
 
-               # If the C code returns, we are good to go, and the
+               # If the 32-bit code returns, we are good to go, and the
                # new boot sector is already loaded
                cli
                movw $0x7c00,%sp
@@ -178,3 +180,10 @@ endcmd:
                movw %si,%gs
                movw %si,%ss
                ljmp $0,$0x7c00         # Entrypoint at 0000:7C00
+
+               .section ".rodata","a"
+memdisk_version:
+               .ascii "MEMDISK " VERSION " " DATE
+               .ascii "Copyright " FIRSTYEAR "-" COPYYEAR " H. Peter Anvin"
+               .byte 0
+
index b54968d..c149d62 100644 (file)
@@ -1,7 +1,7 @@
 #ident "$Id$"
 /* ----------------------------------------------------------------------- *
  *   
- *   Copyright 2001 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2001-2003 H. Peter Anvin - All Rights Reserved
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
 #ifndef MEMDISK_H
 #define MEMDISK_H
 
+/* We use the com32 interface for calling 16-bit code */
+#include <com32.h>
+
+/* The real-mode segment */
+#define LOW_SEG 0x0800
+
+typedef void (*syscall_t)(uint8_t, com32sys_t *, com32sys_t *);
+extern syscall_t syscall;
+extern void *sys_bounce;
+
 /* What to call when we're dead */
 extern void __attribute__((noreturn)) die(void);
 
+/* Standard routines */
+#define memcpy(a,b,c) __builtin_memcpy(a,b,c)
+#define memset(a,b,c) __builtin_memset(a,b,c)
+
 #endif
index 3c0b1c7..ba3a0bd 100644 (file)
@@ -1,7 +1,7 @@
 #ident "$Id$"
 /* ----------------------------------------------------------------------- *
  *   
- *   Copyright 2001 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2001-2003 H. Peter Anvin - All Rights Reserved
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -28,66 +28,64 @@ static inline int get_e820(void)
     uint64_t base;
     uint64_t len;
     uint32_t type;
-  };
-  struct e820_info buf;
-  uint32_t lastptr = 0;
+  } *buf = sys_bounce;
   uint32_t copied;
   int range_count = 0;
-  uint32_t eax, edx;
+  com32sys_t regs;
+
+  memset(&regs, 0, sizeof regs);
 
   do {
-    copied = sizeof(buf);
-    eax = 0x0000e820;
-    edx = 0x534d4150;
-    
-    asm volatile("int $0x15 ; "
-                "jnc 1f ; "
-                "xorl %0,%0\n"
-                "1:"
-                : "+c" (copied), "+b" (lastptr),
-                "+a" (eax), "+d" (edx)
-                : "D" (&buf)
-                : "esi", "ebp");
+    regs.eax.l = 0x0000e820;
+    regs.ecx.l = sizeof(*buf);
+    regs.edx.l = 0x534d4150;
+    regs.edi.w[0] = OFFS(buf);
+    regs.es = SEG(buf);
+  
+    syscall(0x15, &regs, &regs);
+    copied = (regs.eflags.l & 1) ? 0 : regs.ecx.l;
     
-    if ( eax != 0x534d4150 || copied < 20 )
+    if ( regs.eax.l != 0x534d4150 || copied < 20 )
       break;
     
-    insertrange(buf.base, buf.len, buf.type);
+    printf("e820: %08x%08x %08x%08x %d\n",
+          (uint32_t)(buf->base >> 32), (uint32_t)buf->base,
+          (uint32_t)(buf->len >> 32), (uint32_t)buf->len,
+          buf->type);
+
+    insertrange(buf->base, buf->len, buf->type);
     range_count++;
 
-  } while ( lastptr );
+  } while ( regs.ebx.l );
 
   return !range_count;
 }
 
 static inline void get_dos_mem(void)
 {
-  uint16_t dos_kb;
+  com32sys_t regs;
 
-  asm volatile("int $0x12" : "=a" (dos_kb)
-              :: "ebx", "ecx", "edx", "esi", "edi", "ebp");
-
-  insertrange(0, (uint64_t)((uint32_t)dos_kb << 10), 1);
+  memset(&regs, 0, sizeof regs);
+  syscall(0x12, &regs, &regs);
+  insertrange(0, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1);
 }
 
 static inline int get_e801(void)
 {
-  uint16_t low_mem;
-  uint16_t high_mem;
-  uint8_t err;
-
-  asm volatile("movw $0xe801, %%ax ; "
-              "int $0x15 ; "
-              "setc %2"
-              : "=a" (low_mem), "=b" (high_mem), "=d" (err)
-              :: "ecx", "esi", "edi", "ebp");
-
-  if ( !err ) {
-    if ( low_mem ) {
-      insertrange(0x100000, (uint64_t)((uint32_t)low_mem << 10), 1);
+  int err;
+  com32sys_t regs;
+
+  memset(&regs, 0, sizeof regs);
+
+  regs.eax.w[0] = 0xe801;
+  syscall(0x15, &regs, &regs);
+
+  if ( !(err = regs.eflags.l & 1) ) {
+    if ( regs.eax.w[0] ) {
+      insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1);
     }
-    if ( high_mem ) {
-      insertrange(0x1000000, (uint64_t)((uint32_t)high_mem << 16), 1);
+    if ( regs.ebx.w[0] ) {
+      insertrange(0x1000000, (uint64_t)((uint32_t)regs.ebx.w[0] << 16), 1);
     }
   }
 
@@ -96,18 +94,18 @@ static inline int get_e801(void)
 
 static inline int get_88(void)
 {
-  uint16_t low_mem;
-  uint8_t err;
-
-  asm volatile("movb $0x88,%%ah ; "
-              "int $0x15 ; "
-              "setc %1"
-              : "=a" (low_mem), "=d" (err)
-              :: "ebx", "ecx", "esi", "edi", "ebp");
-
-  if ( !err ) {
-    if ( low_mem ) {
-      insertrange(0x100000, (uint64_t)((uint32_t)low_mem << 10), 1);
+  com32sys_t regs;
+  int err;
+
+  memset(&regs, 0, sizeof regs);
+
+  regs.eax.b[1] = 0x88;
+  syscall(0x15, &regs, &regs);
+
+
+  if ( !(err = regs.eflags.l & 1) ) {
+    if ( regs.eax.w[0] ) {
+      insertrange(0x100000, (uint64_t)((uint32_t)regs.eax.w[0] << 10), 1);
     }
   }
 
index 894c8b0..a3f823d 100755 (executable)
 # Postprocess the memdisk binary.
 #
 
-($file) = @ARGV;
+eval { use bytes; };
 
-open(FILE, "+< $file\0") or die "$0: Cannot open file: $file\n";
+($out,$file16,$file32) = @ARGV;
+
+open(OUT, "> $out\0") or die "$0: Cannot create file: $out\n";
+open(FILE, "< $file16\0") or die "$0: Cannot open file: $file16\n";
 
 @info = stat(FILE);
 $size = $info[7];
@@ -26,16 +29,28 @@ $size = $info[7];
 $sectors = ($size + 511) >> 9;
 $xsize = $sectors << 9;
 
-seek(FILE, $size, SEEK_SET);
+read(FILE, $f16, $size);
+
+print OUT $f16;
 
 if ( $size != $xsize ) {
     # Pad to a sector boundary
-    print FILE "\0" x ($xsize-$size);
+    print OUT "\0" x ($xsize-$size);
 }
 
-seek(FILE, 0x1f1, SEEK_SET);   # setup_sects
+seek(OUT, 0x1f1, SEEK_SET);    # setup_sects
 # All sectors are setup except the first
-print FILE pack("C", $sectors-1);
+print OUT pack("C", $sectors-1);
+
+seek(OUT, $xsize, SEEK_SET);
+close(FILE);
+
+open(FILE, "+< $file32\0") or die "$0: Cannot open file: $file32\n";
+
+while ( ($n = read(FILE, $f32, 65536)) > 0 ) {
+    print OUT $f32;
+}
 
 close(FILE);
+close(OUT);
 
index 473d005..50e6a96 100644 (file)
@@ -15,6 +15,7 @@
 #include "e820.h"
 #include "conio.h"
 #include "version.h"
+#include "memdisk.h"
 
 /* A pointer to this is stored in the header */
 const char memdisk_version[] =
@@ -116,112 +117,40 @@ struct setup_header {
   uint32_t initrd_addr_max;
 };
 
-const struct setup_header * const shdr = (struct setup_header *)0;
+const struct setup_header * const shdr = (struct setup_header *)(LOW_SEG << 4);
 
 /* Access to high memory */
 
-struct high_mover {
-  uint32_t resv1[4];           /* For the BIOS */
-  uint16_t src_limit;          /* 0xffff */
-  uint16_t src01;              /* Bytes 0-1 of src */
-  uint8_t src2;                        /* Byte 2 of src */
-  uint8_t src_perms;           /* 0x93 */
-  uint8_t src_xperms;          /* 0x00 */
-  uint8_t src3;                        /* Byte 3 of src */
-  uint16_t dst_limit;          /* 0xffff */
-  uint16_t dst01;              /* Bytes 0-1 of dst */
-  uint8_t dst2;                        /* Byte 2 of dst */
-  uint8_t dst_perms;           /* 0x93 */
-  uint8_t dst_xperms;          /* 0x00 */
-  uint8_t dst3;                        /* Byte 3 of dst */
-  uint32_t resv2[4];           /* For the BIOS */
-};
-
-/* Note: this version of high_bcopy() is limited to 64K */
-static void high_bcopy(uint32_t dst, uint32_t src, uint16_t len)
-{
-  static struct high_mover high_mover = 
-  {
-    { 0, 0, 0, 0 },
-    0xffff, 0, 0, 0x93, 0x00, 0,
-    0xffff, 0, 0, 0x93, 0x00, 0,
-    { 0, 0, 0, 0 }
-  };
-  
-  high_mover.src01 = (uint16_t)src;
-  high_mover.src2  = src >> 16;
-  high_mover.src3  = src >> 24;
-
-  high_mover.dst01 = (uint16_t)dst;
-  high_mover.dst2  = dst >> 16;
-  high_mover.dst3  = dst >> 24;
-
-  asm volatile("pushal ; "
-              "pushfl ; "
-              "movb $0x87,%%ah ; "
-              "int $0x15 ; "
-              "popfl ; "
-              "popal"
-              :: "S" (&high_mover), "c" (len >> 1)
-              : "memory");
-}
-
-#define LOWSEG 0x0800          /* Should match init.S16 */
-
-static inline uint32_t
-ptr2linear(void *ptr)
-{
-  return (LOWSEG << 4) + (uint32_t)ptr;
-}
-
-static inline void
-copy_to_high(uint32_t dst, void *src, uint16_t len)
-{
-  high_bcopy(dst, ptr2linear(src), len);
-}
-
-static inline void
-copy_from_high(void *dst, uint32_t src, uint16_t len)
-{
-  high_bcopy(ptr2linear(dst), src, len);
-}
-
 /* Access to objects in the zero page */
 static inline void
 wrz_8(uint32_t addr, uint8_t data)
 {
-  asm volatile("movb %0,%%fs:%1" :: "ri" (data), "m" (*(uint8_t *)addr));
+  *((uint8_t *)addr) = data;
 }
 static inline void
 wrz_16(uint32_t addr, uint16_t data)
 {
-  asm volatile("movw %0,%%fs:%1" :: "ri" (data), "m" (*(uint16_t *)addr));
+  *((uint16_t *)addr) = data;
 }
 static inline void
 wrz_32(uint32_t addr, uint32_t data)
 {
-  asm volatile("movl %0,%%fs:%1" :: "ri" (data), "m" (*(uint32_t *)addr));
+  *((uint32_t *)addr) = data;
 }
 static inline uint8_t
 rdz_8(uint32_t addr)
 {
-  uint8_t data;
-  asm volatile("movb %%fs:%1,%0" : "=r" (data) : "m" (*(uint8_t *)addr));
-  return data;
+  return *((uint8_t *)addr);
 }
 static inline uint16_t
 rdz_16(uint32_t addr)
 {
-  uint16_t data;
-  asm volatile("movw %%fs:%1,%0" : "=r" (data) : "m" (*(uint16_t *)addr));
-  return data;
+  return *((uint16_t *)addr);
 }
 static inline uint32_t
 rdz_32(uint32_t addr)
 {
-  uint32_t data;
-  asm volatile("movl %%fs:%1,%0" : "=r" (data) : "m" (*(uint32_t *)addr));
-  return data;
+  return *((uint32_t *)addr);
 }
 
 /* Addresses in the zero page */
@@ -363,7 +292,7 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
   hd_geometry.offset  = offset;
 
   /* Do we have a DOSEMU header? */
-  copy_from_high(&dosemu, where+hd_geometry.offset, sizeof dosemu);
+  memcpy(&dosemu, (char *)where+hd_geometry.offset, sizeof dosemu);
   if ( !__builtin_memcmp("DOSEMU", dosemu.magic, 7) ) {
     /* Always a hard disk unless overruled by command-line options */
     hd_geometry.driveno = 0x80;
@@ -396,7 +325,7 @@ const struct geometry *get_disk_image_geometry(uint32_t where, uint32_t size)
   if ( (hd_geometry.c == 0) || (hd_geometry.h == 0) ||
        (hd_geometry.s == 0) ) {
     /* Hard disk image, need to examine the partition table for geometry */
-    copy_from_high(&ptab, where+hd_geometry.offset+(512-2-4*16), sizeof ptab);
+    memcpy(&ptab, (char *)where+hd_geometry.offset+(512-2-4*16), sizeof ptab);
     
     max_c = max_h = 0;  max_s = 1;
     for ( i = 0 ; i < 4 ; i++ ) {
@@ -452,14 +381,17 @@ void __attribute__((noreturn)) die(void)
     asm volatile("hlt");
 }
 
-#define STACK_NEEDED   128     /* Number of bytes of stack */
+#define STACK_NEEDED   256     /* Number of bytes of stack */
 
 /*
  * Actual setup routine
  * Returns the drive number (which is then passed in %dl to the
  * called routine.)
  */
-uint32_t setup(void)
+syscall_t syscall;
+void *sys_bounce;
+
+uint32_t setup(syscall_t cs_syscall, void *cs_bounce)
 {
   unsigned int bin_size = (int) &_binary_memdisk_bin_size;
   struct memdisk_header *hptr;
@@ -468,10 +400,13 @@ uint32_t setup(void)
   uint32_t driverptr, driveraddr;
   uint16_t dosmem_k;
   uint32_t stddosmem;
-  uint8_t status;
-  uint16_t exitcode;
   const struct geometry *geometry;
   int total_size;
+  com32sys_t regs;
+
+  /* Set up global variables */
+  syscall = cs_syscall;
+  sys_bounce = cs_bounce;
 
   /* Show signs of life */
   printf("%s  %s\n", memdisk_version, copyright);
@@ -612,62 +547,34 @@ uint32_t setup(void)
   }
 
   /* Query drive parameters of this type */
-  {
-    uint16_t bpt_es, bpt_di;
-    uint8_t cf, dl;
-
-    asm volatile("pushw %%es ; "
-                "xorw %1,%1 ; "
-                "movw %1,%%es ; "
-                "movb $0x08,%%ah ; "
-                "int $0x13 ; "
-                "setc %2 ; "
-                "movw %%es,%0 ;"
-                "popw %%es"
-                : "=a" (bpt_es), "=D" (bpt_di),
-                "=c" (cf), "=d" (dl)
-                : "d" (geometry->driveno & 0x80)
-                : "esi", "ebx", "ebp");
-
-    if ( cf ) {
-      printf("INT 13 08: Failure, assuming this is the only drive\n");
-      pptr->drivecnt = 1;
-    } else {
-      printf("INT 13 08: Success, count = %u, BPT = %04x:%04x\n",
-            dl, bpt_es, bpt_di);
-      pptr->drivecnt = dl+1;
-    }
+  memset(&regs, 0, sizeof regs);
+  regs.es = 0;
+  regs.eax.b[1] = 0x08;
+  regs.edx.b[0] = geometry->driveno;
+  syscall(0x13, &regs, &regs);
+  
+  if ( regs.eflags.l & 1 ) {
+    printf("INT 13 08: Failure, assuming this is the only drive\n");
+    pptr->drivecnt = 1;
+  } else {
+    printf("INT 13 08: Success, count = %u, BPT = %04x:%04x\n",
+          regs.edx.b[0], regs.es, regs.edi.w[0]);
+    pptr->drivecnt = regs.edx.b[0]+1;
   }
 
   /* Copy driver followed by E820 table */
-  asm volatile("pushal ; "
-              "pushw %%es ; "
-              "movw %0,%%es ; "
-              "cld ; "
-              "rep ; movsl %%ds:(%%si), %%es:(%%di) ; "
-              "movw %1,%%cx ; "
-              "movw %2,%%si ; "
-              "rep ; movsl %%ds:(%%si), %%es:(%%di) ; "
-              "popw %%es ; "
-              "popal"
-              :: "r" (driverseg),
-              "r" ((uint16_t)((nranges+1)*3)), /* 3 dwords/range */
-              "r" ((uint16_t)&ranges),
-              "c" (bin_size >> 2),
-              "S" (&_binary_memdisk_bin_start),
-              "D" (0));
+  memcpy((void *)(driverseg << 4), &_binary_memdisk_bin_start, bin_size);
+  memcpy((void *)((driverseg << 4) + bin_size), ranges, (nranges+1)*3);
 
   /* Install the interrupt handlers */
-  {
-    printf("old: int13 = %08x  int15 = %08x\n",
-          rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
-
-    wrz_32(BIOS_INT13, driverptr+hptr->int13_offs);
-    wrz_32(BIOS_INT15, driverptr+hptr->int15_offs);
-
-    printf("new: int13 = %08x  int15 = %08x\n",
-          rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
-  }
+  printf("old: int13 = %08x  int15 = %08x\n",
+        rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
+  
+  wrz_32(BIOS_INT13, driverptr+hptr->int13_offs);
+  wrz_32(BIOS_INT15, driverptr+hptr->int15_offs);
+  
+  printf("new: int13 = %08x  int15 = %08x\n",
+        rdz_32(BIOS_INT13), rdz_32(BIOS_INT15));
 
   /* Update various BIOS magic data areas (gotta love this shit) */
 
@@ -675,7 +582,6 @@ uint32_t setup(void)
     /* Update BIOS hard disk count */
     wrz_8(BIOS_HD_COUNT, rdz_8(BIOS_HD_COUNT)+1);
   } else {
-#if 1                          /* Apparently this is NOT wanted... */
     /* Update BIOS floppy disk count */
     uint8_t equip = rdz_8(BIOS_EQUIP);
     if ( equip & 1 ) {
@@ -687,41 +593,31 @@ uint32_t setup(void)
       equip &= ~(3 << 6);
     }
     wrz_8(BIOS_EQUIP, equip);
-#endif
   }
 
-  /* Reboot into the new "disk" */
-  asm volatile("pushl %%ebp ; "
-              "pushl %%edx ; "
-              "pushw %%es ; "
-              "xorw %%cx,%%cx ; "
-              "movw %%cx,%%es ; "
-              "incw %%cx ; "
-              "movw $0x0201,%%ax ; "
-              "movw $0x7c00,%%bx ; "
-              "int $0x13 ; "
-              "popw %%es ; "
-              "popl %%edx ; "
-              "popl %%ebp ; "
-              "setc %0"
-              : "=rm" (status), "=a" (exitcode)
-              : "d" ((uint16_t)geometry->driveno)
-              : "ecx", "ebx", "esi", "edi");
-
-  if ( status ) {
+  /* Reboot into the new "disk"; this is also a test for the interrupt hooks */
+  puts("Loading boot sector... ");
+
+  memset(&regs, 0, sizeof regs);
+  // regs.es = 0;
+  regs.eax.w[0] = 0x0201;      /* Read sector */
+  regs.ebx.w[0] = 0x7c00;      /* 0000:7C00 */
+  regs.ecx.w[0] = 1;           /* One sector */
+  regs.edx.w[0] = geometry->driveno;
+  syscall(0x13, &regs, &regs);
+
+  if ( regs.eflags.l & 1 ) {
     puts("MEMDISK: Failed to load new boot sector\n");
     die();
   }
   
   if ( getcmditem("pause") != CMD_NOTFOUND ) {
     puts("Press any key to boot... ");
-    asm volatile("pushal ; "
-                "xorw %ax,%ax ; "
-                "int $0x16 ; "
-                "popal");
+    regs.eax.w[0] = 0;
+    syscall(0x16, &regs, NULL);
   }
 
-  puts("Booting...\n");
+  puts("booting...\n");
 
   /* On return the assembly code will jump to the boot vector */
   return geometry->driveno;