diff --git a/src/p_vmlinx.cpp b/src/p_vmlinx.cpp index 55c15e57..695ac41d 100644 --- a/src/p_vmlinx.cpp +++ b/src/p_vmlinx.cpp @@ -487,39 +487,38 @@ void PackVmlinuxI386::unpack(OutputFile *fo) //----- // //----- arch/i386/boot/compressed/upx-head.S -//#include -//#ifndef __BOOT_CS /* Linux 2.4.x */ -//#define __BOOT_CS __KERNEL_CS -//#define __BOOT_DS __KERNEL_DS -//#endif -// -// .text +// .text //startup_32: .globl startup_32 # In: %esi=0x90000 setup data "real_mode pointer" -// cli # but if it matters, then there is a race! +// #cli # this must be true already // -// movl $ __BOOT_DS,%eax -// movl %eax,%ss; leal 0x9000(%esi),%esp # 0x99000 typical -// /* Linux Documentation/i386/boot.txt "SAMPLE BOOT CONFIGURATION" says -// 0x8000-0x8FFF Stack and heap [inside the "real mode segment", -// just below the command line at offset 0x9000]. +// /* The only facts about segments here, that are true for all kernels: +// * %cs is a valid "flat" code segment; no other segment reg is valid; +// * the next segment after %cs is a valid "flat" data segment, but +// * no segment register designates it yet. +// */ +// movl %cs,%eax; addl $1<<3,%eax # the next segment after %cs +// movl %eax,%ds +// movl %eax,%es +// leal 0x9000(%esi),%ecx # 0x99000 typical +// movl %ecx,-8(%ecx) # 32-bit offset for stack pointer +// movl %eax,-4(%ecx) # segment for stack pointer +// lss -8(%ecx),%esp # %ss:%esp= %ds:0x99000 +// /* Linux Documentation/i386/boot.txt "SAMPLE BOOT CONFIGURATION" says +// 0x8000-0x8FFF Stack and heap [inside the "real mode segment", +// just below the command line at offset 0x9000]. // -// arch/i386/boot/compressed/head.S "Do the decompression ..." says -// %esi contains the "real mode pointer" [as a 32-bit addr]. +// arch/i386/boot/compressed/head.S "Do the decompression ..." says +// %esi contains the "real mode pointer" [as a 32-bit addr]. // -// In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000. -// boot.txt says 0x9A000 is the limit. LILO goes up to 0x9B000. -// */ +// In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000. +// boot.txt says 0x9A000 is the limit. LILO goes up to 0x9B000. +// */ // -// pushl $0; popf # subsumes "cli; cld"; also clears NT for buggy BIOS +// pushl $0; popf # subsumes "cli; cld"; also clears NT for buggy BIOS // -// movl %eax,%ds # all non-code segments identical -// movl %eax,%es -// movl %eax,%fs -// movl %eax,%gs -// -// movl $ 0x100000,%eax # destination of uncompression (and entry point) -// pushl $ __BOOT_CS -///* Fall into .text of upx-compressed vmlinux. */ +// movl $ 0x100000,%eax # destination of uncompression (and entry point) +// push %cs +/* Fall into .text of upx-compressed vmlinux. */ //----- // Approximate translation for Linux 2.4.x: diff --git a/src/stub/l_vmlinz.asm b/src/stub/l_vmlinz.asm index c38ddac2..ec3014e1 100644 --- a/src/stub/l_vmlinz.asm +++ b/src/stub/l_vmlinz.asm @@ -34,25 +34,38 @@ SECTION .text ORG 0 -; gdt segment 3 is flat data -%define __BOOT_DS 3*8 -; gdt segment 2 is flat code -%define __BOOT_CS 2*8 - ; ============= ; ============= ENTRY POINT ; ============= start: ; __LINUZ000__ - cli - xor eax, eax - mov al, __BOOT_DS - mov ds, eax - mov es, eax -; fs, gs set by startup_32 in arch/i386/kernel/head.S - mov ss, eax - lea esp, ['STAK' + esi] ; (0x9000 + 0x90000) typical + ;cli ;this must be true already + + ; The only facts about segments here, that are true for all kernels: + ; %cs is a valid "flat" code segment; no other segment reg is valid; + ; the next segment after %cs is a valid "flat" data segment, but + ; no segment register designates it yet. + mov eax, cs + add eax, byte 1<<3 ; the next segment after %cs + mov ds, eax + mov es, eax + ; fs, gs set by startup_32 in arch/i386/kernel/head.S + + ; Linux Documentation/i386/boot.txt "SAMPLE BOOT CONFIGURATION" says + ; 0x8000-0x8FFF Stack and heap [inside the "real mode segment", + ; just below the command line at offset 0x9000]. + + ; arch/i386/boot/compressed/head.S "Do the decompression ..." says + ; %esi contains the "real mode pointer" [as a 32-bit addr]. + + ; In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000. + ; boot.txt says 0x9A000 is the limit. LILO goes up to 0x9B000. + + lea ecx, ['STAK' + esi] ; (0x9000 + 0x90000) typical + mov [-8 + ecx], ecx ; 32-bit offset for stack pointer + mov [-4 + ecx], eax ; segment for stack + lss esp, [-8 + ecx] ; %ss:%esp= %ds:0x99000 push byte 0 popf ; BIOS can leave random flags (such as NT) @@ -62,7 +75,7 @@ start: or ebp, byte -1 ; decompressor assumption mov eax, 'KEIP' ; 0x100000 : address of startup_32 - push byte __BOOT_CS ; MATCH00 + push cs ; MATCH00 push eax ; MATCH00 entry address push edi ; MATCH01 save push esi ; MATCH02 save