Compare commits
No commits in common. "978fd364906c82a3c0687c79f5651da8503bc526" and "d97ec36f8c86036b0378e9e900a2c93286b08cd5" have entirely different histories.
978fd36490
...
d97ec36f8c
6 changed files with 52 additions and 122 deletions
6
Makefile
6
Makefile
|
|
@ -1,7 +1,7 @@
|
|||
###CONFIGURATION
|
||||
ARCH := i686
|
||||
CROSS := $(ARCH)-elf-
|
||||
AS := nasm
|
||||
AS := $(CROSS)as
|
||||
CC := $(CROSS)gcc
|
||||
LD := $(CROSS)ld
|
||||
QEMU := qemu-system-i386
|
||||
|
|
@ -9,8 +9,6 @@ INCLUDES:= include/
|
|||
|
||||
CFLAGS := -I $(INCLUDES) -O2 -Wall -Wextra -ffreestanding -nostdlib -lgcc -g
|
||||
LDFLAGS := -T linker.ld -nostdlib
|
||||
ASFLAGS := -f elf32
|
||||
|
||||
|
||||
SRC_DIR := src
|
||||
OBJ_DIR := obj
|
||||
|
|
@ -41,7 +39,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
|||
|
||||
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.s
|
||||
@mkdir -p $(dir $@)
|
||||
$(AS) $(ASFLAGS) $< -o $@
|
||||
$(AS) $< -o $@
|
||||
|
||||
#Related targets
|
||||
|
||||
|
|
|
|||
|
|
@ -34,5 +34,6 @@ SECTIONS
|
|||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
*(.tss_sect)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
56
src/gdt.s
56
src/gdt.s
|
|
@ -1,56 +0,0 @@
|
|||
global gdtr
|
||||
|
||||
section .gdt_sect
|
||||
gdt:
|
||||
;Null descriptor
|
||||
dd 0x00000000
|
||||
dd 0x00000000
|
||||
;Kernel code segment.
|
||||
;Limit: in 4kib pages. 0xFFFFF * 4K = full address space.
|
||||
dw 0xFFFF
|
||||
;Base: Start at 0. We want the whole thing.
|
||||
dw 0
|
||||
;ALSO BASE: bits 16-23. All zeroes, still.
|
||||
db 0
|
||||
;Access byte. Defines flags for access permissions to the segment. This segment is:
|
||||
;RX, and code/data segment
|
||||
db 0b10011010
|
||||
;Next two segments are nibbles so I put them together (cant db only a nibble at once).
|
||||
;Upper limit bits (right hand nibble) is all ones to fill out the full 4gib in pages
|
||||
;Flags (left hand nibble) are set to say that the limit is meant to be read as pages, and we're working in 32bit.
|
||||
db 0b11001111
|
||||
;Final upper base bits. Still zero lol.
|
||||
db 0
|
||||
;Done! Now we move onto our next table entries, they are back to back.
|
||||
;Kernel Data Segment
|
||||
dw 0xFFFF
|
||||
dw 0
|
||||
db 0
|
||||
db 0b10010010
|
||||
db 0b11001111
|
||||
db 0
|
||||
;User Code Segment
|
||||
dw 0xFFFF
|
||||
dw 0
|
||||
db 0
|
||||
db 0b11111010
|
||||
db 0b11001111
|
||||
db 0
|
||||
;User Data Segment
|
||||
dw 0xFFFF
|
||||
dw 0
|
||||
db 0
|
||||
db 0b11110010
|
||||
db 0b11001111
|
||||
db 0
|
||||
;Task State Segment
|
||||
;For a lot of this it's going to be zeroes so we can do it dynamically later (such as finding &tss).
|
||||
;Really, we just want to set the access bytes correctly.
|
||||
dd 0
|
||||
db 0
|
||||
db 0b10001001
|
||||
dw 0
|
||||
gdtr:
|
||||
dw gdtr - gdt - 1
|
||||
dd gdt
|
||||
|
||||
|
|
@ -6,13 +6,8 @@
|
|||
#include "kmultiboot.h"
|
||||
|
||||
//finally, main.
|
||||
void kern_main(uint32_t multiboot_magic, mb_info_t* multiboot_info)
|
||||
void kern_main(uint32_t multiboot_magic, multiboot_info_t* multiboot_info)
|
||||
{
|
||||
//Hello C! Let's get to work in cleaning up our environment a bit and creating some safety.
|
||||
//First interrupts.
|
||||
|
||||
|
||||
|
||||
//wipe the screen
|
||||
vga_clear();
|
||||
//We're going to use this buffer as our 8char hex representation for reading mem
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
;multiboot for GRUB to boot it. Ideally stage01_bootloader will be able to support the multiboot standard.
|
||||
;regardless of who's doing it, we have to set the required stuff
|
||||
MB_MAGIC equ 0x1BADB002 ; bytes that bootloader will use to find this place
|
||||
MB_FLAGS equ (1 << 0) | (1 << 1) ; flags request the following from the bootloader: maintain page boundaries + provide a memory map
|
||||
MB_CHECKSUM equ (0 - (MB_MAGIC + MB_FLAGS)) ; Fails if checksum doesn't pass. Kind of arbitrary, but required.
|
||||
|
||||
|
||||
;Now we actually place the multiboot stuff into the resulting executable...
|
||||
section .multiboot align=4
|
||||
dd MB_MAGIC
|
||||
dd MB_FLAGS
|
||||
dd MB_CHECKSUM
|
||||
|
||||
91
src/start.s
91
src/start.s
|
|
@ -1,55 +1,60 @@
|
|||
; Bootloader places us in 32 bit mode :)
|
||||
bits 32
|
||||
;Some symbols we'll need from other files...
|
||||
extern kern_main
|
||||
extern gdtr
|
||||
;This will be our entrypoint function name - gotta initialize it now as global so the linker knows later.
|
||||
global start
|
||||
//C main function for our kernel
|
||||
//See: kernel.c
|
||||
.extern kern_main
|
||||
//This will be our entrypoint function name - gotta initialize it now as global so the linker knows later.
|
||||
.global start
|
||||
|
||||
|
||||
; Set up for C code. Practically the only requirement for C-generated assembly to work properly is alignment and the presence of a stack.
|
||||
section .bss align=16
|
||||
//multiboot for GRUB to boot it. Ideally stage01_bootloader will be able to support the multiboot standard.
|
||||
//regardless of who's doing it, we have to set the required stuff
|
||||
.set MB_MAGIC, 0x1BADB002 // bytes that bootloader will use to find this place
|
||||
.set MB_FLAGS, (1 << 0) | (1 << 1) // flags request the following from the bootloader: maintain page boundaries + provide a memory map
|
||||
.set MB_CHECKSUM, (0 - (MB_MAGIC + MB_FLAGS)) // Fails if checksum doesn't pass. Kind of arbitrary, but required.
|
||||
|
||||
|
||||
//Now we actually place the multiboot stuff into the resulting executable...
|
||||
.section .multiboot
|
||||
.align 4 // 4 byte alignment
|
||||
.long MB_MAGIC
|
||||
.long MB_FLAGS
|
||||
.long MB_CHECKSUM
|
||||
|
||||
// Set up for C code. Practically the only requirement for C-generated assembly to work properly is alignment and the presence of a stack.
|
||||
.section .bss
|
||||
.align 16
|
||||
stack_bottom:
|
||||
resb 4096 ; 4096 bytes (4kb) large stack. by skipping some amount of data (and eventually filling it with zeroes?), we've essentially just reserved space for our stack.
|
||||
;Remember, stack grows DOWNWARD! So the last thing in the section -> the highest memory address -> the very first thing on the stack!
|
||||
;Therefore, we put a label here to represent the top of our stack for later.
|
||||
.skip 4096 // 4096 bytes (4kb) large stack. by skipping some amount of data (and eventually filling it with zeroes?), we've essentially just reserved space for our stack.
|
||||
//Remember, stack grows DOWNWARD! So the last thing in the section -> the highest memory address -> the very first thing on the stack!
|
||||
//Therefore, we put a label here to represent the top of our stack for later.
|
||||
stack_top:
|
||||
;We're gonna throw the TSS here too.
|
||||
//Allocation of some space for our TSS.
|
||||
|
||||
|
||||
.section .tss_sect:
|
||||
.align 8
|
||||
tss:
|
||||
resb 104
|
||||
.skip 104
|
||||
|
||||
.section .gdt_sect:
|
||||
.align 8
|
||||
gdt:
|
||||
.skip 48
|
||||
|
||||
;Actual code. Entry point goes here!
|
||||
section .text
|
||||
;Here it is!
|
||||
|
||||
//Actual code. Entry point goes here!
|
||||
.section .text
|
||||
//Here it is!
|
||||
start:
|
||||
;We made a GDT! Let's use it!
|
||||
lgdt [gdtr]
|
||||
;Now we start by setting the code segment (CS) with a far jump...
|
||||
jmp 0x08:segment_be_gone
|
||||
|
||||
|
||||
segment_be_gone:
|
||||
;Now we go ahead and dump our kernel mode data segment (0x10) into the rest of our segments.
|
||||
;Also preserving eax because it has the bootloader's multiboot magic in it and I want to check it in main.
|
||||
mov cx, 0x10
|
||||
mov ds, cx
|
||||
mov es, cx
|
||||
mov ss, cx
|
||||
mov fs, cx
|
||||
mov gs, cx
|
||||
;Lets set up the stack. Stack grows downward on x86. We did the work earlier of defining where the top of the stack is, so just tell esp.
|
||||
mov esp, stack_top ;set the stack pointer
|
||||
push ebx
|
||||
push eax
|
||||
;To C-land!
|
||||
//Lets set up the stack. Stack grows downward on x86. We did the work earlier of defining where the top of the stack is, so just tell esp.
|
||||
mov $stack_top, %esp //set the stack pointer
|
||||
pushl %ebx
|
||||
pushl %eax
|
||||
//To C-land!
|
||||
call kern_main
|
||||
|
||||
;You should never get here, but in case you do, we will just hang.
|
||||
//You should never get here, but in case you do, we will just hang.
|
||||
hang:
|
||||
cli ;Interrupts: off
|
||||
hlt ;Halt!
|
||||
jmp hang ;just in case...
|
||||
cli //Interrupts: off
|
||||
hlt //Halt!
|
||||
jmp hang //just in case...
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue