higher half kernel

This commit is contained in:
rami 2024-07-04 22:03:10 -04:00
parent bd20049519
commit b2b1fc59b7
4 changed files with 58 additions and 62 deletions

View File

@ -2,4 +2,4 @@ ata0-slave: type=cdrom, path=./build/Hazel.iso, status=inserted
magic_break: enabled=1 magic_break: enabled=1
boot: cdrom boot: cdrom
display_library: sdl2 display_library: x

View File

@ -4,7 +4,7 @@
%define VID 1<<2 %define VID 1<<2
%define FLAGS (ALIGN | MMAP | VID) %define FLAGS (ALIGN | MMAP | VID)
section .multiboot section .multiboot.data
dd MAGIC dd MAGIC
dd FLAGS dd FLAGS
dd -(MAGIC + FLAGS) dd -(MAGIC + FLAGS)
@ -19,7 +19,7 @@ dd 80 ; width
dd 25 ; height dd 25 ; height
dd 0 ; depth dd 0 ; depth
section .text section .multiboot.text
global _start global _start
_start: _start:
cli cli
@ -28,6 +28,37 @@ _start:
cmp eax, 0x2BADB002 cmp eax, 0x2BADB002
jne halt jne halt
; Setup table
; Identity page 0-4 mib
mov eax, 0
mov edx, 0
.fill_table:
mov ecx, edx
or ecx, 3
mov [boot_page_tab-0xC0000000+eax*4], ecx
add edx, 0x1000
inc eax
cmp eax, 1024
jne .fill_table
mov ecx, boot_page_tab
sub ecx, 0xC0000000
or ecx, 3
mov [boot_page_dir-0xC0000000], ecx
mov [boot_page_dir-0xC0000000+768*4], ecx
; Enable paging
mov eax, boot_page_dir
sub eax, 0xC0000000
mov cr3, eax
mov eax, cr0
or eax, (1<<31)
mov cr0, eax
jmp higher_half
section .text
higher_half:
; Load GDT ; Load GDT
lgdt [gdtp] lgdt [gdtp]
; Offset to kernel data descriptor ; Offset to kernel data descriptor
@ -52,7 +83,6 @@ halt:
global pit_isr global pit_isr
pit_isr: pit_isr:
cli
extern pit_handler extern pit_handler
call pit_handler call pit_handler
iret iret
@ -187,6 +217,11 @@ gdtp:
dw gdt_end - gdt - 1 dw gdt_end - gdt - 1
dd gdt dd gdt
align 0x1000
boot_page_dir: times 1024 dd 0
align 0x1000
boot_page_tab: times 1024 dd 0
section .bss section .bss
align 16 align 16
stack_top: stack_top:

View File

@ -37,9 +37,6 @@ typedef struct {
uint32_t cr3; uint32_t cr3;
} task_t; } task_t;
__attribute__((aligned(4096))) uint32_t page_dir[1024];
__attribute__((aligned(4096))) uint32_t page_tab[1024];
void kernel(multiboot_info_t *info) { void kernel(multiboot_info_t *info) {
if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules
if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map
@ -93,31 +90,11 @@ void kernel(multiboot_info_t *info) {
#define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF) #define PAGE_TAB_INDEX(x) (((x) >> 12) & 0x3FF)
#define PAGE_OFFSET(x) ((x) & 0xFFF) #define PAGE_OFFSET(x) ((x) & 0xFFF)
for (int i = 0; i < 1024; i++) {
page_tab[i] = (i * 0x1000) | PAGE_PRESENT | PAGE_RW | PAGE_USER;
}
for (int i = 0; i < 1024; i++) {
page_dir[i] = ((uint32_t)page_tab) | PAGE_PRESENT | PAGE_RW | PAGE_USER;
}
//enable_paging(page_dir);
asm volatile("mov %0, %%cr3" :: "r" (page_dir));
asm volatile(
"mov %%cr0, %%eax;"
"or $0x80000000, %%eax;"
"mov %%eax, %%cr0;"
:
:
: "%eax"
);
uint32_t stack = (uint32_t)mmap_find_first_free_block(); uint32_t stack = (uint32_t)mmap_find_first_free_block();
multi_mod_t *init = (multi_mod_t *)info->moduleaddress; multi_mod_t *init = (multi_mod_t *)info->moduleaddress;
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", init->mod_start, stack+0x1000); LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", init->mod_start, stack+0x1000);
jmp_user_mode(stack+0x1000, init->mod_start); //jmp_user_mode(stack+0x1000, init->mod_start);
halt: halt:
for (;;) {} for (;;) {}

View File

@ -1,52 +1,36 @@
/* The bootloader will look at this image and start execution at the symbol
designated as the entry point. */
ENTRY(_start) ENTRY(_start)
/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS SECTIONS
{ {
/* It used to be universally recommended to use 1M as a start offset,
as it was effectively guaranteed to be available under BIOS systems.
However, UEFI has made things more complicated, and experimental data
strongly suggests that 2M is a safer place to load. In 2016, a new
feature was introduced to the multiboot2 spec to inform bootloaders
that a kernel can be loaded anywhere within a range of addresses and
will be able to relocate itself to run from such a loader-selected
address, in order to give the loader freedom in selecting a span of
memory which is verified to be available by the firmware, in order to
work around this issue. This does not use that feature, so 2M was
chosen as a safer option than the traditional 1M. */
. = 1M; . = 1M;
_kernel_start = .;
/* First put the multiboot header, as it is required to be put very early .multiboot.data : {
in the image or the bootloader won't recognize the file format. *(.multiboot.data)
Next we'll put the .text section. */ }
.text BLOCK(4K) : ALIGN(4K) .multiboot.text : {
{ *(.multiboot.text)
*(.multiboot)
*(.text)
} }
/* Read-only data. */ . += 0xC0000000;
.rodata BLOCK(4K) : ALIGN(4K)
.text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
{
*(.text)
}
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
{ {
*(.rodata) *(.rodata)
} }
.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{ {
*(.data) *(.data)
} }
.bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{ {
*(COMMON) *(COMMON)
*(.bss) *(.bss)
*(.bootstrap_stack)
} }
/* The compiler may produce other sections, by default it will put them in _kernel_end = .;
a segment with the same name. Simply add stuff here as needed. */
} }