1/* 2 * Copyright 2004-2005, Axel D��rfler, axeld@pinc-software.de. All rights reserved. 3 * Copyright 2006, Marcus Overhagen, marcus@overhagen.de. All rights reserved. 4 * Copyright 2007, Ingo Weinhold, bonefish@cs.tu-berlin.de. All rights reserved. 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9// system state according to PXE specification: 10// CS:IP 0000:7C00 11// ES:BX address of the PXENV+ structure 12// SS:[SP+4] address of the !PXE structure. 13// SS:SP at least 1.5KB of free stack 14 15// memory map: 16// 0x00000 - 0x07bff real mode IDT, stack 17// 0x07C00 - 0x08FFF original boot loader location 18// 0x10000 - 0x8AFFF relocated boot loader 19// 0x8B000 - 0x8CFFF used by stage2 trampoline code 20// 0x8D000 - 0x9F7FF PXE and UNDI code and data segments 21// 0x9F800 - 0xA0000 extended BIOS data area 22 23#define GLOBAL(x) .globl x ; x 24 25.equ LOAD_ADDRESS, 0x10000 26.equ INITIAL_LOAD_ADDRESS, 0x07C00 27.equ INITIAL_LOAD_OFFSET, INITIAL_LOAD_ADDRESS - LOAD_ADDRESS 28 29.text 30.code16 31 32pxe_start: 33 // setup segments 34 xorw %ax, %ax 35 movw %ax, %ds 36 movw %ax, %es 37 movw %ax, %ss 38 movw $0x7c00, %sp 39 40 cld 41 42 // print start banner 43 mov $kStartMessage + INITIAL_LOAD_OFFSET, %esi 44 call puts 45 46 // switch to unreal mode 47 cli 48 call enable_a20 49 call go_unreal 50 sti 51 movl $kUnrealMessage + INITIAL_LOAD_OFFSET, %esi 52 call puts 53 54 // relocate boot loader code to expected start address 55 movl $_end, %ecx // desired end address 56 addl $3, %ecx // long word align 57 andb $0xfc, %cl // (should be page aligned anyway, though) 58 movl %ecx, %edi 59 subl $LOAD_ADDRESS, %ecx // number of bytes to copy 60 movl $INITIAL_LOAD_ADDRESS, %esi 61 addl %ecx, %esi // current end address 62 shrl $2, %ecx // number of long words 63_copy: subl $4, %esi 64 subl $4, %edi 65 movl (%esi), %eax 66 movl %eax, (%edi) 67 decl %ecx 68 jnz _copy 69 70 // jump into the relocated boot loader 71.code32 72 .byte 0x66 73 ljmp $0x1000, $relocated_start - LOAD_ADDRESS 74.code16 75 76relocated_start: 77 cli 78 79 // switch to PM 80 .code32 81 .byte 0x66 82 .byte 0x67 83 lgdt pm_gdt_descriptor 84 .code16 85 86 movl %cr0, %eax 87 orb $0x1, %al 88 movl %eax, %cr0 89 90.code32 91 .byte 0x66 92 ljmp $0x8, $pm_start 93pm_start: 94 mov $0x10, %ax 95 mov %ax, %ds 96 mov %ax, %es 97 mov %ax, %fs 98 mov %ax, %gs 99 mov %ax, %ss 100 101 call _start 102 103 104.code16 105stop: hlt 106 jmp stop 107 108 109 110puts: pushal 111_puts2: lodsb 112 testb %al, %al 113 jnz putc 114 popal 115 ret 116putc: movw $0x7, %bx 117 movb $0xe, %ah 118 int $0x10 119 jmp _puts2 120 121 122enable_a20: inb $0x92, %al 123 testb $0x02, %al 124 jnz _a20_out 125 orb $0x02, %al 126 andb $0xfe, %al 127 outb %al, $0x92 128_a20_out: ret 129 130 131go_unreal: pushw %ds 132 pushw %es 133 pushw %bx 134 .code32 135 .byte 0x66 136 .byte 0x67 137 lgdt unreal_gdt_descriptor + INITIAL_LOAD_OFFSET 138 .code16 139 movl %cr0, %eax 140 orb $1, %al 141 movl %eax, %cr0 142 movw $8, %bx 143 movw %bx, %ds 144 movw %bx, %es 145 decb %al 146 movl %eax, %cr0 147 popw %bx 148 popw %es 149 popw %ds 150 ret 151 152 153kStartMessage: .asciz "\r\nHaiku PXE bootloader version 1.0\r\n\r\n" 154kUnrealMessage: .asciz "Switch to unreal mode done\r\n" 155 156 157.balign 8 158unreal_gdt: 159 .long 0 160 .long 0 161 .long 0x0000ffff 162 .long 0x00cf9200 163 164unreal_gdt_descriptor: 165 .word 0x10 166 .long unreal_gdt + INITIAL_LOAD_OFFSET 167 168.balign 8 169pm_gdt: 170 // null descriptor 171 .long 0 172 .long 0 173 174 // kernel code segment 175 .long 0x0000ffff 176 .long 0x00cf9e00 177 // kernel data and stack segment 178 .long 0x0000ffff 179 .long 0x00cf9200 180 181 // real mode 16 bit code segment 182 .long 0x0000ffff 183 .long 0x00009e01 184 // real mode 16 bit data and stack segment 185 .long 0x0000ffff 186 .long 0x00009201 187 // real mode 16 bit stack segment 188 .long 0x0000ffff 189 .long 0x00009200 190 191pm_gdt_descriptor: 192 .word 0x2f 193 .long pm_gdt 194 195 196 197//-------------------------------------------------------------- 198 199 200/* global data table */ 201.balign 8 202 203GLOBAL(gMultiBootInfo): 204 .long 0 205 206GLOBAL(gBootPartitionOffset): 207 .long 0xffffffff 208 209GLOBAL(gBootedFromImage): 210 .byte 1 211 212GLOBAL(gBootDriveID): 213 .byte 0xff 214 215.balign 8 216