From: H. Peter Anvin Date: Tue, 30 Mar 2010 00:34:22 +0000 (-0700) Subject: Merge branch 'master' into pathbased X-Git-Tag: syslinux-4.00-pre37~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b6e84b7f93c5b4a0cffd132f3c6dbf6bf58ba2b9;p=platform%2Fupstream%2Fsyslinux.git Merge branch 'master' into pathbased Resolved Conflicts: MCONFIG.embedded com32/MCONFIG com32/include/com32.h core/com32.inc core/pxelinux.asm doc/comboot.txt Signed-off-by: H. Peter Anvin --- b6e84b7f93c5b4a0cffd132f3c6dbf6bf58ba2b9 diff --cc MCONFIG.embedded index 1369265,4b42e0d..9f5846d --- a/MCONFIG.embedded +++ b/MCONFIG.embedded @@@ -16,21 -16,16 +16,22 @@@ 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) diff --cc com32/MCONFIG index 80f92f6,0e152de..0b774d4 --- a/com32/MCONFIG +++ b/com32/MCONFIG @@@ -17,24 -17,17 +17,25 @@@ 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 diff --cc com32/include/com32.h index 252dab5,665fa0b..6b14208 --- a/com32/include/com32.h +++ b/com32/include/com32.h @@@ -97,13 -95,13 +97,14 @@@ struct com32_pmapi extern struct com32_sys_args { uint32_t cs_sysargs; char *cs_cmdline; - void __cdecl(*cs_intcall) (uint8_t, const com32sys_t *, com32sys_t *); + void __cdecl (*cs_intcall)(uint8_t, const com32sys_t *, com32sys_t *); void *cs_bounce; uint32_t cs_bounce_size; - void __cdecl(*cs_farcall) (uint32_t, const com32sys_t *, com32sys_t *); - int __cdecl(*cs_cfarcall) (uint32_t, const void *, uint32_t); + void __cdecl (*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *); + int __cdecl (*cs_cfarcall)(uint32_t, const void *, uint32_t); uint32_t cs_memsize; + const char *cs_name; + const struct com32_pmapi *cs_pm; } __com32; /* diff --cc com32/lib/sys/entry.S index 629f336,c34dbdf..7bfde8b --- a/com32/lib/sys/entry.S +++ b/com32/lib/sys/entry.S @@@ -30,7 -30,7 +30,7 @@@ */ /* Number of arguments in our version of the entry structure */ --#define COM32_ARGS 8 ++#define COM32_ARGS 9 .section ".init","ax" .globl _start diff --cc core/cmdline.inc index 54d85f4,642e5e1..7fa5381 --- a/core/cmdline.inc +++ b/core/cmdline.inc @@@ -19,6 -19,6 +19,8 @@@ ;; Not used by plain kernel due to BOOT_IMAGE= etc. ;; ++ section .text16 ++ ; ; Assumes DS == CS ; diff --cc core/com32.inc index 9a29c95,8c3f181..111590c --- a/core/com32.inc +++ b/core/com32.inc @@@ -47,9 -65,13 +47,13 @@@ is_com32_image 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 @@@ -79,56 -124,317 +83,63 @@@ com32_start ; 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, - ; 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 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 diff --cc core/pxelinux.asm index 5ba3acd,55444db..3020cf2 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@@ -500,9 -2849,36 +500,9 @@@ copyright_str db ' Copyright (C) 1994 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 ; diff --cc doc/comboot.txt index 8adff33,81d0602..0f64097 --- a/doc/comboot.txt +++ b/doc/comboot.txt @@@ -90,22 -87,7 +90,24 @@@ The following arguments are passed to t [ESP+24] dword Pointer to FAR call helper function (new in 2.05) [ESP+28] dword Pointer to CDECL helper function (new in 3.54) [ESP+32] dword Amount of memory controlled by the Syslinux core (new in 3.74) - [ESP+36] dword Pointer to protected-mode functions (new in 4.00) + [ESP+36] dword Pointer to the filename of the com32 module (new in 3.86) ++ [ESP+40] dword Pointer to protected-mode functions (new in 4.00) + +The libcom32 startup code loads this into a structure named __com32, +defined in : + +extern struct com32_sys_args { + uint32_t cs_sysargs; + char *cs_cmdline; + void __cdecl(*cs_intcall)(uint8_t, const com32sys_t *, com32sys_t *); + void *cs_bounce; + uint32_t cs_bounce_size; + void __cdecl(*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *); + int __cdecl(*cs_cfarcall)(uint32_t, const void *, uint32_t); + uint32_t cs_memsize; - struct com32_pmapi *cs_pm; ++ const char *cs_name; ++ const struct com32_pmapi *cs_pm; +} __com32; The intcall helper function can be used to issue BIOS or Syslinux API calls, and takes the interrupt number as first argument. The second