PXE stage 1 bootloader for Haiku

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18884 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2006-09-18 21:51:07 +00:00
parent 0f15994178
commit b8759025a9

View File

@ -0,0 +1,277 @@
/*
** Copyright 2006, Marcus Overhagen. All rights reserved.
** Distributed under the terms of the MIT License.
*/
// as -o pxe_stage1.o pxe_stage1.S
// ld --oformat binary --Ttext 0x7C00 -o pxe_stage1.bin pxe_stage1.o
// cp pxe_stage1.bin /tftpboot/pxehaiku
// objdump -mi8086 -d pxe_stage1.o
// objdump -mi8086 -bbinary -D -z pxe_stage1.bin
// system state according to PXE specification:
// CS:IP 0000:7C00
// ES:BX address of the PXENV+ structure
// SS:[SP+4] address of the !PXE structure.
// SS:SP at least 1.5KB of free stack
.equ PXENV_GET_CACHED_INFO, 0x71
.equ PXENV_TFTP_OPEN, 0x20
.equ PXENV_TFTP_CLOSE, 0x21
.equ PXENV_TFTP_READ, 0x22
.equ PXENV_TFTP_GET_FSIZE, 0x25
.equ PXENV_PACKET_TYPE_DHCP_DISCOVER, 1
.equ PXENV_PACKET_TYPE_DHCP_ACK, 2
.equ PXENV_PACKET_TYPE_CACHED_REPLY, 3
.equ BOOTP_OPCODE_REQ, 1
.equ BOOTP_OPCODE_REP, 2
.code16
.text
.globl _start
_start:
// save es segment to dx
movw %es, %dx
// setup segments
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw $0x7c00, %sp
// print start banner
movw $startmsg, %si
call puts
// print PXE struct address
movw $pxenvmsg, %si
call puts
movw %dx, %ax
call puthex16
movw $colon, %si
call puts
movw %bx, %ax
call puthex16
movw $crlf, %si
call puts
// switch to unreal mode
cli
call enable_a20
call go_unreal
sti
movw $unrealmsg, %si
call puts
// store PXE struct address as linear 32 bit pointer in edx
andl $0xffff, %edx
shll $4, %edx
andl $0xffff, %ebx
addl %ebx, %edx
// API version
movw $apivermsg, %si
call puts
movw 0x6(%edx), %ax
call puthex16
movw $crlf, %si
call puts
// store API entry as seg:ofs in pxenv_api
movl 0xa(%edx), %eax
movl %eax, pxenv_api
// print API entry address
movw $apimsg, %si
call puts
movl pxenv_api, %eax
shrl $16, %eax
call puthex16
movw $colon, %si
call puts
movl pxenv_api, %eax
call puthex16
movw $crlf, %si
call puts
movw $PXENV_PACKET_TYPE_CACHED_REPLY, %ax
// movw $PXENV_PACKET_TYPE_DHCP_ACK, %ax
movw %ax, s_PXENV_GET_CACHED_INFO_PacketType
movw $300, %ax
movw %ax, s_PXENV_GET_CACHED_INFO_BufferSize
movl $cached_info, %eax
movl %eax, s_PXENV_GET_CACHED_INFO_Buffer
movw $PXENV_GET_CACHED_INFO, %bx
movw $s_PXENV_GET_CACHED_INFO, %di
lcall * pxenv_api
test %ax, %ax
andl $0xffff, %eax
call puthex32
movw $crlf, %si
call puts
movw s_PXENV_GET_CACHED_INFO_Status, %ax
andl $0xffff, %eax
call puthex32
movw $crlf, %si
call puts
movl cached_info_cip, %eax
call puthex32
movw $crlf, %si
call puts
movl cached_info_yip, %eax
call puthex32
movw $crlf, %si
call puts
movl cached_info_sip, %eax
call puthex32
movw $crlf, %si
call puts
movl cached_info_gip, %eax
call puthex32
movw $crlf, %si
call puts
loop:
jmp loop
puts: pushal
_puts2: lodsb
testb %al, %al
jnz putc
popal
ret
putc: movw $0x7, %bx
movb $0xe, %ah
int $0x10
jmp _puts2
puthex32:
pushl %eax
shrl $16, %eax
call puthex16
popl %eax
call puthex16
ret
puthex16: pushal
movw %ax, %cx
rolw $4, %cx
call puthexc
rolw $4, %cx
call puthexc
rolw $4, %cx
call puthexc
rolw $4, %cx
call puthexc
popal
ret
puthexc: movb %cl, %al
andb $0xf, %al
cmpb $0xa, %al
jb _puthexc2
addb $0x27, %al
_puthexc2: addb $0x30, %al
movb $0xe, %ah
movw $0x7, %bx
int $0x10
ret
enable_a20: inb $0x92, %al
testb $0x02, %al
jnz _a20_out
orb $0x02, %al
andb $0xfe, %al
outb %al, $0x92
_a20_out: ret
go_unreal: pushw %ds
pushw %es
pushw %bx
.code32
.byte 0x66
.byte 0x67
lgdt gdt_descriptor
.code16
movl %cr0, %eax
orb $1, %al
movl %eax, %cr0
movw $8, %bx
movw %bx, %ds
movw %bx, %es
decb %al
movl %eax, %cr0
popw %bx
popw %es
popw %ds
ret
startmsg: .asciz "\r\nHaiku PXE bootloader version 0.1\r\n\r\n"
unrealmsg: .asciz "Switch to unreal mode done\r\n"
pxenvmsg: .asciz "PXENV+ data structure at "
apimsg: .asciz "PXENV+ API entry point at "
apivermsg: .asciz "API version is "
colon: .asciz ":"
dot: .asciz "."
crlf: .asciz "\r\n"
.balign 8
gdt:
.long 0
.long 0
.long 0x0000ffff
.long 0x00cf9200
gdt_descriptor:
.word 0x10
.long gdt
.balign 8
pxenv_api: .long 0
s_PXENV_GET_CACHED_INFO:
s_PXENV_GET_CACHED_INFO_Status: .word 0
s_PXENV_GET_CACHED_INFO_PacketType: .word 0
s_PXENV_GET_CACHED_INFO_BufferSize: .word 0
s_PXENV_GET_CACHED_INFO_Buffer: .long 0
s_PXENV_GET_CACHED_INFO_BufferLimit: .word 0
cached_info:
cached_info_opcode: .byte 0
cached_info_hardware: .byte 0
cached_info_hardlen: .byte 0
cached_info_gatehops: .byte 0
cached_info_ident: .long 0
cached_info_seconds: .word 0
cached_info_flags: .word 0
cached_info_cip: .long 0
cached_info_yip: .long 0
cached_info_sip: .long 0
cached_info_gip: .long 0
cached_info_mac_addr: .fill 16
cached_info_server_name: .fill 64
cached_info_bootfile: .fill 128
cached_info_vendorspec: .fill 64
end: