Moved switching to protected mode into stage1 loader, so code above 1MB can be executed in protected mode.

Executing the stage2 loader works now, up to the point where mmu_init() reuses the same address space.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19033 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2006-10-08 20:17:03 +00:00
parent ee93bd93e8
commit ffffd44b12
2 changed files with 76 additions and 64 deletions

View File

@ -1,4 +1,5 @@
/*
** Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Copyright 2006, Marcus Overhagen. All rights reserved.
** Distributed under the terms of the MIT License.
*/
@ -49,6 +50,8 @@ _start:
movw %ax, %ss
movw $0x7c00, %sp
cld
// print start banner
movw $startmsg, %si
call puts
@ -232,19 +235,19 @@ _start:
xorl %eax, %eax
movw s_PXENV_TFTP_OPEN_PacketSize, %ax
imull $65535, %eax
movl %eax, max_file_size
movl %eax, max_fsize
// print max file size
movw $maxfsize, %si
call puts
movl max_file_size, %eax
movl max_fsize, %eax
call puthex32
movw $crlf, %si
call puts
// check if file is small enough
movl s_PXENV_TFTP_GET_FSIZE_FileSize, %eax
movl max_file_size, %ebx
movl max_fsize, %ebx
cmpl %ebx, %eax
ja err_etoobig
@ -312,8 +315,34 @@ _no_dot:
// execute
movw $executing, %si
call puts
ljmp $load_addr_seg, $load_addr_ofs
cli
// switch to PM
.code32
.byte 0x66
.byte 0x67
lgdt pm_gdt_descriptor
.code16
movl %cr0, %eax
orb $0x1, %al
movl %eax, %cr0
.code32
.byte 0x66
ljmp $0x8, $pm_start
pm_start:
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
ljmp $0x8, $0x100000
.code16
stop: hlt
jmp stop
@ -400,7 +429,7 @@ go_unreal: pushw %ds
.code32
.byte 0x66
.byte 0x67
lgdt gdt_descriptor
lgdt unreal_gdt_descriptor
.code16
movl %cr0, %eax
orb $1, %al
@ -442,23 +471,50 @@ dot: .asciz "."
crlf: .asciz "\r\n"
.balign 8
gdt:
unreal_gdt:
.long 0
.long 0
.long 0x0000ffff
.long 0x00cf9200
gdt_descriptor:
unreal_gdt_descriptor:
.word 0x10
.long gdt
.long unreal_gdt
.balign 8
pm_gdt:
// null descriptor
.long 0
.long 0
// kernel code segment
.long 0x0000ffff
.long 0x00cf9e00
// kernel data and stack segment
.long 0x0000ffff
.long 0x00cf9200
// real mode 16 bit code segment
.long 0x0000ffff
.long 0x00009e01
// real mode 16 bit data and stack segment
.long 0x0000ffff
.long 0x00009201
// real mode 16 bit stack segment
.long 0x0000ffff
.long 0x00009200
pm_gdt_descriptor:
.word 0x2f
.long pm_gdt
.balign 8
pxenv_api: .long 0
client_ip: .long 0
server_ip: .long 0
max_file_size: .long 0
max_fsize: .long 0
pos: .word 0

View File

@ -7,46 +7,26 @@
/** This file contains the stage 2 boot loader for the PXE (preboot execution
* environment) image.
* It gets loaded by the PXE stage1 loader to 0xffff:0010 (0x100000), and is
* starts execution in 16 bit real mode. Entry point is at offset 0.
* This code will then switch to protected mode and will directly call
* the entry function of the embedded ELF part of the loader.
* It gets loaded by the PXE stage1 loader to 0xffff:0010 (0x100000), and it
* starts execution in 32 bit protected mode. Entry point is at offset 0.
* This code will directly call the entry function of the embedded ELF part
* of the loader.
*/
#define GLOBAL(x) .globl x ; x
.text
.code16
.code32
.org 0
pxe_start:
cli
cld
.code32 // This forces a 32 bit relocation entry
.byte 0x66 // that allows linking with others
.byte 0x67
lgdt gdt_descriptor
.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
// stop: hlt
// jmp stop
call _start
//--------------------------------------------------------------
@ -55,31 +35,8 @@ _protected_code_segment:
/* global data table */
.balign 8
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: 0x10000, limit: 64 kB
.long 0x00009e01
// real mode 16 bit data and stack segment
.long 0x0000ffff // base: 0x10000, limit: 64 kB
.long 0x00009201
// real mode 16 bit stack segment
.long 0x0000ffff // base: 0, limit: 64 kB
.long 0x00009200
gdt_descriptor:
.word 0x2f // 6 entries in the GDT (8 bytes each)
.long gdt
GLOBAL(gBootPartitionOffset):
.long 0xffffffff
GLOBAL(gBootedFromImage):
.byte 1
@ -87,5 +44,4 @@ GLOBAL(gBootedFromImage):
GLOBAL(gBootDriveID):
.byte 0xff
GLOBAL(gBootPartitionOffset):
.long 0xffffffff
.balign 8