Espresso 0.0.1e
This commit is contained in:
21
Documentation/Modules and drivers API.txt
Normal file
21
Documentation/Modules and drivers API.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
Modules and Drivers API
|
||||||
|
|
||||||
|
|
||||||
|
This file contains documentation for the Module/Driver API.
|
||||||
|
|
||||||
|
|
||||||
|
The kernel symtab is always at 0xC0101000, and can go up to 0xC0101000 + 0x8086 ( See what I did there?)
|
||||||
|
|
||||||
|
|
||||||
|
ID number -- Function -- Returns -- Arguments
|
||||||
|
0 -- get_kinfo -- kinfo_t -- uint32_t leaf
|
||||||
|
1 -- make_kfunc -- kfunc_t -- void* addr, bool module, uint16_t module_id, uint32_t function_id
|
||||||
|
2 -- add_kfunc -- uint32_t -- void* addr, bool module, uint16_t module_id, uint32_t function_id
|
||||||
|
3 -- printf -- void -- const char* format, ...
|
||||||
|
4 -- malloc -- void* -- size_t size
|
||||||
|
5 -- free -- void -- void* ptr
|
||||||
|
6 -- calloc -- void* -- size_t nmemb, size_t size
|
||||||
|
7 -- realloc -- void* -- void* ptr, size_t size
|
||||||
|
8 -- get_key -- uint16_t -- void
|
||||||
|
9 -- get_string -- char* -- void
|
||||||
|
10 --
|
19
Makefile
19
Makefile
@ -9,12 +9,15 @@ MKFS_VFAT := sudo mkfs.vfat
|
|||||||
MKFS_FLAGS := -F 32 -S 512
|
MKFS_FLAGS := -F 32 -S 512
|
||||||
NASMFLAGS := -f elf32
|
NASMFLAGS := -f elf32
|
||||||
WNOFLAGS := -Wno-discarded-qualifiers
|
WNOFLAGS := -Wno-discarded-qualifiers
|
||||||
CFLAGS := -std=gnu99 -ffreestanding -O2 -Wall -Wextra -msse $(WNOFLAGS)
|
CFLAGS := -std=gnu99 -ffreestanding -O2 -Wall -Wextra -msse4 $(WNOFLAGS)
|
||||||
LDFLAGS := -T linker.ld -ffreestanding -O2 -nostdlib
|
LDFLAGS := -T linker.ld -ffreestanding -O2 -nostdlib
|
||||||
QEMUFLAGS := -boot d -cdrom $(ISO) -drive file=espresso.img,format=raw,if=ide,readonly=off,rerror=report,werror=report -cpu qemu32,sse4.1
|
QEMUFLAGS := -boot d -cdrom $(ISO) -drive file=espresso.img,format=raw,if=ide,readonly=off,rerror=report,werror=report -cpu qemu32,sse4.1
|
||||||
QEMUFLGS_EXT := -net none -netdev user,id=n0 -device rtl8139,netdev=n0 #-singlestep
|
QEMUFLGS_EXT := -net none -netdev user,id=n0 -device rtl8139,netdev=n0 -vga std #-singlestep
|
||||||
SRC_DIRS := kernel drivers lib
|
SRC_DIRS := kernel drivers lib
|
||||||
INCLUDE_DIRS := include
|
INCLUDE_DIRS := include
|
||||||
|
ARCH_DIR := arch
|
||||||
|
X86_ARCH_DIR := $(ARCH_DIR)/x86
|
||||||
|
X86_BOOT_DIR := $(X86_ARCH_DIR)/boot
|
||||||
INCLUDES := $(addprefix -I, $(INCLUDE_DIRS))
|
INCLUDES := $(addprefix -I, $(INCLUDE_DIRS))
|
||||||
ISO_DIR := isodir
|
ISO_DIR := isodir
|
||||||
BOOT_DIR := $(ISO_DIR)/boot
|
BOOT_DIR := $(ISO_DIR)/boot
|
||||||
@ -23,8 +26,8 @@ GRUB_CFG := grub.cfg
|
|||||||
|
|
||||||
# === File collection ===
|
# === File collection ===
|
||||||
C_SRCS := $(foreach dir, $(SRC_DIRS), $(shell find $(dir) -name '*.c'))
|
C_SRCS := $(foreach dir, $(SRC_DIRS), $(shell find $(dir) -name '*.c'))
|
||||||
S_SRCS := boot.s crti.s crtn.s misc_asm.s
|
S_SRCS := $(foreach dir, $(ARCH_DIR), $(shell find $(dir) -name '*.s'))
|
||||||
NASM_SRCS := gdt.asm pit.asm isr.asm
|
NASM_SRCS := $(foreach dir, $(ARCH_DIR), $(shell find $(dir) -name '*.asm'))
|
||||||
CRTI_OBJ := crti.o
|
CRTI_OBJ := crti.o
|
||||||
CRTBEGIN_OBJ := $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
|
CRTBEGIN_OBJ := $(shell $(CC) $(CFLAGS) -print-file-name=crtbegin.o)
|
||||||
CRTEND_OBJ := $(shell $(CC) $(CFLAGS) -print-file-name=crtend.o)
|
CRTEND_OBJ := $(shell $(CC) $(CFLAGS) -print-file-name=crtend.o)
|
||||||
@ -37,11 +40,17 @@ INTERNAL_OBJS := $(CRTI_OBJ) $(OBJS) $(CRTN_OBJ)
|
|||||||
# === Build all targets ===
|
# === Build all targets ===
|
||||||
build: all iso run
|
build: all iso run
|
||||||
|
|
||||||
|
# === Build all targets and clean ===
|
||||||
|
buildc: test all iso run clean
|
||||||
|
|
||||||
# === Default target ===
|
# === Default target ===
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
|
test:
|
||||||
|
printf $(CRTI_OBJ)
|
||||||
|
|
||||||
# === Linking ===
|
# === Linking ===
|
||||||
$(TARGET): boot.o $(filter-out boot.o, $(OBJ_LINK_LIST))
|
$(TARGET): ./arch/x86/boot/boot.o $(filter-out boot.o, $(OBJ_LINK_LIST))
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ -lgcc
|
$(CC) $(LDFLAGS) -o $@ $^ -lgcc
|
||||||
|
|
||||||
|
86
arch/x86/vga_fonts.asm
Normal file
86
arch/x86/vga_fonts.asm
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
global _get_fonts_asm
|
||||||
|
|
||||||
|
_get_fonts_asm:
|
||||||
|
|
||||||
|
; NOTE: this code is taken from https://wiki.osdev.org/VGA_Fonts
|
||||||
|
|
||||||
|
;in: edi=4k buffer
|
||||||
|
;out: buffer filled with font
|
||||||
|
;clear even/odd mode
|
||||||
|
mov dx, 03ceh
|
||||||
|
mov ax, 5
|
||||||
|
out dx, ax
|
||||||
|
;map VGA memory to 0A0000h
|
||||||
|
mov ax, 0406h
|
||||||
|
out dx, ax
|
||||||
|
;set bitplane 2
|
||||||
|
mov dx, 03c4h
|
||||||
|
mov ax, 0402h
|
||||||
|
out dx, ax
|
||||||
|
;clear even/odd mode (the other way, don't ask why)
|
||||||
|
mov ax, 0604h
|
||||||
|
out dx, ax
|
||||||
|
;copy charmap
|
||||||
|
mov esi, 0A0000h
|
||||||
|
mov ecx, 256
|
||||||
|
;copy 16 bytes to bitmap
|
||||||
|
@@: movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
;skip another 16 bytes
|
||||||
|
add esi, 16
|
||||||
|
loop @@
|
||||||
|
;restore VGA state to normal operation
|
||||||
|
mov ax, 0302h
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0204h
|
||||||
|
out dx, ax
|
||||||
|
mov dx, 03ceh
|
||||||
|
mov ax, 1005h
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0E06h
|
||||||
|
out dx, ax
|
||||||
|
|
||||||
|
|
||||||
|
_set_fonts_asm:
|
||||||
|
; NOTE: this code is taken from https://wiki.osdev.org/VGA_Fonts and edited a little bit
|
||||||
|
|
||||||
|
;in: esi=4k buffer
|
||||||
|
;out: buffer filled with font
|
||||||
|
;clear even/odd mode
|
||||||
|
mov dx, 03ceh
|
||||||
|
mov ax, 5
|
||||||
|
out dx, ax
|
||||||
|
;map VGA memory to 0A0000h
|
||||||
|
mov ax, 0406h
|
||||||
|
out dx, ax
|
||||||
|
;set bitplane 2
|
||||||
|
mov dx, 03c4h
|
||||||
|
mov ax, 0402h
|
||||||
|
out dx, ax
|
||||||
|
;clear even/odd mode (the other way, don't ask why)
|
||||||
|
mov ax, 0604h
|
||||||
|
out dx, ax
|
||||||
|
;copy charmap
|
||||||
|
mov edi, 0A0000h
|
||||||
|
mov ecx, 256
|
||||||
|
;copy 16 bytes to bitmap
|
||||||
|
m: movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
;skip another 16 bytes
|
||||||
|
add esi, 16
|
||||||
|
loop m
|
||||||
|
;restore VGA state to normal operation
|
||||||
|
mov ax, 0302h
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0204h
|
||||||
|
out dx, ax
|
||||||
|
mov dx, 03ceh
|
||||||
|
mov ax, 1005h
|
||||||
|
out dx, ax
|
||||||
|
mov ax, 0E06h
|
||||||
|
out dx, ax
|
@ -9,6 +9,8 @@
|
|||||||
irq_func_t func_list[NUM_IRQS];
|
irq_func_t func_list[NUM_IRQS];
|
||||||
irq_func_t aux_func_list[NUM_IRQS];
|
irq_func_t aux_func_list[NUM_IRQS];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static volatile uint32_t num_irqs_missed = 0;
|
static volatile uint32_t num_irqs_missed = 0;
|
||||||
|
|
||||||
void irq_init(void)
|
void irq_init(void)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <port_io.h>
|
#include <port_io.h>
|
||||||
#include <tty.h>
|
#include <tty.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <ksymtab.h>
|
||||||
|
|
||||||
#include <drivers/ps2_keyboard.h>
|
#include <drivers/ps2_keyboard.h>
|
||||||
|
|
||||||
|
@ -3,4 +3,21 @@
|
|||||||
|
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
typedef struct kfunc {
|
||||||
|
/*
|
||||||
|
Bit 31 = 1 -> driver/module function, Bit 31 = 0 -> kernel function
|
||||||
|
Bits 30-20 -> module/driver ID (11 bits)
|
||||||
|
Bits 19-0 -> function ID (20 bits)
|
||||||
|
*/
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
uint32_t addr; /* Pointer to function, 0x0 if nonexistent */
|
||||||
|
} kfunc_t;
|
||||||
|
|
||||||
|
uint64_t kfunc_call(kfunc_t* func, uint32_t a, uint32_t b, uint32_t c, uint32_t d);
|
||||||
|
uint64_t call_kfunc_by_id(uint32_t id, uint32_t a, uint32_t b, uint32_t c, uint32_t d);
|
||||||
|
|
||||||
|
uint32_t add_kfunc(void* addr, bool module, uint16_t module_id, uint32_t function_id);
|
||||||
|
kfunc_t make_kfunc(void* addr, bool module, uint16_t module_id, uint32_t function_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -51,7 +51,7 @@ void kernel_main(multiboot_info_t* mbd, uint32_t magic)
|
|||||||
|
|
||||||
/* --- BEGIN INITIALIZATION SECTION --- */
|
/* --- BEGIN INITIALIZATION SECTION --- */
|
||||||
|
|
||||||
const char* espresso_kernel_version = "0.0.1d";
|
const char* espresso_kernel_version = "0.0.1e";
|
||||||
|
|
||||||
/* We need to initialize the terminal so that any error/debugging messages show. */
|
/* We need to initialize the terminal so that any error/debugging messages show. */
|
||||||
terminal_initialize();
|
terminal_initialize();
|
||||||
|
@ -2,20 +2,12 @@
|
|||||||
|
|
||||||
#include <ksymtab.h>
|
#include <ksymtab.h>
|
||||||
|
|
||||||
typedef struct kfunc {
|
|
||||||
/*
|
|
||||||
Bit 31 = 1 -> driver/module function, Bit 31 = 0 -> kernel function
|
|
||||||
Bits 30-20 -> module/driver ID (11 bits)
|
|
||||||
Bits 19-0 -> function ID (20 bits)
|
|
||||||
*/
|
|
||||||
uint32_t id;
|
|
||||||
|
|
||||||
uint32_t addr; /* Pointer to function, 0x0 if nonexistent */
|
|
||||||
} kfunc_t;
|
|
||||||
|
|
||||||
|
|
||||||
#define KFUNC_TABLE_ADDRESS 0xC0101000
|
#define KFUNC_TABLE_ADDRESS 0xC0101000
|
||||||
#define KFUNC_TABLE_SIZE (2 ^ 31) /* Maybe? who knows? */
|
|
||||||
|
#define KSYMTAB_MAX 0x8086FF
|
||||||
|
|
||||||
#define IS_MODULE_FUNC(id) ((id) & 0x80000000)
|
#define IS_MODULE_FUNC(id) ((id) & 0x80000000)
|
||||||
#define GET_MODULE_ID(id) (((id) >> 20) & 0x7FF)
|
#define GET_MODULE_ID(id) (((id) >> 20) & 0x7FF)
|
||||||
@ -26,9 +18,10 @@ typedef struct kfunc {
|
|||||||
|
|
||||||
#define MAKE_MODULE_FUNC(mid, fid) (0x80000000 | ((mid) << 20) | ((fid) & 0xFFFFF))
|
#define MAKE_MODULE_FUNC(mid, fid) (0x80000000 | ((mid) << 20) | ((fid) & 0xFFFFF))
|
||||||
|
|
||||||
|
|
||||||
kfunc_t* kfunc_table = (kfunc_t*)KFUNC_TABLE_ADDRESS;
|
kfunc_t* kfunc_table = (kfunc_t*)KFUNC_TABLE_ADDRESS;
|
||||||
|
|
||||||
|
static uint32_t ktab_size = 0;
|
||||||
|
|
||||||
|
|
||||||
uint64_t kfunc_call(kfunc_t* func, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
uint64_t kfunc_call(kfunc_t* func, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
||||||
{
|
{
|
||||||
@ -53,7 +46,7 @@ uint64_t kfunc_call(kfunc_t* func, uint32_t a, uint32_t b, uint32_t c, uint32_t
|
|||||||
|
|
||||||
uint64_t call_kfunc_by_id(uint32_t id, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
uint64_t call_kfunc_by_id(uint32_t id, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < KFUNC_TABLE_SIZE; i++)
|
for (int i = 0; i < (int)ktab_size; i++)
|
||||||
{
|
{
|
||||||
if (kfunc_table[i].id == id)
|
if (kfunc_table[i].id == id)
|
||||||
{
|
{
|
||||||
@ -67,3 +60,65 @@ uint64_t call_kfunc_by_id(uint32_t id, uint32_t a, uint32_t b, uint32_t c, uint3
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t add_kfunc(void* addr, bool module, uint16_t module_id, uint32_t function_id)
|
||||||
|
{
|
||||||
|
if (ktab_size >= KSYMTAB_MAX)
|
||||||
|
{
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfunc_t kf = make_kfunc(addr, module, module_id, function_id);
|
||||||
|
kfunc_table[ktab_size] = kf;
|
||||||
|
|
||||||
|
ktab_size++;
|
||||||
|
|
||||||
|
return kf.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Constructs and returns a kfunc_t:
|
||||||
|
- 'addr' is the address of the function (can be NULL/0)
|
||||||
|
- 'module' indicates if it's a module/driver function
|
||||||
|
- 'module_id' is used only if 'module' is true (11 bits max)
|
||||||
|
- 'function_id':
|
||||||
|
- 20 bits if module is true
|
||||||
|
- 31 bits if kernel function
|
||||||
|
*/
|
||||||
|
kfunc_t make_kfunc(void* addr, bool module, uint16_t module_id, uint32_t function_id)
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
if (module)
|
||||||
|
{
|
||||||
|
id = 0x80000000 | ((module_id & 0x7FF) << 20) | (function_id & 0xFFFFF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (function_id == UINT32_MAX)
|
||||||
|
{
|
||||||
|
function_id = ktab_size;
|
||||||
|
}
|
||||||
|
id = function_id & 0x7FFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfunc_t result = {
|
||||||
|
.id = id,
|
||||||
|
.addr = (uint32_t)(uintptr_t)addr
|
||||||
|
};
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
kfunc_t* find_kfunc(uint32_t id)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < ktab_size; i++)
|
||||||
|
{
|
||||||
|
if (kfunc_table[i].id == id)
|
||||||
|
{
|
||||||
|
return &kfunc_table[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -134,3 +134,4 @@ void free(void* ptr)
|
|||||||
prev->next = block->next;
|
prev->next = block->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,3 +79,4 @@ void map_page(void* phys_addr, void* virt_addr)
|
|||||||
asm volatile ("invlpg (%0)" :: "r" (virt_addr) : "memory");
|
asm volatile ("invlpg (%0)" :: "r" (virt_addr) : "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,3 +77,4 @@ void free_page(void* ptr)
|
|||||||
uint32_t idx = (uint32_t)ptr / PAGE_SIZE;
|
uint32_t idx = (uint32_t)ptr / PAGE_SIZE;
|
||||||
clear_bit(idx);
|
clear_bit(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ void printdc(const char* str, uint8_t color)
|
|||||||
terminal_setcolor(c);
|
terminal_setcolor(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printf(const char* format, ...) {
|
void printf(const char* format, ...)
|
||||||
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user