(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
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
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
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.
; 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]
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...
;
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
;; loading the rest.
;;
bootsec equ $
+
+StackBuf equ $-44
+
_start: ; Far jump makes sure we canonicalize the address
cli
jmp 0:_start1
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
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
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
; "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
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
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.
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
.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 $@ $<
--- /dev/null
+#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;
+}
+
+
+