Add an API for COMBOOT images, and add support for "COM32" -- 32-bit
authorhpa <hpa>
Tue, 11 Jun 2002 05:48:29 +0000 (05:48 +0000)
committerhpa <hpa>
Tue, 11 Jun 2002 05:48:29 +0000 (05:48 +0000)
linear .com files.

18 files changed:
Makefile
NEWS
bcopy32.inc
com32.inc [new file with mode: 0644]
comboot.doc [new file with mode: 0644]
comboot.inc
config.inc
conio.inc
cpuinit.inc
highmem.inc [new file with mode: 0644]
isolinux.asm
ldlinux.asm
pxelinux.asm
runkernel.inc
sample/Makefile
sample/hello.c [new file with mode: 0644]
version
version.pl [new file with mode: 0755]

index 761dd7e..a3cd083 100644 (file)
--- 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 aa7b920..024a0cd 100644 (file)
--- 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.
index d81f00b..c3be39a 100644 (file)
@@ -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 (file)
index 0000000..ac0440f
--- /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 (file)
index 0000000..db9203a
--- /dev/null
@@ -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.
+
+
index 5d7019e..319e500 100644 (file)
@@ -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
index 3282d5b..52a1846 100644 (file)
@@ -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!
index 5850b9d..7dc1572 100644 (file)
--- 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
index a6923b5..b63ae64 100644 (file)
 ;; 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 (file)
index 0000000..e3a830b
--- /dev/null
@@ -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!
index 6c84773..5d5e418 100644 (file)
@@ -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'
index bf8ebbc..f35deb6 100644 (file)
@@ -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'
index bb08d6e..67894fa 100644 (file)
@@ -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'
index eabb792..3ee28f9 100644 (file)
@@ -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)
 ;
index f4ad1bc..e6b648a 100644 (file)
 ## 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 (file)
index 0000000..194092e
--- /dev/null
@@ -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 07cde98..2888737 100644 (file)
--- a/version
+++ b/version
@@ -1 +1 @@
-1.75
+2.00
diff --git a/version.pl b/version.pl
new file mode 100755 (executable)
index 0000000..fa09e40
--- /dev/null
@@ -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);
+
+