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

View File

@ -25,7 +25,8 @@ DUMP_FLAGS = -x86-asm-syntax=intel \
-disassemble \ -disassemble \
-r \ -r \
-t \ -t \
-triple=x86_64-pc-none-elf -triple=x86_64-pc-none-elf \
-print-imm-hex
LD_FLAGS = -fuse-ld=$(LD) \ LD_FLAGS = -fuse-ld=$(LD) \
-nostdlib \ -nostdlib \
@ -52,12 +53,9 @@ clean:
rm -rf $(OUT) rm -rf $(OUT)
.PHONY: compile .PHONY: compile
compile: $(TGT) compile: $(TGT) $(DMP)
.PHONY: dump
dump: $(DMP)
.PHONY: all .PHONY: all
all: compile dump iso all: compile iso
include $(MK)/epilogue.mk 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 target remote localhost:1234
symbol-file out/secxkrnl.elf break sys_entry_64.high
break *0x1001000

View File

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

View File

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

View File

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

View File

@ -110,7 +110,7 @@ hal_exception_dispatcher(uint64 exc_vec, struct interrupt_context *context, uint
} }
static void static void
halp_populate_idt(void) populate_idt(void)
{ {
hal_set_interrupt_handler(0, hal_interrupt_handler_0); hal_set_interrupt_handler(0, hal_interrupt_handler_0);
hal_set_interrupt_handler(1, hal_interrupt_handler_1); hal_set_interrupt_handler(1, hal_interrupt_handler_1);
@ -380,16 +380,23 @@ impl_hal_get_core_id(void)
int32 int32
hal_interrupt_init(void) hal_interrupt_init(void)
{ {
uint32 coreid = hal_get_core_id(); uint32 coreid;
uint32 eax = 0, ebx = 0, ecx = 0, edx = 0; uint32 eax;
uint32 ebx;
uint32 ecx;
uint32 edx;
// detect APIC first
eax = 1; eax = 1;
hal_cpuid(&eax, &ebx, &ecx, &edx); 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; return 1;
} }
coreid = hal_get_core_id();
// get idt ptr ready // get idt ptr ready
cpu_idt_ptrs[coreid].base = (uint64) &cpu_idts[coreid]; cpu_idt_ptrs[coreid].base = (uint64) &cpu_idts[coreid];
cpu_idt_ptrs[coreid].limit = IDT_ENTRY_NUM * IDT_ENTRY_SIZE - 1; 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; k_intr_disps[coreid] = NULL;
// hook asm interrupt handlers // hook asm interrupt handlers
halp_populate_idt(); populate_idt();
hal_flush_idt(&cpu_idt_ptrs[coreid]); hal_flush_idt(&cpu_idt_ptrs[coreid]);

View File

@ -5,43 +5,44 @@
extern hmain extern hmain
global hal_main_32 global hal_main_32
ASM_MULTIBOOT_CHECK_SUM equ (0xFFFFFFFF - (MULTIBOOT2_HEADER_MAGIC + ASM_MULTIBOOT_HEADER_SIZE + MULTIBOOT_ARCHITECTURE_I386) + 1)
section .multiboot_header section .multiboot_header
bits 32 bits 32
align KERNEL_PAGE_SIZE 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 align MULTIBOOT_HEADER_ALIGN
multiboot_header_tag: start_hdr:
dd MULTIBOOT2_HEADER_MAGIC dd MULTIBOOT2_HEADER_MAGIC
dd MULTIBOOT_ARCH dd MULTIBOOT_ARCHITECTURE_I386
dd MULTIBOOT_HEADER_SIZE dd ASM_MULTIBOOT_HEADER_SIZE
dd MULTIBOOT_CHECK_SUM dd ASM_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
;==================== ;====================
align MULTIBOOT_INFO_ALIGN align MULTIBOOT_INFO_ALIGN
;End_tag dw MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST
dw 0x0 dw 0 ; flag
dw 0x0 dd (8+4*4) ; size
dd 0x8 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 static void
halp_vprintf(char const *format, va_list args) halp_vprintf(char const *format, va_list args)
{ {
char buf[2] = {0, 0}; char buf[2];
int64 int64 d;
d; uint64 u;
uint64
u;
char *s; char *s;
char c; char c;
buf[1] = '\0';
for (; *format != '\0'; format++) for (; *format != '\0'; format++)
{ {
if (*format != '%') if (*format != '%')
@ -210,8 +210,7 @@ hal_printf(char const *format, ...)
} }
void void
hal_assert(uint32 expression, char *message hal_assert(uint32 expression, char *message)
)
{ {
if (!expression) if (!expression)
{ {

View File

@ -18,7 +18,11 @@ typedef _Bool bool;
#define TRUE (1) #define TRUE (1)
#define FALSE (0) #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);} #define UNREFERENCED(x) {(x) = (x);}

View File

@ -17,15 +17,22 @@
* ----------------------- 0xFFFF,FFFF,FFFF,FFFF * ----------------------- 0xFFFF,FFFF,FFFF,FFFF
**/ **/
/**
* kernel loaded at physical address 16MB
* 0x1000000 = 16777216 = 16 * 1024 * 1024
*/
#define KERNEL_IMAGE_PADDR (0x1000000) #define KERNEL_IMAGE_PADDR (0x1000000)
#define KERNEL_PAGE_SIZE (0x1000) #define KERNEL_PAGE_SIZE (0x1000)
#define KERNEL_SPACE_VADDR (0xFFFF800000000000) #define KERNEL_SPACE_VADDR (0xFFFF800000000000)
#define KERNEL_RESERVED_VADDR KERNEL_SPACE_VADDR #define KERNEL_RESERVED_VADDR KERNEL_SPACE_VADDR
#define KERNEL_RESERVED_SIZE (0x00007F0000000000)
#define KERNEL_PAGE_TABLE_VADDR (0xFFFFFF0000000000) #define KERNEL_PAGE_TABLE_VADDR (0xFFFFFF0000000000)
#define KERNEL_PAGE_TABLE_SIZE (0x0000008000000000)
#define KERNEL_DYNAMIC_VADDR (0xFFFFFF8000000000) #define KERNEL_DYNAMIC_VADDR (0xFFFFFF8000000000)
#define KERNEL_DYNAMIC_SIZE (0x0000007F80000000)
/**
* Minus 2GB
*/
#define KERNEL_IMAGE_VADDR (0xFFFFFFFF80000000) #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 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) *(.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) *(.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) *(.data)
*(.rodata*) *(.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) *(.bss)
*(COMMON) *(COMMON)

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/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