initial commit
This commit is contained in:
commit
0fa2351940
19 changed files with 693 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
compile_flags.txt
|
||||
bin
|
49
Makefile
Normal file
49
Makefile
Normal file
|
@ -0,0 +1,49 @@
|
|||
CC=i386-elf-gcc
|
||||
LD=i386-elf-ld
|
||||
CFLAGS=-ffreestanding -g -m32 -std=c2x -O2 -Wall -Wextra -pedantic -lgcc -isystem ./libk/include
|
||||
|
||||
C_SOURCE=$(shell find kernel -type f -name "*.c")
|
||||
C_OBJ=$(patsubst %.c,bin/%.o,$(C_SOURCE))
|
||||
|
||||
A_SOURCE=$(shell find kernel -type f -name "*.asm")
|
||||
A_OBJ=$(patsubst %.asm,bin/%_asm.o,$(A_SOURCE))
|
||||
|
||||
LIBK_SOURCE=$(shell find libk -type f -name "*.c")
|
||||
LIBK_OBJ=$(patsubst %.c,bin/%.o,$(LIBK_SOURCE))
|
||||
|
||||
.PHONY: test all run clean
|
||||
|
||||
all: bin/os.iso
|
||||
|
||||
$(A_OBJ): bin/%_asm.o : %.asm
|
||||
@mkdir -p $(@D)
|
||||
nasm $< -f elf -o $@
|
||||
|
||||
$(C_OBJ): bin/%.o : %.c
|
||||
@mkdir -p $(@D)
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
$(LIBK_OBJ): bin/%.o : %.c
|
||||
@mkdir -p $(@D)
|
||||
$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
bin/libk.a: $(LIBK_OBJ)
|
||||
@mkdir -p $(@D)
|
||||
$(AR) rcs bin/libk.a $(LIBK_OBJ)
|
||||
|
||||
bin/kernel.bin: bin/libk.a $(A_OBJ) $(C_OBJ)
|
||||
@mkdir -p $(@D)
|
||||
$(LD) -nmagic -o bin/kernel.bin -T linker.ld $(A_OBJ) $(C_OBJ) bin/libk.a
|
||||
|
||||
bin/os.iso: bin/kernel.bin
|
||||
@mkdir -p $(@D)
|
||||
@mkdir -p bin/iso/boot/grub
|
||||
cp grub.cfg bin/iso/boot/grub
|
||||
cp bin/kernel.bin bin/iso/boot
|
||||
grub-mkrescue -o bin/os.iso bin/iso
|
||||
|
||||
run: all
|
||||
qemu-system-i386 -cdrom bin/os.iso
|
||||
|
||||
clean:
|
||||
rm -rf bin
|
7
grub.cfg
Normal file
7
grub.cfg
Normal file
|
@ -0,0 +1,7 @@
|
|||
set timeout=0
|
||||
set default=0
|
||||
|
||||
menuentry "trios" {
|
||||
multiboot2 /boot/kernel.bin
|
||||
boot
|
||||
}
|
87
kernel/interrupt/idt.asm
Normal file
87
kernel/interrupt/idt.asm
Normal file
|
@ -0,0 +1,87 @@
|
|||
extern idt_exception_handler
|
||||
extern idt_pic_timer
|
||||
extern idt_pic_keyboard
|
||||
extern idt_pic_handler
|
||||
global isr_stub_table
|
||||
|
||||
%macro ISRErrorStub 1
|
||||
isr_stub_%+%1:
|
||||
push dword %1
|
||||
call idt_exception_handler
|
||||
pop eax
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
%macro PICGeneric 1
|
||||
isr_stub_%+%1:
|
||||
push dword %1
|
||||
call idt_pic_handler
|
||||
pop eax
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
%macro PICTimer 1
|
||||
isr_stub_%+%1:
|
||||
push dword %1
|
||||
call idt_pic_handler
|
||||
call idt_pic_timer
|
||||
pop eax
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
%macro PICKeyboard 1
|
||||
isr_stub_%+%1:
|
||||
push dword %1
|
||||
call idt_pic_handler
|
||||
call idt_pic_keyboard
|
||||
pop eax
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
%macro ISRSyscall 1
|
||||
isr_stub_%+%1:
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
call idt_syscall
|
||||
add esp, 16
|
||||
pop eax
|
||||
iret
|
||||
%endmacro
|
||||
|
||||
section .text
|
||||
%assign i 0
|
||||
%rep 32
|
||||
ISRErrorStub i
|
||||
%assign i i+1
|
||||
%endrep
|
||||
PICTimer 32
|
||||
PICKeyboard 33
|
||||
PICGeneric 34
|
||||
PICGeneric 35
|
||||
PICGeneric 36
|
||||
PICGeneric 37
|
||||
PICGeneric 38
|
||||
PICGeneric 39
|
||||
PICGeneric 40
|
||||
PICGeneric 41
|
||||
PICGeneric 42
|
||||
PICGeneric 43
|
||||
PICGeneric 44
|
||||
PICGeneric 45
|
||||
PICGeneric 46
|
||||
PICGeneric 47
|
||||
%assign i 48
|
||||
%rep 256 - 48
|
||||
ISRErrorStub i
|
||||
%assign i i+1
|
||||
%endrep
|
||||
|
||||
section .rodata
|
||||
isr_stub_table:
|
||||
%assign i 0x00
|
||||
%rep 256
|
||||
dd isr_stub_%+i
|
||||
%assign i i+0x01
|
||||
%endrep
|
81
kernel/interrupt/idt.c
Normal file
81
kernel/interrupt/idt.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys.h>
|
||||
#include "idt.h"
|
||||
#include "../term.h"
|
||||
#include "pic.h"
|
||||
|
||||
static int timer = 0;
|
||||
|
||||
void idt_pic_handler(uint8_t exception) {
|
||||
pic_eoi(exception - PIC_REMAP_OFFSET);
|
||||
}
|
||||
|
||||
void idt_pic_timer(void) {
|
||||
uint32_t state = term_save();
|
||||
term_setcol(0x0a);
|
||||
char buf[20];
|
||||
itoa(timer, buf);
|
||||
term_setpos(0, 20);
|
||||
puts(" ");
|
||||
term_setpos(0, 20);
|
||||
puts(buf);
|
||||
timer += 1;
|
||||
term_load(state);
|
||||
}
|
||||
|
||||
void idt_pic_keyboard(void) {
|
||||
uint8_t c = inb(0x60);
|
||||
uint32_t state = term_save();
|
||||
term_setcol(0x0c);
|
||||
term_setpos(0, 21);
|
||||
puts(" ");
|
||||
term_setpos(0, 21);
|
||||
char buf[20];
|
||||
itoa(c, buf);
|
||||
puts(buf);
|
||||
term_load(state);
|
||||
}
|
||||
|
||||
void idt_exception_handler(uint8_t exception) {
|
||||
switch(exception) {
|
||||
case 0x00:
|
||||
puts("Div by zero");
|
||||
break;
|
||||
case 0x08:
|
||||
puts("Double fault");
|
||||
break;
|
||||
default:
|
||||
puts("Error");
|
||||
break;
|
||||
}
|
||||
halt();
|
||||
}
|
||||
|
||||
__attribute__((aligned(0x10)))
|
||||
static struct IdtEntry idt[256];
|
||||
static struct Idtr idtr;
|
||||
extern void* isr_stub_table[];
|
||||
|
||||
static void set_descriptor(uint8_t vector, void* isr, uint8_t flags) {
|
||||
struct IdtEntry* entry = &idt[vector];
|
||||
entry->isr_low = (size_t)isr & 0xffff;
|
||||
entry->kernel_cs = 0x08;
|
||||
entry->attributes = flags;
|
||||
entry->isr_high = (size_t)isr >> 16;
|
||||
entry->_reserved = 0;
|
||||
}
|
||||
|
||||
void idt_init(void) {
|
||||
idtr.base = (uintptr_t)&idt[0];
|
||||
idtr.limit = (uint16_t)sizeof(struct IdtEntry) * IDT_SIZE - 1;
|
||||
|
||||
for(uint8_t i = 0; i < IDT_INTERRUPTS; i++) {
|
||||
set_descriptor(i, isr_stub_table[i], 0x8e);
|
||||
}
|
||||
|
||||
__asm__ volatile ("lidt %0" : : "m"(idtr));
|
||||
}
|
||||
|
36
kernel/interrupt/idt.h
Normal file
36
kernel/interrupt/idt.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define IDT_SIZE 256
|
||||
#define IDT_INTERRUPTS 48
|
||||
|
||||
struct IdtEntry {
|
||||
uint16_t isr_low;
|
||||
uint16_t kernel_cs;
|
||||
uint8_t _reserved;
|
||||
uint8_t attributes;
|
||||
uint16_t isr_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct Idtr {
|
||||
uint16_t limit;
|
||||
uint32_t base;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef enum {
|
||||
IDT_FLAG_GATE_TASK = 0x5,
|
||||
IDT_FLAG_GATE_16BIT_INT = 0x6,
|
||||
IDT_FLAG_GATE_16BIT_TRAP = 0x7,
|
||||
IDT_FLAG_GATE_32BIT_INT = 0xE,
|
||||
IDT_FLAG_GATE_32BIT_TRAP = 0xF,
|
||||
|
||||
IDT_FLAG_RING0 = (0 << 5),
|
||||
IDT_FLAG_RING1 = (1 << 5),
|
||||
IDT_FLAG_RING2 = (2 << 5),
|
||||
IDT_FLAG_RING3 = (3 << 5),
|
||||
|
||||
IDT_FLAG_PRESENT = 0x80,
|
||||
|
||||
} IDTFlags;
|
||||
|
||||
void idt_init(void);
|
82
kernel/interrupt/pic.c
Normal file
82
kernel/interrupt/pic.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
#include "pic.h"
|
||||
#include "../term.h"
|
||||
#include <sys.h>
|
||||
|
||||
#define PIC1_COMMAND_PORT 0x20
|
||||
#define PIC1_DATA_PORT 0x21
|
||||
#define PIC2_COMMAND_PORT 0xA0
|
||||
#define PIC2_DATA_PORT 0xA1
|
||||
|
||||
|
||||
void pic_remap(uint8_t offset) {
|
||||
char a1 = inb(PIC1_DATA_PORT);
|
||||
char a2 = inb(PIC2_DATA_PORT);
|
||||
// control word 1
|
||||
// 0x11: initialize, enable ICW4
|
||||
outb(PIC1_COMMAND_PORT, 0x11);
|
||||
io_wait();
|
||||
outb(PIC2_COMMAND_PORT, 0x11);
|
||||
io_wait();
|
||||
// control word 2
|
||||
// interrupt offset
|
||||
outb(PIC1_DATA_PORT, offset);
|
||||
io_wait();
|
||||
outb(PIC2_DATA_PORT, offset + 8);
|
||||
io_wait();
|
||||
// control word 3
|
||||
// primary pic: set which pin secondary is connected to
|
||||
// (pin 2)
|
||||
outb(PIC1_DATA_PORT, 0b00000100);
|
||||
io_wait();
|
||||
outb(PIC2_DATA_PORT, 2);
|
||||
io_wait();
|
||||
// control word 3
|
||||
// 0x01: enable 8086 mode
|
||||
outb(PIC1_DATA_PORT, 0x01);
|
||||
io_wait();
|
||||
outb(PIC2_DATA_PORT, 0x01);
|
||||
io_wait();
|
||||
// clear data registers
|
||||
outb(PIC1_DATA_PORT, a1);
|
||||
outb(PIC2_DATA_PORT, a2);
|
||||
}
|
||||
|
||||
void pic_mask(int irq) {
|
||||
uint8_t port;
|
||||
if(irq < 8) {
|
||||
port = PIC1_DATA_PORT;
|
||||
} else {
|
||||
irq -= 8;
|
||||
port = PIC2_DATA_PORT;
|
||||
}
|
||||
uint8_t mask = inb(port);
|
||||
outb(port, mask | (1 << irq));
|
||||
}
|
||||
|
||||
void pic_unmask(int irq) {
|
||||
uint8_t port;
|
||||
if(irq < 8) {
|
||||
port = PIC1_DATA_PORT;
|
||||
} else {
|
||||
irq -= 8;
|
||||
port = PIC2_DATA_PORT;
|
||||
}
|
||||
uint8_t mask = inb(port);
|
||||
outb(port, mask & ~(1 << irq));
|
||||
}
|
||||
|
||||
// completely disable the PIC
|
||||
void pic_disable() {
|
||||
outb(PIC1_DATA_PORT, 0xff);
|
||||
io_wait();
|
||||
outb(PIC2_DATA_PORT, 0xff);
|
||||
io_wait();
|
||||
}
|
||||
|
||||
// end of interrupt
|
||||
void pic_eoi(int irq) {
|
||||
if(irq >= 8) {
|
||||
outb(PIC2_COMMAND_PORT, 0x20);
|
||||
}
|
||||
outb(PIC1_COMMAND_PORT, 0x20);
|
||||
}
|
10
kernel/interrupt/pic.h
Normal file
10
kernel/interrupt/pic.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define PIC_REMAP_OFFSET 0x20
|
||||
|
||||
void pic_remap(uint8_t offset);
|
||||
void pic_mask(int irq);
|
||||
void pic_unmask(int irq);
|
||||
void pic_disable();
|
||||
void pic_eoi(int irq);
|
22
kernel/main.c
Normal file
22
kernel/main.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <sys.h>
|
||||
#include "term.h"
|
||||
#include "interrupt/pic.h"
|
||||
#include "interrupt/idt.h"
|
||||
|
||||
extern void kmain(void) {
|
||||
term_clear();
|
||||
term_setcol(0x0f);
|
||||
puts("loading kernel\n");
|
||||
idt_init();
|
||||
puts("initialized idt\n");
|
||||
pic_remap(PIC_REMAP_OFFSET);
|
||||
puts("remapped pic\n");
|
||||
int_enable();
|
||||
puts("enabled interrupts\n");
|
||||
outb(0x60, 0xF4);
|
||||
puts("enabled keyboard\n");
|
||||
|
||||
while(1) {
|
||||
int_wait();
|
||||
}
|
||||
}
|
66
kernel/start.asm
Normal file
66
kernel/start.asm
Normal file
|
@ -0,0 +1,66 @@
|
|||
global start
|
||||
extern kmain
|
||||
bits 32
|
||||
|
||||
; base, limit, access, flags
|
||||
%macro gdt_entry 4
|
||||
db %2 & 0xff
|
||||
db (%2 >> 8) & 0xff
|
||||
db %1 & 0xff
|
||||
db (%1 >> 8) & 0xff
|
||||
db (%1 >> 16) & 0xff
|
||||
db %3
|
||||
db ((%2 >> 16) & 0x0f) | (%4 << 4)
|
||||
db (%1 >> 24) & 0xff
|
||||
%endmacro
|
||||
|
||||
section .multiboot_header
|
||||
align 8
|
||||
mb_start:
|
||||
dd 0xe85250d6
|
||||
dd 0
|
||||
dd mb_end - mb_start
|
||||
dd 0x100000000 - (0xe85250d6 + (mb_end - mb_start))
|
||||
dw 0
|
||||
dw 0
|
||||
dd 8
|
||||
mb_end:
|
||||
|
||||
section .bss
|
||||
align 16
|
||||
stack_start:
|
||||
resb 16384
|
||||
stack_end:
|
||||
|
||||
section .rodata
|
||||
align 16
|
||||
gdt_start:
|
||||
gdt_entry 0, 0, 0, 0
|
||||
gdt_entry 0, 0xFFFFF, 0x9A, 0xC
|
||||
gdt_entry 0, 0xFFFFF, 0x92, 0xC
|
||||
gdt_end:
|
||||
gdt_descriptor:
|
||||
dw gdt_end - gdt_start - 1
|
||||
dd gdt_start
|
||||
|
||||
|
||||
section .text
|
||||
align 8
|
||||
start:
|
||||
cli
|
||||
lgdt [gdt_descriptor]
|
||||
jmp 0x08:after_lgdt
|
||||
after_lgdt:
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov ss, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov esp, stack_end
|
||||
mov ebp, stack_end
|
||||
call kmain
|
||||
cli
|
||||
halt:
|
||||
hlt
|
||||
jmp halt
|
63
kernel/term.c
Normal file
63
kernel/term.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "term.h"
|
||||
|
||||
static uint16_t* screen = (uint16_t*)0xb8000;
|
||||
static size_t x = 0;
|
||||
static size_t y = 0;
|
||||
static uint8_t color = 0x0f;
|
||||
|
||||
static inline uint16_t screen_entry(char c, uint8_t col) {
|
||||
return (uint16_t)c | ((uint16_t)col << 8);
|
||||
}
|
||||
|
||||
void putc(char c) {
|
||||
switch(c) {
|
||||
case '\n':
|
||||
x = TERM_W;
|
||||
break;
|
||||
case '\t':
|
||||
if(x % 8 == 0) x += 8;
|
||||
x += 7 - (x % 8);
|
||||
break;
|
||||
default:
|
||||
screen[x + y * TERM_W] = screen_entry(c, color);
|
||||
x += 1;
|
||||
break;
|
||||
}
|
||||
if(x >= TERM_W) {
|
||||
x = 0;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void puts(char* s) {
|
||||
for(char* c = s; *c != '\0'; c++) {
|
||||
putc(*c);
|
||||
}
|
||||
}
|
||||
|
||||
void term_clear(void) {
|
||||
memset(screen, 0, TERM_W * TERM_H * 2);
|
||||
}
|
||||
|
||||
void term_setpos(size_t new_x, size_t new_y) {
|
||||
x = new_x;
|
||||
y = new_y;
|
||||
}
|
||||
|
||||
void term_setcol(uint8_t new_col) {
|
||||
color = new_col;
|
||||
}
|
||||
|
||||
uint32_t term_save(void) {
|
||||
return color | ((x + y * TERM_W) << 8);
|
||||
}
|
||||
|
||||
void term_load(uint32_t state) {
|
||||
color = state & 0xff;
|
||||
state >>= 8;
|
||||
x = state % TERM_W;
|
||||
y = state / TERM_W;
|
||||
}
|
15
kernel/term.h
Normal file
15
kernel/term.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define TERM_W 80
|
||||
#define TERM_H 25
|
||||
|
||||
void putc(char c);
|
||||
void puts(char* s);
|
||||
void term_clear(void);
|
||||
void term_setcol(uint8_t new_col);
|
||||
void term_setpos(size_t new_x, size_t new_y);
|
||||
uint32_t term_save(void);
|
||||
void term_load(uint32_t pos);
|
4
libk/include/stdlib.h
Normal file
4
libk/include/stdlib.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
int atoi(const char* s);
|
||||
void itoa(int n, char* buf);
|
8
libk/include/string.h
Normal file
8
libk/include/string.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int memcmp(const void *lhs, const void *rhs, size_t n);
|
||||
void *memcpy(void *restrict dst, const void *restrict src, size_t n);
|
||||
void *memmove(void *dst, const void *src, size_t n);
|
||||
void *memset(void *dest, int c, size_t n);
|
12
libk/include/sys.h
Normal file
12
libk/include/sys.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <stdint.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t inb(uint16_t port);
|
||||
void outb(uint16_t port, uint8_t val);
|
||||
void io_wait(void);
|
||||
|
||||
void int_enable(void);
|
||||
void int_disable(void);
|
||||
void int_wait(void);
|
||||
|
||||
void halt(void);
|
46
libk/stdlib.c
Normal file
46
libk/stdlib.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include <stdbool.h>
|
||||
#include "include/stdlib.h"
|
||||
|
||||
int atoi(const char* s) {
|
||||
bool neg = false;
|
||||
if(*s == '+') {
|
||||
s++;
|
||||
} else if(*s == '-') {
|
||||
neg = true;
|
||||
s++;
|
||||
}
|
||||
int n = 0;
|
||||
while(*s >= '0' && *s <= '9') {
|
||||
n *= 10;
|
||||
n += (*s - '0');
|
||||
s++;
|
||||
}
|
||||
return neg ? -n : n;
|
||||
}
|
||||
|
||||
void itoa(int n, char* buf) {
|
||||
if(n < 0) {
|
||||
n = -n;
|
||||
*buf = '-';
|
||||
buf++;
|
||||
} else if(n == 0) {
|
||||
buf[0] = '0';
|
||||
buf[1] = '\0';
|
||||
return;
|
||||
}
|
||||
char* start = buf;
|
||||
while(n > 0) {
|
||||
*buf= n % 10 + '0';
|
||||
n /= 10;
|
||||
buf++;
|
||||
}
|
||||
*buf = '\0';
|
||||
buf--;
|
||||
while(start < buf) {
|
||||
char tmp = *start;
|
||||
*start = *buf;
|
||||
*buf = tmp;
|
||||
start++;
|
||||
buf--;
|
||||
}
|
||||
}
|
47
libk/string.c
Normal file
47
libk/string.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include <stddef.h>
|
||||
#include "include/string.h"
|
||||
|
||||
int memcmp(const void *lhs, const void *rhs, size_t n) {
|
||||
const unsigned char *l = lhs;
|
||||
const unsigned char *r = rhs;
|
||||
while(n != 0 && *l == *r) {
|
||||
n--;
|
||||
l++;
|
||||
r++;
|
||||
}
|
||||
return (n == 0) ? 0 : *l - *r;
|
||||
}
|
||||
|
||||
void *memcpy(void *restrict dst, const void *restrict src, size_t n) {
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
while(n--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t n) {
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
if(s < d) {
|
||||
d += n;
|
||||
s += n;
|
||||
while(n--) {
|
||||
*--d = *--s;
|
||||
}
|
||||
} else {
|
||||
while(n--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memset(void *dest, int c, size_t n) {
|
||||
unsigned char *d = dest;
|
||||
while(n--) {
|
||||
*d = c;
|
||||
}
|
||||
return dest;
|
||||
}
|
31
libk/sys.c
Normal file
31
libk/sys.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include <stdint.h>
|
||||
|
||||
uint8_t inb(uint16_t port) {
|
||||
uint8_t ret;
|
||||
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void outb(uint16_t port, uint8_t val) {
|
||||
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
|
||||
void io_wait(void) {
|
||||
outb(0x80, 0);
|
||||
}
|
||||
|
||||
void int_enable(void) {
|
||||
__asm__ volatile ("sti");
|
||||
}
|
||||
|
||||
void int_disable(void) {
|
||||
__asm__ volatile ("cli");
|
||||
}
|
||||
|
||||
void int_wait(void) {
|
||||
__asm__ volatile ("hlt");
|
||||
}
|
||||
|
||||
void halt(void) {
|
||||
__asm__ volatile ("cli; hlt");
|
||||
}
|
25
linker.ld
Normal file
25
linker.ld
Normal file
|
@ -0,0 +1,25 @@
|
|||
ENTRY(start)
|
||||
|
||||
SECTIONS {
|
||||
. = 1M;
|
||||
|
||||
.boot :
|
||||
{
|
||||
*(.multiboot_header)
|
||||
}
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue