include $(topdir)/MCONFIG
-GCCOPT := $(call gcc_ok,-m32,) \
- $(call gcc_ok,-ffreestanding,) \
- $(call gcc_ok,-fno-stack-protector,) \
- $(call gcc_ok,-falign-functions=0,-malign-functions=0) \
- $(call gcc_ok,-falign-jumps=0,-malign-jumps=0) \
- $(call gcc_ok,-falign-loops=0,-malign-loops=0) \
- $(call gcc_ok,-mpreferred-stack-boundary=2,) \
- $(call gcc_ok,-mincoming-stack-boundary=2,) \
- -march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3 \
+GCCOPT := $(call gcc_ok,-m32,)
+GCCOPT += $(call gcc_ok,-ffreestanding,)
+GCCOPT += $(call gcc_ok,-fno-stack-protector,)
+GCCOPT += $(call gcc_ok,-fwrapv,)
+GCCOPT += $(call gcc_ok,-freg-struct-return,)
+GCCOPT += -march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3 \
-msoft-float
+GCCOPT += $(call gcc_ok,-fno-exceptions,)
+GCCOPT += $(call gcc_ok,-fno-asynchronous-unwind-tables,)
+GCCOPT += $(call gcc_ok,-fno-strict-aliasing,)
+GCCOPT += $(call gcc_ok,-falign-functions=0,-malign-functions=0)
+GCCOPT += $(call gcc_ok,-falign-jumps=0,-malign-jumps=0)
+GCCOPT += $(call gcc_ok,-falign-labels=0,-malign-labels=0)
+GCCOPT += $(call gcc_ok,-falign-loops=0,-malign-loops=0)
+GCCOPT += $(call gcc_ok,-mpreferred-stack-boundary=2,)
++GCCOPT += $(call gcc_ok,-mincoming-stack-boundary=2,)
LIBGCC := $(shell $(CC) $(GCCOPT) --print-libgcc)
include $(topdir)/MCONFIG
-GCCOPT := $(call gcc_ok,-std=gnu99,) \
- $(call gcc_ok,-m32,) \
- $(call gcc_ok,-fno-stack-protector,) \
- $(call gcc_ok,-falign-functions=0,-malign-functions=0) \
- $(call gcc_ok,-falign-jumps=0,-malign-jumps=0) \
- $(call gcc_ok,-falign-loops=0,-malign-loops=0) \
- $(call gcc_ok,-mpreferred-stack-boundary=2,) \
- $(call gcc_ok,-mincoming-stack-boundary=2,) \
- -march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3
-
-com32 = $(topdir)/com32
+GCCOPT := $(call gcc_ok,-std=gnu99,)
+GCCOPT += $(call gcc_ok,-m32,)
+GCCOPT += $(call gcc_ok,-fno-stack-protector,)
+GCCOPT += $(call gcc_ok,-fwrapv,)
+GCCOPT += $(call gcc_ok,-freg-struct-return,)
+GCCOPT += -mregparm=3 -DREGPARM=3 -march=i386 -Os
+GCCOPT += $(call gcc_ok,-fPIE,-fPIC)
+GCCOPT += $(call gcc_ok,-fno-exceptions,)
+GCCOPT += $(call gcc_ok,-fno-asynchronous-unwind-tables,)
+GCCOPT += $(call gcc_ok,-fno-strict-aliasing,)
+GCCOPT += $(call gcc_ok,-falign-functions=0,-malign-functions=0)
+GCCOPT += $(call gcc_ok,-falign-jumps=0,-malign-jumps=0)
+GCCOPT += $(call gcc_ok,-falign-labels=0,-malign-labels=0)
+GCCOPT += $(call gcc_ok,-falign-loops=0,-malign-loops=0)
+GCCOPT += $(call gcc_ok,-mpreferred-stack-boundary=2,)
++GCCOPT += $(call gcc_ok,-incoming-stack-boundary=2,)
+
+com32 := $(topdir)/com32
+RELOCS := $(com32)/tools/relocs
ifneq ($(NOGPL),1)
GPLLIB = $(com32)/gpllib/libcom32gpl.a
sub cx,si
fs rep movsb
- mov si,KernelCName
++ mov si,KernelName
+ mov di,Com32Name
+ call strcpy
+
call comboot_setup_api ; Set up the COMBOOT-style API
- mov edi,pm_entry ; Load address
+ mov edi,com32_entry ; Load address
pop eax ; File length
pop si ; File handle
xor dx,dx ; No padding
; 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 (permitted) high memory
- ;
- mov esp,[word HighMemRsvd]
- xor sp,sp ; Align to a 64K boundary
-
- ;
- ; 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...
+ bits 32
+ section .text
+.pm:
+ ; Set up the calling stack frame
+ push dword pm_api_vector
+ push dword Com32Name ; Module filename
push dword [HighMemSize] ; Memory managed by Syslinux
- push dword com32_cfarcall ; Cfarcall entry point
- push dword com32_farcall ; Farcall entry point
+ push dword core_cfarcall ; Cfarcall entry point
+ push dword core_farcall ; Farcall entry point
push dword (1 << 16) ; 64K bounce buffer
- push dword (xfer_buf_seg << 4) ; Bounce buffer address
- push dword com32_intcall ; Intcall entry point
+ push dword core_real_mode ; Bounce buffer address
+ push dword core_intcall ; Intcall entry point
push dword command_line ; Command line pointer
-- push dword 8 ; Argument count
++ push dword 9 ; Argument count
sti ; Interrupts OK now
- call pm_entry ; Run the program...
+ call com32_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 PM_CS16:.in_pm16 ; Return to 16-bit mode first
+ mov bx,comboot_return
+ jmp enter_rm
bits 16
-.in_pm16:
- mov ax,PM_DS16 ; 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,[RealModeSSSP] ; Restore stack
- jmp bx ; Go to whereever we need to go...
-
-com32_done:
- sti
+ section .text16
+not_com32r:
+ mov si,KernelName
+ call writestr
+ mov si,not_com32r_msg
+ call writestr
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 intcall/farcall handling code
-;
-com32_sys_rm:
- pop gs
- pop fs
- pop es
- pop ds
- popad
- popfd
- mov [cs:Com32SysSP],sp
- retf ; Invoke routine
-.return:
- ; We clean up SP here because we don't know if the
- ; routine returned with RET, RETF or IRET
- mov sp,[cs:Com32SysSP]
- pushfd
- pushad
- push ds
- push es
- push fs
- push gs
- mov ebx,com32_syscall.resume
- jmp com32_enter_pm
-
-;
-; 16-bit cfarcall handing code
-;
-com32_cfar_rm:
- retf
-.return:
- mov sp,[cs:Com32SysSP]
- mov [cs:RealModeEAX],eax
- mov ebx,com32_cfarcall.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
-
-;
-; Intcall/farcall 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_farcall:
- pushfd ; Save IF among other things...
- pushad ; We only need to save some, but...
-
- mov eax,[esp+10*4] ; CS:IP
- jmp com32_syscall
-
+ section .data16
+not_com32r_msg db ': not a COM32R image', CR, LF, 0
-com32_intcall:
- pushfd ; Save IF among other things...
- pushad ; We only need to save some, but...
-
- movzx eax,byte [esp+10*4] ; INT number
- mov eax,[eax*4] ; Get CS:IP from low memory
-
-com32_syscall:
- cld
-
- movzx edi,word [word RealModeSSSP]
- movzx ebx,word [word RealModeSSSP+2]
- sub edi,54 ; Allocate 54 bytes
- mov [word RealModeSSSP],di
- shl ebx,4
- add edi,ebx ; Create linear address
-
- mov esi,[esp+11*4] ; Source regs
- xor ecx,ecx
- mov cl,11 ; 44 bytes to copy
- rep movsd
-
- ; EAX is already set up to be CS:IP
- 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, plus the 10 additional bytes used
- ; by the target address (see above.)
-.resume:
- movzx esi,word [word RealModeSSSP]
- movzx eax,word [word RealModeSSSP+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 RealModeSSSP],54 ; Remove from stack
-
- popad
- popfd
- ret ; Return to 32-bit program
-
-;
-; Cfarcall invocation. We copy the stack frame to the real-mode stack,
-; followed by the return CS:IP and the CS:IP of the target function.
-;
-com32_cfarcall:
- pushfd
- pushad
-
- cld
- mov ecx,[esp+12*4] ; Size of stack frame
-
- movzx edi,word [word RealModeSSSP]
- movzx ebx,word [word RealModeSSSP+2]
- mov [word Com32SysSP],di
- sub edi,ecx ; Allocate space for stack frame
- and edi,~3 ; Round
- sub edi,4*2 ; Return pointer, return value
- mov [word RealModeSSSP],di
- shl ebx,4
- add edi,ebx ; Create linear address
-
- mov eax,[esp+10*4] ; CS:IP
- stosd ; Save to stack frame
- mov eax,com32_cfar_rm.return ; Return seg:off
- stosd
- mov esi,[esp+11*4] ; Stack frame
- mov eax,ecx ; Copy the stack frame
- shr ecx,2
- rep movsd
- mov ecx,eax
- and ecx,3
- rep movsb
-
- mov bx,com32_cfar_rm
- jmp com32_enter_rm
-
-.resume:
- popad
- mov eax,[word RealModeEAX]
- popfd
- ret
-
- bits 16
-
- section .bss1
- alignb 4
-RealModeSSSP resd 1 ; Real-mode SS:SP
-RealModeEAX resd 1 ; Real mode EAX
-PMESP resd 1 ; Protected-mode ESP
-Com32SysSP resw 1 ; SP saved during COM32 syscall
+ ; Ersatz com32 invocation structure, to make libcom32
+ ; code run the same if linked to the core. This is in
+ ; the .data16 segment so HighMemSize can live here.
+ ;
+ ; Danger, Will Robinson: it's not clear the use of
+ ; core_xfer_buf is safe here.
+ global __entry_esp, __com32
+ alignz 4
+__entry_esp:
+ dd 0 ; Dummy to avoid _exit issues
+__com32:
- dd 8 ; Argument count
++ dd 9 ; Argument count
+ dd 0 ; No command line
+ dd core_intcall ; Intcall entry point
+ dd 0 ; Bounce buffer address
+ dd 0 ; 64K bounce buffer
+ dd core_farcall ; Farcall entry point
+ dd core_cfarcall ; Cfarcall entry point
+HighMemSize dd 0 ; End of memory pointer (bytes)
++ dd 0 ; No module name
+ dd pm_api_vector ; Protected mode functions
+
+ section .uibss
-%if IS_SYSLINUX
-Com32Name resb FILENAME_MAX+2
-%else
+ Com32Name resb FILENAME_MAX
-%endif
+
- section .text
++ section .text16
db ' H. Peter Anvin et al', CR, LF, 0
err_bootfailed db CR, LF, 'Boot failed: press a key to retry, or wait for reset...', CR, LF, 0
bailmsg equ err_bootfailed
-err_nopxe db "No !PXE or PXENV+ API found; we're dead...", CR, LF, 0
-err_pxefailed db 'PXE API call failed, error ', 0
-err_udpinit db 'Failed to initialize UDP stack', CR, LF, 0
-err_noconfig db 'Unable to locate configuration file', CR, LF, 0
-err_damage db 'TFTP server sent an incomprehesible reply', CR, LF, 0
-found_pxenv db 'Found PXENV+ structure', CR, LF, 0
-apiver_str db 'PXE API version is ',0
-pxeentry_msg db '!PXE entry point found (we hope) at ', 0
-pxenventry_msg db 'PXENV+ entry point found (we hope) at ', 0
-viaplan_msg db ' via plan '
-plan db 'A', CR, LF, 0
-trymempxe_msg db 'Scanning memory for !PXE structure... ', 0
-trymempxenv_msg db 'Scanning memory for PXENV+ structure... ', 0
-undi_data_msg db 'UNDI data segment at ',0
-undi_code_msg db 'UNDI code segment at ',0
-len_msg db ' len ', 0
-cant_free_msg db 'Failed to free base memory, error ', 0
-notfound_msg db 'not found', CR, LF, 0
-myipaddr_msg db 'My IP address seems to be ',0
-tftpprefix_msg db 'TFTP prefix: ', 0
localboot_msg db 'Booting from local disk...', CR, LF, 0
- syslinux_banner db CR, LF, 'PXELINUX ', VERSION_STR, ' ', DATE_STR, ' ', 0
-trying_msg db 'Trying to load: ', 0
-default_str db 'default', 0
+ syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
-cfgprefix db 'pxelinux.cfg/' ; No final null!
-cfgprefix_len equ ($-cfgprefix)
-; This one we make ourselves
-bootif_str db 'BOOTIF='
-bootif_str_len equ $-bootif_str
;
; Config file keyword table
;