CPU IO ports, and basic serial driver

This commit is contained in:
notsomeidiot123 2024-10-30 11:16:25 -04:00
parent 52303cb629
commit 90eb69f424
14 changed files with 284 additions and 6 deletions

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"files.associations": {
"serial.h": "c"
}
}

View File

@ -2,7 +2,7 @@ CC := gcc
AS := nasm
CFLAGS = -c -mno-sse -mno-sse2 -mno-red-zone -ffreestanding -m32 -nostdlib -O3 -fno-pie -fno-stack-protector -mno-mmx
BL_ASFLAGS := -f bin
SRCS := $(wildcard src/kernel/*.c)
SRCS := $(wildcard src/kernel/*/*.c)
OBJS := $(patsubst src/kernel/%.c, bin/kernel/%.o, $(SRCS))
all: bootloader tools kernel
@ -16,12 +16,15 @@ tools:
bootloader:
$(AS) src/bootloader/main.s $(BL_ASFLAGS) -o bin/bootloader.bin
kernel: $(OBJS)
# kernel: $(OBJS)
kernel:
nasm src/kernel/entry.s -o bin/kernel/entry.o -f elf32
sh c_build_helper.sh
# ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386
ld -T linker.ld bin/kernel/*.o -melf_i386
%.o: $(SRCS)
$(CC) $(CFLAGS) $< -o $@
# %.o: $(SRCS)
# mkdir -p bin/kernel/$(shell dirname $@)
# $(CC) $(CFLAGS) $< -o $@
init:
@mkdir mount

View File

@ -779,6 +779,7 @@ k_info:
.yres: dw 25
.framebuffer_ptr: dd 0xb8000
.loaded_modules: dd 0
.loaded_module_c: dd 0
;loaded_modules points to a struct array containing a ptr to the entry point of each pre-loaded module to be executed during startup
;module_struct:
;.entry_point: dd 0

View File

@ -0,0 +1,5 @@
#include "../shared/interrupts.h"
void init_idt(){
}

View File

@ -0,0 +1,20 @@
#include <stdint.h>
#include "../shared/memory.h"
#include "../shared/kstdlib.h"
uint8_t pm_map[0x20000];
int pm_alloc(){
}
int pm_init(kernel_info_t *kernel_info){
}
void map(void *vaddr, void *paddr, uint32_t flags){
uint32_t pd_index = (uint32_t)vaddr >> 22;
uint32_t pt_index = (uint32_t)vaddr >> 12 & 0x3ff;
uint32_t *pd = (uint32_t*)0xfffff000;
if(!pd[pd_index]){
pd[pd_index] = pm_alloc();
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
inline void outb(uint16_t port, uint8_t data){
asm volatile ("outb %0, %1" :: "a"(data), "Nd"(port));
}
inline void outw(uint16_t port, uint16_t data){
asm volatile ("outw %0, %1" :: "a"(data), "Nd"(port));
}
inline uint8_t inb(uint16_t port){
uint8_t byte = 0;
asm volatile ("inb %1, %0" : "=a"(byte) : "Nd"(port));
return byte;
}
inline uint16_t inw(uint16_t port){
uint16_t word = 0;
asm volatile ("inw %1, %0" : "=a"(word) : "Nd"(port));
return word;
}

View File

@ -0,0 +1,65 @@
#include "serial.h"
#include "../shared/memory.h"
#include "../shared/string.h"
#include "cpuio.h"
#include <stdarg.h>
#include <stdint.h>
// #include <string.h>
uint16_t com_ports[8];
uint8_t com_buffer[8][128];
uint8_t com_buffer_index[8] = {0};
void init_serial(){
bda_t *bda = (void*)0x400;
for(int i = 0; i < 4; i++){
com_ports[i] = bda->com_ports[i];
}
}
void serial_writeb(uint8_t port, uint8_t data){
if(com_ports[port] == 0){
com_buffer[port][com_buffer_index[port]++] = data;
}
outb(com_ports[port], data);
}
uint8_t serial_readb(uint8_t port){
if(com_ports[port] == 0){
return com_buffer[port][com_buffer_index[port]--];
}
return inb(com_ports[port]);
}
void serial_writereg(uint8_t port, uint8_t reg, uint8_t data){
if(com_ports[port] == 0 || reg > 8) return;
outb(com_ports[port] + reg, data);
}
uint8_t serial_readreg(uint8_t port, uint8_t reg){
if(com_ports[port] == 0 || reg > 8) return -1;
return inb(com_ports[port] + reg);
}
void debug_puts(char *string){
while(*string){
// serial_writeb(0, *(string++));
outb(com_ports[0], *string++);
}
}
void printf(char *string, ...){
va_list vars;
va_start(vars, string);
while(*string){
if(*string == '%'){
switch(*(string + 1)){
case 'd':
string += 2;
int32_t num = va_arg(vars, int32_t);
char numb[12];
itoa(num, numb, 10);
debug_puts(numb);
continue;
}
}
outb(com_ports[0], *string);
string++;
}
}

View File

@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
void init_serial();
void serial_writeb(uint8_t port, uint8_t data);
void serial_writereg(uint8_t port, uint8_t reg, uint8_t data);
uint8_t serial_readreg(uint8_t port, uint8_t reg);
uint8_t serial_readb(uint8_t port);
void debug_puts(char *string);
void printf(char *string, ...);

View File

@ -1,5 +1,10 @@
#include "shared/memory.h"
extern void kmain(){
pm_init();
#include "shared/string.h"
#include "shared/kstdlib.h"
#include "drivers/serial.h"
extern void kmain(kernel_info_t *kernel_info){
init_serial();
pm_init(kernel_info);
return;
}

View File

@ -0,0 +1 @@
void init_idt();

View File

@ -0,0 +1,12 @@
#include "memory.h"
typedef struct kernel_info{
memory_map_entry *mmap_ptr;
uint16_t mmap_entry_count;
uint8_t padding;
uint8_t pixel_depth;
uint16_t monitor_x_resolution;
uint16_t monitor_y_resolution;
void *framebuffer;
void *loaded_modues;
uint32_t loaded_module_count;
}__attribute__((packed)) kernel_info_t;

View File

@ -0,0 +1,64 @@
#pragma once
#include <stdint.h>
#define PD_PRESENT 0x0001
#define PD_USER_RW 0x0002
#define PD_USER 0x0004
#define PD_PWT 0x0008
#define PD_PCD 0x0010
#define PD_ACCESSED 0x0020
#define PD_DIRTY 0x0040
#define PD_PAGE_SZ 0x0080
#define PD_GLOBAL 0x0100
#define PD_PAT 0x1000
#define PD_LINK_N 0x0200
#define PD_LINK_L 0x0400
#define PD_ALLOC 0x0800
#define PT_PRESENT 0X0001
#define PT_USER_RW 0x0002
#define PT_USER 0x0004
#define PT_PWT 0x0008
#define PT_PCD 0x0010
#define PT_ACCESSED 0x0020
#define PT_DIRTY 0x0040
#define PT_PAT 0x0080
#define PT_GLOBAL 0x0100
#define PT_LINK_N 0x0200
#define PT_LINK_L 0x0400
#define PT_ALLOC 0x0800
#define BIOS_MMAP_USABLE 1
#define BIOS_MMAP_RESERVED 2
#define BIOS_MMAP_RECLAIM 3
#define BIOS_MMAP_NVS 4
#define BIOS_MMAP_BAD_MEMORY 5
typedef struct BIOS_data{
uint16_t com_ports[4];
uint16_t lpt_ports[3];
uint16_t ebda_addr;
uint16_t hw_bitflags;
uint16_t kb_to_ebda;
uint16_t kbd_state;
char kbd_buffer[32];
uint8_t display_mode;
uint16_t columns_text;
uint16_t base_video_port;
uint16_t irq0_boot;
uint8_t hard_drives;
uint16_t kbd_buffer_start;
uint16_t kbd_buffer_end;
uint8_t kbd_led_state;
}__attribute__((packed)) bda_t;
typedef struct memory_map_entry{
uint64_t entry_base;
uint64_t entry_length;
uint32_t type;
uint32_t extended_bitflags;
}__attribute__((packed))mmap_entry_t;
void map(void *vaddr, void *paddr, uint32_t flags);
void map_4mb(void *vaddr, void* paddr, uint32_t flags);
int pm_init(kernel_info_t *kernel_info);

View File

@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
void itoa(int64_t data, char *res, uint8_t base);
void strpad(char *string, char padding, uint32_t length);
inline uint32_t strlen(char *str){
uint32_t c = 0;
while(*str){
str++;
c++;
}
return c;
}
void strcpy(char *src, char *dest);

View File

@ -0,0 +1,52 @@
#include <stdint.h>
#include "../shared/string.h"
//res needs to allocate enough space for 12 chars minimum
void itoa(int64_t data, char *res, uint8_t base){
char carr[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char negative = 0;
if(res == 0) return;
if(data < 0 && base == 10){
data *= -1;
negative = 1;
}
int ptr = 0;
char buffer[12] = {0};
// res[11] = 0;
if(data == 0){
res[0] = '0';
res[1] = 0;
}
uint32_t tmp = data;
while(tmp){
buffer[ptr++] = carr[tmp % base];
tmp /= base;
}
uint32_t rindex = 0;
res[ptr] = 0;
while(ptr > 0){
res[--ptr + negative] = buffer[rindex++];
}
res[0] += negative * '-';
return;
}
void strcpy(char *src, char *dest){
if(src == 0 || dest == 0){
return;
}
uint32_t len = strlen(src);
for(int i = 0; i < len; i++){
dest[i] = src[i];
}
dest[len] = 0;
}
void strpad(char *string, char padding, uint32_t length){
if(strlen(string) >= padding) return;
char tmp[length];
for(int i = 0; i < length - strlen(string); i++){
tmp[i] = padding;
}
strcpy(string, tmp + length - strlen(string));
strcpy(tmp, string);
}