+ Set up intital page mapping to support high address

+ Add multiboot framebuffer request tag
+ Cleaned up some code
This commit is contained in:
secXsQuared 2018-10-09 15:13:31 -04:00
parent eb33f2c35c
commit 34949452db
13 changed files with 177 additions and 140 deletions

View File

@ -28,32 +28,30 @@ INC_COMMON := inc
MK := mk
OUT := out
C_IGNORED_WARNINGS = -Wno-cast-align \
-Wno-padded
C_FLAGS_ARCH_X86_64 := -mcmodel=kernel \
-target x86_64-pc-none-elf \
-mno-red-zone \
-mno-mmx \
-mno-sse \
-mno-sse2 \
-mno-sse3 \
-mno-3dnow
# generic freestanding cflags used for target
# each submodule can append to this flag
C_FLAGS = -xc\
-g \
C_FLAGS = -x c \
-g \
-c \
-O2 \
-std=c11 \
-Weverything \
-std=c17 \
-Wall \
-Wextra \
-Wpedantic \
-Werror \
$(C_IGNORED_WARNINGS) \
-ffreestanding \
-fno-builtin \
-nostdlib \
-fno-pic \
-mcmodel=kernel \
-fno-stack-protector \
-mno-red-zone \
-mno-mmx \
-mno-sse \
-mno-sse2 \
-mno-sse3 \
-mno-3dnow \
-target x86_64-pc-none-elf \
$(C_FLAGS_ARCH_X86_64) \
-I$(INC_COMMON) \
$(C_FLAGS_$(MOD))

View File

@ -25,7 +25,8 @@ DUMP_FLAGS = -x86-asm-syntax=intel \
-disassemble \
-r \
-t \
-triple=x86_64-pc-none-elf
-triple=x86_64-pc-none-elf \
-print-imm-hex
LD_FLAGS = -fuse-ld=$(LD) \
-nostdlib \
@ -52,12 +53,9 @@ clean:
rm -rf $(OUT)
.PHONY: compile
compile: $(TGT)
.PHONY: dump
dump: $(DMP)
compile: $(TGT) $(DMP)
.PHONY: all
all: compile dump iso
all: compile iso
include $(MK)/epilogue.mk

5
dbgq
View File

@ -1,3 +1,4 @@
file out/secxkrnl.elf
set arch i386:x86-64:intel
target remote localhost:1234
symbol-file out/secxkrnl.elf
break *0x1001000
break sys_entry_64.high

View File

@ -2,10 +2,12 @@
#include "mlayout.h"
#include "multiboot2.h"
%define GET_PADDR(x) ((x) - KERNEL_IMAGE_VADDR + KERNEL_IMAGE_PADDR)
%define BOCHS_BREAK xchg bx,bx
%define GET_PADDR(x) ((x) - KERNEL_IMAGE_VADDR)
%define GET_PML4(vaddr) (((vaddr) >> 39 ) & 0x1FF)
%define GET_PDPT(vaddr) (((vaddr) >> 30 ) & 0x1FF)
global sys_entry
global sys_entry_64
extern hmain
section .text
@ -13,48 +15,46 @@ bits 32
sys_entry:
cli
cld
cmp eax,MULTIBOOT2_BOOTLOADER_MAGIC
je .loaded_by_grub
hlt
cmp eax, MULTIBOOT2_BOOTLOADER_MAGIC
jne .end
.loaded_by_grub:
; save multiboot_info*
mov esi,ebx
call halp_check_long_mode
cmp eax,1
je .init_long_mode
hlt
; save multiboot info
mov dword [GET_PADDR(multiboot_info_ptr)], ebx
; setup stack
call check_long_mode ; check support for long mode
cmp eax, 1
jne .end
.init_long_mode:
; disable paging first
mov eax, cr0 ; Set the A-register to control register 0.
and eax, 0x7FFFFFFF ; Clear the PG-bit, which is bit 31.
and eax, ~(1 << 31) & 0xFFFFFFFF ; Clear the PG-bit, which is bit 31, and hack to get rid of warning
mov cr0, eax ; Set control register 0 to the A-register.
; point the first PML4 entry to the identity pdpt
mov eax, GET_PADDR(init_pml4)
mov dword [eax], GET_PADDR(init_pdpt_iden) + 11b ; write the lower bits, higher = 0
; point the nth PML4 entry to the kernel pdpt
add eax, GET_PML4(KERNEL_IMAGE_VADDR) * 8
mov dword [eax], GET_PADDR(init_pdpt_kern) + 11b
; identity map the first 4GB
; ATTRIBUTE = READ/WRITE + SU
mov eax, GET_PADDR(_pml4)
mov dword [eax], GET_PADDR(_pdpt) + 11b
mov eax, GET_PADDR(init_pdpt_iden)
mov ebx, 10000011b ; R/W + SU + 1G page
mov ecx, 4 ; loop 4 times
.l0:
mov dword [eax], ebx
add ebx, 1*1024*1024*1024 ; 1G
add eax, 8
loop .l0
; write values for pdpt
mov ecx, 10000011b
mov eax, GET_PADDR(_pdpt)
mov dword [eax], ecx
add eax,8
add ecx,0x40000000 ;1G
mov dword [eax], ecx
add eax,8
add ecx,0x40000000 ;1G
mov dword [eax], ecx
add eax,8
add ecx,0x40000000 ;1G
mov dword [eax], ecx
BOCHS_BREAK
; map the first 1 GB, which contains the kernel, to KERNEL_BASE_VADDR
mov eax, GET_PADDR(init_pdpt_kern)
; extract the PML4 entry
add eax, GET_PDPT(KERNEL_IMAGE_VADDR) * 8
mov ebx, 10000011b ; R/W + SU + 1G page
mov dword [eax], ebx
; enable PAE
mov eax, cr4 ; Set the A-register to control register 4.
@ -68,7 +68,7 @@ sys_entry:
wrmsr ; Write to the model-specific register.
; let cr3 point at page table
mov eax, GET_PADDR(_pml4)
mov eax, GET_PADDR(init_pml4)
mov cr3, eax
; enable paging, enter compatibility mode
@ -76,12 +76,18 @@ sys_entry:
or eax, 1 << 31 ; Set the PG-bit, which is bit 31.
mov cr0, eax ; Set control register 0 to the A-register.
; enter long mode
lgdt [GET_PADDR(_gdt.ptr)]
jmp _gdt.code:GET_PADDR(hmain_stub)
; now we are in compat mode
; load the long mode GDT
lgdt [GET_PADDR(init_gdt.ptr)]
; switch to long mode
jmp init_gdt.code:GET_PADDR(sys_entry_64)
.end:
hlt
halp_check_long_mode:
check_long_mode:
push ebp
mov ebp,esp
pushfd
@ -113,51 +119,70 @@ halp_check_long_mode:
pop ebp
ret
section .data
bits 32
multiboot_info_ptr:
dd 0
section .text
bits 64
hmain_stub:
; note that we are still at the identity mapping
mov ax,_gdt.data
sys_entry_64:
; note that we are in long mode but rip is still lower
; switch to high address
mov rax, .high
jmp rax
.high:
; set proper segment registers
mov ax,init_gdt.data
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov rsp, GET_PADDR(_stack)
mov rdi, rsi ; multiboot_info*
mov rsp, init_stack
xor edi, edi
mov edi, dword [multiboot_info_ptr]
mov rdi, rsi
call hmain
.end:
hlt
section .data
bits 64
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
_stack:
init_stack:
_pml4:
init_pml4:
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
_pdpt:
init_pdpt_iden:
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
_gdt: ; Global Descriptor Table (long mode).
.null: equ $ - _gdt ; The null descriptor.
init_pdpt_kern:
align KERNEL_PAGE_SIZE
times KERNEL_PAGE_SIZE db 0
init_gdt: ; Global Descriptor Table (long mode).
.null: equ $ - init_gdt ; The null descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 0 ; Access.
db 0 ; Granularity.
db 0 ; Base (high).
.code: equ $ - _gdt ; The code descriptor.
.code: equ $ - init_gdt ; The code descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
db 10011010b ; Access (exec/read).
db 00100000b ; Granularity.
db 0 ; Base (high).
.data: equ $ - _gdt ; The data descriptor.
.data: equ $ - init_gdt ; The data descriptor.
dw 0 ; Limit (low).
dw 0 ; Base (low).
db 0 ; Base (middle)
@ -166,5 +191,5 @@ _gdt: ; Global Descriptor Table (long mode).
db 0 ; Base (high).
.ptr:
; GDT PTR
dw $ - _gdt - 1 ; Limit.
dq GET_PADDR(_gdt) ; Base.
dw $ - init_gdt - 1 ; Limit.
dq GET_PADDR(init_gdt) ; Base.

View File

@ -20,9 +20,6 @@
// hal_info->cpu_vd_str[12] = 0;
//}
void HABI
hmain(void *m_info);
void HABI
hmain(void *m_info)
{

View File

@ -4,13 +4,13 @@
#define HAL_CORE_COUNT 1
struct STRUCT_PACKED hal_gdt_ptr
struct PRAGMA_PACKED hal_gdt_ptr
{
uint16 limit;
uint64 base;
};
struct STRUCT_PACKED hal_idt_ptr
struct PRAGMA_PACKED hal_idt_ptr
{
uint16 limit;
uint64 base;

View File

@ -110,7 +110,7 @@ hal_exception_dispatcher(uint64 exc_vec, struct interrupt_context *context, uint
}
static void
halp_populate_idt(void)
populate_idt(void)
{
hal_set_interrupt_handler(0, hal_interrupt_handler_0);
hal_set_interrupt_handler(1, hal_interrupt_handler_1);
@ -380,16 +380,23 @@ impl_hal_get_core_id(void)
int32
hal_interrupt_init(void)
{
uint32 coreid = hal_get_core_id();
uint32 eax = 0, ebx = 0, ecx = 0, edx = 0;
uint32 coreid;
uint32 eax;
uint32 ebx;
uint32 ecx;
uint32 edx;
// detect APIC first
eax = 1;
hal_cpuid(&eax, &ebx, &ecx, &edx);
if (!(edx & bit_mask(9)))
if (!(edx & (1 << 9)))
{
hal_printf("ERROR: APIC not supported by CPU.\n");
hal_printf("ERROR: APIC is not present.\n");
return 1;
}
coreid = hal_get_core_id();
// get idt ptr ready
cpu_idt_ptrs[coreid].base = (uint64) &cpu_idts[coreid];
cpu_idt_ptrs[coreid].limit = IDT_ENTRY_NUM * IDT_ENTRY_SIZE - 1;
@ -399,7 +406,7 @@ hal_interrupt_init(void)
k_intr_disps[coreid] = NULL;
// hook asm interrupt handlers
halp_populate_idt();
populate_idt();
hal_flush_idt(&cpu_idt_ptrs[coreid]);

View File

@ -5,43 +5,44 @@
extern hmain
global hal_main_32
ASM_MULTIBOOT_CHECK_SUM equ (0xFFFFFFFF - (MULTIBOOT2_HEADER_MAGIC + ASM_MULTIBOOT_HEADER_SIZE + MULTIBOOT_ARCHITECTURE_I386) + 1)
section .multiboot_header
bits 32
align KERNEL_PAGE_SIZE
MULTIBOOT_ARCH equ 0
MULTIBOOT_CHECK_SUM equ (0xFFFFFFFF - (MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_HEADER_SIZE + MULTIBOOT_ARCH) + 1)
MULTIBOOT_REQ_LOADERNAME equ 2
MULTIBOOT_REQ_MMAP equ 6
MULTIBOOT_REQ_ACPI_RSDP equ 15
;====================
;header tag
align MULTIBOOT_HEADER_ALIGN
multiboot_header_tag:
start_hdr:
dd MULTIBOOT2_HEADER_MAGIC
dd MULTIBOOT_ARCH
dd MULTIBOOT_HEADER_SIZE
dd MULTIBOOT_CHECK_SUM
;====================
;INFO_REQUEST_TAG
align MULTIBOOT_INFO_ALIGN
multiboot_info_tag:
dw 0x1 ; type=1
dw 0x0 ; flag=0
dd MULTIBOOT_INFO_TAG_SIZE
dd MULTIBOOT_REQ_LOADERNAME
dd MULTIBOOT_REQ_MMAP
MULTIBOOT_INFO_TAG_SIZE equ ($ - multiboot_info_tag)
;====================
;MODULE ALIGNMENT TAG
align MULTIBOOT_INFO_ALIGN
dw 0x6; type=6
dw 0x0; flag=0
dd 0x8
dd MULTIBOOT_ARCHITECTURE_I386
dd ASM_MULTIBOOT_HEADER_SIZE
dd ASM_MULTIBOOT_CHECK_SUM
;====================
align MULTIBOOT_INFO_ALIGN
;End_tag
dw 0x0
dw 0x0
dd 0x8
dw MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST
dw 0 ; flag
dd (8+4*4) ; size
dd MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME
dd MULTIBOOT_TAG_TYPE_MMAP
dd MULTIBOOT_TAG_TYPE_ACPI_NEW
dd MULTIBOOT_TAG_TYPE_BOOTDEV
;====================
MULTIBOOT_HEADER_SIZE equ ($ - multiboot_header_tag)
align MULTIBOOT_INFO_ALIGN
dw MULTIBOOT_HEADER_TAG_FRAMEBUFFER; type=5
dw 0 ; flag
dw 20 ; size
dd 0 ; width
dd 0 ; depth
dd 0 ; height
;====================
align MULTIBOOT_INFO_ALIGN
dw MULTIBOOT_HEADER_TAG_MODULE_ALIGN; type=6
dw 0 ; flag
dd 8 ; size
;====================
align MULTIBOOT_INFO_ALIGN
dw MULTIBOOT_HEADER_TAG_END
dw 0 ; flag
dd 8 ; size
;====================
ASM_MULTIBOOT_HEADER_SIZE equ ($ - start_hdr)

View File

@ -144,13 +144,13 @@ hal_clear_screen(void)
static void
halp_vprintf(char const *format, va_list args)
{
char buf[2] = {0, 0};
int64
d;
uint64
u;
char buf[2];
int64 d;
uint64 u;
char *s;
char c;
buf[1] = '\0';
for (; *format != '\0'; format++)
{
if (*format != '%')
@ -210,8 +210,7 @@ hal_printf(char const *format, ...)
}
void
hal_assert(uint32 expression, char *message
)
hal_assert(uint32 expression, char *message)
{
if (!expression)
{

View File

@ -18,7 +18,11 @@ typedef _Bool bool;
#define TRUE (1)
#define FALSE (0)
#define STRUCT_PACKED __attribute__((packed))
#define PRAGMA_PACKED __attribute__((packed))
#define PRAGMA_SECTION(x) __attribute__ ((section (x)))
#define PRAGMA_ALIGN(x) __attribute__ ((aligned(x)))
#define UNREFERENCED(x) {(x) = (x);}

View File

@ -17,15 +17,22 @@
* ----------------------- 0xFFFF,FFFF,FFFF,FFFF
**/
/**
* kernel loaded at physical address 16MB
* 0x1000000 = 16777216 = 16 * 1024 * 1024
*/
#define KERNEL_IMAGE_PADDR (0x1000000)
#define KERNEL_PAGE_SIZE (0x1000)
#define KERNEL_SPACE_VADDR (0xFFFF800000000000)
#define KERNEL_RESERVED_VADDR KERNEL_SPACE_VADDR
#define KERNEL_RESERVED_SIZE (0x00007F0000000000)
#define KERNEL_PAGE_TABLE_VADDR (0xFFFFFF0000000000)
#define KERNEL_PAGE_TABLE_SIZE (0x0000008000000000)
#define KERNEL_DYNAMIC_VADDR (0xFFFFFF8000000000)
#define KERNEL_DYNAMIC_SIZE (0x0000007F80000000)
/**
* Minus 2GB
*/
#define KERNEL_IMAGE_VADDR (0xFFFFFFFF80000000)
#define KERNEL_IMAGE_SIZE (0x0000000080000000)
#define KERNEL_IMAGE_OFFSET (KERNEL_IMAGE_PADDR)

View File

@ -5,25 +5,25 @@ ENTRY(sys_entry)
SECTIONS
{
. = KERNEL_IMAGE_VADDR;
. = KERNEL_IMAGE_VADDR + KERNEL_IMAGE_OFFSET;
.multiboot_header ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.multiboot_header) + KERNEL_IMAGE_PADDR - KERNEL_IMAGE_VADDR)
.multiboot_header ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.multiboot_header) - KERNEL_IMAGE_VADDR)
{
*(.multiboot_header)
}
.text ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.text) + KERNEL_IMAGE_PADDR - KERNEL_IMAGE_VADDR)
.text ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.text) - KERNEL_IMAGE_VADDR)
{
*(.text)
}
.data ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.data) + KERNEL_IMAGE_PADDR - KERNEL_IMAGE_VADDR)
.data ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.data) - KERNEL_IMAGE_VADDR)
{
*(.data)
*(.rodata*)
}
.bss ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.bss) + KERNEL_IMAGE_PADDR - KERNEL_IMAGE_VADDR)
.bss ALIGN(KERNEL_PAGE_SIZE) : AT(ADDR(.bss) - KERNEL_IMAGE_VADDR)
{
*(.bss)
*(COMMON)

View File

@ -1,4 +1,4 @@
#!/bin/bash
qemu-system-x86_64 -bios qemu_bios.bin -vnc :10 -monitor stdio -cdrom out/secxkrnl.iso -s -S
qemu-system-x86_64 -bios qemu_bios.bin -vnc :10 -monitor stdio -cdrom out/secxkrnl.iso -s -S -no_reboot