remove 64 bit for now
This commit is contained in:
24
makefile
24
makefile
@@ -1,7 +1,7 @@
|
|||||||
CC = x86_64-elf-gcc
|
CC = i386-elf-gcc
|
||||||
LD = x86_64-elf-ld
|
LD = i386-elf-ld
|
||||||
|
|
||||||
CFLAGS = -ffreestanding -m64
|
CFLAGS = -ffreestanding -m32
|
||||||
|
|
||||||
all: .build/nub-os.iso
|
all: .build/nub-os.iso
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@ build-dir:
|
|||||||
cp .build/kernel.bin .build/iso/boot/
|
cp .build/kernel.bin .build/iso/boot/
|
||||||
grub-mkrescue -o .build/nub-os.iso .build/iso/
|
grub-mkrescue -o .build/nub-os.iso .build/iso/
|
||||||
|
|
||||||
.build/kernel.bin: build-dir .build/boot.o .build/kernel.o .build/print.o .build/idt.o .build/keyboard.o .build/exceptions.o .build/interrupts.o
|
.build/kernel.bin: build-dir .build/boot.o .build/kernel.o .build/print.o
|
||||||
$(LD) -Ttext 0x100000 -o .build/kernel.bin .build/boot.o .build/kernel.o .build/print.o .build/idt.o .build/keyboard.o .build/exceptions.o .build/interrupts.o
|
$(LD) -Ttext 0x100000 -o .build/kernel.bin .build/boot.o .build/kernel.o .build/print.o
|
||||||
|
|
||||||
.build/kernel.o: build-dir src/kernel.c
|
.build/kernel.o: build-dir src/kernel.c
|
||||||
$(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c
|
$(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c
|
||||||
@@ -26,17 +26,5 @@ build-dir:
|
|||||||
.build/print.o: build-dir src/print.c
|
.build/print.o: build-dir src/print.c
|
||||||
$(CC) $(CFLAGS) -c -o .build/print.o src/print.c
|
$(CC) $(CFLAGS) -c -o .build/print.o src/print.c
|
||||||
|
|
||||||
.build/idt.o: build-dir src/idt.c
|
|
||||||
$(CC) $(CFLAGS) -c -o .build/idt.o src/idt.c
|
|
||||||
|
|
||||||
.build/keyboard.o: build-dir src/keyboard.c
|
|
||||||
$(CC) $(CFLAGS) -c -o .build/keyboard.o src/keyboard.c
|
|
||||||
|
|
||||||
.build/exceptions.o: build-dir src/exceptions.c
|
|
||||||
$(CC) $(CFLAGS) -c -o .build/exceptions.o src/exceptions.c
|
|
||||||
|
|
||||||
.build/interrupts.o: build-dir src/interrupts.asm
|
|
||||||
nasm -f elf64 -o .build/interrupts.o src/interrupts.asm
|
|
||||||
|
|
||||||
.build/boot.o: build-dir src/boot.asm
|
.build/boot.o: build-dir src/boot.asm
|
||||||
nasm -f elf64 -o .build/boot.o src/boot.asm
|
nasm -f elf32 -o .build/boot.o src/boot.asm
|
||||||
128
src/boot.asm
128
src/boot.asm
@@ -14,14 +14,6 @@ align 4
|
|||||||
header_end:
|
header_end:
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
align 4096
|
|
||||||
page_table_l4:
|
|
||||||
resb 4096
|
|
||||||
page_table_l3:
|
|
||||||
resb 4096
|
|
||||||
page_table_l2:
|
|
||||||
resb 4096
|
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
resb 16384
|
resb 16384
|
||||||
stack_top:
|
stack_top:
|
||||||
@@ -29,129 +21,11 @@ stack_top:
|
|||||||
extern kernel_main
|
extern kernel_main
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
bits 32
|
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
mov esp, stack_top
|
mov esp, stack_top
|
||||||
|
|
||||||
call check_cpuid
|
|
||||||
call check_long_mode
|
|
||||||
|
|
||||||
call setup_page_tables
|
|
||||||
call enable_paging
|
|
||||||
|
|
||||||
lgdt [gdt64.pointer]
|
|
||||||
|
|
||||||
jmp gdt64.kernel_code:long_mode_start
|
|
||||||
|
|
||||||
check_cpuid:
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
mov ecx, eax
|
|
||||||
xor eax, 1 << 21
|
|
||||||
push eax
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
pop eax
|
|
||||||
push ecx
|
|
||||||
popfd
|
|
||||||
xor eax, ecx
|
|
||||||
jz .no_cpuid
|
|
||||||
ret
|
|
||||||
.no_cpuid:
|
|
||||||
mov al, 'I'
|
|
||||||
jmp error
|
|
||||||
|
|
||||||
check_long_mode:
|
|
||||||
mov eax, 0x80000000
|
|
||||||
cpuid
|
|
||||||
cmp eax, 0x80000001
|
|
||||||
jb .no_long_mode
|
|
||||||
|
|
||||||
mov eax, 0x80000001
|
|
||||||
cpuid
|
|
||||||
test edx, 1 << 29
|
|
||||||
jz .no_long_mode
|
|
||||||
ret
|
|
||||||
.no_long_mode:
|
|
||||||
mov al, 'L'
|
|
||||||
jmp error
|
|
||||||
|
|
||||||
setup_page_tables:
|
|
||||||
mov edi, page_table_l4
|
|
||||||
mov ecx, 4096 * 3 / 4
|
|
||||||
xor eax, eax
|
|
||||||
rep stosd
|
|
||||||
|
|
||||||
mov eax, page_table_l3
|
|
||||||
or eax, 0b11
|
|
||||||
mov [page_table_l4], eax
|
|
||||||
|
|
||||||
mov eax, page_table_l2
|
|
||||||
or eax, 0b11
|
|
||||||
mov [page_table_l3], eax
|
|
||||||
|
|
||||||
mov ecx, 0
|
|
||||||
.map_p2_table:
|
|
||||||
mov eax, 0x200000
|
|
||||||
mul ecx
|
|
||||||
or eax, 0b10000011
|
|
||||||
mov [page_table_l2 + ecx * 8], eax
|
|
||||||
inc ecx
|
|
||||||
cmp ecx, 512
|
|
||||||
jne .map_p2_table
|
|
||||||
ret
|
|
||||||
|
|
||||||
enable_paging:
|
|
||||||
mov eax, page_table_l4
|
|
||||||
mov cr3, eax
|
|
||||||
|
|
||||||
mov eax, cr4
|
|
||||||
or eax, 1 << 5
|
|
||||||
mov cr4, eax
|
|
||||||
|
|
||||||
mov ecx, 0xC0000080
|
|
||||||
rdmsr
|
|
||||||
or eax, 1 << 8
|
|
||||||
wrmsr
|
|
||||||
|
|
||||||
mov eax, cr0
|
|
||||||
or eax, 1 << 31
|
|
||||||
mov cr0, eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
bits 64
|
|
||||||
long_mode_start:
|
|
||||||
mov ax, gdt64.kernel_data
|
|
||||||
mov ss, ax
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
|
|
||||||
mov rsp, stack_top
|
|
||||||
|
|
||||||
call kernel_main
|
call kernel_main
|
||||||
|
|
||||||
cli
|
|
||||||
hang:
|
hang:
|
||||||
|
cli
|
||||||
hlt
|
hlt
|
||||||
jmp hang
|
jmp hang
|
||||||
|
|
||||||
error:
|
|
||||||
mov dword [0xb8000], 0x4f524f45
|
|
||||||
mov dword [0xb8004], 0x4f3a4f52
|
|
||||||
mov dword [0xb8008], 0x4f204f20
|
|
||||||
mov byte [0xb800a], al
|
|
||||||
hlt
|
|
||||||
|
|
||||||
section .rodata
|
|
||||||
gdt64:
|
|
||||||
dq 0
|
|
||||||
.kernel_code: equ $ - gdt64
|
|
||||||
dq (1<<44) | (1<<47) | (1<<41) | (1<<43) | (1<<53)
|
|
||||||
.kernel_data: equ $ - gdt64
|
|
||||||
dq (1<<44) | (1<<47) | (1<<41)
|
|
||||||
.pointer:
|
|
||||||
dw $ - gdt64 - 1
|
|
||||||
dq gdt64
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#include "print.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void exception_handler(uint64_t* stack)
|
|
||||||
{
|
|
||||||
uint64_t interrupt_num = stack[0];
|
|
||||||
uint64_t error_code = stack[1];
|
|
||||||
|
|
||||||
print("EXCEPTION: ");
|
|
||||||
if (interrupt_num == 0)
|
|
||||||
{
|
|
||||||
print("Division by zero");
|
|
||||||
}
|
|
||||||
else if (interrupt_num == 13)
|
|
||||||
{
|
|
||||||
print("General protection fault");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print("Unknown exception");
|
|
||||||
}
|
|
||||||
print("\nError code: ");
|
|
||||||
// You'd need to implement number printing here
|
|
||||||
print("\nSystem halted.\n");
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
__asm__ volatile("hlt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
59
src/idt.c
59
src/idt.c
@@ -1,59 +0,0 @@
|
|||||||
#include "idt.h"
|
|
||||||
#include "print.h"
|
|
||||||
|
|
||||||
#define IDT_ENTRIES 256
|
|
||||||
|
|
||||||
struct idt_entry
|
|
||||||
{
|
|
||||||
uint16_t offset_low;
|
|
||||||
uint16_t selector;
|
|
||||||
uint8_t ist;
|
|
||||||
uint8_t type_attr;
|
|
||||||
uint16_t offset_mid;
|
|
||||||
uint32_t offset_high;
|
|
||||||
uint32_t zero;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
struct idt_ptr
|
|
||||||
{
|
|
||||||
uint16_t limit;
|
|
||||||
uint64_t base;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
static struct idt_entry idt[IDT_ENTRIES];
|
|
||||||
static struct idt_ptr idt_pointer;
|
|
||||||
|
|
||||||
extern void isr0(void);
|
|
||||||
extern void isr13(void);
|
|
||||||
extern void keyboard_handler_asm(void);
|
|
||||||
|
|
||||||
static void idt_set_gate(uint8_t num, uint64_t handler, uint16_t sel, uint8_t flags)
|
|
||||||
{
|
|
||||||
idt[num].offset_low = handler & 0xFFFF;
|
|
||||||
idt[num].selector = sel;
|
|
||||||
idt[num].ist = 0;
|
|
||||||
idt[num].type_attr = flags;
|
|
||||||
idt[num].offset_mid = (handler >> 16) & 0xFFFF;
|
|
||||||
idt[num].offset_high = (handler >> 32) & 0xFFFFFFFF;
|
|
||||||
idt[num].zero = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void idt_init(void)
|
|
||||||
{
|
|
||||||
idt_pointer.limit = (sizeof(struct idt_entry) * IDT_ENTRIES) - 1;
|
|
||||||
idt_pointer.base = (uint64_t)&idt;
|
|
||||||
|
|
||||||
for (int i = 0; i < IDT_ENTRIES; i++)
|
|
||||||
{
|
|
||||||
idt_set_gate(i, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
idt_set_gate(0, (uint64_t)isr0, 0x08, 0x8E);
|
|
||||||
idt_set_gate(13, (uint64_t)isr13, 0x08, 0x8E);
|
|
||||||
idt_set_gate(33, (uint64_t)keyboard_handler_asm, 0x08, 0x8E);
|
|
||||||
|
|
||||||
__asm__ volatile("lidt %0" : : "m"(idt_pointer));
|
|
||||||
|
|
||||||
print_clr("[success]", FG_GREEN, BG_BLACK);
|
|
||||||
print(" idt initialized\n");
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
section .text
|
|
||||||
|
|
||||||
global isr0
|
|
||||||
global isr13
|
|
||||||
global keyboard_handler_asm
|
|
||||||
|
|
||||||
extern exception_handler
|
|
||||||
extern keyboard_handler
|
|
||||||
|
|
||||||
isr0:
|
|
||||||
push 0
|
|
||||||
push 0
|
|
||||||
jmp exception_common
|
|
||||||
|
|
||||||
isr13:
|
|
||||||
push 13
|
|
||||||
jmp exception_common
|
|
||||||
|
|
||||||
exception_common:
|
|
||||||
push rax
|
|
||||||
push rbx
|
|
||||||
push rcx
|
|
||||||
push rdx
|
|
||||||
push rsi
|
|
||||||
push rdi
|
|
||||||
push rbp
|
|
||||||
push r8
|
|
||||||
push r9
|
|
||||||
push r10
|
|
||||||
push r11
|
|
||||||
push r12
|
|
||||||
push r13
|
|
||||||
push r14
|
|
||||||
push r15
|
|
||||||
|
|
||||||
mov rdi, rsp
|
|
||||||
call exception_handler
|
|
||||||
|
|
||||||
pop r15
|
|
||||||
pop r14
|
|
||||||
pop r13
|
|
||||||
pop r12
|
|
||||||
pop r11
|
|
||||||
pop r10
|
|
||||||
pop r9
|
|
||||||
pop r8
|
|
||||||
pop rbp
|
|
||||||
pop rdi
|
|
||||||
pop rsi
|
|
||||||
pop rdx
|
|
||||||
pop rcx
|
|
||||||
pop rbx
|
|
||||||
pop rax
|
|
||||||
|
|
||||||
add rsp, 16
|
|
||||||
iretq
|
|
||||||
|
|
||||||
keyboard_handler_asm:
|
|
||||||
push rax
|
|
||||||
push rbx
|
|
||||||
push rcx
|
|
||||||
push rdx
|
|
||||||
push rsi
|
|
||||||
push rdi
|
|
||||||
push rbp
|
|
||||||
push r8
|
|
||||||
push r9
|
|
||||||
push r10
|
|
||||||
push r11
|
|
||||||
push r12
|
|
||||||
push r13
|
|
||||||
push r14
|
|
||||||
push r15
|
|
||||||
|
|
||||||
call keyboard_handler
|
|
||||||
|
|
||||||
mov al, 0x20
|
|
||||||
out 0x20, al
|
|
||||||
|
|
||||||
pop r15
|
|
||||||
pop r14
|
|
||||||
pop r13
|
|
||||||
pop r12
|
|
||||||
pop r11
|
|
||||||
pop r10
|
|
||||||
pop r9
|
|
||||||
pop r8
|
|
||||||
pop rbp
|
|
||||||
pop rdi
|
|
||||||
pop rsi
|
|
||||||
pop rdx
|
|
||||||
pop rcx
|
|
||||||
pop rbx
|
|
||||||
pop rax
|
|
||||||
|
|
||||||
iretq
|
|
||||||
@@ -1,12 +1,6 @@
|
|||||||
#include "idt.h"
|
|
||||||
#include "keyboard.h"
|
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
|
||||||
void kernel_main(void)
|
void kernel_main(void)
|
||||||
{
|
{
|
||||||
idt_init();
|
|
||||||
keyboard_init();
|
|
||||||
|
|
||||||
print("Welcome to nub OS\n");
|
print("Welcome to nub OS\n");
|
||||||
print("> ");
|
|
||||||
}
|
}
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
#include "print.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define KEYBOARD_DATA_PORT 0x60
|
|
||||||
#define KEYBOARD_STATUS_PORT 0x64
|
|
||||||
|
|
||||||
static char scancode_to_ascii[] = { 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
|
|
||||||
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0,
|
|
||||||
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z',
|
|
||||||
'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ' };
|
|
||||||
|
|
||||||
static char input_buffer[256];
|
|
||||||
static int buffer_index = 0;
|
|
||||||
static bool key_available = false;
|
|
||||||
|
|
||||||
static uint8_t inb(uint16_t port)
|
|
||||||
{
|
|
||||||
uint8_t result;
|
|
||||||
__asm__ volatile("inb %1, %0" : "=a"(result) : "Nd"(port));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyboard_handler(void)
|
|
||||||
{
|
|
||||||
uint8_t scancode = inb(KEYBOARD_DATA_PORT);
|
|
||||||
|
|
||||||
if (scancode & 0x80)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scancode < sizeof(scancode_to_ascii))
|
|
||||||
{
|
|
||||||
char ascii = scancode_to_ascii[scancode];
|
|
||||||
if (ascii)
|
|
||||||
{
|
|
||||||
if (ascii == '\b')
|
|
||||||
{
|
|
||||||
if (buffer_index > 0)
|
|
||||||
{
|
|
||||||
buffer_index--;
|
|
||||||
print("\b \b");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ascii == '\n')
|
|
||||||
{
|
|
||||||
input_buffer[buffer_index] = '\0';
|
|
||||||
print("\n");
|
|
||||||
key_available = true;
|
|
||||||
}
|
|
||||||
else if (buffer_index < 255)
|
|
||||||
{
|
|
||||||
input_buffer[buffer_index++] = ascii;
|
|
||||||
char str[2] = { ascii, '\0' };
|
|
||||||
print(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* keyboard_get_line(void)
|
|
||||||
{
|
|
||||||
buffer_index = 0;
|
|
||||||
key_available = false;
|
|
||||||
|
|
||||||
while (!key_available)
|
|
||||||
{
|
|
||||||
__asm__ volatile("hlt");
|
|
||||||
}
|
|
||||||
|
|
||||||
return input_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyboard_init(void)
|
|
||||||
{
|
|
||||||
__asm__ volatile("sti");
|
|
||||||
print_clr("[success]", FG_GREEN, BG_BLACK);
|
|
||||||
print(" keyboard initialized\n");
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
void keyboard_init(void);
|
|
||||||
char* keyboard_get_line(void);
|
|
||||||
Reference in New Issue
Block a user