summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2002-06-11 05:48:29 +0000
committerhpa <hpa>2002-06-11 05:48:29 +0000
commitabac6f53695c0b99e0235ca3da81ab3cd822f475 (patch)
tree42c9c90abcb685ec654b25e680f6a0e272d1fe52
parent73d0682dcdd250939e560d333b591d7a5a8299ca (diff)
downloadsyslinux-abac6f53695c0b99e0235ca3da81ab3cd822f475.tar.gz
Add an API for COMBOOT images, and add support for "COM32" -- 32-bit
linear .com files.
-rw-r--r--Makefile29
-rw-r--r--NEWS5
-rw-r--r--bcopy32.inc5
-rw-r--r--com32.inc319
-rw-r--r--comboot.doc266
-rw-r--r--comboot.inc277
-rw-r--r--config.inc7
-rw-r--r--conio.inc2
-rw-r--r--cpuinit.inc38
-rw-r--r--highmem.inc107
-rw-r--r--isolinux.asm15
-rw-r--r--ldlinux.asm18
-rw-r--r--pxelinux.asm21
-rw-r--r--runkernel.inc82
-rw-r--r--sample/Makefile18
-rw-r--r--sample/hello.c47
-rw-r--r--version2
-rwxr-xr-xversion.pl25
18 files changed, 1102 insertions, 181 deletions
diff --git a/Makefile b/Makefile
index 761dd7ef..a3cd0839 100644
--- a/Makefile
+++ b/Makefile
@@ -41,12 +41,13 @@ CSRC = syslinux.c gethostip.c
NASMSRC = ldlinux.asm syslinux.asm copybs.asm \
pxelinux.asm mbr.asm isolinux.asm isolinux-debug.asm
SOURCES = $(CSRC) $(NASMSRC) *.inc
-BTARGET = kwdhash.gen ldlinux.bss ldlinux.sys ldlinux.bin \
+BTARGET = kwdhash.gen version.gen ldlinux.bss ldlinux.sys ldlinux.bin \
pxelinux.0 mbr.bin isolinux.bin isolinux-debug.bin
ITARGET = syslinux.com syslinux copybs.com gethostip
DOCS = COPYING NEWS README TODO *.doc sample
OTHER = Makefile bin2c.pl now.pl genhash.pl keywords findpatch.pl \
- keytab-lilo.pl version sys2ansi.pl ppmtolss16 lss16toppm memdisk
+ keytab-lilo.pl version version.pl sys2ansi.pl \
+ ppmtolss16 lss16toppm memdisk
OBSOLETE = pxelinux.bin
# Things to install in /usr/bin
@@ -79,22 +80,22 @@ samples:
memdisk:
$(MAKE) -C memdisk all
+version.gen: version version.pl
+ $(PERL) version.pl version
+
kwdhash.gen: keywords genhash.pl
$(PERL) genhash.pl < keywords > kwdhash.gen
-ldlinux.bin: ldlinux.asm kwdhash.gen
- $(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
- -dHEXDATE="$(HEXDATE)" \
+ldlinux.bin: ldlinux.asm kwdhash.gen version.gen
+ $(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l ldlinux.lst -o ldlinux.bin ldlinux.asm
-pxelinux.bin: pxelinux.asm kwdhash.gen
- $(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
- -dHEXDATE="$(HEXDATE)" \
+pxelinux.bin: pxelinux.asm kwdhash.gen version.gen
+ $(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l pxelinux.lst -o pxelinux.bin pxelinux.asm
-isolinux.bin: isolinux.asm kwdhash.gen
- $(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
- -dHEXDATE="$(HEXDATE)" \
+isolinux.bin: isolinux.asm kwdhash.gen version.gen
+ $(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l isolinux.lst -o isolinux.bin isolinux.asm
pxelinux.0: pxelinux.bin
@@ -102,8 +103,7 @@ pxelinux.0: pxelinux.bin
# Special verbose version of isolinux.bin
isolinux-debug.bin: isolinux-debug.asm kwdhash.gen
- $(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
- -dHEXDATE="$(HEXDATE)" \
+ $(NASM) -f bin -DDATE_STR="'$(DATE)'" -DHEXDATE="$(HEXDATE)" \
-l isolinux-debug.lst -o isolinux-debug.bin isolinux-debug.asm
ldlinux.bss: ldlinux.bin
@@ -136,7 +136,8 @@ syslinux: syslinux.o bootsect_bin.o ldlinux_bin.o
syslinux.o bootsect_bin.o ldlinux_bin.o
syslinux.o: syslinux.c patch.offset
- $(CC) $(INCLUDE) $(CFLAGS) -DPATCH_OFFSET=`cat patch.offset` -c -o $@ $<
+ $(CC) $(INCLUDE) $(CFLAGS) -DPATCH_OFFSET=`cat patch.offset` \
+ -c -o $@ $<
gethostip.o: gethostip.c
diff --git a/NEWS b/NEWS
index aa7b920d..024a0cd4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
Starting with 1.47, changes marked with SYSLINUX/PXELINUX/ISOLINUX
apply to that specific program only; other changes apply to both.
+Changes in 2.00:
+ * ALL: Add support for "COM32" (32-bit COMBOOT) images.
+ * ALL: Add an API for COMBOOT/COM32 images. See comboot.doc
+ for details.
+
Changes in 1.75:
* ALL: NASM 0.98.32 or later is now required to build
SYSLINUX from sources.
diff --git a/bcopy32.inc b/bcopy32.inc
index d81f00b7..c3be39a9 100644
--- a/bcopy32.inc
+++ b/bcopy32.inc
@@ -43,6 +43,11 @@ bcopy_gdt: dw bcopy_gdt_size-1 ; Null descriptor - contains GDT
dd 008f9300h ; present, dpl 0, cover all 4G
dd 0000ffffh ; Data segment, use16, read/write,
dd 00009300h ; present, dpl 0, cover 64K
+ ; The rest are used for COM32 only
+ dd 0000ffffh ; Code segment, use32, readable,
+ dd 00cf9b00h ; present, dpl 0, cover all 4G
+ dd 0000ffffh ; Data segment, use32, read/write,
+ dd 00cf9300h ; present, dpl 0, cover all 4G
bcopy_gdt_size: equ $-bcopy_gdt
;
diff --git a/com32.inc b/com32.inc
new file mode 100644
index 00000000..ac0440f8
--- /dev/null
+++ b/com32.inc
@@ -0,0 +1,319 @@
+;; $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.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; com32.inc
+;;
+;; Common code for running a COM32 image
+;;
+
+;
+; Load a COM32 image. A COM32 image is the 32-bit analogue to a DOS
+; .com file. A COM32 image is loaded at address 0x101000, with %esp
+; set to the high end of usable memory.
+;
+; A COM32 image should begin with the magic bytes:
+; B8 FF 4C CD 21, which is "mov eax,0x21cd4cff" in 32-bit mode and
+; "mov ax,0x4cff; int 0x21" in 16-bit mode. This will abort the
+; program with an error if run in 16-bit mode.
+;
+pm_idt: equ 0x100000
+pm_entry: equ 0x101000
+
+ bits 16
+ align 2
+com32_pmidt:
+ dw 8*256 ; Limit
+ dd pm_idt ; Address
+
+com32_rmidt:
+ dw 0ffffh ; Limit
+ dd 0 ; Address
+
+is_com32_image:
+ call highmemsize ; We need the high memory size...
+ call comboot_setup_api ; Set up the COMBOOT-style API
+
+ mov edi,pm_entry ; Load address
+ xchg eax,edx ; Gotta fix this insanity...
+ shl eax,16
+ mov ax,dx
+ call load_high
+ call crlf
+
+com32_start:
+ mov ebx,com32_call_start ; Where to go in PM
+
+com32_enter_pm:
+ mov [SavedSSSP],sp
+ mov [SavedSSSP+2],ss
+
+ cli
+ cld
+ call a20_test
+ jnz .a20ok
+ call enable_a20
+
+.a20ok:
+ lgdt [bcopy_gdt] ; We can use the same GDT just fine
+ lidt [com32_pmidt] ; Set up the IDT
+ mov eax,cr0
+ or al,1
+ mov cr0,eax ; Enter protected mode
+ jmp 20h:.in_pm
+
+ bits 32
+.in_pm:
+ xor eax,eax ; Available for future use...
+ mov fs,eax
+ mov gs,eax
+
+ mov al,28h ; Set up data segments
+ mov es,eax
+ mov ds,eax
+ mov ss,eax
+
+ mov esp,[PMESP] ; Load protmode %esp if available
+ jmp ebx ; Go to where we need to go
+
+;
+; This is invoked right before the actually starting the COM32
+; progam, in 32-bit mode...
+;
+com32_call_start:
+ ;
+ ; Point the stack to the end of high memory
+ ;
+ mov esp,[word HighMemSize]
+
+ ;
+ ; Set up the protmode IDT and the interrupt jump buffers
+ ; We set these up in the system area at 0x100000,
+ ; but we could also put them beyond the stack.
+ ;
+ mov edi,pm_idt
+
+ ; Form an interrupt gate descriptor
+ mov eax,0x00200000+((pm_idt+8*256)&0x0000ffff)
+ mov ebx,0x0000ee00+((pm_idt+8*256)&0xffff0000)
+ xor ecx,ecx
+ inc ch ; ecx <- 256
+
+ push ecx
+.make_idt:
+ stosd
+ add eax,8
+ xchg eax,ebx
+ stosd
+ xchg eax,ebx
+ loop .make_idt
+
+ pop ecx
+
+ ; Each entry in the interrupt jump buffer contains
+ ; the following instructions:
+ ;
+ ; 00000000 60 pushad
+ ; 00000001 B0xx mov al,<interrupt#>
+ ; 00000003 E9xxxxxxxx jmp com32_handle_interrupt
+
+ mov eax,0e900b060h
+ mov ebx,com32_handle_interrupt-(pm_idt+8*256+8)
+
+.make_ijb:
+ stosd
+ sub [edi-2],cl ; Interrupt #
+ xchg eax,ebx
+ stosd
+ sub eax,8
+ xchg eax,ebx
+ loop .make_ijb
+
+ ; Now everything is set up for interrupts...
+
+ push dword (1 << 16) ; 64K bounce buffer
+ push dword (comboot_seg << 4) ; Bounce buffer address
+ push dword com32_syscall ; Syscall entry point
+ movzx esi,word [word CmdOptPtr]
+ push esi ; Command line pointer
+ push dword 4 ; Argument count
+ sti ; Interrupts OK now
+ call pm_entry ; Run the program...
+ ; ... on return, fall through to com32_exit ...
+
+com32_exit:
+ mov bx,com32_done ; Return to command loop
+
+com32_enter_rm:
+ cli
+ cld
+ mov [PMESP],esp ; Save exit %esp
+ xor esp,esp ; Make sure the high bits are zero
+ jmp 08h:.in_pm16 ; Return to 16-bit mode first
+
+ bits 16
+.in_pm16:
+ mov ax,18h ; Real-mode-like segment
+ mov es,ax
+ mov ds,ax
+ mov ss,ax
+ mov fs,ax
+ mov gs,ax
+
+ lidt [com32_rmidt] ; Real-mode IDT (rm needs no GDT)
+ mov eax,cr0
+ and al,~1
+ mov cr0,eax
+ jmp 0:.in_rm
+
+.in_rm: ; Back in real mode
+ mov ax,cs ; Set up sane segments
+ mov ds,ax
+ mov es,ax
+ mov fs,ax
+ mov gs,ax
+ lss sp,[SavedSSSP] ; Restore stack
+ jmp bx ; Go to whereever we need to go...
+
+com32_done:
+ call disable_a20
+ sti
+ jmp enter_command
+
+;
+; 16-bit support code
+;
+ bits 16
+
+;
+; 16-bit interrupt-handling code
+;
+com32_int_rm:
+ pushf ; Flags on stack
+ push cs ; Return segment
+ push word .cont ; Return address
+ push dword edx ; Segment:offset of IVT entry
+ retf ; Invoke IVT routine
+.cont: ; ... on resume ...
+ mov ebx,com32_int_resume
+ jmp com32_enter_pm ; Go back to PM
+
+;
+; 16-bit system call handling code
+;
+com32_sys_rm:
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ popad
+ popfd
+ retf ; Invoke routine
+.return:
+ pushfd
+ pushad
+ push ds
+ push es
+ push fs
+ push gs
+ mov ebx,com32_sys_resume
+ jmp com32_enter_pm
+
+;
+; 32-bit support code
+;
+ bits 32
+
+;
+; This is invoked on getting an interrupt in protected mode. At
+; this point, we need to context-switch to real mode and invoke
+; the interrupt routine.
+;
+; When this gets invoked, the registers are saved on the stack and
+; AL contains the register number.
+;
+com32_handle_interrupt:
+ movzx eax,al
+ xor ebx,ebx ; Actually makes the code smaller
+ mov edx,[ebx+eax*4] ; Get the segment:offset of the routine
+ mov bx,com32_int_rm
+ jmp com32_enter_rm ; Go to real mode
+
+com32_int_resume:
+ popad
+ iret
+
+;
+; Syscall invocation. We manifest a structure on the real-mode stack,
+; containing the com32sys_t structure from <com32.h> as well as
+; the following entries (from low to high address):
+; - Target offset
+; - Target segment
+; - Return offset
+; - Return segment (== real mode cs == 0)
+; - Return flags
+;
+com32_syscall:
+ pushfd ; Save IF among other things...
+ pushad ; We only need to save some, but...
+ cld
+
+ movzx edi,word [word SavedSSSP]
+ movzx eax,word [word SavedSSSP+2]
+ sub edi,54 ; Allocate 54 bytes
+ mov [word SavedSSSP],di
+ shl eax,4
+ add edi,eax ; Create linear address
+
+ mov esi,[esp+11*4] ; Source regs
+ xor ecx,ecx
+ mov cl,11 ; 44 bytes to copy
+ rep movsd
+
+ movzx eax,byte [esp+10*4] ; Interrupt number
+ ; ecx == 0 here; adding it to the EA makes the
+ ; encoding smaller
+ mov eax,[ecx+eax*4] ; Get IVT entry
+ stosd ; Save in stack frame
+ mov eax,com32_sys_rm.return ; Return seg:offs
+ stosd ; Save in stack frame
+ mov eax,[edi-12] ; Return flags
+ and eax,0x200cd7 ; Mask (potentially) unsafe flags
+ mov [edi-12],eax ; Primary flags entry
+ stosw ; Return flags
+
+ mov bx,com32_sys_rm
+ jmp com32_enter_rm ; Go to real mode
+
+ ; On return, the 44-byte return structure is on the
+ ; real-mode stack.
+com32_sys_resume:
+ movzx esi,word [word SavedSSSP]
+ movzx eax,word [word SavedSSSP+2]
+ mov edi,[esp+12*4] ; Dest regs
+ shl eax,4
+ add esi,eax ; Create linear address
+ and edi,edi ; NULL pointer?
+ jnz .do_copy
+.no_copy: mov edi,esi ; Do a dummy copy-to-self
+.do_copy: xor ecx,ecx
+ mov cl,11 ; 44 bytes
+ rep movsd ; Copy register block
+
+ add dword [word SavedSSSP],44 ; Remove from stack
+
+ popad
+ popfd
+ ret ; Return to 32-bit program
+
+ bits 16
diff --git a/comboot.doc b/comboot.doc
new file mode 100644
index 00000000..db9203ac
--- /dev/null
+++ b/comboot.doc
@@ -0,0 +1,266 @@
+$Id$
+
+ COMBOOT and COM32 files
+
+
+SYSLINUX supports simple standalone programs, using a file format
+similar to DOS ".com" files. A 32-bit version, called COM32, is also
+provided. A simple API provides access to a limited set of filesystem
+and console functions.
+
+
+ ++++ COMBOOT file format ++++
+
+A COMBOOT file is a raw binary file containing 16-bit code. It should
+be linked to run at offset 0x100, and contain no absolute segment
+references. It is run in 16-bit real mode.
+
+A COMBOOT image can be written to be compatible with MS-DOS. Such a
+file will usually have extension ".com". A COMBOOT file which is not
+compatible with MS-DOS will usually have extension ".cbt".
+
+Before running the program, SYSLINUX sets up the following fields in
+the Program Segment Prefix (PSP), a structure at offset 0 in the
+program segment:
+
+ Offset Size Meaning
+ 0 word Contains an INT 20h instruction
+ 2 word Contains the paragraph (16-byte "segment" address) at
+ the end of memory available to the program.
+ 128 byte Length of the command line arguments, including the leading
+ space but not including the final CR character.
+ 129 127b Command line arguments, starting with a space and ending
+ with a CR character (ASCII 13).
+
+The program is allowed to use memory between the PSP paragraph (which
+all the CS, DS, ES and SS registers point to at program start) and the
+paragraph value given at offset 2.
+
+On startup, SP is set up to point to the end of the 64K segment, at
+0xfffe. Under DOS it is possible for SP to contain a smaller
+value if memory is very tight; this is never the case under SYSLINUX.
+
+The program should make no assumptions about what segment address it
+will be loaded at; instead it should look at the segment registers on
+program startup. Both DOS and SYSLINUX will guarantee CS == DS == ES
+== SS on program start; the program should not assume anything about
+the values of FS or GS.
+
+To exit, a program can either execute a near RET (which will jump to
+offset 0 which contains an INT 20h instruction, terminating the
+program), or execute INT 20h or INT 21h AH=00h or INT 21h AH=4Ch.
+If compatiblity with SYSLINUX 1.xx is desired, use INT 20h.
+
+
+ ++++ COM32 file format ++++
+
+A COM32 file is a raw binary file containing 32-bit code. It should
+be linked to run at address 0x101000, and should not contain any
+segment references. It will be run in flat-memory 32-bit protected
+mode. Under SYSLINUX, it will be run in CPL 0, however, since it may
+be possible to create a COM32 execution engine that would run under
+something like Linux DOSEMU, it is recommended that the code does not
+assume CPL 0 unless absolutely necessary.
+
+A COM32 file should have extension ".c32".
+
+On startup, CS will be set up as a flat 32-bit code segment, and DS ==
+ES == SS will be set up as the equivalent flat 32-bit data segment.
+FS and GS are reserved for future use and are currently initialized to
+zero. A COM32 image should not assume any particular values of
+segment selectors.
+
+ESP is set up at the end of available memory and also serves as
+notification to the program how much memory is available.
+
+The following arguments are passed to the program on the stack:
+
+ Address Size Meaning
+ [ESP+4] dword Number of additional arguments (currently 4)
+ [ESP+8] dword Pointer to the command line arguments (null-terminated string)
+ [ESP+12] dword Pointer to system call helper function
+ [ESP+16] dword Pointer to low memory bounce buffer
+ [ESP+20] dword Size of low memory bounce buffer
+
+This corresponds to the following C prototype, available in the file com32.h:
+
+/* The standard prototype for _start() */
+int _start(unsigned int __nargs,
+ char *__cmdline,
+ void (*__syscall)(unsigned char, com32sys_t *, com32sys_t *),
+ void *__bounce_ptr,
+ unsigned int __bounce_len);
+
+The system call helper function can be used to issue BIOS or SYSLINUX
+API calls, and takes the interrupt number as first argument. The
+second argument is a pointer to the input register definition, an
+instance of the following structure (also available in com32.h):
+
+typedef struct {
+ unsigned short gs; /* Offset 0 */
+ unsigned short fs; /* Offset 2 */
+ unsigned short es; /* Offset 4 */
+ unsigned short ds; /* Offset 6 */
+
+ unsigned int edi; /* Offset 8 */
+ unsigned int esi; /* Offset 12 */
+ unsigned int ebp; /* Offset 16 */
+ unsigned int _unused; /* Offset 20 */
+ unsigned int ebx; /* Offset 24 */
+ unsigned int edx; /* Offset 28 */
+ unsigned int ecx; /* Offset 32 */
+ unsigned int eax; /* Offset 36 */
+
+ unsigned int eflags; /* Offset 40 */
+} com32sys_t;
+
+The third argument is a pointer to the output register definition, an
+instance of the same structure. The third argument can also be zero
+(NULL).
+
+Since BIOS or SYSLINUX API calls can generally only manipulate data
+below address 0x100000, a "bounce buffer" in low memory, at least 64K
+in size, is available, to copy data in and out.
+
+
+ ++++ SYSLINUX API CALLS +++
+
+SYSLINUX provides the following API calls. SYSLINUX 1.xx only
+supported INT 20h - terminate program.
+
+
+ ++++ DOS-COMPATIBLE API CALLS ++++
+
+INT 20h: Terminate program
+INT 21h AH=00h Terminate program
+
+ ++++ SYSLINUX-SPECIFIC API CALLS ++++
+
+SYSLINUX-specific API calls are executed using INT 22h, with a
+function number in AX. INT 22h is used by DOS for internal purposes;
+do not execute INT 22h under DOS.
+
+DOS-compatible function INT 21h, AH=30h can be used to detect if the
+SYSLINUX API calls are available.
+
+All INT 22h API calls may clobber the general-purpose registers (EAX,
+EBX, ECX, EDX, EBP, ESI and EDI). Segment registers are left
+unchanged unless otherwise noted.
+
+All calls return CF=0 on success, CF=1 on failure. The noted outputs
+apply if CF=0 only unless otherwise noted.
+
+
+AX=0000h No Operation
+
+ Input: AX 0000h
+ Output: None
+
+ This API call does nothing.
+
+
+AX=0001h Get Version
+
+ Input: AX 0001h
+ Output: AX number of INT 22h API functions available
+ CH SYSLINUX major version number
+ CL SYSLINUX minor version number
+ DL SYSLINUX derivative ID (e.g. 32h = PXELINUX)
+ ES:SI SYSLINUX version string
+ ES:DI SYSLINUX copyright string
+
+ This API call returns the SYSLINUX version and API
+ information.
+
+
+AX=0002h Write String
+
+ Input: AX 0002h
+ ES:BX null-terminated string
+ Output: None
+
+ Writes a null-terminated string on the console.
+
+
+AX=0003h Run command
+
+ Input: AX 0003h
+ ES:BX null-terminated command string
+ Output: None
+
+ This API call terminates the program and executes the command
+ string as if the user had entered it at the SYSLINUX command
+ line. This API call does not return.
+
+
+AX=0004h Run default command
+
+ Input: AX 0004h
+ Output: None
+
+ This API call terminates the program and executes the default
+ command string as if the user had pressed Enter alone on the
+ SYSLINUX command line. This API call does not return.
+
+
+AX=0005h Force text mode
+
+ Input: AX 0005h
+ Output: None
+
+ If the screen was in graphics mode (due to displaying a splash
+ screen using the <Ctrl-X> command in a message file, or
+ similar), return to text mode.
+
+
+AX=0006h Open file
+
+ Input: AX 0006h
+ ES:SI null-terminated filename
+ Output: SI file handle
+ EAX length of file in bytes
+ CX file block size
+
+ Open a file for reading. The exact syntax of the filenames
+ allowed depends on the particular SYSLINUX derivative.
+
+ The SYSLINUX file system is block-oriented. The size of a
+ block will always be a power of two and no greater than 16K.
+
+ Note: SYSLINUX considers a zero-length file to be nonexistent.
+
+
+AX=0007h Read file
+
+ Input: AX 0007h
+ SI file handle
+ ES:BX buffer
+ CX number of blocks to read
+ Output: SI file handle, or 0 if EOF was reached
+
+ Read blocks from a file. Note that the file handle that is
+ returned in SI may not be the same value that was passed in.
+
+ If end of file was reached (SI=0), the file was automatically
+ closed.
+
+ The address of the buffer (ES:BX) should be at least 512-byte
+ aligned. SYSLINUX guarantees at least this alignment for the
+ COMBOOT load segment or the COM32 bounce buffer.
+
+ WARNING: Calling this function with an invalid file handle
+ will probably crash the system.
+
+
+AX=0008h Close file
+
+ Input: AX 0008h
+ SI file handle
+ Output: None
+
+ Close a file before reaching the end of file.
+
+ WARNING: Calling this function with an invalid file handle
+ will probably crash the system.
+
+
diff --git a/comboot.inc b/comboot.inc
index 5d7019ed..319e5005 100644
--- a/comboot.inc
+++ b/comboot.inc
@@ -21,7 +21,7 @@
comboot_too_large:
mov si,err_comlarge
call cwritestr
-cb_enter: jmp enter_command
+ jmp enter_command
;
; Load a COMBOOT image. A COMBOOT image is basically a DOS .COM file,
@@ -34,17 +34,7 @@ is_comboot_image:
cmp ax,0ff00h ; Max size in bytes
jae comboot_too_large
- ;
- ; Set up the DOS vectors in the IVT (INT 20h-3fh)
- ;
- mov di,4*0x20 ; DOS interrupt vectors
- mov eax,comboot_return
- stosd
- mov ax,comboot_int21
- stosd
- mov ax,comboot_bogus
- mov cx,30 ; All remaining DOS vectors
- rep stosd
+ call comboot_setup_api
mov cx,comboot_seg
mov es,cx
@@ -84,8 +74,6 @@ comboot_end_cmd: mov al,0Dh ; CR after last character
mov [SavedSSSP],sp
mov [SavedSSSP+2],ss ; Save away SS:SP
- call vgaclearmode ; Reset video
-
mov ax,es
mov ds,ax
mov ss,ax
@@ -99,9 +87,40 @@ comboot_return: cli ; Don't trust anyone
xor ax,ax
jmp comboot_exit
+;
+; Set up the COMBOOT API interrupt vectors. This is also used
+; by the COM32 code.
+;
+comboot_setup_api:
+ mov di,4*0x20 ; DOS interrupt vectors
+ mov eax,comboot_return ; INT 20h = exit
+ stosd
+ mov ax,comboot_int21 ; INT 21h = DOS-compatible syscalls
+ stosd
+ mov ax,comboot_int22 ; INT 22h = proprietary syscalls
+ stosd
+ mov ax,comboot_bogus
+ mov cx,29 ; All remaining DOS vectors
+ rep stosd
+ ret
+
; INT 21h: generic DOS system call
-comboot_int21: and ah,ah ; 00 = return
+comboot_int21: push ds
+ push cs
+ pop ds ; Set DS <- CS
+ and ah,ah ; 00 = return
je comboot_return
+ cmp ah,02h
+ jb comboot_getkeyecho ; 01 = get key with echo
+ je comboot_writechr ; 02 = writechr
+ cmp ah,08h ; 08 = get key w/o echo
+ je comboot_getkey
+ cmp ah,09h ; 09 = writestr
+ je comboot_writestr
+ cmp ah,0Bh ; 0B = check keyboard
+ je comboot_checkkey
+ cmp ah,30h ; 30 = check version
+ je comboot_checkver
cmp ah,4Ch ; 4C = return with status
je comboot_return
@@ -110,15 +129,18 @@ comboot_int21: and ah,ah ; 00 = return
; Attempted to execute non-21h DOS system call
comboot_bogus: cli ; Don't trust anyone
mov ax,err_notdos
-
;
; Generic COMBOOT return to command line code
+; AX -> message (if any)
+; BX -> where to go next
;
comboot_exit:
- lss sp,[cs:SavedSSSP]
+ mov bx,enter_command ; Normal return to command prompt
+comboot_exit_special:
xor dx,dx
mov ds,dx
mov es,dx
+ lss sp,[SavedSSSP]
sti
cld
and ax,ax
@@ -127,5 +149,224 @@ comboot_exit:
call cwritestr
xchg si,ax
call cwritestr
-.nomsg: jmp cb_enter
+.nomsg: jmp bx
+
+;
+; INT 21h system calls
+;
+comboot_getkeyecho: ; 01 = get key with echo
+ call vgashowcursor
+ call getchar
+ call vgahidecursor
+ call writechr
+ jmp comboot_resume_ok
+
+comboot_writechr: ; 02 = writechr
+ xchg ax,dx
+ call writechr
+ xchg ax,dx
+ jmp comboot_resume_ok
+
+comboot_getkey: ; 08 = get key w/o echo
+ call vgashowcursor
+ call getchar
+ call vgahidecursor
+ jmp comboot_resume_ok
+
+comboot_writestr: ; 09 = write string
+ pusha
+ push es
+ mov bp,sp
+ mov es,[bp-20] ; Old DS
+ mov si,dx
+.loop: es lodsb
+ cmp al,'$' ; End string with $ - bizarre
+ je .done
+ call writechr
+ jmp short .loop
+.done: pop es
+ popa
+ jmp comboot_resume_ok
+
+comboot_checkkey: ; 0B = check keyboard status
+ call pollchar
+ setz al
+ dec al ; AL = 0FFh if present, 0 if not
+ jmp comboot_resume_ok
+
+comboot_checkver: ; 30 = check DOS version
+ ; We return 0 in all DOS-compatible version registers,
+ ; but the high part of eax-ebx-ecx-edx spell "SYSLINUX"
+ mov eax,'SY' << 16
+ mov ebx,'SL' << 16
+ mov ecx,'IN' << 16
+ mov edx,'UX' << 16
+ ;jmp comboot_resume_ok
+
+;
+; Resume comboot execution
+;
+comboot_resume_ok:
+ clc
+comboot_resume:
+ pop ds
+ iret
+
+comboot_apierr:
+ stc
+ jmp comboot_resume
+
+;
+; INT 22h - SYSLINUX-specific system calls
+; System call number in ax
+;
+comboot_int22:
+ push ds
+ push cs
+ pop ds
+
+ cmp ax,int22_count
+ jae comboot_apierr
+
+ xchg ax,bx
+ add bx,bx
+ call [bx+int22_table]
+ jmp comboot_resume ; On return
+
+;
+; INT 22h AX=0000h Null system call
+; INT 22h AX=0001h Get SYSLINUX version
+;
+comapi_get_version:
+ ; Number of API functions supported
+ mov ax,int22_count
+ ; SYSLINUX version
+ mov cx,(VER_MAJOR << 8)+VER_MINOR
+ ; SYSLINUX derivative ID byte
+ mov dx,my_id
+ ; For future use
+ xor bx,bx
+
+ push cs
+ pop es
+ ; ES:SI -> version banner
+ mov si,syslinux_banner
+ ; ES:DI -> copyright string
+ mov di,copyright_str
+
+comapi_nop:
+ clc
+ ret
+
+;
+; INT 22h AX=0002h Write string
+;
+; Write null-terminated string in ES:BX
+;
+comapi_writestr:
+ push es
+ pop ds
+ mov si,ax
+ jmp writestr ; Write string from ES:BX
+
+;
+; INT 22h AX=0003h Run command
+;
+; Terminates the COMBOOT program and executes the command line in
+; ES:BX as if it had been entered by the user.
+;
+comapi_run:
+ push es
+ push ds
+ pop es
+ pop ds
+ mov si,ax
+ mov di,command_line
+.copyloop:
+ lodsb
+ stosb
+ and al,al
+ jnz .copyloop
+ xor ax,ax
+ mov bx,load_kernel ; Run a new kernel
+ jmp comboot_exit_special ; Terminate task, clean up
+
+;
+; INT 22h AX=0004h Run default command
+;
+; Terminates the COMBOOT program and executes the default command line
+; as if a timeout had happened or the user pressed <Enter>.
+;
+comapi_run_default:
+ mov bx,auto_boot
+ jmp comboot_exit_special
+
+;
+; INT 22h AX=0005h Force text mode
+;
+; Puts the video in standard text mode
+;
+comapi_textmode:
+ call vgaclearmode
+ clc
+ ret
+
+;
+; INT 22h AX=0006h Open file
+;
+comapi_open:
+ push ds
+ push ds
+ push es
+ pop ds
+ pop es
+ mov di,InitRD
+ push di
+ call mangle_name
+ pop di
+ pop ds
+ call searchdir
+ jz .err
+ xchg eax,edx
+ shr eax,16
+ xchg ax,dx
+ mov cx,[SecPerClust]
+ clc
+ ret
+.err:
+ stc
+ ret
+
+
+;
+; INT 22h AX=0007h Read file
+;
+comapi_read:
+ xchg ax,bx
+ call getfssec
+ jnc .noteof
+ xor si,si ; SI <- 0 on EOF, CF <- 0
+.noteof: ret
+
+;
+; INT 22h AX=0008h Close file
+;
+comapi_close:
+ ; Do nothing for now. Eventually implement
+ ; an internal API for this.
+ clc
+ ret
+
+ align 2, db 0
+int22_table:
+ dw comapi_nop ; 0000 null 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
+int22_count equ ($-int22_table)/2
diff --git a/config.inc b/config.inc
index 3282d5b9..52a1846a 100644
--- a/config.inc
+++ b/config.inc
@@ -28,6 +28,13 @@ BAUD_DIVISOR equ 115200 ; Serial port parameter
%assign DO_WBINVD 0 ; Should we use WBINVD or not?
;
+; Version number definitinons
+;
+%ifndef DEPEND ; Generated file
+%include "version.gen"
+%endif
+
+;
; Should be updated with every release to avoid bootsector/SYS file mismatch
;
%define version_str VERSION ; Must be 4 characters long!
diff --git a/conio.inc b/conio.inc
index 5850b9df..7dc1572e 100644
--- a/conio.inc
+++ b/conio.inc
@@ -158,7 +158,7 @@ msg_formfeed: ; Form feed character
mov bh,[TextAttribute]
mov ax,0600h ; Clear screen region
int 10h
- jmp short msg_gotoxy
+ jmp msg_gotoxy
msg_setbg: ; Color background character
call unhexchar
jc msg_color_bad
diff --git a/cpuinit.inc b/cpuinit.inc
index a6923b54..b63ae64d 100644
--- a/cpuinit.inc
+++ b/cpuinit.inc
@@ -17,49 +17,13 @@
;; CPU-dependent initialization and related checks.
;;
-;
-; Check that no moron is trying to boot Linux on a 286 or so. According
-; to Intel, the way to check is to see if the high 4 bits of the FLAGS
-; register are either all stuck at 1 (8086/8088) or all stuck at 0
-; (286 in real mode), if not it is a 386 or higher. They didn't
-; say how to check for a 186/188, so I *hope* it falls out as a 8086
-; or 286 in this test.
-;
-; Also, provide an escape route in case it doesn't work.
-;
check_escapes:
mov ah,02h ; Check keyboard flags
int 16h
mov [KbdFlags],al ; Save for boot prompt check
test al,04h ; Ctrl->skip 386 check
jnz skip_checks
-test_8086:
- pushf ; Get flags
- pop ax
- and ax,0FFFh ; Clear top 4 bits
- push ax ; Load into FLAGS
- popf
- pushf ; And load back
- pop ax
- and ax,0F000h ; Get top 4 bits
- cmp ax,0F000h ; If set -> 8086/8088
- je not_386
-test_286:
- pushf ; Get flags
- pop ax
- or ax,0F000h ; Set top 4 bits
- push ax
- popf
- pushf
- pop ax
- and ax,0F000h ; Get top 4 bits
- jnz is_386 ; If not clear -> 386
-not_386:
- mov si,err_not386
- call writestr
- jmp kaboom
-is_386:
- ; Now we know it's a 386 or higher
+
;
; Now check that there is sufficient low (DOS) memory
;
diff --git a/highmem.inc b/highmem.inc
new file mode 100644
index 00000000..e3a830b7
--- /dev/null
+++ b/highmem.inc
@@ -0,0 +1,107 @@
+;; $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.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; highmem.inc
+;;
+;; Probe for the size of high memory. This can be overridden by a
+;; mem= command on the command line while booting a new kernel.
+;;
+
+;
+; This is set up as a subroutine; it will set up the global variable
+; HighMemSize. All registers are preserved. Assumes DS == CS.
+;
+highmemsize:
+ push es
+ pushad
+
+;
+; First, try INT 15:E820 (get BIOS memory map)
+;
+get_e820:
+ xor ebx,ebx ; Start with first record
+ mov es,bx ; Need ES = DS = 0 for now
+ jmp short .do_e820 ; Skip "at end" check first time!
+.int_loop: and ebx,ebx ; If we're back at beginning...
+ jz no_e820 ; ... bail; nothing found
+.do_e820: mov eax,0000E820h
+ mov edx,534D4150h ; "SMAP" backwards
+ xor ecx,ecx
+ mov cl,20 ; ECX <- 20
+ mov di,E820Buf
+ int 15h
+ jc no_e820
+ cmp eax,534D4150h
+ jne no_e820
+;
+; Look for a memory block starting at <= 1 MB and continuing upward
+;
+ cmp dword [E820Buf+4], byte 0
+ ja .int_loop ; Start >= 4 GB?
+ mov edx, (1 << 20)
+ sub edx, [E820Buf]
+ jb .int_loop ; Start >= 1 MB?
+ stc
+ sbb eax,eax ; eax <- 0xFFFFFFFF
+ cmp dword [E820Buf+12], byte 0
+ ja .huge ; Size >= 4 GB
+ mov eax, [E820Buf+8]
+.huge: sub eax, edx ; Adjust size to start at 1 MB
+ jbe .int_loop ; Completely below 1 MB?
+
+ ; Now EAX contains the size of memory 1 MB...up
+ cmp dword [E820Buf+16], byte 1
+ jne near err_nohighmem ; High memory isn't usable memory!!!!
+
+ ; We're good!
+ jmp short got_highmem_add1mb ; Still need to add low 1 MB
+
+;
+; INT 15:E820 failed. Try INT 15:E801.
+;
+no_e820:
+ mov ax,0e801h ; Query high memory (semi-recent)
+ int 15h
+ jc no_e801
+ cmp ax,3c00h
+ ja no_e801 ; > 3C00h something's wrong with this call
+ jb e801_hole ; If memory hole we can only use low part
+
+ mov ax,bx
+ shl eax,16 ; 64K chunks
+ add eax,(16 << 20) ; Add first 16M
+ jmp short got_highmem
+
+;
+; INT 15:E801 failed. Try INT 15:88.
+;
+no_e801:
+ mov ah,88h ; Query high memory (oldest)
+ int 15h
+ cmp ax,14*1024 ; Don't trust memory >15M
+ jna e801_hole
+ mov ax,14*1024
+e801_hole:
+ and eax,0ffffh
+ shl eax,10 ; Convert from kilobytes
+got_highmem_add1mb:
+ add eax,(1 << 20) ; First megabyte
+got_highmem:
+%if HIGHMEM_SLOP != 0
+ sub eax,HIGHMEM_SLOP
+%endif
+ mov [HighMemSize],eax
+ popad
+ pop es
+ ret ; Done!
diff --git a/isolinux.asm b/isolinux.asm
index 6c847736..5d5e4185 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -145,6 +145,7 @@ HighMemSize resd 1 ; End of memory pointer (bytes)
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
+PMESP resd 1 ; Protected-mode ESP
RootDir resb dir_t_size ; Root directory
CurDir resb dir_t_size ; Current directory
KernelClust resd 1 ; Kernel size in clusters
@@ -1163,6 +1164,7 @@ kernel_corrupt: mov si,err_notkernel
;
; .com - COMBOOT image
; .cbt - COMBOOT image
+; .c32 - COM32 image
; .bs - Boot sector
; .0 - PXE bootstrap program (PXELINUX only)
; .bin - Boot sector
@@ -1202,6 +1204,8 @@ kernel_good:
je is_comboot_image
cmp ecx,'.cbt'
je is_comboot_image
+ cmp ecx,'.c32'
+ je is_com32_image
cmp ecx,'.img'
je is_disk_image
cmp ecx,'.bss'
@@ -1225,6 +1229,7 @@ kernel_good:
; COMBOOT-loading code
;
%include "comboot.inc"
+%include "com32.inc"
;
; Boot sector loading code
@@ -1845,6 +1850,7 @@ getfssec:
%include "loadhigh.inc" ; Load a file into high memory
%include "font.inc" ; VGA font stuff
%include "graphics.inc" ; VGA graphics
+%include "highmem.inc" ; High memory sizing
; -----------------------------------------------------------------------------
; Begin data section
@@ -1859,15 +1865,6 @@ boot_prompt db 'boot: ', 0
wipe_char db BS, ' ', BS, 0
err_notfound db 'Could not find kernel image: ',0
err_notkernel db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0
-err_not386 db 'It appears your computer uses a 286 or lower CPU.'
- db CR, LF
- db 'You cannot run Linux unless you have a 386 or higher CPU'
- db CR, LF
- db 'in your machine. If you get this message in error, hold'
- db CR, LF
- db 'down the Ctrl key while booting, and I will take your'
- db CR, LF
- db 'word for it.', CR, LF, 0
err_noram db 'It appears your computer has less than 360K of low ("DOS")'
db 0Dh, 0Ah
db 'RAM. Linux needs at least this amount to boot. If you get'
diff --git a/ldlinux.asm b/ldlinux.asm
index bf8ebbc2..f35deb6b 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -139,6 +139,7 @@ HighMemSize resd 1 ; End of memory pointer (bytes)
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
+PMESP resd 1 ; Protected-mode ESP
ClustPerMoby resd 1 ; Clusters per 64K
ClustSize resd 1 ; Bytes/cluster
KernelName resb 12 ; Mangled name for kernel
@@ -793,7 +794,8 @@ all_read_jmp:
; SI -> Starting cluster number (2-based)
; CX -> Cluster count (0FFFFh = until end of file)
;
- ; 386 check
+; Returns CF=1 on EOF
+;
getfssec:
getfragment: xor ebp,ebp ; Fragment sector count
movzx eax,si ; Get sector address
@@ -1311,6 +1313,7 @@ kernel_corrupt: mov si,err_notkernel
;
; .com - COMBOOT image
; .cbt - COMBOOT image
+; .c32 - COM32 image
; .bs - Boot sector
; .0 - PXE bootstrap program (PXELINUX only)
; .bin - Boot sector
@@ -1334,6 +1337,8 @@ kernel_good:
je is_comboot_image
cmp ecx,'CBT'
je is_comboot_image
+ cmp ecx,'C32'
+ je is_com32_image
cmp ecx,'BS '
je is_bootsector
cmp ecx,'BIN'
@@ -1351,6 +1356,7 @@ kernel_good:
; COMBOOT-loading code
;
%include "comboot.inc"
+%include "com32.inc"
;
; Boot sector loading code
@@ -1625,6 +1631,7 @@ lc_ret: ret
%include "loadhigh.inc" ; Load a file into high memory
%include "font.inc" ; VGA font stuff
%include "graphics.inc" ; VGA graphics
+%include "highmem.inc" ; High memory sizing
; -----------------------------------------------------------------------------
; Begin data section
@@ -1651,15 +1658,6 @@ boot_prompt db 'boot: ', 0
wipe_char db BS, ' ', BS, 0
err_notfound db 'Could not find kernel image: ',0
err_notkernel db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0
-err_not386 db 'It appears your computer uses a 286 or lower CPU.'
- db CR, LF
- db 'You cannot run Linux unless you have a 386 or higher CPU'
- db CR, LF
- db 'in your machine. If you get this message in error, hold'
- db CR, LF
- db 'down the Ctrl key while booting, and I will take your'
- db CR, LF
- db 'word for it.', CR, LF, 0
err_noram db 'It appears your computer has less than 488K of low ("DOS")'
db CR, LF
db 'RAM. Linux needs at least this amount to boot. If you get'
diff --git a/pxelinux.asm b/pxelinux.asm
index bb08d6e2..67894fa1 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -193,6 +193,7 @@ HighMemSize resd 1 ; End of memory pointer (bytes)
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
+PMESP resd 1 ; Protected-mode ESP
Stack resd 1 ; Pointer to reset stack
PXEEntry resd 1 ; !PXE API entry point
RebootTime resd 1 ; Reboot timeout, if set by option
@@ -1037,6 +1038,7 @@ kernel_corrupt: mov si,err_notkernel
;
; .com - COMBOOT image
; .cbt - COMBOOT image
+; .c32 - COM32 image
; .bs - Boot sector
; .0 - PXE bootstrap program (PXELINUX only)
; .bin - Boot sector
@@ -1078,6 +1080,8 @@ kernel_good:
je is_comboot_image
cmp ecx,'.cbt'
je is_comboot_image
+ cmp ecx,'.c32'
+ je is_com32_image
cmp ecx,'.bss'
je is_bss_image
cmp ecx,'.bin'
@@ -1124,6 +1128,7 @@ kernel_good:
; COMBOOT-loading code
;
%include "comboot.inc"
+%include "com32.inc"
;
; Boot sector loading code
@@ -2099,21 +2104,21 @@ parse_dhcp_options:
jne .not_subnet
mov edx,[si]
mov [Netmask],edx
- jmp short .opt_done
+ jmp .opt_done
.not_subnet:
cmp dl,3 ; ROUTER option
jne .not_router
mov edx,[si]
mov [Gateway],edx
- jmp short .opt_done
+ jmp .opt_done
.not_router:
cmp dl,52 ; OPTION OVERLOAD option
jne .not_overload
mov dl,[si]
mov [OverLoad],dl
- jmp short .opt_done
+ jmp .opt_done
.not_overload:
cmp dl,67 ; BOOTFILE NAME option
@@ -2222,6 +2227,7 @@ writestr equ cwritestr
%include "loadhigh.inc" ; Load a file into high memory
%include "font.inc" ; VGA font stuff
%include "graphics.inc" ; VGA graphics
+%include "highmem.inc" ; High memory sizing
; -----------------------------------------------------------------------------
; Begin data section
@@ -2238,15 +2244,6 @@ boot_prompt db 'boot: ', 0
wipe_char db BS, ' ', BS, 0
err_notfound db 'Could not find kernel image: ',0
err_notkernel db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0
-err_not386 db 'It appears your computer uses a 286 or lower CPU.'
- db CR, LF
- db 'You cannot run Linux unless you have a 386 or higher CPU'
- db CR, LF
- db 'in your machine. If you get this message in error, hold'
- db CR, LF
- db 'down the Ctrl key while booting, and I will take your'
- db CR, LF
- db 'word for it.', CR, LF, 0
err_noram db 'It appears your computer has less than 384K of low ("DOS")'
db 0Dh, 0Ah
db 'RAM. Linux needs at least this amount to boot. If you get'
diff --git a/runkernel.inc b/runkernel.inc
index eabb792b..3ee28f9b 100644
--- a/runkernel.inc
+++ b/runkernel.inc
@@ -96,89 +96,15 @@ kernel_sane: push ax
call getfssec
cmp word [es:bs_bootsign],0AA55h
jne kernel_corrupt ; Boot sec signature missing
-;
-; Get the BIOS' idea of what the size of high memory is.
-;
- push si ; Save our cluster pointer!
-;
-; First, try INT 15:E820 (get BIOS memory map)
-;
-get_e820:
- push es
- xor ebx,ebx ; Start with first record
- mov es,bx ; Need ES = DS = 0 for now
- jmp short .do_e820 ; Skip "at end" check first time!
-.int_loop: and ebx,ebx ; If we're back at beginning...
- jz no_e820 ; ... bail; nothing found
-.do_e820: mov eax,0000E820h
- mov edx,534D4150h ; "SMAP" backwards
- mov ecx,20
- mov di,E820Buf
- int 15h
- jc no_e820
- cmp eax,534D4150h
- jne no_e820
-;
-; Look for a memory block starting at <= 1 MB and continuing upward
-;
- cmp dword [E820Buf+4], byte 0
- ja .int_loop ; Start >= 4 GB?
- mov edx, (1 << 20)
- sub edx, [E820Buf]
- jb .int_loop ; Start >= 1 MB?
- stc
- sbb eax,eax ; eax <- 0xFFFFFFFF
- cmp dword [E820Buf+12], byte 0
- ja .huge ; Size >= 4 GB
- mov eax, [E820Buf+8]
-.huge: sub eax, edx ; Adjust size to start at 1 MB
- jbe .int_loop ; Completely below 1 MB?
-
- ; Now EAX contains the size of memory 1 MB...up
- cmp dword [E820Buf+16], byte 1
- jne err_nohighmem ; High memory isn't usable memory!!!!
-
- ; We're good!
- pop es
- jmp short got_highmem_add1mb ; Still need to add low 1 MB
;
-; INT 15:E820 failed. Try INT 15:E801.
+; Save the cluster pointer for later...
;
-no_e820: pop es
-
- mov ax,0e801h ; Query high memory (semi-recent)
- int 15h
- jc no_e801
- cmp ax,3c00h
- ja no_e801 ; > 3C00h something's wrong with this call
- jb e801_hole ; If memory hole we can only use low part
-
- mov ax,bx
- shl eax,16 ; 64K chunks
- add eax,(16 << 20) ; Add first 16M
- jmp short got_highmem
-
+ push si
;
-; INT 15:E801 failed. Try INT 15:88.
+; Get the BIOS' idea of what the size of high memory is.
;
-no_e801:
- mov ah,88h ; Query high memory (oldest)
- int 15h
- cmp ax,14*1024 ; Don't trust memory >15M
- jna e801_hole
- mov ax,14*1024
-e801_hole:
- and eax,0ffffh
- shl eax,10 ; Convert from kilobytes
-got_highmem_add1mb:
- add eax,(1 << 20) ; First megabyte
-got_highmem:
-%if HIGHMEM_SLOP != 0
- sub eax,HIGHMEM_SLOP
-%endif
- mov [HighMemSize],eax
-
+ call highmemsize
;
; Construct the command line (append options have already been copied)
;
diff --git a/sample/Makefile b/sample/Makefile
index f4ad1bcf..e6b648a0 100644
--- a/sample/Makefile
+++ b/sample/Makefile
@@ -15,15 +15,31 @@
## samples for syslinux users
##
+CC = gcc
+LD = ld
+CFLAGS = -O2 -fomit-frame-pointer -I..
+LDFLAGS = -s
+OBJCOPY = objcopy
PPMTOLSS16 = ../ppmtolss16
-all: syslogo.lss
+.SUFFIXES: .lss .c .o .elf .c32
+
+all: syslogo.lss hello.c32
+
+.c.o:
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+.elf.c32:
+ $(OBJCOPY) -O binary $< $@
syslogo.lss: syslogo.png $(PPMTOLSS16)
pngtopnm syslogo.png | \
$(PPMTOLSS16) \#000000=0 \#d0d0d0=7 \#f6f6f6=15 \
> syslogo.lss
+hello.elf: hello.o
+ $(LD) -Ttext 0x101000 -e _start -o $@ $<
+
clean:
rm -f *.lss
diff --git a/sample/hello.c b/sample/hello.c
new file mode 100644
index 00000000..194092e3
--- /dev/null
+++ b/sample/hello.c
@@ -0,0 +1,47 @@
+#ident "$Id$"
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * hello.c
+ *
+ * Simple COM32 image
+ */
+
+#include <com32.h>
+
+#define NULL ((void *)0)
+
+static inline void memset(void *buf, int ch, unsigned int len)
+{
+ asm volatile("cld; rep; stosb"
+ : "+D" (buf), "+c" (len) : "a" (ch) : "memory");
+}
+
+int _start(unsigned int nargs, char *cmdline,
+ void (*syscall)(unsigned char, com32sys_t *, com32sys_t *),
+ void *bounce_ptr, unsigned int bounce_len)
+{
+ const char *msg = "Hello, World!\r\n";
+ com32sys_t inreg, outreg;
+ const char *p;
+
+ memset(&inreg, 0, sizeof inreg);
+
+ for ( p = msg ; *p ; p++ ) {
+ inreg.edx = *p;
+ inreg.eax = 0x0200;
+ syscall(0x21, &inreg, NULL);
+ }
+
+ return 0;
+}
diff --git a/version b/version
index 07cde984..28887373 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-1.75
+2.00
diff --git a/version.pl b/version.pl
new file mode 100755
index 00000000..fa09e40d
--- /dev/null
+++ b/version.pl
@@ -0,0 +1,25 @@
+#!/usr/bin/perl
+#
+# Read the "version" file and produce some macro declarations
+#
+
+use Fcntl;
+
+$vfile = $ARGV[0];
+sysopen(VERSION, $vfile, O_RDONLY) or die "$0: Cannot open $vfile\n";
+$version = <VERSION>;
+chomp $version;
+close(VERSION);
+
+unless ( $version =~ /^([0-9]+)\.([0-9]+)$/ ) {
+ die "$0: Cannot parse version format\n";
+}
+$vma = $1+0; $vmi = $2+0;
+
+open(VI, "> version.gen") or die "$0: Cannot create version.gen\n";
+print VI "%define VERSION \"$version\"\n";
+print VI "%define VER_MAJOR $vma\n";
+print VI "%define VER_MINOR $vmi\n";
+close(VI);
+
+