summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--bcopy32.inc51
-rw-r--r--bootsect.inc102
-rw-r--r--comboot.inc18
-rw-r--r--isolinux.asm21
-rw-r--r--ldlinux.asm74
-rw-r--r--loadhigh.inc1
-rw-r--r--pxelinux.asm25
-rw-r--r--runkernel.inc5
9 files changed, 196 insertions, 104 deletions
diff --git a/NEWS b/NEWS
index 91ad69d1..94a35b7e 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,9 @@ apply to that specific program only; other changes apply to both.
Changes in 1.73:
* Work on removing gratuitous differences between modules.
* Break up the source in common and module-specific files.
+ * PXELINUX: Allow chaining of other PXE NBPs.
+ * ISOLINUX: Allow loading "CD-ROM boot sectors".
+ * ALL: generalize the definition of a boot sector/NBP.
Changes in 1.72:
* PXELINUX, ISOLINUX: Fix bugs in the new core code.
diff --git a/bcopy32.inc b/bcopy32.inc
index daa061e9..4910fbb0 100644
--- a/bcopy32.inc
+++ b/bcopy32.inc
@@ -45,6 +45,21 @@ bcopy_gdt: dw bcopy_gdt_size-1 ; Null descriptor - contains GDT
dd 00009300h ; present, dpl 0, cover 64K
bcopy_gdt_size: equ $-bcopy_gdt
+;
+; bcopy:
+; 32-bit copy
+;
+; Inputs:
+; ESI - source pointer
+; EDI - target pointer
+; ECX - byte count
+; DF - zero
+;
+; Outputs:
+; ESI - first byte after source
+; EDI - first byte after target
+; ECX - zero
+;
bcopy: push eax
pushf ; Saves, among others, the IF flag
push gs
@@ -72,8 +87,19 @@ bcopy: push eax
mov ss,ax
mov fs,ax
mov gs,ax
-
+
+ mov al,cl ; Save low bits
+ shr ecx,2 ; Convert to dwords
a32 rep movsd ; Do our business
+
+ test al,2
+ jz .noword
+ a32 movsw
+.noword:
+ test al,1
+ jz .nobyte
+ a32 movsb
+.nobyte:
mov es,ax ; Set to "real-mode-like"
mov ds,ax
@@ -350,10 +376,15 @@ try_wbinvd:
; After performing the copy, this routine resets the stack and
; jumps to 0:7c00.
;
+; IMPORTANT: This routine does not canonicalize the stack or the
+; SS register. That is the responsibility of the caller.
+;
; Inputs:
; ESI, EDI, ECX - same as bcopy
; EDX - edx on invocation
; EAX - esi on invocation
+; EBX - ebx on invocation
+; ES - es on invocation
;
%define ADJUST (__bcopy_start - trackbuf)
@@ -366,20 +397,20 @@ adjlist dw bcopy_gdt.adj1 - ADJUST
adjlist_cnt equ ($-adjlist)/2
bcopy_over_self:
- cli
- cld
- xor bx,bx
- mov ds,bx
- mov es,bx
- mov ss,bx
- mov sp,7c00h
-
+ push es
+ push ebx
push eax
push edx
push esi
push edi
push ecx
+ xor bx,bx
+ mov es,bx
+ mov ds,bx
+ mov fs,bx
+ mov gs,bx
+
mov si,__bcopy_start
mov di,trackbuf
mov cx,(__bcopy_end - __bcopy_start + 3) >> 2
@@ -410,5 +441,7 @@ bcopy_over_self:
pop edx
pop esi
+ pop ebx
+ pop es
jmp 0:7c00h
__bcopy_end:
diff --git a/bootsect.inc b/bootsect.inc
new file mode 100644
index 00000000..4546eda2
--- /dev/null
+++ b/bootsect.inc
@@ -0,0 +1,102 @@
+;; $Id$
+;; -----------------------------------------------------------------------
+;;
+;; Copyright 1994-2002 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.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; bootsect.inc
+;;
+;; Load a boot sector (or other bootstrap program.)
+;;
+;; Unlike previous versions of this software, this doesn't require that
+;; the length is 512 bytes. This allows PXE bootstraps and WinNT
+;; "CD boot sectors" to be invoked.
+;;
+
+;
+; Load a boot sector
+;
+is_bootsector:
+%if IS_SYSLINUX
+ ; Transfer zero bytes
+ xor cx,cx
+ jmp short load_bootsec
+is_bss_sector:
+ ; Transfer the superblock
+ mov cx,superblock_len
+load_bootsec:
+ push cx
+%endif
+ xchg dx,ax
+ shr eax,16
+ xchg dx,ax ; Now EAX = file length
+ mov edi, 100000h
+ call load_high
+
+%if IS_SYSLINUX
+ pop cx
+%endif
+
+ sub edi,100000h
+ push edi ; Save length
+
+%if IS_SYSLINUX
+ 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
+%if IS_SYSLINUX
+ mov dl,[bsDriveNumber]
+
+ mov si,PartInfo
+ mov di,800h-18 ; Put partition info here
+ push di
+ mov cx,8 ; 16 bytes
+ rep movsw
+ pop ax ; DS:SI points to partition info
+%elif IS_ISOLINUX
+ mov dl,[DriveNo]
+%endif
+
+ mov esi,7C00h
+ mov edi,100000h
+ pop ecx ; Byte count
+
+ cli
+ xor ebx,ebx
+ mov ds,bx
+%if IS_PXELINUX
+ lss sp,[Stack] ; Reset stack to PXE original
+ les bx,[InitESBX] ; ES:BX -> PXENV+
+%else
+ mov es,bx
+ mov esp,esi
+%endif
+ jmp bcopy_over_self
+
+%if IS_SYSLINUX = 0
+is_bss_image:
+ mov si,err_bssimage
+ call cwritestr
+ jmp enter_command
+%endif
diff --git a/comboot.inc b/comboot.inc
index db199145..fbda0973 100644
--- a/comboot.inc
+++ b/comboot.inc
@@ -17,6 +17,12 @@
;; Common code for running a COMBOOT image
;;
+; Looks like a COMBOOT image but too large
+comboot_too_large:
+ mov si,err_comlarge
+ call cwritestr
+cb_enter: jmp enter_command
+
;
; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
; except that it may, of course, not contain any DOS system calls. We
@@ -24,7 +30,7 @@
;
is_comboot_image:
and dx,dx
- jnz near comboot_too_large
+ jnz comboot_too_large
cmp ax,0ff00h ; Max size in bytes
jae comboot_too_large
@@ -86,12 +92,6 @@ comboot_end_cmd: mov al,0Dh ; CR after last character
jmp comboot_seg:100h ; Run it
-; Looks like a COMBOOT image but too large
-comboot_too_large:
- mov si,err_comlarge
- call cwritestr
-cb_enter: jmp enter_command
-
; Proper return vector
comboot_return: cli ; Don't trust anyone
lss sp,[cs:SavedSSSP]
@@ -99,7 +99,7 @@ comboot_return: cli ; Don't trust anyone
mov es,ax
sti
cld
- jmp short cb_enter
+ jmp cb_enter
; Attempted to execute DOS system call
comboot_bogus: cli ; Don't trust anyone
@@ -112,5 +112,5 @@ comboot_bogus: cli ; Don't trust anyone
call cwritestr
mov si,err_notdos
call cwritestr
- jmp short cb_enter
+ jmp cb_enter
diff --git a/isolinux.asm b/isolinux.asm
index f560e117..d9e6682c 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -1194,9 +1194,11 @@ kernel_corrupt: mov si,err_notkernel
;
; .com - COMBOOT image
; .cbt - COMBOOT image
-; .bs - Boot sector (SYSLINUX only)
-; .bss - DOS boot sector (SYSLINUX only)
-; .img - Disk image (ISOLINUX only)
+; .bs - Boot sector
+; .0 - PXE bootstrap program (PXELINUX only)
+; .bin - Boot sector
+; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only)
+; .img - Floppy image (ISOLINUX only)
;
; Anything else is assumed to be a Linux kernel.
;
@@ -1234,10 +1236,12 @@ kernel_good:
cmp ecx,'.img'
je near is_disk_image
cmp ecx,'.bss'
- je near is_bss_sector
+ je near is_bss_image
and ecx, 00ffffffh
cmp ecx,'.bs'
je near is_bootsector
+ cmp cx,'.0'
+ je near is_bootsector
; Otherwise Linux kernel
;
@@ -1251,12 +1255,9 @@ kernel_good:
%include "comboot.inc"
;
-; Load a boot sector
+; Boot sector loading code
;
-is_bootsector:
-is_bss_sector:
- ; Can't load these from the network, dang it!
-.badness: jmp short .badness
+%include "bootsect.inc"
;
; Enable disk emulation. The kind of disk we emulate is dependent on the size of
@@ -1911,7 +1912,7 @@ err_oldkernel db 'Cannot load a ramdisk with an old kernel image.'
db CR, LF, 0
err_notdos db ': attempted DOS system call', CR, LF, 0
err_comlarge db 'COMBOOT image too large.', CR, LF, 0
-err_bootsec db 'Invalid or corrupt boot sector image.', CR, LF, 0
+err_bssimage db 'BSS images not supported.', CR, LF, 0
err_a20 db CR, LF, 'A20 gate not responding!', CR, LF, 0
notfound_msg db 'not found', CR, LF, 0
localboot_msg db 'Booting from local disk...', CR, LF, 0
diff --git a/ldlinux.asm b/ldlinux.asm
index af4243ad..ec8157d1 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -1345,10 +1345,13 @@ kernel_corrupt: mov si,err_notkernel
; that decision on the file extension. The following extensions are
; recognized:
;
-; .COM - COMBOOT image
-; .CBT - COMBOOT image
-; .BS - Boot sector
-; .BSS - Boot sector, but transfer over DOS superblock
+; .com - COMBOOT image
+; .cbt - COMBOOT image
+; .bs - Boot sector
+; .0 - PXE bootstrap program (PXELINUX only)
+; .bin - Boot sector
+; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only)
+; .img - Floppy image (ISOLINUX only)
;
; Anything else is assumed to be a Linux kernel.
;
@@ -1368,6 +1371,8 @@ kernel_good:
je near is_comboot_image
cmp ecx,'BS '
je near is_bootsector
+ cmp ecx,'BIN'
+ je near is_bootsector
cmp ecx,'BSS'
je near is_bss_sector
; Otherwise Linux kernel
@@ -1383,65 +1388,9 @@ kernel_good:
%include "comboot.inc"
;
-; Load a boot sector
-;
-is_bootsector:
- ; Transfer zero bytes
- push word 0
- jmp short load_bootsec
-is_bss_sector:
- ; Transfer the superblock
- push word superblock_len
-load_bootsec:
- and dx,dx
- jnz bad_bootsec
- mov bx,[bsBytesPerSec]
- cmp ax,bx
- jne bad_bootsec
-
- ; Make sure we don't test this uninitialized
- mov [bx+trackbuf-2],dx ; Note DX == 0
-
- mov bx,trackbuf
- mov cx,1 ; 1 cluster >= 1 sector
- call getfssec
-
- mov bx,[bsBytesPerSec]
- mov ax,[bx+trackbuf-2]
- cmp ax,0AA55h ; Boot sector signature
- jne bad_bootsec
-
- mov si,superblock
- mov di,trackbuf+(superblock-bootsec)
- pop cx ; Transfer count
- rep movsb
+; Boot sector loading code
;
-; Okay, here we go... copy over our own boot sector and run the new one
-;
- call vgaclearmode ; Reset video
-
- cli ; Point of no return
-
- mov dl,[bsDriveNumber] ; May not be in new bootsector!
-
- mov si,trackbuf
- mov di,bootsec
- mov cx,[bsBytesPerSec]
- rep movsb ; Copy the boot sector!
-
- mov si,PartInfo
- mov di,800h-18 ; Put partition info here
- push di
- mov cx,8 ; 16 bytes
- rep movsw
- pop si ; DS:SI points to partition info
-
- jmp bootsec
-
-bad_bootsec:
- mov si,err_bootsec
- call cwritestr
- jmp enter_command
+%include "bootsect.inc"
;
; abort_check: let the user abort with <ESC> or <Ctrl-C>
@@ -1774,7 +1723,6 @@ err_oldkernel db 'Cannot load a ramdisk with an old kernel image.'
db CR, LF, 0
err_notdos db ': attempted DOS system call', CR, LF, 0
err_comlarge db 'COMBOOT image too large.', CR, LF, 0
-err_bootsec db 'Invalid or corrupt boot sector image.', CR, LF, 0
err_a20 db CR, LF, 'A20 gate not responding!', CR, LF, 0
err_bootfailed db CR, LF, 'Boot failed: please change disks and press '
db 'a key to continue.', CR, LF, 0
diff --git a/loadhigh.inc b/loadhigh.inc
index c952ae87..a7757a7a 100644
--- a/loadhigh.inc
+++ b/loadhigh.inc
@@ -80,7 +80,6 @@ load_high:
inc ecx
jmp short .fix_slop
.noslop:
- shr ecx,2 ; Convert to dwords
push esi ; <D> File handle/cluster pointer
mov esi,(xfer_buf_seg << 4) ; Source address
call bcopy ; Copy to high memory
diff --git a/pxelinux.asm b/pxelinux.asm
index 8c83faca..3d1da266 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -198,6 +198,7 @@ RamdiskMax resd 1 ; Highest address for a ramdisk
KernelSize resd 1 ; Size of kernel (bytes)
SavedSSSP resd 1 ; Our SS:SP while running a COMBOOT image
Stack resd 1 ; Pointer to reset stack
+InitESBX resd 1 ; Initial ES:BX pointer
PXEEntry resd 1 ; !PXE API entry point
RebootTime resd 1 ; Reboot timeout, if set by option
KernelClust resd 1 ; Kernel size in clusters
@@ -275,6 +276,10 @@ _start1:
push fs
push gs
+ mov [cs:InitESBX],bx
+ mov bx,es
+ mov [cs:InitESBX+2],bx
+
mov bp,sp
les bx,[bp+48] ; Initial !PXE structure pointer
@@ -1111,7 +1116,10 @@ kernel_corrupt: mov si,err_notkernel
; .com - COMBOOT image
; .cbt - COMBOOT image
; .bs - Boot sector
-; .bss - Boot sector, but transfer over DOS superblock
+; .0 - PXE bootstrap program (PXELINUX only)
+; .bin - Boot sector
+; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only)
+; .img - Floppy image (ISOLINUX only)
;
; Boot sectors are currently not supported by PXELINUX.
;
@@ -1145,10 +1153,14 @@ kernel_good:
cmp ecx,'.cbt'
je near is_comboot_image
cmp ecx,'.bss'
- je near is_bss_sector
+ je near is_bss_image
+ cmp ecx,'.bin'
+ je near is_bootsector
and ecx, 00ffffffh
cmp ecx,'.bs'
je near is_bootsector
+ cmp cx,'.0'
+ je near is_bootsector
; Otherwise Linux kernel
;
; Linux kernel loading code is common. However, we need to define
@@ -1187,12 +1199,9 @@ kernel_good:
%include "comboot.inc"
;
-; Load a boot sector
+; Boot sector loading code
;
-is_bootsector:
-is_bss_sector:
- ; Can't load these from the network, dang it!
-.badness: jmp short .badness
+%include "bootsect.inc"
;
; Boot to the local disk by returning the appropriate PXE magic.
@@ -2327,7 +2336,7 @@ err_oldkernel db 'Cannot load a ramdisk with an old kernel image.'
db CR, LF, 0
err_notdos db ': attempted DOS system call', CR, LF, 0
err_comlarge db 'COMBOOT image too large.', CR, LF, 0
-err_bootsec db 'Invalid or corrupt boot sector image.', CR, LF, 0
+err_bssimage db 'BSS images not supported.', CR, LF, 0
err_a20 db CR, LF, 'A20 gate not responding!', CR, LF, 0
err_bootfailed db CR, LF, 'Boot failed: press a key to retry, or wait for reset...', CR, LF, 0
bailmsg equ err_bootfailed
diff --git a/runkernel.inc b/runkernel.inc
index cc1dfb1e..1240444c 100644
--- a/runkernel.inc
+++ b/runkernel.inc
@@ -44,7 +44,7 @@
;
is_linux_kernel:
cmp dx,80h ; 8 megs
- ja kernel_corrupt
+ ja near kernel_corrupt
and dx,dx
jnz kernel_sane
cmp ax,1024 ; Bootsect + 1 setup sect
@@ -323,7 +323,6 @@ read_kernel:
mov ecx,8000h ; 32K
sub ecx,esi ; Number of bytes to copy
push ecx
- shr ecx,2 ; Convert to dwords
add esi,(real_mode_seg << 4) ; Pointer to source
mov edi,100000h ; Copy to address 100000h
call bcopy ; Transfer to high memory
@@ -489,8 +488,6 @@ need_high_cmdline:
; Copy the kernel down to the "low" location
;
mov ecx,[KernelSize]
- add ecx,3 ; Round upwards
- shr ecx,2 ; Bytes -> dwords
mov esi,100000h
mov edi,10000h
call bcopy