aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-02-15 22:51:46 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-02-15 22:54:28 -0800
commitc9cddae667ebea9bdeba68db49c0e3230e85f9d4 (patch)
tree2b9662f35bafc8f9197269d6ff0101bd601ffa06
parent8404cd587d44f412819ce09adfb5f62b9b5e05e7 (diff)
downloadsyslinux-elf-c9cddae667ebea9bdeba68db49c0e3230e85f9d4.tar.gz
syslinux-elf-c9cddae667ebea9bdeba68db49c0e3230e85f9d4.tar.xz
syslinux-elf-c9cddae667ebea9bdeba68db49c0e3230e85f9d4.zip
Put virtual kernels (CLI labels) in high memorysyslinux-3.62-pre7
Support putting virtual kernels in high memory instead of using a dedicated segment for it. This both reduces the low memory footprint by 64K, and allows for functionally unlimited labels (tested with over a hundred thousand.)
-rw-r--r--NEWS3
-rw-r--r--com32.inc6
-rw-r--r--configinit.inc6
-rw-r--r--extlinux.asm7
-rw-r--r--isolinux.asm5
-rw-r--r--ldlinux.asm7
-rw-r--r--parseconfig.inc26
-rw-r--r--pxelinux.asm7
-rw-r--r--rllpack.inc86
-rw-r--r--runkernel.inc15
-rw-r--r--ui.inc13
11 files changed, 97 insertions, 84 deletions
diff --git a/NEWS b/NEWS
index 6810082f..8626a1d5 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,9 @@ Changes in 3.62:
Linux kernel limit.
* vesamenu: support systems without linear framebuffer support
(sigh, what is this, 1993?) and 15-bit RGB modes.
+ * Move the label storage (for the command-line interface) to
+ high memory, removing the size limit and freeing up 64K of
+ low memory.
Changes in 3.61:
* EXTLINUX: fix crash when accessing an empty file.
diff --git a/com32.inc b/com32.inc
index 220c9d7b..ac513593 100644
--- a/com32.inc
+++ b/com32.inc
@@ -57,7 +57,6 @@ is_com32_image:
sub cx,si
fs rep movsb
- call highmemsize ; We need the high memory size...
call comboot_setup_api ; Set up the COMBOOT-style API
mov edi,pm_entry ; Load address
@@ -115,9 +114,10 @@ com32_enter_pm:
;
com32_call_start:
;
- ; Point the stack to the end of high memory
+ ; Point the stack to the end of (permitted) high memory
;
- mov esp,[word HighMemSize]
+ mov esp,[word HighMemRsvd]
+ xor sp,sp ; Align to a 64K boundary
;
; Set up the protmode IDT and the interrupt jump buffers
diff --git a/configinit.inc b/configinit.inc
index c6591b60..a5eaf1b3 100644
--- a/configinit.inc
+++ b/configinit.inc
@@ -19,9 +19,10 @@
section .text
reset_config:
- xor eax,eax
+ call highmemsize
; Initialize the .config section
+ xor eax,eax
mov si,section..config.start
mov di,section..config.vstart
mov cx,section..config.end.start
@@ -50,6 +51,9 @@ mkkeymap: stosb
inc al
loop mkkeymap
+ mov eax,[HighMemSize]
+ mov [VKernelEnd],eax
+
ret
section .data
diff --git a/extlinux.asm b/extlinux.asm
index 232a58f3..8b2eff5b 100644
--- a/extlinux.asm
+++ b/extlinux.asm
@@ -56,7 +56,7 @@ SYMLINK_SECTORS equ 2 ; Max number of sectors in a symlink
; The following structure is used for "virtual kernels"; i.e. LILO-style
; option labels. The options we permit here are `kernel' and `append
; Since there is no room in the bottom 64K for all of these, we
-; stick them at vk_seg:0000 and copy them down before we need them.
+; stick them in high memory and copy them down before we need them.
;
struc vkernel
vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
@@ -76,9 +76,8 @@ vk_end: equ $ ; Should be <= vk_size
;
; 0000h - main code/data segment (and BIOS segment)
;
-real_mode_seg equ 4000h
-cache_seg equ 3000h ; 64K area for metadata cache
-vk_seg equ 2000h ; Virtual kernels
+real_mode_seg equ 3000h
+cache_seg equ 2000h ; 64K area for metadata cache
xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
diff --git a/isolinux.asm b/isolinux.asm
index 81caf766..be8fd0f7 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -50,7 +50,7 @@ SECTOR_SIZE equ (1 << SECTOR_SHIFT)
; The following structure is used for "virtual kernels"; i.e. LILO-style
; option labels. The options we permit here are `kernel' and `append
; Since there is no room in the bottom 64K for all of these, we
-; stick them at vk_seg:0000 and copy them down before we need them.
+; stick them in high memory and copy them down before we need them.
;
struc vkernel
vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
@@ -67,8 +67,7 @@ vk_end: equ $ ; Should be <= vk_size
; Segment assignments in the bottom 640K
; 0000h - main code/data segment (and BIOS segment)
;
-real_mode_seg equ 3000h
-vk_seg equ 2000h ; Virtual kernels
+real_mode_seg equ 2000h
xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
diff --git a/ldlinux.asm b/ldlinux.asm
index 0c5c94f8..0f063154 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -58,7 +58,7 @@ SECTOR_SIZE equ (1 << SECTOR_SHIFT)
; The following structure is used for "virtual kernels"; i.e. LILO-style
; option labels. The options we permit here are `kernel' and `append
; Since there is no room in the bottom 64K for all of these, we
-; stick them at vk_seg:0000 and copy them down before we need them.
+; stick them in high memory and copy them down before we need them.
;
struc vkernel
vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
@@ -78,9 +78,8 @@ vk_end: equ $ ; Should be <= vk_size
;
; 0000h - main code/data segment (and BIOS segment)
;
-real_mode_seg equ 4000h
-cache_seg equ 3000h ; 64K area for metadata cache
-vk_seg equ 2000h ; Virtual kernels
+real_mode_seg equ 3000h
+cache_seg equ 2000h ; 64K area for metadata cache
xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
diff --git a/parseconfig.inc b/parseconfig.inc
index 739a884b..90c1f3c9 100644
--- a/parseconfig.inc
+++ b/parseconfig.inc
@@ -399,23 +399,12 @@ commit_vk:
xor ax,ax
rep stosb
- ; Pack temporarily into trackbuf
+ ; Pack into high memory
mov si,VKernelBuf
- mov di,trackbuf
+ mov edi,[VKernelEnd]
mov cx,vk_size
call rllpack
- ; Now DX = number of bytes
- mov di,[VKernelBytes]
- mov cx,dx
- add dx,di
- jc .overflow ; If > 1 segment
- mov [VKernelBytes],dx
- mov si,trackbuf
- push es
- push word vk_seg
- pop es
- rep movsb
- pop es
+ mov [VKernelEnd],edi
ret
.overflow:
mov si,vk_overflow_msg
@@ -426,6 +415,14 @@ commit_vk:
vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
SerialNotice db 1 ; Only print this once
+ section .bss
+ alignb 4
+VKernelEnd resd 1 ; Lowest high memory address used
+
+ ; This symbol should be used by loaders to indicate
+ ; the highest address *they* are allowed to use.
+HighMemRsvd equ VKernelEnd
+ ; by vkernels
section .config
align 4, db 0
KbdTimeout dd 0 ; Keyboard timeout (if any)
@@ -440,7 +437,6 @@ AllowImplicit dw 1 ; Allow implicit kernels
AllowOptions dw 1 ; User-specified options allowed
IncludeLevel dw 1 ; Nesting level
SerialPort dw 0 ; Serial port base (or 0 for no serial port)
-VKernelBytes dw 0 ; Number of bytes used by vkernels
VKernel db 0 ; Have we seen any "label" statements?
%if IS_PXELINUX
diff --git a/pxelinux.asm b/pxelinux.asm
index 7237fff4..8bb87c26 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -101,7 +101,7 @@ TFTP_EOPTNEG equ htons(8) ; Option negotiation failure
; The following structure is used for "virtual kernels"; i.e. LILO-style
; option labels. The options we permit here are `kernel' and `append
; Since there is no room in the bottom 64K for all of these, we
-; stick them at vk_seg:0000 and copy them down before we need them.
+; stick them in high memory and copy them down before we need them.
;
struc vkernel
vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
@@ -119,9 +119,8 @@ vk_end: equ $ ; Should be <= vk_size
; Segment assignments in the bottom 640K
; 0000h - main code/data segment (and BIOS segment)
;
-real_mode_seg equ 4000h
-pktbuf_seg equ 3000h ; Packet buffers segments
-vk_seg equ 2000h ; Virtual kernels
+real_mode_seg equ 3000h
+pktbuf_seg equ 2000h ; Packet buffers segments
xfer_buf_seg equ 1000h ; Bounce buffer for I/O to high mem
comboot_seg equ real_mode_seg ; COMBOOT image loading zone
diff --git a/rllpack.inc b/rllpack.inc
index 0714956a..e5d1d5e5 100644
--- a/rllpack.inc
+++ b/rllpack.inc
@@ -1,5 +1,4 @@
-; -*- fundamental -*-
-; -----------------------------------------------------------------------
+; -*- fundamental -*- ---------------------------------------------------
;
; Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
;
@@ -22,29 +21,37 @@
; 129-255 = (x-126) times subsequent byte
; 0 = end of data
;
+; These structures are stored *in reverse order* in high memory.
+; High memory pointers point to one byte beyond the end.
+;
section .text
;
; rllpack:
-; Pack CX bytes from DS:SI into ES:DI
-; Returns updated SI, DI and CX = number of bytes output
+; Pack CX bytes from SI into EDI.
+; Returns updated SI and EDI.
;
rllpack:
- push ax
- push bx
+ push word .pmentry
+ call simple_pm_call
+ ret
+
+.pmentry:
push cx
- push bp
- push di
+ push ebx
+ push edx
.startseq:
xor ax,ax ; Zero byte
- xor bx,bx ; Run length zero
- mov bp,di ; Pointer to header byte
- stosb ; Store header byte (might be zero)
+ xor ebx,ebx ; Run length zero
+ dec edi
+ mov edx,edi ; Pointer to header byte
+ mov [edi],al
jcxz .done_null
.stdbyte:
lodsb
- stosb
+ dec edi
+ mov [edi],al
dec cx
cmp ah,al
je .same
@@ -53,7 +60,7 @@ rllpack:
xor bx,bx
.plainbyte:
inc bx
- inc byte [es:bp]
+ inc byte [edx]
jcxz .done
jns .stdbyte
jmp .startseq
@@ -61,18 +68,20 @@ rllpack:
cmp bl,2
jb .plainbyte
; 3 bytes or more in a row, time to convert sequence
- sub byte [es:bp],bl
+ sub [edx],bl
jnz .normal
- dec di ; We killed a whole stretch, remove start byte
+ inc edi ; We killed a whole stretch,
+ ; drop start byte
.normal:
inc bx
- sub di,bx
- mov bp,di
+ add edi,ebx
mov al,bl
add al,126
- stosb
- mov al,ah
- stosb
+ dec edi
+ mov edx,edi
+ mov [edi],al
+ dec edi
+ mov [edi],ah
.getrun:
jcxz .done
cmp bl,255-126
@@ -81,52 +90,57 @@ rllpack:
cmp al,ah
jne .nomatch
inc bx
- inc byte [es:bp]
+ inc byte [edx]
dec cx
jmp .getrun
.nomatch:
dec si
jmp .startseq
.done:
- xor al,al
- stosb
+ dec edi
+ mov [edi],cl ; CX = 0 here
.done_null:
- pop dx
- sub dx,di
- neg dx
- pop bp
+ pop edx
+ pop ebx
pop cx
- pop bx
- pop ax
ret
;
; rllunpack:
-; Unpack bytes from DS:SI into ES:DI
-; On return SI, DI are updated and CX contains number of bytes output
+; Unpack bytes from ESI into DI
+; On return ESI, DI are updated and CX contains number of bytes output.
;
rllunpack:
- push ax
+ push word .pmentry
+ call simple_pm_call
+ ret
+
+.pmentry:
push di
xor cx,cx
.header:
- lodsb
+ dec esi
+ mov al,[esi]
and al,al
jz .done
cmp al,129
jae .isrun
; Not a run
mov cl,al
- rep movsb
+.copy:
+ dec esi
+ mov al,[esi]
+ stosb
+ loop .copy
jmp .header
.isrun:
sub al,126
mov cl,al
- lodsb
+ dec esi
+ mov al,[esi]
rep stosb
jmp .header
.done:
pop cx
sub cx,di
neg cx
- pop ax
ret
diff --git a/runkernel.inc b/runkernel.inc
index 39d8e908..98d826f0 100644
--- a/runkernel.inc
+++ b/runkernel.inc
@@ -97,10 +97,14 @@ kernel_sane: push ax
; Save the cluster pointer for later...
;
push si
+
;
-; Get the BIOS' idea of what the size of high memory is.
+; Initialize our end of memory pointer
;
- call highmemsize
+ mov eax,[HighMemRsvd]
+ xor ax,ax ; Align to a 64K boundary
+ mov [MyHighMemSize],eax
+
;
; Construct the command line (append options have already been copied)
;
@@ -195,7 +199,7 @@ is_mem_cmd:
%if HIGHMEM_SLOP != 0
sub ebx,HIGHMEM_SLOP
%endif
- mov [cs:HighMemSize],ebx
+ mov [cs:MyHighMemSize],ebx
jmp short skip_this_opt
cmdline_end:
push cs ; Restore standard DS
@@ -256,7 +260,7 @@ read_kernel:
mov si,dotdot_msg ; Print dots
call cwritestr
- mov eax,[HighMemSize]
+ mov eax,[MyHighMemSize]
sub eax,100000h ; Load address
cmp eax,[KernelSize]
jb no_high_mem ; Not enough high memory
@@ -592,7 +596,7 @@ loadinitrd:
mov es,ax
push ecx ; Bytes to load
- mov edx,[HighMemSize] ; End of memory
+ mov edx,[MyHighMemSize] ; End of memory
dec edx
mov eax,[RamdiskMax] ; Highest address allowed by kernel
cmp edx,eax
@@ -670,6 +674,7 @@ boot_image_len equ $-boot_image
section .bss
alignb 4
+MyHighMemSize resd 1 ; Possibly adjusted highmem size
RamdiskMax resd 1 ; Highest address for ramdisk
KernelSize resd 1 ; Size of kernel in bytes
KernelSects resd 1 ; Size of kernel in sectors
diff --git a/ui.inc b/ui.inc
index 7e5ac112..69ba7dc6 100644
--- a/ui.inc
+++ b/ui.inc
@@ -297,19 +297,14 @@ clin_opt_ok:
; Now check if it is a "virtual kernel"
;
vk_check:
- xor si,si ; Beginning of vk_seg
+ mov esi,[HighMemSize] ; Start from top of memory
.scan:
- cmp si,[VKernelBytes]
- jae .not_vk
-
- push ds
- push word vk_seg
- pop ds
+ cmp esi,[VKernelEnd]
+ jbe .not_vk
mov di,VKernelBuf
call rllunpack
- pop ds
- ; SI updated on return
+ ; ESI updated on return
sub di,cx ; Return to beginning of buf
push si