merged in removing-assembly branch to do more in C

git-svn-id: svn://anubis/hos/trunk@80 5b3e749e-e535-0410-8002-a9bb6afbdfca
This commit is contained in:
josh 2010-01-07 15:38:15 +00:00
parent 76ac4f88a4
commit e4701b8d96
10 changed files with 104 additions and 147 deletions

View File

@ -1,146 +1,23 @@
; boot.asm ; boot.asm
; Author: Josh Holtrop ; Author: Josh Holtrop
; Date: 2009-06-25 ; Date: 2009-06-25
; Adapted from HOS 0.16 source ; Adapted from HOS 0.16 source
%define MULTIBOOT_HEADER_MAGIC 0x1BADB002
%define MULTIBOOT_HEADER_FLAGS 0x00000003
%define VIRTUAL_OFFSET 0x00000000 ; kernel virtual addr
%define CONSOLE_MEMORY 0xB8000 %define CONSOLE_MEMORY 0xB8000
%define PAGE_SIZE 0x1000 ; 4KB pages
%define KERNEL_STACK_TOP 0xF0000000 ; permanent stack top
; Symbols from the linker
extern _end, _bss
; Symbols from C ; Symbols from C
extern k_bootstrap, bootstrap_stack, mm_gdtr, k_main extern k_bootstrap, bootstrap_stack
;-------------------------------------------------------
[section .text]
;************************************************************************** ;**************************************************************************
;* This is the first symbol in the .text section * ;* This is the first symbol in the .text section *
;************************************************************************** ;**************************************************************************
[global start] [global start]
start: start:
;**************************************************************************
;* Resume execution *
;**************************************************************************
multiboot_entry:
mov cx, 0x0700 + 'a' mov cx, 0x0700 + 'a'
mov [CONSOLE_MEMORY+160*8+0*2], cx mov [CONSOLE_MEMORY+160*8+0*2], cx
lgdt [gdtr_tmp32-VIRTUAL_OFFSET] ; load temporary GDTR mov esp, bootstrap_stack+4096 ; set up temporary stack space
jmp KERNEL_CODE_32_TMP_SEG:segmented_start
;**************************************************************************
;* Multiboot header data block *
;**************************************************************************
align 4
multiboot_header:
dd MULTIBOOT_HEADER_MAGIC ; magic
dd MULTIBOOT_HEADER_FLAGS ; flags
dd -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) ; checksum
;**************************************************************************
;* At this point address 0xE000_0000 is mapped to physical address 0x0 *
;**************************************************************************
segmented_start:
mov cx, KERNEL_DATA_32_TMP_SEG
mov ss, cx
mov ds, cx
mov es, cx
mov gs, cx
mov fs, cx
mov esp, bootstrap_stack+4096-4 ; set up temporary stack space
mov cx, 0x0700 + 'b'
mov [CONSOLE_MEMORY+VIRTUAL_OFFSET+160*8+1*2], cx
add ebx, VIRTUAL_OFFSET
push eax ; multiboot bootloader magic value push eax ; multiboot bootloader magic value
push ebx ; pointer to multiboot info struct push ebx ; pointer to multiboot info struct
call k_bootstrap call k_bootstrap
add esp, 8
mov cx, 0x0700 + 'e'
mov [CONSOLE_MEMORY+VIRTUAL_OFFSET+160*8+4*2], cx
lgdt [mm_gdtr] ; load permanent GDTR
jmp 0x8:segmentation_disabled-VIRTUAL_OFFSET
;**************************************************************************
;* At this point both segmentation and paging are disabled but we can *
;* now enable paging *
;**************************************************************************
segmentation_disabled:
mov cx, 0x10
mov ss, cx
mov ds, cx
mov es, cx
mov gs, cx
mov fs, cx
; at this point paging is still disabled but the PDBR is valid and
; points to a page directory that has all of RAM mapped to the
; beginning of the kernel's virtual address space, and the entire
; kernel mapped in above 0xE000_0000.
; turn on paging
mov eax, cr0
bts eax, 31
mov cr0, eax
; OK, segmentation is disabled and paging is active!
mov cx, 0x0700 + 'f'
mov [CONSOLE_MEMORY+160*8+5*2], cx
mov esp, KERNEL_STACK_TOP
call k_main
idle_loop:
hlt
jmp idle_loop
;-------------------------------------------------------
[section .rodata]
gdtr_tmp32:
dw gdt_end_tmp32-gdt_tmp32-1
dd gdt_tmp32-VIRTUAL_OFFSET
gdt_tmp32: ; 0 = null descriptor
dd 0
dd 0
; a base of 0x2000_0000, when added to 0xE000_0000 will produce
; 0x0000_0000 physical before paging in effect
KERNEL_CODE_32_TMP_SEG equ $-gdt_tmp32 ; 8
db 0xff ; limit 7:0
db 0xff ; limit 15:8
db 0x00 ; base 7:0
db 0x00 ; base 15:8
db 0x00 ; base 23:16
db 0x9a ; access
db 0xcf ; flags / limit 19:16
db 0x00 ; base 31:24
KERNEL_DATA_32_TMP_SEG equ $-gdt_tmp32 ; 16
db 0xff ; limit 7:0
db 0xff ; limit 15:8
db 0x00 ; base 7:0
db 0x00 ; base 15:8
db 0x00 ; base 23:16
db 0x92 ; access
db 0xcf ; flags / limit 19:16
db 0x00 ; base 31:24
gdt_end_tmp32:

View File

@ -1,10 +1,11 @@
#include "k_bootstrap.h"
#include "k_main.h"
#include "hos_types.h" #include "hos_types.h"
#include "hos_defines.h" #include "hos_defines.h"
#include "multiboot.h" #include "multiboot.h"
#include "k_early_panic.h" #include "k_early_panic.h"
#include "mm/mm.h" #include "mm/mm.h"
#include "mm/stack.h"
#include "lang/kio.h" #include "lang/kio.h"
#include "isr/interrupts.h" #include "isr/interrupts.h"
@ -16,12 +17,20 @@ extern "C" {
u8_t bootstrap_stack[4096]; u8_t bootstrap_stack[4096];
/************************************************************************** /**************************************************************************
* This function is invoked before paging is enabled. Segmentation is * * Multiboot header data block *
* utilized to map virtual address 0xE000_0000 to physical address 0x0. *
*************************************************************************/ *************************************************************************/
u32_t k_bootstrap(mb_info_t * mb_info, u32_t mb_magic) u32_t mb_header[] __attribute__ ((section (".multiboot_header") )) = {
MB_HEADER_MAGIC, /* magic */
MB_HEADER_FLAGS, /* flags */
-(MB_HEADER_MAGIC + MB_HEADER_FLAGS) /* checksum */
};
/**************************************************************************
* This function is invoked to bootstrap the kernel. *
*************************************************************************/
void k_bootstrap(mb_info_t * mb_info, u32_t mb_magic)
{ {
DEBUG_LETTER(2, 'c'); DEBUG_LETTER(1, 'b');
if (mb_magic != MB_BOOTLOADER_MAGIC) if (mb_magic != MB_BOOTLOADER_MAGIC)
{ {
@ -40,7 +49,7 @@ u32_t k_bootstrap(mb_info_t * mb_info, u32_t mb_magic)
mmap = (mb_mmap_t *) (((u32_t)mmap) + mmap->size + 4); mmap = (mb_mmap_t *) (((u32_t)mmap) + mmap->size + 4);
} }
DEBUG_LETTER(3, 'd'); DEBUG_LETTER(2, 'c');
/* /*
* These functions could destroy the multiboot information block and * These functions could destroy the multiboot information block and
@ -48,11 +57,27 @@ u32_t k_bootstrap(mb_info_t * mb_info, u32_t mb_magic)
* before calling them. * before calling them.
*/ */
mm_bootstrap(); mm_bootstrap();
stack_bootstrap(); DEBUG_LETTER(3, 'd');
interrupts_bootstrap(); interrupts_bootstrap();
DEBUG_LETTER(4, 'e');
kio_bootstrap(); kio_bootstrap();
DEBUG_LETTER(5, 'f');
return 0; __asm__ __volatile__ ("mov $0xF0000000, %%esp;"
: /* no outputs */
: /* no inputs */
: /* no clobbers */);
k_main();
idle_loop();
}
void idle_loop()
{
for (;;)
{
__asm__ __volatile__ ("hlt");
}
} }
} /* extern "C" */ } /* extern "C" */

17
kernel/boot/k_bootstrap.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef K_BOOTSTRAP_H
#define K_BOOTSTRAP_H
#include "hos_types.h"
#include "multiboot.h"
extern "C" {
void k_bootstrap(mb_info_t * mb_info, u32_t mb_magic)
__attribute__ ((noreturn));
void idle_loop()
__attribute__ ((noreturn));
}
#endif

View File

@ -1,4 +1,5 @@
#include "k_main.h"
#include "lang/kio.h" #include "lang/kio.h"
#include "mm/mm.h" #include "mm/mm.h"
#include "sys/timer.h" #include "sys/timer.h"

11
kernel/boot/k_main.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef K_MAIN_H
#define K_MAIN_H
extern "C" {
void k_main();
}
#endif

View File

@ -10,6 +10,7 @@ extern "C" {
/* The magic number for the Multiboot header. */ /* The magic number for the Multiboot header. */
#define MB_HEADER_MAGIC 0x1BADB002 #define MB_HEADER_MAGIC 0x1BADB002
#define MB_HEADER_FLAGS 0x00000003
#define MB_HEADER_ALIGN_MODULES (1 << 0) #define MB_HEADER_ALIGN_MODULES (1 << 0)
#define MB_HEADER_MEM_INFO (1 << 1) #define MB_HEADER_MEM_INFO (1 << 1)

View File

@ -6,6 +6,7 @@ SECTIONS
{ {
.text virt : AT(phys) { .text virt : AT(phys) {
code = .; _code = .; __code = .; code = .; _code = .; __code = .;
*(.multiboot_header*)
*(.text*) *(.text*)
*(.gnu.linkonce*) *(.gnu.linkonce*)
. = ALIGN(4096); . = ALIGN(4096);

View File

@ -154,8 +154,27 @@ void mm_bootstrap()
mm_gdtr.limit = 3 * sizeof(mm_gdt[0]) - 1; mm_gdtr.limit = 3 * sizeof(mm_gdt[0]) - 1;
mm_gdtr.base = gdt_base; mm_gdtr.base = gdt_base;
__asm__ __volatile__ (
"lgdt (mm_gdtr);\n"
"jmp $0x08, $42f;\n"
"42:\n"
"mov $0x10, %%cx\n"
"mov %%cx, %%ss\n"
"mov %%cx, %%ds\n"
"mov %%cx, %%es\n"
"mov %%cx, %%fs\n"
"mov %%cx, %%gs\n"
: /* no outputs */
: /* no inputs */
: "ecx");
/* set the page directory base register */ /* set the page directory base register */
set_cr3(page_directory); write_cr3(page_directory);
/* turn on paging */
write_cr0(read_cr0() | (1 << 31));
stack_bootstrap();
} }
/************************************************************************** /**************************************************************************

View File

@ -21,17 +21,6 @@ typedef struct
u64_t length; u64_t length;
} mm_mem_range_t; } mm_mem_range_t;
void mm_record_mmap_entry(mb_mmap_t * mmap);
void mm_bootstrap();
int mm_early_map(u32_t virtual_address, u32_t physical_address,
u32_t user_mode, u32_t writable);
int mm_map(u32_t virtual_address, u32_t physical_address,
u32_t user_mode, u32_t writable);
u32_t mm_early_page_alloc();
u32_t mm_page_alloc();
/* http://courses.ece.illinois.edu/ece391/references/descriptors.pdf */ /* http://courses.ece.illinois.edu/ece391/references/descriptors.pdf */
/* granularity: 0: limit in bytes; 1: limit in pages */ /* granularity: 0: limit in bytes; 1: limit in pages */
/* dpl: 0: system mode; 3: user mode */ /* dpl: 0: system mode; 3: user mode */
@ -50,6 +39,19 @@ u32_t mm_page_alloc();
| ( (((u64_t) base) & 0x00FFFFFFull) << 16) /* base 23:00 */ \ | ( (((u64_t) base) & 0x00FFFFFFull) << 16) /* base 23:00 */ \
| ( (((u64_t) limit) & 0x0000FFFFull) ) ) /* limit 15:00 */ | ( (((u64_t) limit) & 0x0000FFFFull) ) ) /* limit 15:00 */
typedef u64_t descriptor_t;
void mm_record_mmap_entry(mb_mmap_t * mmap);
void mm_bootstrap();
int mm_early_map(u32_t virtual_address, u32_t physical_address,
u32_t user_mode, u32_t writable);
int mm_map(u32_t virtual_address, u32_t physical_address,
u32_t user_mode, u32_t writable);
u32_t mm_early_page_alloc();
u32_t mm_page_alloc();
void mm_print_memory_map(); void mm_print_memory_map();
#endif #endif

View File

@ -4,6 +4,7 @@
#include "hos_types.h" #include "hos_types.h"
static u32_t read_cr0() __attribute__ ((unused));
static u32_t read_cr0() static u32_t read_cr0()
{ {
u32_t val; u32_t val;
@ -11,6 +12,7 @@ static u32_t read_cr0()
return val; return val;
} }
static u32_t read_cr2() __attribute__ ((unused));
static u32_t read_cr2() static u32_t read_cr2()
{ {
u32_t val; u32_t val;
@ -18,6 +20,7 @@ static u32_t read_cr2()
return val; return val;
} }
static u32_t read_cr3() __attribute__ ((unused));
static u32_t read_cr3() static u32_t read_cr3()
{ {
u32_t val; u32_t val;
@ -25,10 +28,10 @@ static u32_t read_cr3()
return val; return val;
} }
#define set_cr0(val) \ #define write_cr0(val) \
__asm__ __volatile__ ("movl %0, %%cr0" : : "r" (val)); __asm__ __volatile__ ("movl %0, %%cr0" : : "r" (val));
#define set_cr3(val) \ #define write_cr3(val) \
__asm__ __volatile__ ("movl %0, %%cr3" : : "r" (val)); __asm__ __volatile__ ("movl %0, %%cr3" : : "r" (val));
#endif #endif