Add a bootstrap chainloading API, and include a sample program for it.
authorhpa <hpa>
Wed, 26 Nov 2003 05:42:33 +0000 (05:42 +0000)
committerhpa <hpa>
Wed, 26 Nov 2003 05:42:33 +0000 (05:42 +0000)
NEWS
bootsect.inc
comboot.doc
comboot.inc
isolinux.asm
ldlinux.asm
pxelinux.asm
sample/Makefile
sample/fd.c [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 236ba35..d4e31a3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,9 @@ Changes in 2.08:
          (including file not found.)  This bug would cause us to run
          out of sockets and thus "go deaf" after a while.
        * MEMDISK: Add an API to query for the existence of MEMDISK.
+       * SYSLINUX: Fix loading boot sectors (.bs/.bss) from floppy
+         disk.
+       * .c32 is now one of the extensions searched for automatically.
 
 Changes in 2.07:
        * MEMDISK: Workaround for BIOSes which go into a snit when
index 24ebab6..f0dc260 100644 (file)
 is_bootsector:
 %if IS_SYSLINUX || IS_MDSLINUX
                ; Transfer zero bytes
-               xor cx,cx
+               mov byte [CopySuper],0
                jmp short load_bootsec
+
 is_bss_sector:
                ; Transfer the superblock
-               mov cx,superblock_len
-load_bootsec:
-               push cx
+               mov byte [CopySuper],superblock_len
 %endif
+load_bootsec:
                xchg dx,ax
                shl eax,16
                xchg dx,ax              ; Now EAX = file length
                mov edi, 100000h
+               push edi                ; Save load address
                call load_high
                call crlf
 
-%if IS_SYSLINUX || IS_MDSLINUX
-               pop cx
-%endif
-
                sub edi,100000h
                push edi                ; Save length
 
 %if IS_SYSLINUX || IS_MDSLINUX
+               movzx ecx,byte [CopySuper]
                jcxz .not_bss
 
                ; For a BSS boot sector we have to patch.
                mov esi,superblock
                mov edi,100000h+(superblock-bootsec)
-               movzx ecx,cx
                call bcopy
 
 .not_bss:
 %endif
-;
-; Prepare for shutting down
-;
-               call vgaclearmode
+
                xor edx,edx
-               xor eax,eax
+               xor esi,esi
 %if IS_SYSLINUX || IS_MDSLINUX
-               mov dl,[bsDriveNumber]
+               ; Restore original FDC table
+               mov eax,[OrigFDCTabPtr]
+               mov [fdctab],eax
 
-               mov si,PartInfo
+               mov dl,[bsDriveNumber]
+               mov si,PartInfo         ; Partition info buffer
                mov di,800h-18          ; Put partition info here
                push di
                mov cx,8                ; 16 bytes
+               xor ax,ax
                rep movsw
                pop si                  ; DS:SI points to partition info
 %elif IS_ISOLINUX
                mov dl,[DriveNo]
 %elif IS_PXELINUX
-               ; Close the UDP stack so the PXE stack is in a known state for
-               ; the new NBP
+               mov byte [KeepPXE],1    ; Chainloading another NBP
                call reset_pxe
 %endif
+               xor bx,bx
 
-               pop ecx                 ; Byte count to copy
+; 
+; Entrypoint for "shut down and replace bootstrap" -- also invoked by
+; the COMBOOT API.  This routine expects two dword on the stack:
+; linear address and length.  Additionally, the values of ESI and EDX
+; are passed on to the new bootstrap; the value of BX becomes the new
+; DS.
+; 
+replace_bootstrap:
+
+               ;
+               ; Prepare for shutting down
+               ;
+               call vgaclearmode
+
+               ;
+               ; Set up initial stack frame (not used by PXE if keeppxe is set)
+               ;
+               xor ax,ax
+               mov ds,ax
+               mov es,ax               
 
-               cli
-               xor ebx,ebx
-               mov ds,bx
-               mov es,bx
 %if IS_PXELINUX
-               lss sp,[InitStack]      ; Reset stack to PXE original
-%else
-               mov esp,7C00h
-               pushfd
-               pushad
-               push bx ; ds
-               push bx ; es
-               push bx ; fs
-               push bx ; gs
+               test byte [KeepPXE],01h
+               jz .stdstack
+               les di,[InitStack]      ; Reset stack to PXE original
+               jmp .stackok
 %endif
+.stdstack:
+               mov di,7C00h-44
+               push di
+               mov cx,22               ; 44 bytes
+               rep stosw
+               pop di
+.stackok:
+
+               mov [es:di+28],edx
+               mov [es:di+12],esi
+               mov [es:di+6],bx
 
-               mov esi,100000h         ; Copy from...
+               pop ecx                 ; Byte count to copy
+               pop esi                 ; Copy from...
+
+               cli
+               mov ax,es
+               mov ss,ax
+               movzx esp,di
                mov edi,7C00h           ; Copy to...
 
                jmp bcopy_over_self
index 5d1a954..768bf3c 100644 (file)
@@ -439,7 +439,7 @@ AX=000Ch    Perform final cleanup
        MAKE SURE TO DISABLE INTERRUPTS, AND INSTALL NEW GDT AND IDTS
        BEFORE OVERWRITING THESE MEMORY AREAS.
 
-       The permissible values for DX are as follows:
+       The permissible values for DX is an OR of these values:
 
        SYSLINUX:       0000h   Normal cleanup
 
@@ -450,3 +450,28 @@ AX=000Ch   Perform final cleanup
 
        All other values are undefined, and may have different
        meanings in future versions of SYSLINUX.
+
+
+AX=000Dh       Cleanup and replace bootstrap code
+       Input:  AX      000Ch
+               DX      derivative-specific flags (see previous function)
+               EDI     bootstrap code (linear address, can be in high memory)
+               ECX     bootstrap code length in bytes (max 
+               EBX(!)  initial value of EDX after bootstrap
+               ESI     initial value of ESI after bootstrap
+               DS      initial value of DS after bootstrap
+       Output: None
+
+       This routine performs final cleanup, then takes a piece of
+       code, copies it over the primary bootstrap at address 7C00h,
+       and jumps to it.  This can be used to chainload boot sectors,
+       MBRs, bootstraps, etc.
+
+       Normal boot sectors expect DL to contain the drive number,
+       and, for hard drives (DL >= 80h) DS:SI to contain a pointer to
+       the 16-byte partition table entry.  The memory between
+       600h-7FFh is available to put the partition table entry in.
+
+       For PXELINUX, if the PXE stack is not unloaded, all registers
+       (except DS, ESI and EDX) and the stack will be set up as they
+       were set up by the PXE ROM.
index c8dbff1..e421d67 100644 (file)
@@ -518,7 +518,9 @@ comapi_cleanup:
                ; Unload PXE if requested
                test dl,3
                setnz [KeepPXE]
+               sub bp,sp               ; unload_pxe may move the stack around
                call unload_pxe
+               add bp,sp               ; restore frame pointer...
 %elif IS_SYSLINUX || IS_MDSLINUX
                ; Restore original FDC table
                mov eax,[OrigFDCTabPtr]
@@ -531,6 +533,19 @@ comapi_cleanup:
                clc
                ret
 
+
+;
+; INT 22h AX=000Dh     Clean up then replace bootstrap
+;
+comapi_chainboot:
+               call comapi_cleanup
+               mov esi,P_ESI
+               mov edx,P_EBX
+               mov bx,P_DS
+               push P_EDI
+               push P_ECX
+               jmp replace_bootstrap
+
 ;
 ; This stuff should really be in the data section...
 ;
@@ -567,6 +582,7 @@ int22_table:
                dw comapi_derinfo               ; 000A derivative-specific info
                dw comapi_serialcfg             ; 000B get serial port config
                dw comapi_cleanup               ; 000C perform final cleanup
+               dw comapi_chainboot             ; 000D clean up then bootstrap
 int22_count    equ ($-int22_table)/2
 
 APIKeyWait     db 0
index ad1c324..57488cb 100644 (file)
@@ -224,6 +224,9 @@ Files               resb MAX_OPEN*open_file_t_size
 ;; loading the rest.
 ;;
 bootsec                equ $
+
+StackBuf       equ $-44
+
 _start:                ; Far jump makes sure we canonicalize the address
                cli
                jmp 0:_start1
@@ -241,7 +244,7 @@ _start1:    mov [cs:InitStack],sp           ; Save initial stack pointer
                mov [cs:InitStack+2],ss
                xor ax,ax
                mov ss,ax
-               mov sp,_start                   ; Set up stack
+               mov sp,StackBuf                 ; Set up stack
                mov ds,ax
                mov es,ax
                mov fs,ax
@@ -1578,6 +1581,7 @@ exten_table:      db '.cbt'               ; COMBOOT (specific)
                db '.img'               ; Disk image
                db '.bin'               ; CD boot sector
                db '.com'               ; COMBOOT (same as DOS)
+               db '.c32'               ; COM32
 exten_table_end:
                dd 0, 0                 ; Need 8 null bytes here
 
index 9bbaab9..13b9b36 100644 (file)
@@ -201,6 +201,7 @@ LoadFlags   resb 1                  ; Loadflags from kernel
 A20Tries       resb 1                  ; Times until giving up on A20
 FuncFlag       resb 1                  ; Escape sequences received from keyboard
 DisplayMask    resb 1                  ; Display modes mask
+CopySuper      resb 1                  ; Distinguish .bs versus .bss
 MNameBuf        resb 11                ; Generic mangled file name buffer
 InitRD          resb 11                 ; initrd= mangled name
 KernelCName     resb 13                 ; Unmangled kernel name
@@ -217,7 +218,7 @@ VGAFileMBuf resb 11                 ; Mangled VGA image name
 ; "close" to the initial stack pointer offset, in order to
 ; reduce the code size...
 ;
-StackBuf       equ $-32                ; Start the stack here (grow down - 4K)
+StackBuf       equ $-44-32             ; Start the stack here (grow down - 4K)
 PartInfo       equ StackBuf            ; Saved partition table entry
 FloppyTable    equ PartInfo+16         ; Floppy info table (must follow PartInfo)
 OrigFDCTabPtr  equ StackBuf-4          ; The high dword on the stack
@@ -1421,6 +1422,7 @@ exten_table:      db 'CBT',0              ; COMBOOT (specific)
                db 'BSS',0              ; Boot Sector (add superblock)
                db 'BS ',0              ; Boot Sector 
                db 'COM',0              ; COMBOOT (same as DOS)
+               db 'C32',0              ; COM32
 exten_table_end:
                dd 0, 0                 ; Need 8 null bytes here
 
index 7b16811..d53924b 100644 (file)
@@ -310,7 +310,7 @@ packet_buf_size     equ $-packet_buf
 
                section .text
                 org 7C00h
-StackBuf       equ $                   ; Base of stack if we use our own
+StackBuf       equ $-44                ; Base of stack if we use our own
 
 ;
 ; Primary entry point.
@@ -2432,6 +2432,7 @@ bootif_str_len    equ $-bootif_str
 exten_table:   db '.cbt'               ; COMBOOT (specific)
                db '.0', 0, 0           ; PXE bootstrap program
                db '.com'               ; COMBOOT (same as DOS)
+               db '.c32'               ; COM32
 exten_table_end:
                dd 0, 0                 ; Need 8 null bytes here
 
index 0bd4512..900acbd 100644 (file)
@@ -31,7 +31,7 @@ LIBOBJS          = conio.o
 
 .SUFFIXES: .lss .c .o .elf .c32
 
-all: syslogo.lss comecho.com hello.c32 hello2.c32 filetest.c32 c32echo.c32
+all: syslogo.lss comecho.com hello.c32 hello2.c32 filetest.c32 c32echo.c32 fd.c32
 
 %.o: %.S
        $(CC) $(SFLAGS) -c -o $@ $<
diff --git a/sample/fd.c b/sample/fd.c
new file mode 100644 (file)
index 0000000..03e13d1
--- /dev/null
@@ -0,0 +1,63 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 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
+ *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * fd.c
+ *
+ * Chainload a floppy disk (currently rather braindead.)
+ */
+
+#include <com32.h>
+#define NULL ((void *)0)
+
+int printf(const char *, ...);
+unsigned int atou(const char *);
+
+int __start(void)
+{
+  int whichfd = atou(__com32.cs_cmdline);
+  static com32sys_t inreg, outreg; /* In bss, so zeroed automatically */
+  int retry;
+
+  for ( retry = 0 ; retry < 6 ; retry++ ) {
+    printf(">");
+    inreg.eax.w[0] = 0x0201;   /* Read one sector */
+    inreg.ecx.w[0] = 0x0001;   /* Cyl 0 sector 1 */
+    inreg.edx.b[1] = 0;                /* Head 0 */
+    inreg.edx.b[0] = whichfd;  /* Drive number */
+    inreg.es = SEG(__com32.cs_bounce); /* Read into the bounce buffer */
+    inreg.ebx.w[0] = OFFS(__com32.cs_bounce);
+    __com32.cs_intcall(0x13, &inreg, &outreg);
+
+    if ( (outreg.eflags.l & 1) == 0 )
+      break;
+  }
+
+  if ( (outreg.eflags.l & 1) == 0 ) {
+    printf("!\n");
+    inreg.eax.w[0] = 0x000d;
+    inreg.edx.w[0] = 0;
+    inreg.edi.l    = (uint32_t) __com32.cs_bounce;
+    inreg.ecx.l    = 512;
+    inreg.ebx.l    = whichfd & 0xff;
+    inreg.esi.l    = 0;                /* No partitions */
+    inreg.ds       = 0;                /* No partitions */
+    __com32.cs_intcall(0x22, &inreg, NULL);
+  }
+
+  /* If we get here, badness happened */
+  return 255;
+}
+
+
+