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:
Axel Dörfler
2004-04-13 16:43:12 +00:00
parent 9fd63d6d0e
commit b911d01e3d
+168
View File
@@ -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