removed some unused code. not finished yet
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18997 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,264 +1,31 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
* Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||||
|
* Copyright 2006, Marcus Overhagen, marcus@overhagen.de. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** This file contains the boot floppy and BFS boot block entry points for
|
/** This file contains the stage 2 boot loader for the PXE (preboot execution
|
||||||
* the stage 2 boot loader.
|
* environment) image.
|
||||||
* The floppy entry point is at offset 0. It's loaded at 0x07c0:0x000. It
|
* It gets loaded by the PXE stage1 loader to 0xffff:0010 (0x100000), and is
|
||||||
* will load the rest of the loader to 0x1000:0x0200 and execute it.
|
* starts execution in 16 bit real mode. Entry point is at offset 0.
|
||||||
* The BFS boot block will load the whole stage 2 loader to 0x1000:0x0000
|
|
||||||
* and will then jump to 0x1000:0x0200 as its entry point.
|
|
||||||
* This code will then switch to protected mode and will directly call
|
* This code will then switch to protected mode and will directly call
|
||||||
* the entry function of the embedded ELF part of the loader.
|
* the entry function of the embedded ELF part of the loader.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define GLOBAL(x) .globl x ; x
|
#define GLOBAL(x) .globl x ; x
|
||||||
|
|
||||||
// this saves us some trouble with relocation (I didn't manage GAS to
|
|
||||||
// create 32 bit references to labels)
|
|
||||||
#define FAILURE_STRING 0x1d0
|
|
||||||
#define DOT_STRING 0x1fc
|
|
||||||
|
|
||||||
#define DRIVE_RETRIES 3
|
|
||||||
// when the drive reading fails for some reason, it will
|
|
||||||
// retry this many times until it will report a failure
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.code16
|
.code16
|
||||||
|
|
||||||
/** This is the entry point when we were written directly to a floppy disk */
|
pxe_start:
|
||||||
|
|
||||||
jmp floppy_start
|
|
||||||
|
|
||||||
sNumSectors:
|
|
||||||
// this location will contain the length of the boot loader as
|
|
||||||
// written by the "makeflop" command in 512 byte blocks
|
|
||||||
// 0x180 is the allowed maximum, as the zipped TAR with the
|
|
||||||
// kernel and the boot module might start at offset 192 kB
|
|
||||||
.word 0x0180
|
|
||||||
|
|
||||||
floppy_start:
|
|
||||||
cli
|
cli
|
||||||
cld
|
cld
|
||||||
|
|
||||||
// set up the stack to 0x0000:0x9000
|
|
||||||
xor %ax, %ax
|
|
||||||
mov %ax, %ss
|
|
||||||
mov $0x9000, %sp
|
|
||||||
|
|
||||||
push $0x07c0
|
|
||||||
pop %ds
|
|
||||||
push $0x1000
|
|
||||||
pop %es
|
|
||||||
|
|
||||||
// load the rest of the boot loader to 0x1000:0x0200
|
|
||||||
.code32 // we need to create a 32-bit relocation entry for the linker...
|
|
||||||
.byte 0x67
|
|
||||||
movw sNumSectors - 0x10000, %di
|
|
||||||
// the loader symbols are located at offset 0x10000
|
|
||||||
.code16
|
|
||||||
xor %dh, %dh // head 0, don't change BIOS boot device
|
|
||||||
mov $0x2, %cx // sector 2
|
|
||||||
mov $0x200, %bx // to 0x1000:0x0200
|
|
||||||
call load_sectors
|
|
||||||
|
|
||||||
// ToDo: this seems to be problematic, at least under Bochs (reboot will fail)
|
|
||||||
#if 0
|
|
||||||
or %dl, %dl // if it's a floppy, turn off its motor
|
|
||||||
jnz start_loader
|
|
||||||
call disable_floppy_motor
|
|
||||||
#endif
|
|
||||||
|
|
||||||
start_loader:
|
|
||||||
// indicate that we were booted from CD/floppy/whatever
|
|
||||||
.code32
|
|
||||||
.byte 0x67
|
|
||||||
movb $1, gBootedFromImage - 0x7c00
|
|
||||||
// %ds is 0x7c0 right now, but the symbol were loaded
|
|
||||||
// to offset 0x10000
|
|
||||||
.code16
|
|
||||||
|
|
||||||
// set our environment and jump to the standard BFS boot block entry point
|
|
||||||
xor %dx, %dx // boot device ID and partition offset to 0
|
|
||||||
xor %eax, %eax
|
|
||||||
ljmp $0x1000, $0x0200
|
|
||||||
|
|
||||||
|
|
||||||
/** Loads %di sectors from floppy disk, starting at head %dh, sector %cx.
|
|
||||||
* The data is loaded to %es:%bx. On exit, %es:%bx will point immediately
|
|
||||||
* behind the loaded data, so that you can continue to read in data.
|
|
||||||
* %ax, %cx, %dx, %bp, %di and %si will be clobbered.
|
|
||||||
*/
|
|
||||||
|
|
||||||
load_sectors:
|
|
||||||
// first, get information about the drive as we intend to read whole tracks
|
|
||||||
push %bx
|
|
||||||
push %cx
|
|
||||||
push %dx
|
|
||||||
push %di
|
|
||||||
push %es
|
|
||||||
|
|
||||||
movb $8, %ah // get drive parameters - changes a lot of registers
|
|
||||||
int $0x13
|
|
||||||
|
|
||||||
pop %es
|
|
||||||
pop %di
|
|
||||||
// ToDo: store the number of heads somewhere (it's in %dh)
|
|
||||||
pop %dx
|
|
||||||
and $63, %cx // mask out max. sector number (bit 0-5)
|
|
||||||
mov %cx, %si // and remember it
|
|
||||||
pop %cx
|
|
||||||
pop %bx
|
|
||||||
|
|
||||||
load_track:
|
|
||||||
mov %di, %ax // limit the sector count to track boundaries
|
|
||||||
add %cl, %al
|
|
||||||
dec %ax
|
|
||||||
cmp %si, %ax
|
|
||||||
jbe matches_track_boundary
|
|
||||||
mov %si, %ax
|
|
||||||
matches_track_boundary:
|
|
||||||
inc %ax // take the current sector offset into account
|
|
||||||
sub %cl, %al
|
|
||||||
|
|
||||||
// make sure we don't cross a 64kB address boundary or else the read will fail
|
|
||||||
// (this small piece of knowledge took me some time to accept :))
|
|
||||||
shl $9, %ax
|
|
||||||
mov %ax, %bp
|
|
||||||
add %bx, %bp
|
|
||||||
jnc respects_boundary
|
|
||||||
xor %ax, %ax // only read up to the 64kB boundary
|
|
||||||
sub %bx, %ax
|
|
||||||
respects_boundary:
|
|
||||||
shr $9, %ax
|
|
||||||
mov DRIVE_RETRIES, %bp
|
|
||||||
|
|
||||||
try_to_read:
|
|
||||||
pusha
|
|
||||||
movb $2, %ah // load sectors from drive
|
|
||||||
int $0x13
|
|
||||||
jnc read_succeeded
|
|
||||||
|
|
||||||
xor %ax, %ax
|
|
||||||
int $0x13 // reset drive
|
|
||||||
popa
|
|
||||||
|
|
||||||
dec %bp
|
|
||||||
jz load_failed // if already retried often enough, bail out
|
|
||||||
jmp try_to_read
|
|
||||||
|
|
||||||
read_succeeded:
|
|
||||||
mov $DOT_STRING, %si
|
|
||||||
call print_string
|
|
||||||
popa
|
|
||||||
|
|
||||||
xor %ah, %ah
|
|
||||||
add %ax, %cx // next sector start
|
|
||||||
sub %ax, %di // update sectors left to be read
|
|
||||||
|
|
||||||
shl $9, %ax // get byte offset
|
|
||||||
add %ax, %bx // update target address
|
|
||||||
jnz check_sector_start
|
|
||||||
|
|
||||||
mov %es, %ax // overflow to the next 64kB, %bx is already zero
|
|
||||||
add $0x1000, %ax
|
|
||||||
mov %ax, %es
|
|
||||||
|
|
||||||
check_sector_start:
|
|
||||||
mov %si, %ax // compare the sectors, not the cylinders
|
|
||||||
cmp %al, %cl
|
|
||||||
jbe continue_reading
|
|
||||||
|
|
||||||
sub %si, %cx
|
|
||||||
inc %dh // next head
|
|
||||||
cmp $1, %dh
|
|
||||||
// ToDo: check max. number of heads!
|
|
||||||
jbe check_sector_start
|
|
||||||
|
|
||||||
xor %dh, %dh // next cylinder
|
|
||||||
inc %ch
|
|
||||||
jmp check_sector_start
|
|
||||||
|
|
||||||
continue_reading:
|
|
||||||
or %di, %di
|
|
||||||
jnz load_track
|
|
||||||
ret
|
|
||||||
|
|
||||||
load_failed:
|
|
||||||
mov $FAILURE_STRING, %si
|
|
||||||
call print_string
|
|
||||||
|
|
||||||
xor %ax, %ax
|
|
||||||
int $0x16 // wait for key
|
|
||||||
int $0x19 // and reboot
|
|
||||||
|
|
||||||
disable_floppy_motor:
|
|
||||||
xor %al, %al
|
|
||||||
mov $0x3f2, %dx
|
|
||||||
out %al, %dx
|
|
||||||
ret
|
|
||||||
|
|
||||||
print_string:
|
|
||||||
movb $0x0e, %ah
|
|
||||||
xor %bx, %bx
|
|
||||||
print_char:
|
|
||||||
lodsb
|
|
||||||
orb %al, %al // are there still characters left?
|
|
||||||
jz no_more_chars
|
|
||||||
int $0x10
|
|
||||||
jmp print_char
|
|
||||||
no_more_chars:
|
|
||||||
ret
|
|
||||||
|
|
||||||
floppy_end:
|
|
||||||
.org FAILURE_STRING
|
|
||||||
.string " Loading failed! Press key to reboot.\r\n"
|
|
||||||
.org DOT_STRING
|
|
||||||
.string "."
|
|
||||||
|
|
||||||
.org 0x01fe
|
|
||||||
.word 0xaa55
|
|
||||||
// this bumps the "start" label to offset 0x0200 as
|
|
||||||
// expected by the BFS boot loader, and also marks
|
|
||||||
// this block as valid boot block for the BIOS
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
|
|
||||||
/** This is the entry point of the stage2 bootloader when it has
|
|
||||||
* been loaded from the stage1 loader from a BFS disk.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bfs_start:
|
|
||||||
cld // set the data, and extra segment to our code start
|
|
||||||
pushw $0x1000
|
|
||||||
pop %ds
|
|
||||||
push %ds
|
|
||||||
pop %es
|
|
||||||
|
|
||||||
.code32 // save knowledge from the BFS boot block for later use
|
|
||||||
.byte 0x67
|
|
||||||
movb %dl, gBootDriveID - 0x10000
|
|
||||||
.byte 0x67
|
|
||||||
.byte 0x66
|
|
||||||
movl %eax, gBootPartitionOffset - 0x10000
|
|
||||||
.code16
|
|
||||||
|
|
||||||
xor %ax, %ax // set up stack at 0x0000:0x9000
|
|
||||||
mov %ax, %ss
|
|
||||||
mov $0x9000, %sp
|
|
||||||
|
|
||||||
cli // no interrupts please
|
|
||||||
call enable_a20 // enable a20 gate
|
|
||||||
|
|
||||||
.code32 // This forces a 32 bit relocation entry
|
.code32 // This forces a 32 bit relocation entry
|
||||||
.byte 0x66 // that allows linking with others
|
.byte 0x66 // that allows linking with others
|
||||||
.byte 0x67
|
.byte 0x67
|
||||||
lgdt gdt_descriptor - 0x10000
|
lgdt gdt_descriptor + 0x100000
|
||||||
// load global descriptor table; we're still in real mode segment
|
|
||||||
// 0x1000 so we have to manually correct the address
|
|
||||||
|
|
||||||
.code16
|
.code16
|
||||||
movl %cr0, %eax // set the PE bit of cr0 to switch to protected mode
|
movl %cr0, %eax // set the PE bit of cr0 to switch to protected mode
|
||||||
@@ -283,60 +50,9 @@ _protected_code_segment:
|
|||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
/** Enables the a20 gate. It will first try to enable it through
|
|
||||||
* the BIOS, and, if that fails, will use the old style AT mechanism
|
|
||||||
* using the keyboard port.
|
|
||||||
* ToDo: it no longer does this! Now, it just uses the "fast A20"
|
|
||||||
* mechanism using port 0x92. This does work on all systems
|
|
||||||
* I have access to.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enable_a20:
|
|
||||||
inb $0x92, %al
|
|
||||||
testb $0x02, %al
|
|
||||||
jnz _a20_out
|
|
||||||
orb $0x02, %al
|
|
||||||
andb $0xfe, %al
|
|
||||||
outb %al, $0x92
|
|
||||||
_a20_out:
|
|
||||||
ret
|
|
||||||
|
|
||||||
// ToDo: the code below didn't seem to work properly on all machines
|
|
||||||
/* movw $0x2402, %ax // first, query the a20 status
|
|
||||||
int $0x15
|
|
||||||
jc _a20_old_method // if that fails, use the old AT method
|
|
||||||
test $0x1, %al
|
|
||||||
jnz _a20_done // Is a20 gate already enabled?
|
|
||||||
movw $0x2401, %ax
|
|
||||||
int $0x15
|
|
||||||
jnc _a20_done
|
|
||||||
_a20_old_method:
|
|
||||||
call _a20_loop1 // empty the keyboard buffer
|
|
||||||
jnz _a20_done
|
|
||||||
movb $0xd1, %al
|
|
||||||
outb %al, $0x64
|
|
||||||
call _a20_loop1 // empty the keyboard buffer
|
|
||||||
jnz _a20_done
|
|
||||||
movb $0xdf, %al
|
|
||||||
outb %al, $0x60
|
|
||||||
_a20_loop1:
|
|
||||||
movl $0x20000, %ecx
|
|
||||||
_a20_loop2:
|
|
||||||
inb $0x64, %al
|
|
||||||
test $0x2, %al
|
|
||||||
loopne _a20_loop2
|
|
||||||
_a20_done:
|
|
||||||
ret
|
|
||||||
*/
|
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
|
|
||||||
.org 896
|
|
||||||
// since we don't need the above space when the boot loader is
|
|
||||||
// running, it is used as a real mode scratch buffer (as our
|
|
||||||
// boot loader spans over the whole real mode 0x1000 segment)
|
|
||||||
|
|
||||||
/* global data table */
|
/* global data table */
|
||||||
|
.balign 8
|
||||||
|
|
||||||
gdt:
|
gdt:
|
||||||
// null descriptor
|
// null descriptor
|
||||||
@@ -365,12 +81,10 @@ gdt_descriptor:
|
|||||||
.long gdt
|
.long gdt
|
||||||
|
|
||||||
GLOBAL(gBootedFromImage):
|
GLOBAL(gBootedFromImage):
|
||||||
.byte 0
|
.byte 1
|
||||||
|
|
||||||
GLOBAL(gBootDriveID):
|
GLOBAL(gBootDriveID):
|
||||||
.byte 0
|
.byte 0xff
|
||||||
|
|
||||||
GLOBAL(gBootPartitionOffset):
|
GLOBAL(gBootPartitionOffset):
|
||||||
.long 0
|
.long 0xffffffff
|
||||||
|
|
||||||
.org 1024
|
|
||||||
|
|||||||
Reference in New Issue
Block a user