aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2005-01-06 22:34:06 +0000
committerhpa <hpa>2005-01-06 22:34:06 +0000
commita966e54c41674cfb72340fd436bdf85988c14dd7 (patch)
tree93d244d27e6c2f9a6bca7b2432ba66c841be57fb
parentfb7489b14bc413a373e4138157a34e2683a1aa26 (diff)
downloadsyslinux-elf-a966e54c41674cfb72340fd436bdf85988c14dd7.tar.gz
syslinux-elf-a966e54c41674cfb72340fd436bdf85988c14dd7.tar.xz
syslinux-elf-a966e54c41674cfb72340fd436bdf85988c14dd7.zip
Commit 3.10 changes to mainline. In particular, support multi-file
initrd, and the shuffle and boot API.
-rw-r--r--Makefile4
-rw-r--r--NEWS11
-rw-r--r--bcopy32.inc86
-rw-r--r--bootsect.inc36
-rw-r--r--com32.inc1
-rw-r--r--comboot.doc66
-rw-r--r--comboot.inc91
-rw-r--r--ext2_fs.inc6
-rw-r--r--kernel.inc2
-rw-r--r--loadhigh.inc5
-rw-r--r--memdisk/setup.c3
-rw-r--r--parseconfig.inc2
-rw-r--r--runkernel.inc215
-rw-r--r--version2
14 files changed, 384 insertions, 146 deletions
diff --git a/Makefile b/Makefile
index f6927c0f..3b361bed 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
## $Id$
## -----------------------------------------------------------------------
##
-## Copyright 1998-2004 H. Peter Anvin - All Rights Reserved
+## Copyright 1998-2005 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
@@ -50,7 +50,7 @@ VERSION = $(shell cat version)
# directories.
#
CSRC = syslxmod.c gethostip.c
-NASMSRC = ldlinux.asm copybs.asm pxelinux.asm mbr.asm isolinux.asm
+NASMSRC = $(wildcard *.asm)
SOURCES = $(CSRC) *.h $(NASMSRC) *.inc
# _bin.c files required by both BTARGET and ITARGET installers
diff --git a/NEWS b/NEWS
index b03b15d2..9d8735db 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,16 @@ Starting with 1.47, changes marked with SYSLINUX/PXELINUX/ISOLINUX
apply to that specific program only; other changes apply to all of
them.
-Changes in 3.03:
+Changes in 3.10:
+ * New API function "shuffle and boot"; allows COM32 modules to
+ load or construct (almost) arbitrarily complex objects,
+ e.g. a kernel and its initrd/initramfs in pieces, and have
+ the API core reorganize memory for booting.
+ * The initrd= option now supports multiple filenames separated
+ by commas. This is mostly useful for initramfs, which can
+ be composed of multiple separate cpio or cpio.gz archives.
+ (Note: all files except the last one are zero-padded to a 4K
+ page boundary. This should not affect initramfs.)
* EXTLINUX: Fix API function 000Ah (get derivative-specific
info).
* libcom32/ethersel: Support PCI Config Mechanism #2 on
diff --git a/bcopy32.inc b/bcopy32.inc
index 7d049b73..9eb782e2 100644
--- a/bcopy32.inc
+++ b/bcopy32.inc
@@ -1,7 +1,7 @@
;; $Id$
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2005 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
@@ -56,7 +56,7 @@ bcopy_gdt_size: equ $-bcopy_gdt
;
; bcopy:
-; 32-bit copy
+; 32-bit copy, overlap safe
;
; Inputs:
; ESI - source pointer
@@ -70,13 +70,12 @@ bcopy_gdt_size: equ $-bcopy_gdt
; ECX - zero
;
bcopy: push eax
+ push esi
+ push edi
+ push ecx
pushf ; Saves, among others, the IF flag
- push gs
- push fs
push ds
push es
- mov [cs:SavedSSSP],sp
- mov [cs:SavedSSSP+2],ss
cli
call enable_a20
@@ -91,21 +90,45 @@ bcopy: push eax
mov es,ax
mov ds,ax
- mov al,18h ; "Real-mode-like" data segment
- mov ss,ax
- mov fs,ax
- mov gs,ax
+ ; Don't mess with ss, fs, and gs. They are never changed
+ ; and should be able to make it back out of protected mode.
+ ; This works because (and only because) we don't take
+ ; interrupt in protected mode.
+ cmp esi,edi ; If source > destination, we might
+ ja .reverse ; have to copy backwards
+
+.forward:
mov al,cl ; Save low bits
+ and al,3
shr ecx,2 ; Convert to dwords
a32 rep movsd ; Do our business
; At this point ecx == 0
mov cl,al ; Copy any fractional dword
- and cl,3
a32 rep movsb
+ jmp .exit
+
+.reverse:
+ std ; Reverse copy
+ lea esi,[esi+ecx-1] ; Point to final byte
+ lea edi,[edi+ecx-1]
+ mov eax,ecx
+ and ecx,3
+ shr eax,2
+ a32 rep movsb
+
+ ; Change ESI/EDI to point to the last dword, instead
+ ; of the last byte.
+ sub esi,3
+ sub edi,3
+ mov ecx,eax
+ a32 rep movsd
- mov al,18h ; "Real-mode-like" data segment
+ cld
+
+.exit:
+ mov ax,18h ; "Real-mode-like" data segment
mov es,ax
mov ds,ax
@@ -115,15 +138,17 @@ bcopy: push eax
jmp 0:.in_rm
.in_rm: ; Back in real mode
- lss sp,[cs:SavedSSSP]
pop es
pop ds
- pop fs
- pop gs
call disable_a20
popf ; Re-enables interrupts
pop eax
+ pop edi
+ pop esi
+ add edi,eax
+ add esi,eax
+ pop eax
ret
;
@@ -372,8 +397,9 @@ try_wbinvd:
;
; bcopy_over_self:
;
-; This routine is used to copy large blocks of code on top of
-; conventional memory (to 0:7c00). We therefore have to move
+; This routine is used to shuffle memory around, followed by
+; invoking an entry point somewhere in low memory. This routine
+; can clobber any memory above 7C00h, we therefore have to move
; necessary code into the trackbuf area before doing the copy,
; and do adjustments to anything except BSS area references.
;
@@ -381,25 +407,37 @@ try_wbinvd:
; references in the ".earlybss" segment.
;
; After performing the copy, this routine resets the stack and
-; jumps to 0:7c00.
+; jumps to the specified entrypoint.
;
; 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
+; DS:BX -> Pointer to list of (dst, src, len) pairs
+; AX -> Number of list entries
+; [CS:EntryPoint] -> CS:IP to jump to
; On stack - initial state (fd, ad, ds, es, fs, gs)
;
-bcopy_over_self:
+shuffle_and_boot:
+ and ax,ax
+ jz .done
+.loop:
+ mov edi,[bx]
+ mov esi,[bx+4]
+ mov ecx,[bx+8]
call bcopy
-
+ add bx,12
+ dec ax
+ jnz .loop
+
+.done:
pop gs
pop fs
pop es
pop ds
popad
popfd
- jmp 0:7c00h
+ jmp far [cs:EntryPoint]
align 2
A20List dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast
@@ -414,9 +452,7 @@ __bcopy_size equ $-__bcopy_start
section .earlybss
alignb 2
+EntryPoint resd 1 ; CS:IP for shuffle_and_boot
SavedSSSP resd 1 ; Saved real mode SS:SP
A20Test resw 1 ; Counter for testing status of A20
A20Tries resb 1 ; Times until giving up on A20
-
-
-
diff --git a/bootsect.inc b/bootsect.inc
index f901cf5e..67ce6762 100644
--- a/bootsect.inc
+++ b/bootsect.inc
@@ -1,7 +1,7 @@
;; $Id$
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2005 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
@@ -39,12 +39,18 @@ load_bootsec:
shl eax,16
xchg dx,ax ; Now EAX = file length
mov edi, 100000h
+ mov [trackbuf+4],edi ; Copy from this address
push edi ; Save load address
+ xor dx,dx ; No padding
call load_high
call crlf
sub edi,100000h
- push edi ; Save length
+ mov [trackbuf+8],edi ; Save length
+
+ mov eax,7C00h ; Entry point
+ mov [trackbuf],eax ; Copy to this address
+ mov [EntryPoint],eax ; Jump to this address when done
%if IS_SYSLINUX || IS_MDSLINUX
movzx ecx,byte [CopySuper]
@@ -81,15 +87,24 @@ load_bootsec:
%endif
xor bx,bx
+;
+; replace_bootstrap for the special case where we have exactly one
+; descriptor, and it's the first entry in the trackbuf
+;
+
+replace_bootstrap_one:
+ push word trackbuf ; Address of descriptor list
+ push word 1 ; Length of descriptor list
+ ; Fall through
+
;
; 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.
+; the COMBOOT API. This routine expects two words on the stack:
+; address of the copy list (versus DS) and count. 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
;
@@ -120,16 +135,15 @@ replace_bootstrap:
mov [es:di+12],esi
mov [es:di+6],bx
- pop ecx ; Byte count to copy
- pop esi ; Copy from...
+ pop cx ; Copy list count
+ pop bx ; Copy from...
cli
mov ax,es
mov ss,ax
movzx esp,di
- mov edi,7C00h ; Copy to...
- jmp bcopy_over_self
+ jmp shuffle_and_boot
%if IS_SYSLINUX || IS_MDSLINUX
; Nothing
diff --git a/com32.inc b/com32.inc
index 6da6041f..fa312f25 100644
--- a/com32.inc
+++ b/com32.inc
@@ -64,6 +64,7 @@ is_com32_image:
mov edi,pm_entry ; Load address
pop eax ; File length
pop si ; File handle
+ xor dx,dx ; No padding
call load_high
call crlf
diff --git a/comboot.doc b/comboot.doc
index b717d0b7..b8de94ea 100644
--- a/comboot.doc
+++ b/comboot.doc
@@ -423,10 +423,10 @@ AX=000Ah [2.00] Get Derivative-Specific Information
AX=000Bh [2.00] Get Serial Console Configuration
Input: AX 000Bh
- Output: DX Serial port I/O base (e.g. 3F8h = COM1...)
- CX Baud rate divisor (1 = 115200 bps, 2 = 57600 bps...)
- BX Flow control configuration bits (see syslinux.doc)
- -> Bit 15 is set if the video console is disabled
+ Output: DX serial port I/O base (e.g. 3F8h = COM1...)
+ CX baud rate divisor (1 = 115200 bps, 2 = 57600 bps...)
+ BX flow control configuration bits (see syslinux.doc)
+ -> bit 15 is set if the video console is disabled
If no serial port is configured, DX will be set to 0 and the
other registers are undefined.
@@ -447,7 +447,7 @@ AX=000Ch [2.00] Perform final cleanup
For COM32 images, the boot loader will continue to provide
interrupt and BIOS call thunking services as long its memory
- areas (0x1000-0xffff, 0x100000-0x100fff) are not overwritten.
+ areas (0x0800-0xffff, 0x100000-0x100fff) are not overwritten.
MAKE SURE TO DISABLE INTERRUPTS, AND INSTALL NEW GDT AND IDTS
BEFORE OVERWRITING THESE MEMORY AREAS.
@@ -499,10 +499,10 @@ AX=000Eh [2.11] Get configuration file name
AX=000Fh [3.00] Get IPAPPEND strings [PXELINUX]
Input: AX 000Fh
- Output: CX Number of strings (currently 2)
- ES:BX Pointer to an array of NEAR pointers in
+ Output: CX number of strings (currently 2)
+ ES:BX pointer to an array of NEAR pointers in
the same segment, one for each of the above
- strings.
+ strings
Returns the same strings that the "ipappend" option would have
added to the command line, one for each bit of the "ipappend"
@@ -511,7 +511,7 @@ AX=000Fh [3.00] Get IPAPPEND strings [PXELINUX]
AX=0010h [3.00] Resolve hostname [PXELINUX]
- Input: ES:BX Pointer to null-terminated hostname
+ Input: ES:BX pointer to null-terminated hostname
Output: EAX IP address of hostname (zero if not found)
Queries the DNS server(s) for a specific hostname. If the
@@ -527,3 +527,51 @@ AX=0010h [3.00] Resolve hostname [PXELINUX]
all uses of IP addresses in PXE are also in network byte order.
+AX=0011h [3.10] Maximum number of shuffle descriptors
+ Input: AX 0011h
+ Output: CX maximum number of descriptors
+
+ This routine reports the maximum number of shuffle descriptors
+ permitted in a call to function 0012h.
+
+ Typical values are 682 and 1365.
+
+
+AX=0012h [3.10] Cleanup, shuffle and boot
+ Input: AX 0012h
+ DX derivative-specific flags (see previous function)
+ ES:DI shuffle descriptor list (must be in low memory)
+ CX number of shuffle descriptors
+ EBX(!) initial value of EDX after bootstrap
+ ESI initial value of ESI after bootstrap
+ DS initial value of DS after bootstrap
+ EBP CS:IP of routine to jump to
+ Output: Does not return
+ (if CX is too large the routine returns with CF=1)
+
+ This routine performs final cleanup, then performs a sequence
+ of copies, and jumps to a specified real mode entry point.
+ This is a more general version of function 000Dh, which can
+ also be used to load other types of programs.
+
+ The copies must not touch memory below address 7C00h.
+
+ ES:DI points to a list of CX descriptors each of the form:
+
+ Offset Size Meaning
+ 0 dword destination address
+ 4 dword source address
+ 8 dword length in bytes
+
+ The copies are overlap-safe, like memmove().
+
+ 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.
+
+
diff --git a/comboot.inc b/comboot.inc
index ae418b6f..83b57f46 100644
--- a/comboot.inc
+++ b/comboot.inc
@@ -188,7 +188,7 @@ comboot_int21: cli
loopne .again
; The last function in the list is the
; "no such function" function
-
+ clc
call ax ; Call the invoked function
comboot_resume:
setc P_FLAGSL ; Propagate CF->error
@@ -281,14 +281,13 @@ comboot_checkver: ; 30 = check DOS version
mov P_EBX,'SL' << 16
mov P_ECX,'IN' << 16
mov P_EDX,'UX' << 16
- clc
ret
comboot_getchar:
cmp byte [APIKeyFlag],00h
jne .queued
call getchar ; If not queued get input
- and al,al ; Function key?
+ and al,al ; Function key? (CF <- 0)
jnz .done
mov [APIKeyWait],ah ; High part of key
inc byte [APIKeyFlag] ; Set flag
@@ -322,7 +321,7 @@ comboot_int22:
xor ax,ax ; Function 0 -> unimplemented
.ok:
xchg ax,bx
- add bx,bx
+ add bx,bx ; CF <- 0
call [bx+int22_table]
jmp comboot_resume ; On return
@@ -546,12 +545,17 @@ comapi_cleanup:
;
comapi_chainboot:
call comapi_cleanup
+ mov eax,P_EDI
+ mov [trackbuf+4],eax ; Copy from
+ mov eax,P_ECX
+ mov [trackbuf+8],eax ; Total bytes
+ mov eax,7C00h
+ mov [trackbuf],eax ; Copy to
+ mov [EntryPoint],eax ; CS:IP entry point
mov esi,P_ESI
mov edx,P_EBX
mov bx,P_DS
- push P_EDI
- push P_ECX
- jmp replace_bootstrap
+ jmp replace_bootstrap_one
;
@@ -604,6 +608,43 @@ comapi_dnsresolv equ comapi_err
dw %2
%endmacro
+
+;
+; INT 22h AX=0011h Maximum number of shuffle descriptors
+;
+comapi_maxshuffle:
+ mov P_CX,(2*trackbufsize)/12
+ ret
+
+;
+; INT 22h AX=0012h Cleanup, shuffle and boot
+;
+comapi_shuffle:
+ call comapi_cleanup
+ mov cx,P_CX
+ cmp cx,(2*trackbufsize)/12
+ ja .error
+
+ push cx ; On stack: descriptor count
+
+ lea cx,[ecx+ecx*2] ; CX *= 3
+
+ mov fs,P_ES
+ mov si,P_DI
+ mov di,trackbuf
+ push di ; On stack: descriptor list address
+ fs rep movsd ; Copy the list
+
+ mov eax,P_EBP
+ mov [EntryPoint],eax ; CS:IP entry point
+ mov esi,P_ESI
+ mov edx,P_EBX
+ mov bx,P_DS
+ jmp replace_bootstrap
+.error:
+ stc
+ ret
+
int21_table:
int21 00h, comboot_return
int21 01h, comboot_getkey
@@ -619,23 +660,25 @@ int21_count equ ($-int21_table)/3
align 2, db 0
int22_table:
- dw comapi_err ; 0000 unimplemented syscall
- dw comapi_get_version ; 0001 get SYSLINUX version
- dw comapi_writestr ; 0002 write string
- dw comapi_run ; 0003 run specified command
- dw comapi_run_default ; 0004 run default command
- dw comapi_textmode ; 0005 force text mode
- dw comapi_open ; 0006 open file
- dw comapi_read ; 0007 read file
- dw comapi_close ; 0008 close file
- dw comapi_pxecall ; 0009 call PXE stack
- 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
- dw comapi_configfile ; 000E get name of config file
- dw comapi_ipappend ; 000F get ipappend strings
- dw comapi_dnsresolv ; 0010 resolve hostname
+ dw comapi_err ; 0000 unimplemented syscall
+ dw comapi_get_version ; 0001 get SYSLINUX version
+ dw comapi_writestr ; 0002 write string
+ dw comapi_run ; 0003 run specified command
+ dw comapi_run_default ; 0004 run default command
+ dw comapi_textmode ; 0005 force text mode
+ dw comapi_open ; 0006 open file
+ dw comapi_read ; 0007 read file
+ dw comapi_close ; 0008 close file
+ dw comapi_pxecall ; 0009 call PXE stack
+ 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
+ dw comapi_configfile ; 000E get name of config file
+ dw comapi_ipappend ; 000F get ipappend strings
+ dw comapi_dnsresolv ; 0010 resolve hostname
+ dw comapi_maxshuffle ; 0011 maximum shuffle descriptors
+ dw comapi_shuffle ; 0012 cleanup, shuffle and boot
int22_count equ ($-int22_table)/2
APIKeyWait db 0
diff --git a/ext2_fs.inc b/ext2_fs.inc
index 4cedd122..c4c8bf71 100644
--- a/ext2_fs.inc
+++ b/ext2_fs.inc
@@ -90,9 +90,11 @@ s_padding1 resw 1
s_reserved resd 204 ; Padding to the end of the block
endstruc
+%ifndef DEPEND
%if ext2_super_block_size != 1024
%error "ext2_super_block definition bogus"
%endif
+%endif
;
; Structure definition for the ext2 inode
@@ -121,9 +123,11 @@ i_pad1 resw 1
l_i_reserved2 resd 2
endstruc
+%ifndef DEPEND
%if ext2_inode_size != 128
%error "ext2_inode definition bogus"
%endif
+%endif
;
; Structure definition for ext2 block group descriptor
@@ -139,9 +143,11 @@ bg_pad resw 1
bg_reserved resd 3
endstruc
+%ifndef DEPEND
%if ext2_group_desc_size != 32
%error "ext2_group_desc definition bogus"
%endif
+%endif
%define ext2_group_desc_lg2size 5
diff --git a/kernel.inc b/kernel.inc
index 537db4dc..f19eac7d 100644
--- a/kernel.inc
+++ b/kernel.inc
@@ -51,8 +51,6 @@ su_movesize resw 1 ; 0212
su_code32start resd 1 ; 0214 Start of code loaded high
su_ramdiskat resd 1 ; 0218 Start of initial ramdisk
su_ramdisklen equ $ ; Length of initial ramdisk
-su_ramdisklen1 resw 1 ; 021C
-su_ramdisklen2 resw 1 ; 021E
su_bsklugeoffs resw 1 ; 0220
su_bsklugeseg resw 1 ; 0222
su_heapend resw 1 ; 0224
diff --git a/loadhigh.inc b/loadhigh.inc
index 0bad64f0..0eef6858 100644
--- a/loadhigh.inc
+++ b/loadhigh.inc
@@ -27,11 +27,12 @@
; The xfer_buf_seg is used as a bounce buffer.
;
; The input address (EDI) should be dword aligned, and the final
-; dword written is padded with zeroes if necessary.
+; stretch is padded with zeroes if necessary.
;
; Inputs: SI = file handle/cluster pointer
; EDI = target address in high memory
; EAX = size of remaining file in bytes
+; DX = zero-padding mask (e.g. 0003h for pad to dword)
;
; Outputs: SI = file handle/cluster pointer
; EDI = first untouched address (not including padding)
@@ -70,7 +71,7 @@ load_high:
push ecx ; <B> Byte count this round
push edi ; <C> Target buffer
.fix_slop:
- test cl,3
+ test cx,dx
jz .noslop
; The last dword fractional - pad with zeroes
; Zero-padding is critical for multi-file initramfs.
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 24ce060b..0832a266 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -317,7 +317,8 @@ void unzip_if_needed(uint32_t *where_p, uint32_t *size_p)
}
if ( !okmem ) {
- puts("Not enough memory to decompress image\n");
+ printf("Not enough memory to decompress image (need 0x%08x bytes)\n",
+ gzdatasize);
die();
}
diff --git a/parseconfig.inc b/parseconfig.inc
index 1db13a1e..cad86b3a 100644
--- a/parseconfig.inc
+++ b/parseconfig.inc
@@ -353,8 +353,6 @@ OntimeoutLen dw 0 ; Bytes in ontimeout command
OnerrorLen dw 0 ; Bytes in onerror command
KbdTimeOut dw 0 ; Keyboard timeout (if any)
CmdLinePtr dw cmd_line_here ; Command line advancing pointer
-initrd_flag equ $
-initrd_ptr dw 0 ; Initial ramdisk pointer/flag
ForcePrompt dw 0 ; Force prompt
AllowImplicit dw 1 ; Allow implicit kernels
AllowOptions dw 1 ; User-specified options allowed
diff --git a/runkernel.inc b/runkernel.inc
index 7a71350c..bc31f9e1 100644
--- a/runkernel.inc
+++ b/runkernel.inc
@@ -1,7 +1,7 @@
;; $Id$
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2005 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
@@ -126,7 +126,8 @@ construct_cmdline:
; the first option was BOOT_IMAGE=, but that is no longer certain.
;
mov si,cmd_line_here
- mov byte [initrd_flag],0
+ xor ax,ax
+ mov [InitRDPtr],ax ; No initrd= option (yet)
push es ; Set DS <- real_mode_seg
pop ds
get_next_opt: lodsb
@@ -156,15 +157,16 @@ get_next_opt: lodsb
mov di,initrd_cmd
mov cx,initrd_cmd_len
repe cmpsb
- jne not_initrd
-
- mov di,InitRD
- push si ; mangle_dir mangles si
- call mangle_name ; Mangle ramdisk name
- pop si
- cmp byte [es:InitRD+NULLOFFSET],NULLFILE ; Null filename?
- seta byte [es:initrd_flag] ; Set flag if not
-not_initrd: pop es ; Restore ES -> real_mode_seg
+ jne .not_initrd
+
+ cmp al,' '
+ jbe .noramdisk
+ mov [cs:InitRDPtr],si
+ jmp .not_initrd
+.noramdisk:
+ xor ax,ax
+ mov [cs:InitRDPtr],ax
+.not_initrd: pop es ; Restore ES -> real_mode_seg
skip_this_opt: lodsb ; Load from command line
cmp al,' '
ja skip_this_opt
@@ -225,6 +227,9 @@ new_kernel:
mov byte [es:su_loader],my_id ; Show some ID
movzx ax,byte [es:bs_setupsecs] ; Variable # of setup sectors
mov [SetupSecs],ax
+ xor eax,eax
+ mov [es:su_ramdisklen],eax ; No initrd loaded yet
+
;
; About to load the kernel. This is a modern kernel, so use the boot flags
; we were provided.
@@ -272,9 +277,11 @@ read_kernel:
sub eax,8000h ; Amount of kernel not yet loaded
jbe high_load_done ; Zero left (tiny kernel)
+ xor dx,dx ; No padding needed
call load_high ; Copy the file
high_load_done:
+ mov [KernelEnd],edi
mov ax,real_mode_seg ; Set to real mode seg
mov es,ax
@@ -287,49 +294,9 @@ high_load_done:
; if we tried to load initrd using an old kernel
;
load_initrd:
- test byte [initrd_flag],1
+ cmp word [InitRDPtr],0
jz nk_noinitrd
- push es ; ES->real_mode_seg
- push ds
- pop es ; We need ES==DS
- mov si,InitRD
- mov di,InitRDCName
- call unmangle_name ; Create human-readable name
- sub di,InitRDCName
- mov [InitRDCNameLen],di
- mov di,InitRD
- call searchdir ; Look for it in directory
- pop es
- jz initrd_notthere
- mov [es:su_ramdisklen1],ax ; Ram disk length
- mov [es:su_ramdisklen2],dx
- mov edx,[HighMemSize] ; End of memory
- dec edx
- mov eax,[RamdiskMax] ; Highest address allowed by kernel
- cmp edx,eax
- jna memsize_ok
- mov edx,eax ; Adjust to fit inside limit
-memsize_ok:
- inc edx
- xor dx,dx ; Round down to 64K boundary
- sub edx,[es:su_ramdisklen] ; Subtract size of ramdisk
- xor dx,dx ; Round down to 64K boundary
- mov [es:su_ramdiskat],edx ; Load address
- call loadinitrd ; Load initial ramdisk
- jmp short initrd_end
-
-initrd_notthere:
- mov si,err_noinitrd
- call cwritestr
- mov si,InitRDCName
- call cwritestr
- mov si,crlf_msg
- jmp abort_load
-
-no_high_mem: mov si,err_nohighmem ; Error routine
- jmp abort_load
-
-initrd_end:
+ call parse_load_initrd
nk_noinitrd:
;
; Abandon hope, ye that enter here! We do no longer permit aborts.
@@ -496,8 +463,8 @@ kill_motor:
; initrd, and are always loaded low.
;
old_kernel:
- test byte [initrd_flag],1 ; Old kernel can't have initrd
- jz load_old_kernel
+ cmp word [InitRDPtr],0 ; Old kernel can't have initrd
+ je load_old_kernel
mov si,err_oldkernel
jmp abort_load
load_old_kernel:
@@ -506,19 +473,118 @@ load_old_kernel:
jmp read_kernel
;
+; parse_load_initrd
+;
+; Parse an initrd= option and load the initrds. Note that we load
+; from the high end of memory first, so we parse this option from
+; left to right.
+;
+parse_load_initrd:
+ push es
+ push ds
+ mov ax,real_mode_seg
+ mov ds,ax
+ push cs
+ pop es ; DS == real_mode_seg, ES == CS
+
+ mov si,[cs:InitRDPtr]
+.find_end:
+ lodsb
+ cmp al,' '
+ ja .find_end
+ ; Now SI points to one character beyond the
+ ; byte that ended this option.
+
+.get_chunk:
+ dec si
+
+ ; DS:SI points to a termination byte
+
+ xor ax,ax
+ xchg al,[si] ; Zero-terminate
+ push si ; Save ending byte address
+ push ax ; Save ending byte
+
+.find_start:
+ dec si
+ cmp si,[cs:InitRDPtr]
+ je .got_start
+ cmp byte [si],','
+ jne .find_start
+
+ ; It's a comma byte
+ inc si
+
+.got_start:
+ push si
+ mov di,InitRD ; Target buffer for mangled name
+ call mangle_name
+ call loadinitrd
+ pop si
+
+ pop ax
+ pop di
+ mov [di],al ; Restore ending byte
+
+ cmp si,[cs:InitRDPtr]
+ ja .get_chunk
+
+ pop ds
+ pop es
+ ret
+
+;
; Load RAM disk into high memory
;
-; Need to be set:
-; su_ramdiskat - Where in memory to load
-; su_ramdisklen - Size of file
-; SI - initrd filehandle/cluster pointer
+; Input: InitRD - set to the mangled name of the initrd
;
- section .text
loadinitrd:
- push es ; Save ES on entry
+ push ds
+ push es
+ mov ax,cs ; CS == DS == ES
+ mov ds,ax
+ mov es,ax
+ mov si,InitRD
+ mov di,InitRDCName
+ call unmangle_name ; Create human-readable name
+ sub di,InitRDCName
+ mov [InitRDCNameLen],di
+ mov di,InitRD
+ call searchdir ; Look for it in directory
+ jz .notthere
+
+ mov cx,dx
+ shl ecx,16
+ mov cx,ax ; ECX <- ram disk length
+
mov ax,real_mode_seg
- mov es,ax
- mov edi,[es:su_ramdiskat] ; initrd load address
+ mov es,ax
+
+ push ecx ; Bytes to load
+ cmp dword [es:su_ramdisklen],0
+ je .nopadding ; Don't pad the last initrd
+ add ecx,4095
+ and cx,0F000h
+.nopadding:
+ add [es:su_ramdisklen],ecx
+ mov edx,[HighMemSize] ; End of memory
+ dec edx
+ mov eax,[RamdiskMax] ; Highest address allowed by kernel
+ cmp edx,eax
+ jna .memsize_ok
+ mov edx,eax ; Adjust to fit inside limit
+.memsize_ok:
+ inc edx
+ and dx,0F000h ; Round down to 4K boundary
+ sub edx,ecx ; Subtract size of ramdisk
+ and dx,0F000h ; Round down to 4K boundary
+ cmp edx,[KernelEnd] ; Are we hitting the kernel image?
+ jb no_high_mem
+
+ mov [es:su_ramdiskat],edx ; Load address
+ mov [RamdiskMax],edx ; Next initrd loaded here
+
+ mov edi,edx ; initrd load address
push si
mov si,crlfloading_msg ; Write "Loading "
call cwritestr
@@ -528,11 +594,26 @@ loadinitrd:
call cwritestr
pop si
- mov eax,[es:su_ramdisklen]
+ pop eax ; Bytes to load
+ mov dx,0FFFh ; Pad to page
call load_high ; Load the file
- call crlf
- pop es ; Restore original ES
+ pop es
+ pop ds
+ jmp crlf ; Print carriage return and return
+
+.notthere:
+ mov si,err_noinitrd
+ call cwritestr
+ mov si,InitRDCName
+ call cwritestr
+ mov si,crlf_msg
+ jmp abort_load
+
+no_high_mem: ; Error routine
+ mov si,err_nohighmem
+ jmp abort_load
+
ret
section .data
@@ -544,6 +625,8 @@ boot_image_len equ $-boot_image
RamdiskMax resd 1 ; Highest address for ramdisk
KernelSize resd 1 ; Size of kernel in bytes
KernelSects resd 1 ; Size of kernel in sectors
+KernelEnd resd 1 ; Ending address of the kernel image
CmdLineLen resw 1 ; Length of command line including null
SetupSecs resw 1 ; Number of setup sectors
+InitRDPtr resw 1 ; Pointer to initrd= option in command line
LoadFlags resb 1 ; Loadflags from kernel
diff --git a/version b/version
index 95e82b47..c8cfe395 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-3.03
+3.10