CPU IO ports, and basic serial driver
This commit is contained in:
parent
52303cb629
commit
90eb69f424
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"serial.h": "c"
|
||||
}
|
||||
}
|
||||
11
makefile
11
makefile
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
#include "../shared/interrupts.h"
|
||||
|
||||
void init_idt(){
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
@ -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, ...);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
void init_idt();
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue