back to nasm
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
- `make`
|
- `make`
|
||||||
- `i386-elf-gcc`
|
- `i386-elf-gcc`
|
||||||
- `i386-elf-ld`
|
- `i386-elf-ld`
|
||||||
- `i386-elf-as`
|
- `nasm`
|
||||||
|
|
||||||
### Creating a disk image
|
### Creating a disk image
|
||||||
|
|
||||||
|
|||||||
10
makefile
10
makefile
@@ -1,16 +1,14 @@
|
|||||||
CC = i386-elf-gcc
|
CC = i386-elf-gcc
|
||||||
AS = i386-elf-as
|
|
||||||
LD = i386-elf-ld
|
LD = i386-elf-ld
|
||||||
|
|
||||||
CFLAGS = -m32 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23
|
CFLAGS = -m32 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23
|
||||||
LDFLAGS =
|
LDFLAGS =
|
||||||
ASFLAGS =
|
|
||||||
|
|
||||||
SRC_C := src/kernel.c src/string.c src/vga.c
|
SRC_C := src/kernel.c src/string.c src/vga.c
|
||||||
SRC_ASM := src/boot.s
|
SRC_ASM := src/boot.asm
|
||||||
|
|
||||||
OBJ_C := $(SRC_C:src/%.c=.build/%.o)
|
OBJ_C := $(SRC_C:src/%.c=.build/%.o)
|
||||||
OBJ_ASM := $(SRC_ASM:src/%.s=.build/%.o)
|
OBJ_ASM := $(SRC_ASM:src/%.asm=.build/%.o)
|
||||||
OBJS := $(OBJ_C) $(OBJ_ASM)
|
OBJS := $(OBJ_C) $(OBJ_ASM)
|
||||||
|
|
||||||
kernel: .build/kernel
|
kernel: .build/kernel
|
||||||
@@ -37,5 +35,5 @@ build-dir:
|
|||||||
.build/%.o: src/%.c | build-dir
|
.build/%.o: src/%.c | build-dir
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
.build/%.o: src/%.s | build-dir
|
.build/%.o: src/%.asm | build-dir
|
||||||
$(AS) $(ASFLAGS) -o $@ $<
|
nasm -f elf32 -o $@ $<
|
||||||
106
src/boot.asm
Normal file
106
src/boot.asm
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
global _start
|
||||||
|
extern kernel_main
|
||||||
|
|
||||||
|
%define FLAGS 0b10
|
||||||
|
%define MAGIC 0x1BADB002
|
||||||
|
%define CHECKSUM -(MAGIC + FLAGS)
|
||||||
|
|
||||||
|
section .multiboot
|
||||||
|
align 4
|
||||||
|
dd MAGIC
|
||||||
|
dd FLAGS
|
||||||
|
dd CHECKSUM
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
align 4096
|
||||||
|
pml4_table:
|
||||||
|
resb 4096
|
||||||
|
pdpt_table:
|
||||||
|
resb 4096
|
||||||
|
pd_table:
|
||||||
|
resb 4096
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
align 16
|
||||||
|
stack_bottom:
|
||||||
|
resb 16384
|
||||||
|
stack_top:
|
||||||
|
|
||||||
|
section .data
|
||||||
|
align 8
|
||||||
|
gdt64:
|
||||||
|
dq 0x0000000000000000
|
||||||
|
.code:
|
||||||
|
dq 0x00AF9A000000FFFF
|
||||||
|
.descriptor:
|
||||||
|
dw .end - gdt64 - 1
|
||||||
|
dq gdt64
|
||||||
|
.end:
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 32
|
||||||
|
_start:
|
||||||
|
mov esp, stack_top
|
||||||
|
|
||||||
|
; Multiboot will place a magic value in eax
|
||||||
|
; If this magic value is not present, then we might not have multiboot info in ebx,
|
||||||
|
; therefore we throw an error
|
||||||
|
cmp eax, 0x2BADB002
|
||||||
|
jne error
|
||||||
|
|
||||||
|
; Check if cpuid is available by flipping the 22-nth youngest bit
|
||||||
|
; in the eflags register and checking if the cpu flipped it back
|
||||||
|
pushfd
|
||||||
|
pop eax
|
||||||
|
mov ecx, eax
|
||||||
|
xor eax, 1 << 21
|
||||||
|
push eax
|
||||||
|
popfd
|
||||||
|
pushfd
|
||||||
|
pop eax
|
||||||
|
; If cpuid is available, eax should be different than ecx
|
||||||
|
xor eax, ecx
|
||||||
|
jz error
|
||||||
|
; Finally restore eflags register to the original value
|
||||||
|
push ecx
|
||||||
|
popfd
|
||||||
|
|
||||||
|
; Check if extended cpuid is available by calling cpuid with 0x80000000,
|
||||||
|
; If cpuid is available, eax will be greater than 0x80000000 after the call
|
||||||
|
mov eax, 0x80000000
|
||||||
|
cpuid
|
||||||
|
cmp eax, 0x80000001
|
||||||
|
jb error
|
||||||
|
|
||||||
|
; Check if long mode is available by calling cpuid with 0x80000001
|
||||||
|
; this will place the extended features of the cpu in edx
|
||||||
|
; The 30-nth youngest bit tells us if long mode is supported or not
|
||||||
|
mov eax, 0x80000001
|
||||||
|
cpuid
|
||||||
|
test edx, 1 << 29
|
||||||
|
jz error
|
||||||
|
|
||||||
|
; todo(nub31): setup paging
|
||||||
|
; todo(nub31): enter long mode
|
||||||
|
|
||||||
|
; Load global descriptor table which is set up for 64 bit
|
||||||
|
lgdt [gdt64.descriptor]
|
||||||
|
|
||||||
|
call kernel_main
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
error:
|
||||||
|
cli
|
||||||
|
mov byte [0xb8000], 'B'
|
||||||
|
mov byte [0xb8002], 'O'
|
||||||
|
mov byte [0xb8004], 'O'
|
||||||
|
mov byte [0xb8006], 'T'
|
||||||
|
mov byte [0xb8008], ' '
|
||||||
|
mov byte [0xb800a], 'E'
|
||||||
|
mov byte [0xb800c], 'R'
|
||||||
|
mov byte [0xb800e], 'R'
|
||||||
|
mov byte [0xb8010], 'O'
|
||||||
|
mov byte [0xb8012], 'R'
|
||||||
|
hang:
|
||||||
|
hlt
|
||||||
|
jmp hang
|
||||||
108
src/boot.s
108
src/boot.s
@@ -1,108 +0,0 @@
|
|||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
.set ALIGN, 1<<0
|
|
||||||
.set MEMINFO, 1<<1
|
|
||||||
.set FLAGS, ALIGN | MEMINFO
|
|
||||||
.set MAGIC, 0x1BADB002
|
|
||||||
.set CHECKSUM, -(MAGIC + FLAGS)
|
|
||||||
|
|
||||||
.section .multiboot
|
|
||||||
.align 4
|
|
||||||
.long MAGIC
|
|
||||||
.long FLAGS
|
|
||||||
.long CHECKSUM
|
|
||||||
|
|
||||||
.section .bss
|
|
||||||
.align 4096
|
|
||||||
pml4_table:
|
|
||||||
.zero 4096
|
|
||||||
pdpt_table:
|
|
||||||
.zero 4096
|
|
||||||
pd_table:
|
|
||||||
.zero 4096
|
|
||||||
|
|
||||||
.section .bss
|
|
||||||
.align 16
|
|
||||||
stack_bottom:
|
|
||||||
.skip 16384
|
|
||||||
stack_top:
|
|
||||||
|
|
||||||
.section .data
|
|
||||||
.align 8
|
|
||||||
gdt64:
|
|
||||||
.quad 0x0000000000000000
|
|
||||||
gdt64_code:
|
|
||||||
.quad 0x00AF9A000000FFFF
|
|
||||||
gdt64_descriptor:
|
|
||||||
.word gdt64_end - gdt64 - 1
|
|
||||||
.long gdt64
|
|
||||||
gdt64_end:
|
|
||||||
|
|
||||||
.section .text
|
|
||||||
.code32
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
mov esp, stack_top
|
|
||||||
|
|
||||||
// Multiboot will place a magic value in eax
|
|
||||||
// If this magic value is not present, then we might not have multiboot info in ebx,
|
|
||||||
// therefore we throw an error
|
|
||||||
cmp eax, 0x2BADB002
|
|
||||||
jne error
|
|
||||||
|
|
||||||
// Check if cpuid is available by flipping the 22-nth youngest bit
|
|
||||||
// in the eflags register and checking if the cpu flipped it back
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
mov ecx, eax
|
|
||||||
xor eax, 1 << 21
|
|
||||||
push eax
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
// If cpuid is available, eax should be different than ecx
|
|
||||||
xor eax, ecx
|
|
||||||
jz error
|
|
||||||
// Finally restore eflags register to the original value
|
|
||||||
push ecx
|
|
||||||
popfd
|
|
||||||
|
|
||||||
// Check if extended cpuid is available by calling cpuid with 0x80000000,
|
|
||||||
// If cpuid is available, eax will be greater than 0x80000000 after the call
|
|
||||||
mov eax, 0x80000000
|
|
||||||
cpuid
|
|
||||||
cmp eax, 0x80000001
|
|
||||||
jb error
|
|
||||||
|
|
||||||
// Check if long mode is available by calling cpuid with 0x80000001
|
|
||||||
// this will place the extended features of the cpu in edx
|
|
||||||
// The 30-nth youngest bit tells us if long mode is supported or not
|
|
||||||
mov eax, 0x80000001
|
|
||||||
cpuid
|
|
||||||
test edx, 1 << 29
|
|
||||||
jz error
|
|
||||||
|
|
||||||
// todo(nub31): setup paging
|
|
||||||
// todo(nub31): enter long mode
|
|
||||||
|
|
||||||
// Load global descriptor table which is set up for 64 bit
|
|
||||||
lgdt [gdt64_descriptor]
|
|
||||||
|
|
||||||
call kernel_main
|
|
||||||
jmp error
|
|
||||||
|
|
||||||
error:
|
|
||||||
cli
|
|
||||||
mov byte ptr [0xb8000], 'B'
|
|
||||||
mov byte ptr [0xb8002], 'O'
|
|
||||||
mov byte ptr [0xb8004], 'O'
|
|
||||||
mov byte ptr [0xb8006], 'T'
|
|
||||||
mov byte ptr [0xb8008], ' '
|
|
||||||
mov byte ptr [0xb800a], 'E'
|
|
||||||
mov byte ptr [0xb800c], 'R'
|
|
||||||
mov byte ptr [0xb800e], 'R'
|
|
||||||
mov byte ptr [0xb8010], 'O'
|
|
||||||
mov byte ptr [0xb8012], 'R'
|
|
||||||
hang:
|
|
||||||
hlt
|
|
||||||
jmp hang
|
|
||||||
Reference in New Issue
Block a user