aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-05-07 13:47:10 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-05-07 13:47:10 -0700
commitfc4031f2d73a8ab6d49f1170ff8e1a662eb18ae0 (patch)
treedb5b89ec1c2b91dee843ca44c6461e793d3b7e25
parent5d534825f533b09cf6df4dcb7230570139a7a17a (diff)
downloadsyslinux-elf-fc4031f2d73a8ab6d49f1170ff8e1a662eb18ae0.tar.gz
syslinux-elf-fc4031f2d73a8ab6d49f1170ff8e1a662eb18ae0.tar.xz
syslinux-elf-fc4031f2d73a8ab6d49f1170ff8e1a662eb18ae0.zip
More tweaks to allow bigger stack/heap, and boot protocol adjustmentssyslinux-3.50-pre7
Seems the su_heapend field was never set up right; also sanitize the way the pre-2.02 command line is handled.
-rw-r--r--com32/lib/syslinux/load_linux.c2
-rw-r--r--kernel.inc6
-rw-r--r--runkernel.inc49
3 files changed, 33 insertions, 24 deletions
diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index d2ad2644..13a0fa0d 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -190,7 +190,7 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
if (hdr.version < 0x0202 || !(hdr.loadflags & 0x01))
cmdline_offset = (0x9ff0 - cmdline_size) & ~15;
else
- cmdline_offset = (0xfff0 - cmdline_size) & ~15;
+ cmdline_offset = 0x10000;
real_mode_size = (hdr.setup_sects+1) << 9;
real_mode_base = (hdr.loadflags & LOAD_HIGH) ? 0x10000 : 0x90000;
diff --git a/kernel.inc b/kernel.inc
index d72ce2f3..b4d356a6 100644
--- a/kernel.inc
+++ b/kernel.inc
@@ -57,9 +57,9 @@ su_pad1 resw 1 ; 0226
su_cmd_line_ptr resd 1 ; 0228
su_ramdisk_max resd 1 ; 022C
resb (0e000h-12)-($-$$) ; Were bootsect.S puts it...
-linux_stack equ $ ; BFF4
+linux_stack equ $ ; DFF4
linux_fdctab resb 12
-cmd_line_here equ $ ; C000 Should be out of the way
+cmd_line_here equ $ ; E000 Should be out of the way
endstruc
;
@@ -71,7 +71,7 @@ CMD_MAGIC equ 0A33Fh ; Command line magic
; If we're loading the command line old-style, we need a smaller
; heap.
;
-old_cmd_line_here equ 9000h
+old_cmd_line_here equ 9800h
old_linux_fdctab equ old_cmd_line_here-12
old_linux_stack equ old_linux_fdctab
diff --git a/runkernel.inc b/runkernel.inc
index 22e8e69c..04d3bb11 100644
--- a/runkernel.inc
+++ b/runkernel.inc
@@ -214,7 +214,8 @@ prepare_header:
jb old_kernel ; Old kernel, load low
cmp ax,0201h ; Version 2.01+?
jb new_kernel ; If 2.00, skip this step
- mov word [es:su_heapend],linux_stack ; Set up the heap
+ ; Set up the heap (assuming loading high for now)
+ mov word [es:su_heapend],linux_stack-512
or byte [es:su_loadflags],80h ; Let the kernel know we care
cmp ax,0203h ; Version 2.03+?
jb new_kernel ; Not 2.03+
@@ -319,6 +320,7 @@ nk_noinitrd:
; capable of starting their setup from a different address.
;
mov ax,real_mode_seg
+ mov es,ax
mov fs,ax
;
@@ -327,34 +329,38 @@ nk_noinitrd:
; setup doesn't.
;
cli ; In case of hooked interrupts
+ mov dx,[fs:su_version] ; cmdline protocol version
test byte [LoadFlags],LOAD_HIGH
jz need_high_cmdline
- cmp word [fs:su_version],0202h ; Support new cmdline protocol?
+ cmp dx,0202h ; Support new cmdline protocol?
jb need_high_cmdline
; New cmdline protocol
; Store 32-bit (flat) pointer to command line
- mov dword [fs:su_cmd_line_ptr],(real_mode_seg << 4) + cmd_line_here
+ ; This is the "high" location, since we have bzImage
+ mov dword [fs:su_cmd_line_ptr],(real_mode_seg << 4)+cmd_line_here
jmp in_proper_place
need_high_cmdline:
;
-; Copy command line to 90000h (old style) -- this happens either if
-; we have a zImage kernel or the protocol is less than 2.02.
+; Copy command line down to fit in high conventional memory
+; -- this happens if we have a zImage kernel or the protocol
+; is less than 2.02.
;
- mov ax,9000h ; Note AL <- 0
- mov es,ax
mov si,cmd_line_here
mov di,old_cmd_line_here
mov [fs:kern_cmd_magic],word CMD_MAGIC ; Store magic
mov [fs:kern_cmd_offset],di ; Store pointer
mov word [HeapEnd],old_linux_stack
mov ax,255 ; Max cmdline limit
- cmp word [fs:su_version],0201h
+ cmp dx,0201h
jb .adjusted
; Protocol 2.01+
- mov word [fs:su_heapend],old_linux_stack
+ mov word [fs:su_heapend],old_linux_stack-512
jbe .adjusted
; Protocol 2.02+
+ ; Note that the only reason we would end up here is
+ ; because we have a zImage, so we anticipate the move
+ ; to 90000h already...
mov dword [fs:su_cmd_line_ptr],0x90000+old_cmd_line_here
mov ax,4095 ; 2.02+ allow a higher limit
.adjusted:
@@ -366,9 +372,10 @@ need_high_cmdline:
.len_ok:
fs rep movsb
stosb ; Final null, note AL=0 already
-
- push fs
- pop es
+ cmp dx,0200h
+ jb .nomovesize
+ mov [es:su_movesize],di ; Tell the kernel what to move
+.nomovesize:
test byte [LoadFlags],LOAD_HIGH
jnz in_proper_place ; If high load, we're done
@@ -380,9 +387,9 @@ need_high_cmdline:
;
mov ax,9000h
mov es,ax
- mov cx,[SetupSecs]
- inc cx ; Setup + boot sector
- shl cx,7 ; Sectors -> dwords
+ mov cx,di ; == su_movesize (from above)
+ add cx,3 ; Round up
+ shr cx,2 ; Convert to dwords
xor si,si
xor di,di
fs rep movsd ; Copy setup + boot sector
@@ -403,7 +410,8 @@ need_high_cmdline:
xor eax,eax
rep stosd ; Clear region
;
-; Copy the kernel down to the "low" location
+; Copy the kernel down to the "low" location (the kernel will then
+; move itself again, sigh.)
;
mov ecx,[KernelSize]
mov esi,100000h
@@ -441,7 +449,8 @@ root_not_floppy:
%endif
;
; Linux wants the floppy motor shut off before starting the kernel,
-; at least bootsect.S seems to imply so.
+; at least bootsect.S seems to imply so. If we don't load the floppy
+; driver, this is *definitely* so!
;
kill_motor:
xor ax,ax
@@ -466,7 +475,9 @@ kill_motor:
mov fs,bx
mov gs,bx
mov ss,bx
- mov sp,[cs:HeapEnd]
+ mov sp,strict word linux_stack
+ ; Point HeapEnd to the immediate of the instruction above
+HeapEnd equ $-2 ; Self-modifying code! Fun!
;
; We're done... now RUN THAT KERNEL!!!!
@@ -638,8 +649,6 @@ no_high_mem: ; Error routine
ret
section .data
- alignb 2
-HeapEnd dw linux_stack ; Default end of heap
boot_image db 'BOOT_IMAGE='
boot_image_len equ $-boot_image