123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include "elf.h"
- .arch sledgehammer
- .code32
- .equ FLAT_CODE_SEG,_pmcs-_gdt
- .equ FLAT_DATA_SEG,_pmds-_gdt
- .equ MSR_K6_EFER, 0xC0000080
- .equ EFER_LME, 0x00000100
- .equ X86_CR4_PAE, 0x00000020
- .equ CR0_PG, 0x80000000
-
- .section ".prefix", "ax", @progbits
-
- #define LOAD_ADDR 0x10000
-
- /* ELF Header */
- .globl elf_header
- elf_header:
- e_ident: .byte 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
- e_type: .short ET_EXEC
- e_machine: .short EM_X86_64
- e_version: .long 1
- e_entry: .long LOAD_ADDR + elf_start - elf_header
- e_phoff: .long elf_program_header - elf_header
- e_shoff: .long 0
- e_flags: .long 0
- e_ehsize: .short elf_header_end - elf_header
- e_phentsize: .short ELF32_PHDR_SIZE
- e_phnum: .short (elf_program_header_end - elf_program_header)/ELF32_PHDR_SIZE
- e_shentsize: .short 0
- e_shnum: .short 0
- e_shstrndx: .short 0
- elf_header_end:
-
- elf_program_header:
- phdr1_p_type: .long PT_NOTE
- phdr1_p_offset: .long elf_note - elf_header
- phdr1_p_vaddr: .long elf_note
- phdr1_p_paddr: .long elf_note
- phdr1_p_filesz: .long elf_note_end - elf_note
- phdr1_p_memsz: .long elf_note_end - elf_note
- phdr1_p_flags: .long PF_R | PF_W | PF_X
- phdr1_p_align: .long 0
-
- /* The decompressor */
- phdr2_p_type: .long PT_LOAD
- phdr2_p_offset: .long 0
- phdr2_p_vaddr: .long elf_header
- phdr2_p_paddr: .long LOAD_ADDR
- phdr2_p_filesz: .long _verbatim_size
- phdr2_p_memsz: .long _image_size
- phdr2_p_flags: .long PF_R | PF_W | PF_X
- phdr2_p_align: .long 16
-
- elf_program_header_end:
-
- .globl elf_note
- elf_note:
- .balign 4
- .int 2f - 1f
- .int 4f - 3f
- .int EIN_PROGRAM_NAME
- 1: .asciz "ELFBoot"
- 2:
- .balign 4
- 3:
- .asciz "Etherboot"
- 4:
-
-
- .balign 4
- .int 2f - 1f
- .int 4f - 3f
- .int EIN_PROGRAM_VERSION
- 1: .asciz "ELFBoot"
- 2:
- .balign 4
- 3:
- .asciz VERSION
- 4:
-
- #if 0
- .balign 4
- .int 2f - 1f
- .int 4f - 3f
- .int EIN_PROGRAM_CHECKSUM
- 1: .asciz "ELFBoot"
- 2:
- .balign 4
- 3:
- .word 0
- 4:
- #endif
- .balign 4
- elf_note_end:
-
- elf_start:
- .code64
- /* Reload the gdt to something I know */
- leaq _gdt(%rip), %rax
- movq %rax, 0x02 + gdtptr(%rip)
- lgdt gdtptr(%rip)
-
- /* Enter 32bit compatibility mode */
- leaq elf_start32(%rip), %rax
- movl %eax, 0x00 + elf_start32_addr(%rip)
- ljmp *elf_start32_addr(%rip)
-
- elf_start32:
- .code32
- /* Reload the data segments */
- movl $FLAT_DATA_SEG, %eax
- movl %eax, %ds
- movl %eax, %es
- movl %eax, %ss
-
- /* Disable paging */
- movl %cr0, %eax
- andl $~CR0_PG, %eax
- movl %eax, %cr0
-
- /* Disable long mode */
- movl $MSR_K6_EFER, %ecx
- rdmsr
- andl $~EFER_LME, %eax
- wrmsr
-
- /* Disable PAE */
- movl %cr4, %eax
- andl $~X86_CR4_PAE, %eax
- movl %eax, %cr4
-
- /* Save the first argument */
- pushl %ebx
- jmp _start
-
- gdtptr:
- .word _gdt_end - _gdt -1
- .long _gdt
- .long 0
- _gdt:
- elf_start32_addr:
- .long elf_start32
- .long FLAT_CODE_SEG
- _pmcs:
- /* 32 bit protected mode code segment, base 0 */
- .word 0xffff,0
- .byte 0,0x9f,0xcf,0
-
- _pmds:
- /* 32 bit protected mode data segment, base 0 */
- .word 0xffff,0
- .byte 0,0x93,0xcf,0
- _gdt_end:
-
-
- /* Dummy routines to satisfy the build */
- .section ".text16", "ax", @progbits
- prefix_exit:
-
- prefix_exit_end:
- .previous
|