diff options
Diffstat (limited to 'util/mkelfImage/linux-i386/head.S')
-rw-r--r-- | util/mkelfImage/linux-i386/head.S | 581 |
1 files changed, 0 insertions, 581 deletions
diff --git a/util/mkelfImage/linux-i386/head.S b/util/mkelfImage/linux-i386/head.S deleted file mode 100644 index 9c52896e0c..0000000000 --- a/util/mkelfImage/linux-i386/head.S +++ /dev/null @@ -1,581 +0,0 @@ -/* - * exec_kernel/user_space/head.S - * - * Copyright (C) 2000, 2002, 2003 Eric Biederman - * - * Parts of this code were take from the linux startup - * code of linux-2.4.0-test9 - * - * Other parts were taken from etherboot-5.0.5 - */ - -#define ASSEMBLY 1 - -#define RELOC 0x10000 -#define PROT_CODE_SEG 0x10 -#define PROT_DATA_SEG 0x18 -#define REAL_CODE_SEG 0x08 -#define REAL_DATA_SEG 0x20 - - .equ CR0_PE,1 - -.text -.code32 - - -#include "convert.h" - - .globl startup_32 -startup_32: - cld - cli - - # Save the arguments safely out of the way - movl %eax, boot_type - movl %ebx, boot_data - cmp $0,%esp - jz 1f - movl 4(%esp), %eax - movl %eax, boot_param -1: - - movl stack_start, %esp - - # Clear eflags - pushl $0 - popfl - - # Clear BSS - xorl %eax,%eax - movl $ _edata,%edi - movl $ _end,%ecx - subl %edi,%ecx - cld - rep - stosb - - # Move the gdt where Linux will not smash it during decompression - movl $gdt, %esi - movl $GDTLOC, %edi - movl $(gdt_end - gdt), %ecx - rep movsb - - # Linux makes stupid assumptions about the segments - # that are already setup, so setup a new gdt & ldt - # and then reload the segment registers. - - lgdt gdt_48 - lidt idt_48 - - # Load the data segment registers - movl $ PROT_DATA_SEG, %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %fs - movl %eax, %gs - movl %eax, %ss - - pushl $image_params # image build time parameters as forth arg - pushl boot_param # boot_param pointer as third arg - pushl boot_data # boot data pointer as second arg - pushl boot_type # boot data type as first argument - call convert_params - - movl %eax, %esi # put the real mode pointer in a safe place - addl $16, %esp # pop the arguments - - - # Setup the registers before jumping to linux - - - # clear eflags - pushl $0 - popfl - - # Flag to indicate we are the bootstrap processor - xorl %ebx, %ebx - - movl switch_64, %eax - cmp $1, %eax - jz switch_to_64 - - # Clear the unspecified registers for good measure - xorl %eax, %eax - xorl %ecx, %ecx - xorl %edx, %edx - xorl %edi, %edi - xorl %ebp, %ebp - - # do not clear esp, we still need to use lret later - - pushl $PROT_CODE_SEG - movl entry, %eax - pushl %eax - - lret - -switch_to_64: - - /* We need to switch to 64bit before use startup_64 entry go to kernel */ - /* - * Prepare for entering 64 bit mode - */ - # Move the gdt64 where Linux will not smash it during decompression - movl %esi, %eax # save the real mode pointer - movl $gdt64, %esi - movl $GDT64LOC, %edi - movl $(gdt64_end - gdt64), %ecx - rep movsb - movl %eax, %esi - - /* Load new GDT with the 64bit segments using 32bit descriptor */ - lgdt gdt64 - - /* Enable PAE mode */ - xorl %eax, %eax - btsl $5, %eax - movl %eax, %cr4 - - /* - * Build early 4G boot pagetable - */ - /* Initialize Page tables to 0*/ - movl $PGTLOC, %edi - xorl %eax, %eax - movl $((4096*6)/4), %ecx - rep stosl - - /* Build Level 4 */ - movl $(PGTLOC + 0), %edi - leal 0x1007 (%edi), %eax - movl %eax, 0(%edi) - - /* Build Level 3 */ - movl $(PGTLOC + 0x1000), %edi - leal 0x1007(%edi), %eax - movl $4, %ecx -1: movl %eax, 0x00(%edi) - addl $0x00001000, %eax - addl $8, %edi - decl %ecx - jnz 1b - - /* Build Level 2 */ - movl $(PGTLOC + 0x2000), %edi - movl $0x00000183, %eax - movl $2048, %ecx -1: movl %eax, 0(%edi) - addl $0x00200000, %eax - addl $8, %edi - decl %ecx - jnz 1b - - /* Enable the boot page tables */ - movl $PGTLOC, %eax - movl %eax, %cr3 - - /* Enable Long mode in EFER (Extended Feature Enable Register) */ - movl $0xc0000080, %ecx - rdmsr - btsl $8, %eax - wrmsr - - /* Preparing for 64bit jmp */ - pushl $PROT_CODE_SEG - movl entry, %eax - pushl %eax - - /* Enter paged protected Mode, activating Long Mode */ - xorl %eax, %eax - btsl $31, %eax - btsl $0, %eax - movl %eax, %cr0 - - /* - * At this point we're in long mode but in 32bit compatibility mode - * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn - * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use - * the new gdt/idt that has __KERNEL_CS with CS.L = 1. - */ - - lret - - - /* Routines to query the BIOS... */ -/************************************************************************** -E820_MEMSIZE - Get a listing of memory regions -**************************************************************************/ -#define SMAP 0x534d4150 - .globl meme820 -meme820: - pushl %ebp - movl %esp, %ebp - pushl %ebx - pushl %esi - pushl %edi - movl 8(%ebp), %edi /* Address to return e820 structures at */ - subl $RELOC, %edi - movl 12(%ebp), %esi /* Maximum number of e820 structurs to return */ - pushl %esi - call _prot_to_real - .code16 - xorl %ebx, %ebx -jmpe820: - movl $0xe820, %eax - movl $SMAP, %edx - movl $20, %ecx - /* %di was setup earlier */ - int $0x15 - jc bail820 - - cmpl $SMAP, %eax - jne bail820 - -good820: - /* If this is useable memory, we save it by simply advancing %di by - * sizeof(e820rec) - */ - decl %esi - testl %esi,%esi - jz bail820 - - addw $20, %di -again820: - cmpl $0, %ebx /* check to see if %ebx is set to EOF */ - jne jmpe820 - -bail820: - data32 call _real_to_prot - .code32 - popl %eax - subl %esi, %eax /* Compute how many structure we read */ - - /* Restore everything else */ - popl %edi - popl %esi - popl %ebx - movl %ebp, %esp - popl %ebp - ret - - -/************************************************************************** -MEME801 - Determine size of extended memory -**************************************************************************/ - .globl meme801 -meme801: - pushl %ebx - pushl %esi - pushl %edi - call _prot_to_real - .code16 - - stc # fix to work around buggy - xorw %cx,%cx # BIOSes which dont clear/set - xorw %dx,%dx # carry on pass/error of - # e801h memory size call - # or merely pass cx,dx though - # without changing them. - movw $0xe801,%ax - int $0x15 - jc e801absent - - cmpw $0x0, %cx # Kludge to handle BIOSes - jne e801usecxdx # which report their extended - cmpw $0x0, %dx # memory in AX/BX rather than - jne e801usecxdx # CX/DX. The spec I have read - movw %ax, %cx # seems to indicate AX/BX - movw %bx, %dx # are more reasonable anyway... - -e801usecxdx: - andl $0xffff, %edx # clear sign extend - shll $6, %edx # and go from 64k to 1k chunks - movl %edx, %eax # store extended memory size - andl $0xffff, %ecx # clear sign extend - addl %ecx, %eax # and add lower memory into - - jmp e801out -e801absent: - xorl %eax,%eax - -e801out: - data32 call _real_to_prot - .code32 - /* Restore Everything */ - popl %edi - popl %esi - popl %ebx - ret - -/************************************************************************** -MEM88 - Determine size of extended memory -**************************************************************************/ - .globl mem88 -mem88: - pushl %ebx - pushl %esi - pushl %edi - call _prot_to_real - .code16 - - movb $0x88, %ah - int $0x15 - andl $0xffff, %eax - - data32 call _real_to_prot - .code32 - - /* Restore Everything */ - popl %edi - popl %esi - popl %ebx - ret - - -/************************************************************************** -BASEMEMSIZE - Get size of the conventional (base) memory -**************************************************************************/ - .globl basememsize -basememsize: - call _prot_to_real - .code16 - int $0x12 - movw %ax,%cx - DATA32 call _real_to_prot - .code32 - movw %cx,%ax - ret - -/************************************************************************** -_REAL_TO_PROT - Go from REAL mode to Protected Mode -**************************************************************************/ - .globl _real_to_prot -_real_to_prot: - .code16 - cli - cs - addr32 lgdt gdt_48 - RELOC - movl %cr0,%eax - orl $CR0_PE,%eax - movl %eax,%cr0 /* turn on protected mode */ - - /* flush prefetch queue, and reload %cs:%eip */ - data32 ljmp $PROT_CODE_SEG,$1f -1: - .code32 - /* reload other segment registers */ - movl $PROT_DATA_SEG,%eax - movl %eax,%ds - movl %eax,%es - movl %eax,%ss - addl $RELOC,%esp /* Fix up stack pointer */ - xorl %eax,%eax - movl %eax,%fs - movl %eax,%gs - popl %eax /* Fix up return address */ - addl $RELOC,%eax - pushl %eax - - /* switch to protected mode idt */ - cs - lidt idt_48 - ret - -/************************************************************************** -_PROT_TO_REAL - Go from Protected Mode to REAL Mode -**************************************************************************/ - .globl _prot_to_real -_prot_to_real: - .code32 - popl %eax - subl $RELOC,%eax /* Adjust return address */ - pushl %eax - subl $RELOC,%esp /* Adjust stack pointer */ - ljmp $REAL_CODE_SEG,$1f- RELOC /* jump to a 16 bit segment */ -1: - .code16 - /* clear the PE bit of CR0 */ - movl %cr0,%eax - andl $0!CR0_PE,%eax - movl %eax,%cr0 - - /* make intersegment jmp to flush the processor pipeline - * and reload %cs:%eip (to clear upper 16 bits of %eip). - */ - data32 ljmp $(RELOC)>>4,$2f- RELOC -2: - /* we are in real mode now - * set up the real mode segment registers : %ds, $ss, %es - */ - movw %cs,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%ss - movw %ax,%fs - movw %ax,%gs - - /* Switch to the real mode idt */ - cs - addr32 lidt idt_real - RELOC - - sti - data32 ret /* There is a 32 bit return address on the stack */ - .code32 - -boot_type: .long 0 -boot_data: .long 0 -boot_param: .long 0 - -idt_real: - .word 0x400 # idt limit = 256 - .word 0, 0 -idt_48: - .word 0 # idt limit = 0 - .word 0, 0 # idt base = 0L -gdt_48: - .word gdt_end - gdt - 1 # gdt limit=40, - # (5 GDT entries) - .long GDTLOC # gdt base - -# Descriptor tables -# These need to be in a seperate section so I can be -# certain later activities dont stomp them -gdt: - /* 0x00 */ - .word 0, 0, 0, 0 # dummy - - /* 0x08 */ - /* 16 bit real mode code segment */ - .word 0xffff,(RELOC&0xffff) - .byte (RELOC>>16),0x9b,0x00,(RELOC>>24) - - /* 0x10 */ - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9A00 # code read/exec - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) - - /* 0x18 */ - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9200 # data read/write - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) - - /* 0x20 */ - /* 16 bit real mode data segment */ - .word 0xffff,(RELOC&0xffff) - .byte (RELOC>>16),0x93,0x00,(RELOC>>24) - - /* For 2.5.x the kernel segments have moved */ - - /* 0x28 dummy */ - .quad 0 - - /* 0x30 dummy */ - .quad 0 - /* 0x38 dummy */ - .quad 0 - /* 0x40 dummy */ - .quad 0 - /* 0x48 dummy */ - .quad 0 - /* 0x50 dummy */ - .quad 0 - /* 0x58 dummy */ - .quad 0 - - - /* 0x60 */ - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9A00 # code read/exec - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) - - /* 0x68 */ - .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) - .word 0 # base address = 0 - .word 0x9200 # data read/write - .word 0x00CF # granularity = 4096, 386 - # (+5th nibble of limit) - -/* - * The layout of the per-CPU GDT under Linux: - * - * 0 - null - * 1 - reserved - * 2 - reserved - * 3 - reserved - * - * 4 - default user CS <==== new cacheline - * 5 - default user DS - * - * ------- start of TLS (Thread-Local Storage) segments: - * - * 6 - TLS segment #1 [ glibc's TLS segment ] - * 7 - TLS segment #2 [ Wine's %fs Win32 segment ] - * 8 - TLS segment #3 - * 9 - reserved - * 10 - reserved - * 11 - reserved - * - * ------- start of kernel segments: - * - * 12 - kernel code segment <==== new cacheline - * 13 - kernel data segment - * 14 - TSS - * 15 - LDT - * 16 - PNPBIOS support (16->32 gate) - * 17 - PNPBIOS support - * 18 - PNPBIOS support - * 19 - PNPBIOS support - * 20 - PNPBIOS support - * 21 - APM BIOS support - * 22 - APM BIOS support - * 23 - APM BIOS support - */ -gdt_end: - -gdt64: - .word gdt64_end - gdt64 - .long GDT64LOC - .word 0 - .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x00af9a000000ffff /* __KERNEL_CS */ - .quad 0x00cf92000000ffff /* __KERNEL_DS */ -gdt64_end: - - .section ".trailer", "a" - /* Constants set at build time, these are at the very end of my image */ - .balign 16 - .global image_params -image_params: - -convert_magic: - .long CONVERT_MAGIC -gdt_size: - .long gdt_end - gdt -gdt64_size: - .long gdt64_end - gdt64 -pgt_size: - .long 4096*6 -bss_size: - .long bss_sizex -ramdisk_flags: - .word 0 -root_dev: - .word DEFAULT_ROOT_DEV -entry: - .long 0 -switch_64: - .long 0 -initrd_start: - .long 0 -initrd_size: - .long 0 -cmdline: - .asciz "BOOT_IMAGE=head.S console=ttyS0 ip=dhcp root=/dev/nfs" - .org cmdline + CMDLINE_MAX, 0 -cmdline_end: |