%cs at entry to decompressor varies a _lot_ among Linux 2.4.x, 2.6.y kernels.
Decompressor must adapt; no universal constants exist for __BOOT_CS, _BOOT_DS. p_vmlinx.cpp stub/l_vmlinz.asm committer: jreiser <jreiser> 1103605278 +0000
This commit is contained in:
+26
-27
@@ -487,39 +487,38 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
|||||||
//-----
|
//-----
|
||||||
//
|
//
|
||||||
//----- arch/i386/boot/compressed/upx-head.S
|
//----- arch/i386/boot/compressed/upx-head.S
|
||||||
//#include <asm/segment.h>
|
// .text
|
||||||
//#ifndef __BOOT_CS /* Linux 2.4.x */
|
|
||||||
//#define __BOOT_CS __KERNEL_CS
|
|
||||||
//#define __BOOT_DS __KERNEL_DS
|
|
||||||
//#endif
|
|
||||||
//
|
|
||||||
// .text
|
|
||||||
//startup_32: .globl startup_32 # In: %esi=0x90000 setup data "real_mode pointer"
|
//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
|
// /* The only facts about segments here, that are true for all kernels:
|
||||||
// movl %eax,%ss; leal 0x9000(%esi),%esp # 0x99000 typical
|
// * %cs is a valid "flat" code segment; no other segment reg is valid;
|
||||||
// /* Linux Documentation/i386/boot.txt "SAMPLE BOOT CONFIGURATION" says
|
// * the next segment after %cs is a valid "flat" data segment, but
|
||||||
// 0x8000-0x8FFF Stack and heap [inside the "real mode segment",
|
// * no segment register designates it yet.
|
||||||
// just below the command line at offset 0x9000].
|
// */
|
||||||
|
// 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
|
// arch/i386/boot/compressed/head.S "Do the decompression ..." says
|
||||||
// %esi contains the "real mode pointer" [as a 32-bit addr].
|
// %esi contains the "real mode pointer" [as a 32-bit addr].
|
||||||
//
|
//
|
||||||
// In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000.
|
// In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000.
|
||||||
// boot.txt says 0x9A000 is the limit. LILO goes up to 0x9B000.
|
// 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 $ 0x100000,%eax # destination of uncompression (and entry point)
|
||||||
// movl %eax,%es
|
// push %cs
|
||||||
// movl %eax,%fs
|
/* Fall into .text of upx-compressed vmlinux. */
|
||||||
// movl %eax,%gs
|
|
||||||
//
|
|
||||||
// movl $ 0x100000,%eax # destination of uncompression (and entry point)
|
|
||||||
// pushl $ __BOOT_CS
|
|
||||||
///* Fall into .text of upx-compressed vmlinux. */
|
|
||||||
//-----
|
//-----
|
||||||
|
|
||||||
// Approximate translation for Linux 2.4.x:
|
// Approximate translation for Linux 2.4.x:
|
||||||
|
|||||||
+27
-14
@@ -34,25 +34,38 @@
|
|||||||
SECTION .text
|
SECTION .text
|
||||||
ORG 0
|
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
|
; ============= ENTRY POINT
|
||||||
; =============
|
; =============
|
||||||
|
|
||||||
start:
|
start:
|
||||||
; __LINUZ000__
|
; __LINUZ000__
|
||||||
cli
|
;cli ;this must be true already
|
||||||
xor eax, eax
|
|
||||||
mov al, __BOOT_DS
|
; The only facts about segments here, that are true for all kernels:
|
||||||
mov ds, eax
|
; %cs is a valid "flat" code segment; no other segment reg is valid;
|
||||||
mov es, eax
|
; the next segment after %cs is a valid "flat" data segment, but
|
||||||
; fs, gs set by startup_32 in arch/i386/kernel/head.S
|
; no segment register designates it yet.
|
||||||
mov ss, eax
|
mov eax, cs
|
||||||
lea esp, ['STAK' + esi] ; (0x9000 + 0x90000) typical
|
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
|
push byte 0
|
||||||
popf ; BIOS can leave random flags (such as NT)
|
popf ; BIOS can leave random flags (such as NT)
|
||||||
@@ -62,7 +75,7 @@ start:
|
|||||||
|
|
||||||
or ebp, byte -1 ; decompressor assumption
|
or ebp, byte -1 ; decompressor assumption
|
||||||
mov eax, 'KEIP' ; 0x100000 : address of startup_32
|
mov eax, 'KEIP' ; 0x100000 : address of startup_32
|
||||||
push byte __BOOT_CS ; MATCH00
|
push cs ; MATCH00
|
||||||
push eax ; MATCH00 entry address
|
push eax ; MATCH00 entry address
|
||||||
push edi ; MATCH01 save
|
push edi ; MATCH01 save
|
||||||
push esi ; MATCH02 save
|
push esi ; MATCH02 save
|
||||||
|
|||||||
Reference in New Issue
Block a user