Started the "shell" of the 2nd stage boot loader: it will enable the A20
gate, switch to protected mode, and will then jump to the platform dependent loader initialization. This is the start of the zbeos equivalent. It can already be executed using the BFS boot block, but it cannot yet load itself from a floppy like the original does. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7197 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
/** This file contains the boot floppy and BFS boot block entry points for
|
||||
* the stage 2 boot loader.
|
||||
* The floppy entry point is at offset 0. It's loaded at 0x07c0:0x000. It
|
||||
* will load the rest of the loader to 0x1000:0x0200 and execute it.
|
||||
* 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
|
||||
* the entry function of the embedded ELF part of the loader.
|
||||
*/
|
||||
|
||||
.text
|
||||
.code16
|
||||
|
||||
/** This is the entry point when we were written directly to a floppy disk */
|
||||
|
||||
floppy_start:
|
||||
ljmp $0x07c0, $0x0005 // make sure we're on the right segment
|
||||
|
||||
jmp floppy_start
|
||||
// ToDo: implement the rest of the floppy loader!
|
||||
|
||||
|
||||
floppy_end:
|
||||
.org 0x01fe-floppy_end
|
||||
.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
|
||||
|
||||
// mov $hello_string, %si
|
||||
// call printString
|
||||
|
||||
cli // no interrupts please
|
||||
call enable_a20 // enable a20 gate
|
||||
|
||||
.code32 // This forces a 32 bit relocation entry
|
||||
.byte 0x66 // that allows linking with others
|
||||
.byte 0x67
|
||||
lgdt gdt_descriptor - 0x10000
|
||||
// load global descriptor table; we're still in real mode segment
|
||||
// 0x1000 so we have to manually correct the address
|
||||
|
||||
.code16
|
||||
movl %cr0, %eax // set the PE bit of cr0 to switch to protected mode
|
||||
orb $0x1, %al
|
||||
movl %eax, %cr0
|
||||
.code32
|
||||
.byte 0x66
|
||||
ljmp $0x8, $_protected_code_segment
|
||||
_protected_code_segment:
|
||||
mov $0x10, %ax // load descriptor 2 in the data and stack segment selectors
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
mov %ax, %ss
|
||||
|
||||
mov $0x10000, %ebp // setup new stack
|
||||
mov %ebp, %esp
|
||||
|
||||
call _start
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
.code16
|
||||
printString:
|
||||
// write a 0 terminated string from ds:si to screen
|
||||
// si - string to be printed
|
||||
// changes al, ah
|
||||
push %bx
|
||||
_printstart:
|
||||
lodsb
|
||||
test %al, %al
|
||||
jz _printdone
|
||||
mov $0x0e, %ah
|
||||
mov $0x0007, %bx
|
||||
int $0x10
|
||||
jmp _printstart
|
||||
_printdone:
|
||||
pop %bx
|
||||
ret
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
|
||||
enable_a20:
|
||||
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
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
hello_string:
|
||||
.byte 10, 13
|
||||
.string "Welcome to the OpenBeOS Bootloader"
|
||||
|
||||
/* global data table */
|
||||
|
||||
gdt:
|
||||
// null descriptor
|
||||
.long 0
|
||||
.long 0
|
||||
|
||||
// kernel code segment
|
||||
.long 0x0000ffff // base: 0, limit: 4 GB
|
||||
.long 0x00cf9e00 // type: 32 bit, exec-only conforming, privilege 0
|
||||
// kernel data and stack segment
|
||||
.long 0x0000ffff // base: 0, limit: 4 GB
|
||||
.long 0x00cf9200 // type: 32 bit, data read/write, privilege 0
|
||||
|
||||
// real mode 16 bit code segment
|
||||
.long 0x0000ffff // base: 0, limit: 4 GB
|
||||
.long 0x00009e00
|
||||
// real mode 16 bit data and stack segment
|
||||
.long 0x0000ffff // base: 0, limit: 4 GB
|
||||
.long 0x00009200
|
||||
|
||||
gdt_descriptor:
|
||||
.word 0x27 // 5 entries in the GDT (8 bytes each)
|
||||
.long gdt
|
||||
|
||||
.org 1024
|
||||
Reference in New Issue
Block a user