Work and cleanup
This commit is contained in:
parent
7131f4ae5a
commit
99d7fed783
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ stuff/*
|
||||
cpu/memory.h
|
||||
os.iso
|
||||
disk.img
|
||||
iso/boot/initrd
|
||||
|
7
Makefile
7
Makefile
@ -3,7 +3,7 @@ C_SOURCES = $(wildcard kernel/*.c drivers/$(PLAT)/*.c drivers/$(PLAT)/*/*.c libc
|
||||
OBJ = $(C_SOURCES:.c=.o $(shell cat psinfo/$(PLAT)/o.txt))
|
||||
CC = $(shell cat psinfo/$(PLAT)/cc.txt)
|
||||
GDB = $(shell cat psinfo/$(PLAT)/gdb.txt)
|
||||
CFLAGS = -Ilibc -Wextra -Wall -g -ffreestanding
|
||||
CFLAGS = -Ilibc -Wextra -Wall -Wno-unused-parameter -g -ffreestanding
|
||||
QFLAGS = -m 2G -boot d -cdrom os.iso -serial vc #-chardev socket,id=s1,port=3000,host=localhost -serial chardev:s1
|
||||
|
||||
all: os.iso
|
||||
@ -36,10 +36,5 @@ h_files: cpu/$(PLAT)/memory.h
|
||||
rm -f cpu/memory.h
|
||||
cp cpu/$(PLAT)/memory.h cpu/memory.h
|
||||
|
||||
pipe:
|
||||
rm -f pipe.in pipe.out
|
||||
mkfifo pipe.in
|
||||
ln pipe.in pipe.out
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJ) kernel/cstart.o cpu/memory.h os.iso */*.elf iso/boot/initrd.tar
|
||||
|
@ -6,7 +6,7 @@
|
||||
void cpu_init() {
|
||||
gdt_init();
|
||||
isr_install();
|
||||
//asm volatile("sti");
|
||||
asm volatile("sti");
|
||||
paging_init();
|
||||
tasking_init();
|
||||
}
|
||||
|
@ -51,15 +51,15 @@ typedef struct {
|
||||
uint8_t set_ff;
|
||||
} __attribute__((packed)) tss_entry;
|
||||
|
||||
gdt_entry gdt[NUM_ENTRIES];
|
||||
gdt_description gdt_desc;
|
||||
tss_entry tss;
|
||||
static gdt_entry gdt[NUM_ENTRIES];
|
||||
static gdt_description gdt_desc;
|
||||
static tss_entry tss;
|
||||
|
||||
void tss_stack_reset() {
|
||||
tss.esp0=int_stack_top+0xC0000000;
|
||||
}
|
||||
|
||||
void set_entry(int i,uint32_t base,uint32_t limit,uint8_t access) {
|
||||
static void set_entry(int i,uint32_t base,uint32_t limit,uint8_t access) {
|
||||
gdt[i].limit_low16=limit&0xFFFF;
|
||||
gdt[i].base_low16=base&0xFFFFF;
|
||||
gdt[i].base_mid8=(base&0xFF0000)>>16;
|
||||
@ -69,7 +69,7 @@ void set_entry(int i,uint32_t base,uint32_t limit,uint8_t access) {
|
||||
gdt[i].base_high8=(base&0xFF000000)>>24;
|
||||
}
|
||||
|
||||
void write_tss(int32_t num, uint16_t ss0, uint32_t esp0) {
|
||||
static void write_tss(int32_t num, uint16_t ss0, uint32_t esp0) {
|
||||
// Firstly, let's compute the base and limit of our entry into the GDT.
|
||||
uint32_t base = (uint32_t) &tss;
|
||||
uint32_t limit = base + sizeof(tss_entry);
|
||||
|
@ -1,10 +1,41 @@
|
||||
#include "idt.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Segment selectors */
|
||||
#define KERNEL_CS 0x08
|
||||
|
||||
/* How every interrupt gate (handler) is defined */
|
||||
typedef struct {
|
||||
uint16_t low_offset; /* Lower 16 bits of handler function address */
|
||||
uint16_t sel; /* Kernel segment selector */
|
||||
uint8_t always0;
|
||||
/* First byte
|
||||
* Bit 7: "Interrupt is present"
|
||||
* Bits 6-5: Privilege level of caller (0=kernel..3=user)
|
||||
* Bit 4: Set to 0 for interrupt gates
|
||||
* Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */
|
||||
uint8_t flags;
|
||||
uint16_t high_offset; /* Higher 16 bits of handler function address */
|
||||
} __attribute__((packed)) idt_gate_t ;
|
||||
|
||||
/* A pointer to the array of interrupt handlers.
|
||||
* Assembly instruction 'lidt' will read it */
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint32_t base;
|
||||
} __attribute__((packed)) idt_register_t;
|
||||
|
||||
#define IDT_ENTRIES 256
|
||||
|
||||
static idt_gate_t idt[IDT_ENTRIES];
|
||||
static idt_register_t idt_reg;
|
||||
|
||||
#define low_16(address) (uint16_t)((address) & 0xFFFF)
|
||||
#define high_16(address) (uint16_t)(((address) >> 16) & 0xFFFF)
|
||||
|
||||
void set_idt_gate(int n,uint32_t handler) {
|
||||
|
||||
|
||||
void idt_set_gate(int n,uint32_t handler) {
|
||||
idt[n].low_offset=low_16(handler);
|
||||
idt[n].sel=KERNEL_CS;
|
||||
idt[n].always0=0;
|
||||
@ -12,7 +43,7 @@ void set_idt_gate(int n,uint32_t handler) {
|
||||
idt[n].high_offset=high_16(handler);
|
||||
}
|
||||
|
||||
void set_idt() {
|
||||
void load_idt() {
|
||||
idt_reg.base=(uint32_t) &idt;
|
||||
idt_reg.limit=IDT_ENTRIES * sizeof(idt_gate_t) - 1;
|
||||
/* Don't make the mistake of loading &idt -- always load &idt_reg */
|
||||
|
@ -3,37 +3,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Segment selectors */
|
||||
#define KERNEL_CS 0x08
|
||||
|
||||
/* How every interrupt gate (handler) is defined */
|
||||
typedef struct {
|
||||
uint16_t low_offset; /* Lower 16 bits of handler function address */
|
||||
uint16_t sel; /* Kernel segment selector */
|
||||
uint8_t always0;
|
||||
/* First byte
|
||||
* Bit 7: "Interrupt is present"
|
||||
* Bits 6-5: Privilege level of caller (0=kernel..3=user)
|
||||
* Bit 4: Set to 0 for interrupt gates
|
||||
* Bits 3-0: bits 1110 = decimal 14 = "32 bit interrupt gate" */
|
||||
uint8_t flags;
|
||||
uint16_t high_offset; /* Higher 16 bits of handler function address */
|
||||
} __attribute__((packed)) idt_gate_t ;
|
||||
|
||||
/* A pointer to the array of interrupt handlers.
|
||||
* Assembly instruction 'lidt' will read it */
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint32_t base;
|
||||
} __attribute__((packed)) idt_register_t;
|
||||
|
||||
#define IDT_ENTRIES 256
|
||||
idt_gate_t idt[IDT_ENTRIES];
|
||||
idt_register_t idt_reg;
|
||||
|
||||
|
||||
/* Functions implemented in idt.c */
|
||||
void set_idt_gate(int n,uint32_t handler);
|
||||
void set_idt();
|
||||
void idt_set_gate(int n,uint32_t handler);
|
||||
void load_idt();
|
||||
|
||||
#endif
|
||||
|
56
cpu/i386/interrupt.h
Normal file
56
cpu/i386/interrupt.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef INERRUPT_H
|
||||
#define INTERRUPT_H
|
||||
|
||||
/* ISRs reserved for CPU exceptions */
|
||||
void isr0();
|
||||
void isr1();
|
||||
void isr2();
|
||||
void isr3();
|
||||
void isr4();
|
||||
void isr5();
|
||||
void isr6();
|
||||
void isr7();
|
||||
void isr8();
|
||||
void isr9();
|
||||
void isr10();
|
||||
void isr11();
|
||||
void isr12();
|
||||
void isr13();
|
||||
void isr14();
|
||||
void isr15();
|
||||
void isr16();
|
||||
void isr17();
|
||||
void isr18();
|
||||
void isr19();
|
||||
void isr20();
|
||||
void isr21();
|
||||
void isr22();
|
||||
void isr23();
|
||||
void isr24();
|
||||
void isr25();
|
||||
void isr26();
|
||||
void isr27();
|
||||
void isr28();
|
||||
void isr29();
|
||||
void isr30();
|
||||
void isr31();
|
||||
void isr80();
|
||||
/* IRQ definitions */
|
||||
void irq0();
|
||||
void irq1();
|
||||
void irq2();
|
||||
void irq3();
|
||||
void irq4();
|
||||
void irq5();
|
||||
void irq6();
|
||||
void irq7();
|
||||
void irq8();
|
||||
void irq9();
|
||||
void irq10();
|
||||
void irq11();
|
||||
void irq12();
|
||||
void irq13();
|
||||
void irq14();
|
||||
void irq15();
|
||||
|
||||
#endif
|
107
cpu/i386/isr.c
107
cpu/i386/isr.c
@ -5,47 +5,48 @@
|
||||
#include "../halt.h"
|
||||
#include "../drivers/vga.h"
|
||||
#include "../tasking.h"
|
||||
#include "interrupt.h"
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
void irq_handler(registers_t r);
|
||||
isr_t interrupt_handlers[256];
|
||||
static isr_t interrupt_handlers[256];
|
||||
|
||||
/* Can't do this with a loop because we need the address
|
||||
* of the function names */
|
||||
void isr_install() {
|
||||
set_idt_gate(0,(uint32_t)isr0);
|
||||
set_idt_gate(1,(uint32_t)isr1);
|
||||
set_idt_gate(2,(uint32_t)isr2);
|
||||
set_idt_gate(3,(uint32_t)isr3);
|
||||
set_idt_gate(4,(uint32_t)isr4);
|
||||
set_idt_gate(5,(uint32_t)isr5);
|
||||
set_idt_gate(6,(uint32_t)isr6);
|
||||
set_idt_gate(7,(uint32_t)isr7);
|
||||
set_idt_gate(8,(uint32_t)isr8);
|
||||
set_idt_gate(9,(uint32_t)isr9);
|
||||
set_idt_gate(10,(uint32_t)isr10);
|
||||
set_idt_gate(11,(uint32_t)isr11);
|
||||
set_idt_gate(12,(uint32_t)isr12);
|
||||
set_idt_gate(13,(uint32_t)isr13);
|
||||
set_idt_gate(14,(uint32_t)isr14);
|
||||
set_idt_gate(15,(uint32_t)isr15);
|
||||
set_idt_gate(16,(uint32_t)isr16);
|
||||
set_idt_gate(17,(uint32_t)isr17);
|
||||
set_idt_gate(18,(uint32_t)isr18);
|
||||
set_idt_gate(19,(uint32_t)isr19);
|
||||
set_idt_gate(20,(uint32_t)isr20);
|
||||
set_idt_gate(21,(uint32_t)isr21);
|
||||
set_idt_gate(22,(uint32_t)isr22);
|
||||
set_idt_gate(23,(uint32_t)isr23);
|
||||
set_idt_gate(24,(uint32_t)isr24);
|
||||
set_idt_gate(25,(uint32_t)isr25);
|
||||
set_idt_gate(26,(uint32_t)isr26);
|
||||
set_idt_gate(27,(uint32_t)isr27);
|
||||
set_idt_gate(28,(uint32_t)isr28);
|
||||
set_idt_gate(29,(uint32_t)isr29);
|
||||
set_idt_gate(30,(uint32_t)isr30);
|
||||
set_idt_gate(31,(uint32_t)isr31);
|
||||
set_idt_gate(80,(uint32_t)isr80);
|
||||
idt_set_gate(0,(uint32_t)isr0);
|
||||
idt_set_gate(1,(uint32_t)isr1);
|
||||
idt_set_gate(2,(uint32_t)isr2);
|
||||
idt_set_gate(3,(uint32_t)isr3);
|
||||
idt_set_gate(4,(uint32_t)isr4);
|
||||
idt_set_gate(5,(uint32_t)isr5);
|
||||
idt_set_gate(6,(uint32_t)isr6);
|
||||
idt_set_gate(7,(uint32_t)isr7);
|
||||
idt_set_gate(8,(uint32_t)isr8);
|
||||
idt_set_gate(9,(uint32_t)isr9);
|
||||
idt_set_gate(10,(uint32_t)isr10);
|
||||
idt_set_gate(11,(uint32_t)isr11);
|
||||
idt_set_gate(12,(uint32_t)isr12);
|
||||
idt_set_gate(13,(uint32_t)isr13);
|
||||
idt_set_gate(14,(uint32_t)isr14);
|
||||
idt_set_gate(15,(uint32_t)isr15);
|
||||
idt_set_gate(16,(uint32_t)isr16);
|
||||
idt_set_gate(17,(uint32_t)isr17);
|
||||
idt_set_gate(18,(uint32_t)isr18);
|
||||
idt_set_gate(19,(uint32_t)isr19);
|
||||
idt_set_gate(20,(uint32_t)isr20);
|
||||
idt_set_gate(21,(uint32_t)isr21);
|
||||
idt_set_gate(22,(uint32_t)isr22);
|
||||
idt_set_gate(23,(uint32_t)isr23);
|
||||
idt_set_gate(24,(uint32_t)isr24);
|
||||
idt_set_gate(25,(uint32_t)isr25);
|
||||
idt_set_gate(26,(uint32_t)isr26);
|
||||
idt_set_gate(27,(uint32_t)isr27);
|
||||
idt_set_gate(28,(uint32_t)isr28);
|
||||
idt_set_gate(29,(uint32_t)isr29);
|
||||
idt_set_gate(30,(uint32_t)isr30);
|
||||
idt_set_gate(31,(uint32_t)isr31);
|
||||
idt_set_gate(80,(uint32_t)isr80);
|
||||
// Remap the PIC
|
||||
port_byte_out(0x20,0x11);
|
||||
port_byte_out(0xA0,0x11);
|
||||
@ -59,29 +60,29 @@ void isr_install() {
|
||||
port_byte_out(0xA1,0x0);
|
||||
|
||||
// Install the IRQs
|
||||
set_idt_gate(32,(uint32_t)irq0);
|
||||
set_idt_gate(33,(uint32_t)irq1);
|
||||
set_idt_gate(34,(uint32_t)irq2);
|
||||
set_idt_gate(35,(uint32_t)irq3);
|
||||
set_idt_gate(36,(uint32_t)irq4);
|
||||
set_idt_gate(37,(uint32_t)irq5);
|
||||
set_idt_gate(38,(uint32_t)irq6);
|
||||
set_idt_gate(39,(uint32_t)irq7);
|
||||
set_idt_gate(40,(uint32_t)irq8);
|
||||
set_idt_gate(41,(uint32_t)irq9);
|
||||
set_idt_gate(42,(uint32_t)irq10);
|
||||
set_idt_gate(43,(uint32_t)irq11);
|
||||
set_idt_gate(44,(uint32_t)irq12);
|
||||
set_idt_gate(45,(uint32_t)irq13);
|
||||
set_idt_gate(46,(uint32_t)irq14);
|
||||
set_idt_gate(47,(uint32_t)irq15);
|
||||
idt_set_gate(32,(uint32_t)irq0);
|
||||
idt_set_gate(33,(uint32_t)irq1);
|
||||
idt_set_gate(34,(uint32_t)irq2);
|
||||
idt_set_gate(35,(uint32_t)irq3);
|
||||
idt_set_gate(36,(uint32_t)irq4);
|
||||
idt_set_gate(37,(uint32_t)irq5);
|
||||
idt_set_gate(38,(uint32_t)irq6);
|
||||
idt_set_gate(39,(uint32_t)irq7);
|
||||
idt_set_gate(40,(uint32_t)irq8);
|
||||
idt_set_gate(41,(uint32_t)irq9);
|
||||
idt_set_gate(42,(uint32_t)irq10);
|
||||
idt_set_gate(43,(uint32_t)irq11);
|
||||
idt_set_gate(44,(uint32_t)irq12);
|
||||
idt_set_gate(45,(uint32_t)irq13);
|
||||
idt_set_gate(46,(uint32_t)irq14);
|
||||
idt_set_gate(47,(uint32_t)irq15);
|
||||
|
||||
set_idt(); // Load with ASM
|
||||
load_idt();
|
||||
}
|
||||
|
||||
|
||||
/* To print the message which defines every exception */
|
||||
char *exception_messages[] = {
|
||||
static char *exception_messages[] = {
|
||||
"Division By Zero",
|
||||
"Debug",
|
||||
"Non Maskable Interrupt",
|
||||
@ -178,7 +179,7 @@ void isr_handler(registers_t r) {
|
||||
}
|
||||
|
||||
|
||||
void register_interrupt_handler(uint8_t n,isr_t handler) {
|
||||
void isr_register_handler(uint8_t n,isr_t handler) {
|
||||
interrupt_handlers[n] = handler;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,14 @@ extern void irq13();
|
||||
extern void irq14();
|
||||
extern void irq15();
|
||||
|
||||
/* Struct which aggregates many registers */
|
||||
typedef struct {
|
||||
uint32_t ds; /* Data segment selector */
|
||||
uint32_t edi,esi,ebp,esp,ebx,edx,ecx,eax; /* Pushed by pusha. */
|
||||
uint32_t int_no,err_code; /* Interrupt number and error code (if applicable) */
|
||||
uint32_t eip,cs,eflags,useresp,ss; /* Pushed by the processor automatically */
|
||||
} registers_t;
|
||||
|
||||
#define IRQ0 32
|
||||
#define IRQ1 33
|
||||
#define IRQ2 34
|
||||
@ -72,18 +80,12 @@ extern void irq15();
|
||||
#define IRQ14 46
|
||||
#define IRQ15 47
|
||||
|
||||
/* Struct which aggregates many registers */
|
||||
typedef struct {
|
||||
uint32_t ds; /* Data segment selector */
|
||||
uint32_t edi,esi,ebp,esp,ebx,edx,ecx,eax; /* Pushed by pusha. */
|
||||
uint32_t int_no,err_code; /* Interrupt number and error code (if applicable) */
|
||||
uint32_t eip,cs,eflags,useresp,ss; /* Pushed by the processor automatically */
|
||||
} registers_t;
|
||||
typedef void (*isr_t)(registers_t);
|
||||
|
||||
void isr_install();
|
||||
void isr_handler(registers_t r);
|
||||
void irq_handler(registers_t r);
|
||||
|
||||
typedef void (*isr_t)(registers_t);
|
||||
void register_interrupt_handler(uint8_t n,isr_t handler);
|
||||
void isr_register_handler(uint8_t n,isr_t handler);
|
||||
|
||||
#endif
|
||||
|
@ -2,5 +2,9 @@
|
||||
#include <stdint.h>
|
||||
|
||||
void* alloc_memory(uint32_t num_blocks) {
|
||||
return alloc_kern_pages(num_blocks,1);
|
||||
return alloc_pages(num_blocks);
|
||||
}
|
||||
|
||||
void alloc_memory_virt(uint32_t num_blocks,void* addr) {
|
||||
return alloc_pages_virt(num_blocks,addr);
|
||||
}
|
||||
|
@ -5,5 +5,6 @@
|
||||
#define BLK_SZ 4096
|
||||
|
||||
void* alloc_memory(uint32_t blocks);
|
||||
void alloc_memory_virt(uint32_t num_blocks,void* addr);
|
||||
|
||||
#endif
|
||||
|
@ -1,70 +1,116 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "paging_helpers.h"
|
||||
#include "paging.h"
|
||||
uint32_t page_directory [1024] __attribute__((aligned(4096)));
|
||||
uint32_t page_tables [1048576] __attribute__((aligned(4096)));
|
||||
void* next_kern_virt=(void*)KERN_VIRT_START;
|
||||
void* next_kern_phys=(void*)KERN_PHYS_START;
|
||||
void set_directory_entry(int entry,char usr,char wr,char p,uint32_t* page_directory,uint32_t* page_tables) {
|
||||
int flags=p&1;
|
||||
flags=flags|((wr&1)<<1);
|
||||
flags=flags|((usr&1)<<2);
|
||||
page_directory[entry]=(((uint32_t)&(page_tables[entry*1024]))-0xC0000000)|flags;
|
||||
#include "pmem.h"
|
||||
static uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||
static uint32_t kern_page_tables[NUM_KERN_DIRS*1024] __attribute__((aligned(4096)));
|
||||
static uint32_t smap_page_tables[2048] __attribute__((aligned(4096)));
|
||||
static uint32_t* smap=(uint32_t*)0xFF800000;
|
||||
|
||||
static char is_page_present(int page) {
|
||||
int table=page>>10;
|
||||
page=page&0x3FF;
|
||||
if ((smap[table]&0x1)==0) {
|
||||
return 0;
|
||||
}
|
||||
smap_page_tables[table+1]=(smap[table]&0xFFFFFC00)|0x3;
|
||||
return smap[(1024+(1024*table))+page]&0x1;
|
||||
}
|
||||
|
||||
void set_table_entry(uint32_t page,uint32_t base_addr,char usr,char wr,char p,uint32_t* page_tables) {
|
||||
int flags=p&1;
|
||||
flags=flags|((wr&1)<<1);
|
||||
flags=flags|((usr&1)<<2);
|
||||
page_tables[page]=base_addr|flags;
|
||||
}
|
||||
|
||||
void alloc_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr,uint32_t* page_directory,uint32_t* page_tables) {
|
||||
void map_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr) {
|
||||
uint32_t virt_addr=(uint32_t)virt_addr_ptr;
|
||||
uint32_t phys_addr=(uint32_t)phys_addr_ptr;
|
||||
int dir_entry=(virt_addr&0xFFC00000)>>22;
|
||||
int table_entry=(virt_addr&0x3FF000)>>12;
|
||||
for (int i=0;i<=num_pages;i++) {
|
||||
set_table_entry((dir_entry*1024)+table_entry,phys_addr,usr,wr,1,page_tables);
|
||||
if (!(smap[dir_entry]&0x1)) {
|
||||
int flags=1;
|
||||
flags=flags|((wr&1)<<1);
|
||||
flags=flags|((usr&1)<<2);
|
||||
smap[dir_entry]=(uint32_t)pmem_alloc(1)|flags;
|
||||
}
|
||||
smap_page_tables[dir_entry+1]=(smap[dir_entry]&0xFFFFFC00)|0x3;
|
||||
int flags=1;
|
||||
flags=flags|((wr&1)<<1);
|
||||
flags=flags|((usr&1)<<2);
|
||||
smap[(1024+(1024*dir_entry))+table_entry]=phys_addr|flags;
|
||||
table_entry++;
|
||||
phys_addr+=0x1000;
|
||||
if (table_entry==1024) {
|
||||
table_entry=0;
|
||||
set_directory_entry(dir_entry,usr,wr,1,page_directory,page_tables);
|
||||
dir_entry++;
|
||||
} else if (i==num_pages) {
|
||||
set_directory_entry(dir_entry,usr,wr,1,page_directory,page_tables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* alloc_kern_pages(int num_pages,char wr) {
|
||||
void* starting=next_kern_virt;
|
||||
alloc_pages(next_kern_virt,next_kern_phys,num_pages,1,wr,page_directory,page_tables);
|
||||
next_kern_virt+=num_pages*4096;
|
||||
next_kern_phys+=num_pages*4096;
|
||||
return starting;
|
||||
}
|
||||
|
||||
int dir_entry_present(int entry) {
|
||||
uint32_t dir_entry=page_directory[entry];
|
||||
return dir_entry&1;
|
||||
}
|
||||
|
||||
void* virt_to_phys(void* virt_addr_ptr) {
|
||||
uint32_t virt_addr=(uint32_t)virt_addr_ptr;
|
||||
int dir_num=(virt_addr&0xFFC00000)>>22;
|
||||
int table_num=(virt_addr&0x3FF000)>>12;
|
||||
int offset=(virt_addr&0xFFF);
|
||||
uint32_t table_entry=page_tables[(dir_num*1024)+table_num];
|
||||
table_entry=table_entry&0xFFFFF000;
|
||||
return (void*)(table_entry+offset);
|
||||
|
||||
void* alloc_pages(int num_pages) {
|
||||
void* phys_addr=pmem_alloc(num_pages);
|
||||
uint32_t bmap_index;
|
||||
uint32_t remaining_blks;
|
||||
for(uint32_t i=0;i<131072;i++) {
|
||||
char got_0=0;
|
||||
remaining_blks=num_pages;
|
||||
uint32_t old_j;
|
||||
for (uint32_t j=i*8;;j++) {
|
||||
char bit=is_page_present(j);
|
||||
if (got_0) {
|
||||
if (bit) {
|
||||
if (remaining_blks==0) {
|
||||
bmap_index=old_j;
|
||||
break;
|
||||
} else {
|
||||
i+=j/8;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
remaining_blks--;
|
||||
}
|
||||
} else {
|
||||
if (!bit) {
|
||||
got_0=1;
|
||||
old_j=j;
|
||||
remaining_blks--;
|
||||
}
|
||||
}
|
||||
if (remaining_blks==0) {
|
||||
bmap_index=old_j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (remaining_blks==0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (remaining_blks!=0) {
|
||||
return NULL;
|
||||
}
|
||||
// for (int i=0;i<num_pages;i++) {
|
||||
// vmem_set_bmap_bit(bmap_index+i);
|
||||
// }
|
||||
void* addr=(void*)(bmap_index<<12);
|
||||
map_pages(addr,phys_addr,num_pages,1,1);
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
void alloc_pages_virt(int num_pages,void* addr) {
|
||||
void* phys_addr=pmem_alloc(num_pages);
|
||||
map_pages(addr,phys_addr,num_pages,1,1);
|
||||
}
|
||||
|
||||
void paging_init() {
|
||||
alloc_kern_pages(NUM_KERN_DIRS*1024,1);
|
||||
for (uint32_t i=0;i<NUM_KERN_DIRS*1024;i++) {
|
||||
kern_page_tables[i]=(i<<12)|0x7;
|
||||
}
|
||||
smap_page_tables[0]=(((uint32_t)&(page_directory))-0xC0000000)|0x3;
|
||||
for (uint32_t i=1;i<2048;i++) {
|
||||
smap_page_tables[i]=0;
|
||||
}
|
||||
for (uint32_t i=0;i<NUM_KERN_DIRS;i++) {
|
||||
uint32_t entry_virt=(uint32_t)&(kern_page_tables[i*1024]);
|
||||
page_directory[i+768]=(entry_virt-0xC0000000)|0x7;
|
||||
}
|
||||
for (uint32_t i=0;i<2;i++) {
|
||||
uint32_t entry_virt=(uint32_t)&(smap_page_tables[i*1024]);
|
||||
page_directory[i+1022]=(entry_virt-0xC0000000)|0x7;
|
||||
}
|
||||
load_page_directory((uint32_t*)((uint32_t)page_directory-0xC0000000));
|
||||
}
|
||||
|
@ -4,17 +4,11 @@
|
||||
#include <stdint.h>
|
||||
#include "paging_helpers.h"
|
||||
|
||||
#define NUM_KERN_DIRS 4
|
||||
#define KERN_VIRT_START 0xC0000000
|
||||
#define KERN_PHYS_START 0x0
|
||||
#define NUM_KERN_DIRS 2
|
||||
|
||||
|
||||
extern uint32_t page_directory[1024];
|
||||
extern uint32_t page_tables[1048576];
|
||||
void alloc_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr,uint32_t* page_directory,uint32_t* page_tables);
|
||||
void* alloc_kern_pages(int num_pages,char wr);
|
||||
int dir_entry_present(int entry);
|
||||
void* virt_to_phys(void* virt_addr_ptr);
|
||||
void map_pages(void* virt_addr_ptr,void* phys_addr_ptr,int num_pages,char usr,char wr);
|
||||
void* alloc_pages(int num_pages);
|
||||
void alloc_pages_virt(int num_pages,void* addr);
|
||||
void paging_init();
|
||||
|
||||
|
||||
|
117
cpu/i386/pmem.c
Normal file
117
cpu/i386/pmem.c
Normal file
@ -0,0 +1,117 @@
|
||||
#include <grub/multiboot.h>
|
||||
#include "../halt.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <klog.h>
|
||||
|
||||
static char bmap[131072];
|
||||
|
||||
static char get_bmap_bit(int index) {
|
||||
int byte=index/8;
|
||||
int bit=index%8;
|
||||
char entry=bmap[byte];
|
||||
return (entry&(1<<bit))>0;
|
||||
}
|
||||
|
||||
static void set_bmap_bit(int index) {
|
||||
int byte=index/8;
|
||||
int bit=index%8;
|
||||
bmap[byte]=bmap[byte]|(1<<bit);
|
||||
}
|
||||
|
||||
static void clear_bmap_bit(int index) {
|
||||
int byte=index/8;
|
||||
int bit=index%8;
|
||||
bmap[byte]=bmap[byte]&(~(1<<bit));
|
||||
}
|
||||
|
||||
void pmem_init(multiboot_info_t* mbd) {
|
||||
if (!mbd->flags&&MULTIBOOT_INFO_MEM_MAP) {
|
||||
klog("PANIC","No memory map supplied by bootloader!");
|
||||
halt();
|
||||
}
|
||||
for (int i=0;i<131072;i++) {
|
||||
bmap[i]=0xFF;
|
||||
}
|
||||
uint32_t mmap_length=mbd->mmap_length;
|
||||
struct multiboot_mmap_entry* mmap_addr=(struct multiboot_mmap_entry*)(mbd->mmap_addr+0xC0000000);
|
||||
struct multiboot_mmap_entry* mmap_entry=mmap_addr;
|
||||
uint32_t size;
|
||||
for (int i=0;(uint32_t)mmap_entry<((uint32_t)mmap_addr+mmap_length);mmap_entry=(struct multiboot_mmap_entry*)((uint32_t)mmap_entry+size+4)) {
|
||||
size=mmap_entry->size;
|
||||
uint32_t start=mmap_entry->addr;
|
||||
uint32_t end=start+mmap_entry->len-1;
|
||||
uint32_t type=mmap_entry->type;
|
||||
if (type!=1 || start<0x100000) {
|
||||
continue;
|
||||
}
|
||||
if (start&0xFFF) {
|
||||
start+=0x1000;
|
||||
}
|
||||
start=start>>12;
|
||||
end=end>>12;
|
||||
for (uint32_t i=start;i<end;i++) {
|
||||
clear_bmap_bit(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
for (uint32_t i=0;i<2048;i++) {
|
||||
set_bmap_bit(i);
|
||||
}
|
||||
}
|
||||
|
||||
void* pmem_alloc(int num_pages) {
|
||||
uint32_t bmap_index;
|
||||
uint32_t remaining_blks;
|
||||
for(uint32_t i=0;i<131072;i++) {
|
||||
if (bmap[i]!=0xFF) {
|
||||
char got_0=0;
|
||||
remaining_blks=num_pages;
|
||||
uint32_t old_j;
|
||||
for (uint32_t j=i*8;;j++) {
|
||||
char bit=get_bmap_bit(j);
|
||||
if (got_0) {
|
||||
if (bit) {
|
||||
if (remaining_blks==0) {
|
||||
bmap_index=old_j;
|
||||
break;
|
||||
} else {
|
||||
i+=j/8;
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
remaining_blks--;
|
||||
}
|
||||
} else {
|
||||
if (!bit) {
|
||||
got_0=1;
|
||||
old_j=j;
|
||||
remaining_blks--;
|
||||
}
|
||||
}
|
||||
if (remaining_blks==0) {
|
||||
bmap_index=old_j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remaining_blks==0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (remaining_blks!=0) {
|
||||
return NULL;
|
||||
}
|
||||
for (int i=0;i<num_pages;i++) {
|
||||
set_bmap_bit(bmap_index+i);
|
||||
}
|
||||
void* addr=(void*)(bmap_index<<12);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void pmem_free(int start_page,int num_pages) {
|
||||
for (int i=start_page;i<num_pages;i++) {
|
||||
set_bmap_bit(i);
|
||||
}
|
||||
}
|
10
cpu/i386/pmem.h
Normal file
10
cpu/i386/pmem.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef PMEM_H
|
||||
#define PMEM_H
|
||||
|
||||
#include <grub/multiboot.h>
|
||||
|
||||
void pmem_init(multiboot_info_t* mbd);
|
||||
void* pmem_alloc(int num_pages);
|
||||
void pmem_free(int start_page,int num_pages);
|
||||
|
||||
#endif
|
@ -1,29 +1,31 @@
|
||||
unsigned char port_byte_in(unsigned short port) {
|
||||
unsigned char result;
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t port_byte_in(uint16_t port) {
|
||||
uint8_t result;
|
||||
asm("in %%dx, %%al":"=a"(result):"d"(port));
|
||||
return result;
|
||||
}
|
||||
|
||||
void port_byte_out(unsigned short port,unsigned char data) {
|
||||
void port_byte_out(uint16_t port,uint8_t data) {
|
||||
asm("out %%al, %%dx":: "a"(data),"d"(port));
|
||||
}
|
||||
|
||||
unsigned short port_word_in(unsigned short port) {
|
||||
unsigned short result;
|
||||
uint16_t port_word_in(uint16_t port) {
|
||||
uint16_t result;
|
||||
asm("in %%dx, %%ax":"=a"(result):"d"(port));
|
||||
return result;
|
||||
}
|
||||
|
||||
void port_word_out(unsigned short port,unsigned short data) {
|
||||
void port_word_out(uint16_t port,uint16_t data) {
|
||||
asm("out %%ax, %%dx":: "a" (data), "d" (port));
|
||||
}
|
||||
|
||||
unsigned long port_long_in(unsigned short port) {
|
||||
unsigned long result;
|
||||
uint32_t port_long_in(uint16_t port) {
|
||||
uint32_t result;
|
||||
asm("inl %%dx, %%eax":"=a"(result):"d"(port));
|
||||
return result;
|
||||
}
|
||||
|
||||
void port_long_out(unsigned short port,unsigned long data) {
|
||||
void port_long_out(uint16_t port,uint32_t data) {
|
||||
asm("outl %%eax, %%dx":: "a" (data), "d" (port));
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
#ifndef PORTS_H
|
||||
#define PORTS_H
|
||||
|
||||
unsigned char port_byte_in(unsigned short port);
|
||||
void port_byte_out(unsigned short port,unsigned char data);
|
||||
unsigned short port_word_in(unsigned short port);
|
||||
void port_word_out(unsigned short port,unsigned short data);
|
||||
unsigned long port_long_in(unsigned short port);
|
||||
void port_long_out(unsigned short port,unsigned long data);
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t port_byte_in(uint16_t port);
|
||||
void port_byte_out(uint16_t port,uint8_t data);
|
||||
uint16_t port_word_in(uint16_t port);
|
||||
void port_word_out(uint16_t port,uint16_t data);
|
||||
uint32_t port_long_in(uint16_t port);
|
||||
void port_long_out(uint16_t port,uint32_t data);
|
||||
#endif
|
||||
|
@ -73,8 +73,7 @@ Task* tasking_createTask(void* eip) {
|
||||
}
|
||||
|
||||
void send_msg(uint32_t pid,char* msg) {
|
||||
Task* task=headTask;
|
||||
while(task!=NULL) {
|
||||
for (Task* task=headTask;task!=NULL;task=task->next) {
|
||||
if (task->pid==pid) {
|
||||
if (task->msg_store==NULL) {
|
||||
task->msg_store=malloc(sizeof(char*)*256);
|
||||
@ -87,22 +86,7 @@ void send_msg(uint32_t pid,char* msg) {
|
||||
task->wr--;
|
||||
}
|
||||
}
|
||||
task=task->next;
|
||||
}
|
||||
// for (Task* task=headTask;task!=NULL;task=task->next) {
|
||||
// if (task->pid==pid) {
|
||||
// if (task->msg_store==NULL) {
|
||||
// task->msg_store=malloc(sizeof(char*)*256);
|
||||
// task->sender_store=malloc(sizeof(uint32_t)*256);
|
||||
// }
|
||||
// task->msg_store[task->wr]=msg;
|
||||
// task->sender_store[task->wr]=currentTask->pid;
|
||||
// task->wr++;
|
||||
// if (task->wr==task->rd) {
|
||||
// task->wr--;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
char* get_msg(uint32_t* sender) {
|
||||
|
98
drivers/i386/pci.c
Normal file
98
drivers/i386/pci.c
Normal file
@ -0,0 +1,98 @@
|
||||
#include <stdint.h>
|
||||
#include "../../cpu/i386/ports.h"
|
||||
#include <klog.h>
|
||||
#include "pci.h"
|
||||
#include "../vga.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
pci_dev_common_info** pci_devs;
|
||||
static uint32_t max_devs;
|
||||
uint32_t pci_num_devs;
|
||||
|
||||
static uint32_t read_config(uint8_t bus,uint8_t device,uint8_t func,uint8_t offset) {
|
||||
uint32_t address;
|
||||
uint32_t lbus=(uint32_t)bus;
|
||||
uint32_t ldev=(uint32_t)device;
|
||||
uint32_t lfunc=(uint32_t)func;
|
||||
address=(uint32_t)((lbus << 16)|(ldev << 11)|(lfunc<<8)|(offset&0xfc)|((uint32_t)0x80000000));
|
||||
port_long_out(PCI_CONFIG_ADDRESS,address);
|
||||
uint32_t data=port_long_in(PCI_CONFIG_DATA);
|
||||
return data;
|
||||
}
|
||||
|
||||
static void write_config(uint8_t bus,uint8_t device,uint8_t func,uint8_t offset,uint32_t data) {
|
||||
uint32_t address;
|
||||
uint32_t lbus=(uint32_t)bus;
|
||||
uint32_t ldev=(uint32_t)device;
|
||||
uint32_t lfunc=(uint32_t)func;
|
||||
address=(uint32_t)((lbus << 16)|(ldev << 11)|(lfunc<<8)|(offset&0xfc)|((uint32_t)0x80000000));
|
||||
port_long_out(PCI_CONFIG_ADDRESS,address);
|
||||
port_long_out(PCI_CONFIG_DATA,data);
|
||||
}
|
||||
|
||||
pci_dev_common_info* pci_get_dev_info(uint8_t bus,uint8_t device,uint8_t func) {
|
||||
uint32_t* info=malloc(sizeof(uint32_t)*4);
|
||||
info[0]=read_config(bus,device,func,0);
|
||||
info[1]=read_config(bus,device,func,4);
|
||||
info[2]=read_config(bus,device,func,8);
|
||||
info[3]=read_config(bus,device,func,0xC);
|
||||
return (pci_dev_common_info*)info;
|
||||
}
|
||||
|
||||
void pci_set_dev_info(uint8_t bus,uint8_t device,uint8_t func,pci_dev_common_info* inf) {
|
||||
uint32_t* info=(uint32_t*)inf;
|
||||
write_config(bus,device,func,0,info[0]);
|
||||
write_config(bus,device,func,4,info[1]);
|
||||
write_config(bus,device,func,8,info[2]);
|
||||
write_config(bus,device,func,0xC,info[3]);
|
||||
}
|
||||
|
||||
static void checkFunction(uint8_t bus,uint8_t device,uint8_t func,pci_dev_common_info* info);
|
||||
|
||||
static void checkDevice(uint8_t bus, uint8_t device) {
|
||||
pci_dev_common_info* info=pci_get_dev_info(bus,device,0);
|
||||
if(info->vend_id==0xFFFF||info->class_code==0xFF) {
|
||||
return;
|
||||
}
|
||||
checkFunction(bus,device,0,info);
|
||||
if((info->header_type&0x80)!=0) {
|
||||
for(uint8_t function=1;function<8;function++) {
|
||||
pci_dev_common_info* info=pci_get_dev_info(bus,device,function);
|
||||
if(info->vend_id!=0xFFFF&&info->class_code!=0xFF) {
|
||||
checkFunction(bus,device,function,info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkFunction(uint8_t bus,uint8_t device,uint8_t func,pci_dev_common_info* info) {
|
||||
if (pci_num_devs==max_devs) {
|
||||
max_devs+=32;
|
||||
pci_devs=malloc(sizeof(pci_dev_common_info)*max_devs);
|
||||
}
|
||||
klog("INFO","Found PCI device. Class code:%x, Subclass:%x Prog IF:%x",info->class_code,info->subclass,info->prog_if);
|
||||
klog("INFO","Vendor ID:%x, Device ID:%x",info->vend_id,info->dev_id);
|
||||
if ((info->header_type&0x7f)==0) {
|
||||
for (uint8_t offset=0x10;offset<0x10+4*6;offset+=4) {
|
||||
uint32_t bar=read_config(bus,device,func,offset);
|
||||
if (bar!=0) {
|
||||
if (bar&0x1) {
|
||||
klog("INFO","IO BAR%d:%x",(offset-0x10)/4,bar&0xFFFFFFFC);
|
||||
} else {
|
||||
klog("INFO","MEM BAR%d:%x",(offset-0x10)/4,bar&0xFFFFFFF0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pci_init() {
|
||||
pci_devs=malloc(sizeof(pci_dev_common_info)*32);
|
||||
max_devs=32;
|
||||
pci_num_devs=0;
|
||||
for(uint16_t bus=0;bus<1; bus++) {
|
||||
for(uint8_t device=0;device<32; device++) {
|
||||
checkDevice(bus, device);
|
||||
}
|
||||
}
|
||||
}
|
13
drivers/i386/pci.h
Normal file
13
drivers/i386/pci.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef PCI_INTERN_H
|
||||
#define PCI_INTERN_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../pci.h"
|
||||
|
||||
#define PCI_CONFIG_ADDRESS 0xCF8
|
||||
#define PCI_CONFIG_DATA 0xCFC
|
||||
|
||||
pci_dev_common_info* pci_get_dev_info(uint8_t bus,uint8_t device,uint8_t func);
|
||||
void pci_set_dev_info(uint8_t bus,uint8_t device,uint8_t func,pci_dev_common_info* inf);
|
||||
|
||||
#endif
|
159
drivers/i386/serial.c
Normal file
159
drivers/i386/serial.c
Normal file
@ -0,0 +1,159 @@
|
||||
#include "../../cpu/i386/ports.h"
|
||||
#include "../../cpu/i386/isr.h"
|
||||
#include "../serial.h"
|
||||
#include "../../libc/stdio.h"
|
||||
#include "../../libc/string.h"
|
||||
#include "../../libc/devbuf.h"
|
||||
#include "../vga.h"
|
||||
#include "../../fs/devfs.h"
|
||||
#include <klog.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define SERIAL_LINE_ENABLE_DLAB 0x80
|
||||
|
||||
static devbuf* bufs[4];
|
||||
|
||||
static int data_port(int com) {
|
||||
switch (com) {
|
||||
case 0: return 0x3f8;
|
||||
case 1: return 0x2f8;
|
||||
case 2: return 0x3e8;
|
||||
case 3: return 0x2e8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int int_port(int com) {
|
||||
switch (com) {
|
||||
case 0: return 0x3f9;
|
||||
case 1: return 0x2f9;
|
||||
case 2: return 0x3e9;
|
||||
case 3: return 0x2e9;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int fifo_port(int com) {
|
||||
switch (com) {
|
||||
case 0: return 0x3fa;
|
||||
case 1: return 0x2fa;
|
||||
case 2: return 0x3ea;
|
||||
case 3: return 0x2ea;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int line_cmd_port(int com) {
|
||||
switch (com) {
|
||||
case 0: return 0x3fb;
|
||||
case 1: return 0x2fb;
|
||||
case 2: return 0x3eb;
|
||||
case 3: return 0x2eb;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int modem_port(int com) {
|
||||
switch (com) {
|
||||
case 0: return 0x3fc;
|
||||
case 1: return 0x2fc;
|
||||
case 2: return 0x3ec;
|
||||
case 3: return 0x2ec;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int line_stat_port(int com) {
|
||||
switch (com) {
|
||||
case 0: return 0x3fd;
|
||||
case 1: return 0x2fd;
|
||||
case 2: return 0x3ed;
|
||||
case 3: return 0x2ed;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int scratch_port(int com) {
|
||||
switch (com) {
|
||||
case 0: return 0x3ff;
|
||||
case 1: return 0x2ff;
|
||||
case 2: return 0x3ef;
|
||||
case 3: return 0x2ef;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void configure_baud_rate(uint32_t divisor,int com) {
|
||||
port_byte_out(line_cmd_port(com),SERIAL_LINE_ENABLE_DLAB);
|
||||
port_byte_out(data_port(com),(divisor>>8)&0xFF);
|
||||
port_byte_out(data_port(com),divisor&0xFF);
|
||||
}
|
||||
|
||||
static int is_transmit_fifo_empty(int com) {
|
||||
return port_byte_in(line_stat_port(com))&0x20;
|
||||
}
|
||||
|
||||
static void configure(uint32_t com, uint32_t rate) {
|
||||
configure_baud_rate(115200/rate,com);
|
||||
port_byte_out(line_cmd_port(com),0x03);
|
||||
port_byte_out(fifo_port(com),0xC7);
|
||||
port_byte_out(modem_port(com),0x03);
|
||||
port_byte_out(int_port(com),0x01);
|
||||
}
|
||||
|
||||
static int drv(char* filename,int c,long pos,char wr) {
|
||||
int com;
|
||||
switch (filename[4]) {
|
||||
case '0':
|
||||
com=0;
|
||||
break;
|
||||
case '1':
|
||||
com=1;
|
||||
break;
|
||||
case '2':
|
||||
com=2;
|
||||
break;
|
||||
case '3':
|
||||
com=3;
|
||||
break;
|
||||
}
|
||||
if (wr) {
|
||||
while (!is_transmit_fifo_empty(com)) continue;
|
||||
port_byte_out(data_port(com),c);
|
||||
return 0;
|
||||
} else {
|
||||
return devbuf_get(bufs[com]);
|
||||
}
|
||||
}
|
||||
|
||||
void serial_int_handler_1(registers_t regs) {
|
||||
char data=port_byte_in(data_port(0));
|
||||
if (data=='\r') {
|
||||
data='\n';
|
||||
}
|
||||
devbuf_add(data,bufs[0]);
|
||||
}
|
||||
|
||||
void serial_int_handler_2(registers_t regs) {
|
||||
devbuf_add(port_byte_in(data_port(1)),bufs[1]);
|
||||
}
|
||||
|
||||
|
||||
void serial_init() {
|
||||
klog("INFO","Scanning for serial ports");
|
||||
for (int i=0;i<2;i++) {
|
||||
port_byte_out(scratch_port(i),0xaa);
|
||||
if (port_byte_in(scratch_port(i))==0xaa) {
|
||||
klog("INFO","Found COM%d",i+1);
|
||||
bufs[i]=devbuf_init();
|
||||
switch (i) {
|
||||
case 0:
|
||||
isr_register_handler(IRQ4,serial_int_handler_1);
|
||||
configure(0,9600);
|
||||
devfs_add(drv,"ttyS0");
|
||||
break;
|
||||
case 1:
|
||||
isr_register_handler(IRQ3,serial_int_handler_2);
|
||||
configure(1,9600);
|
||||
devfs_add(drv,"ttyS1");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,15 +4,15 @@
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#define xy_to_indx(x,y) ((x+(y*width))*2)
|
||||
char* screen;
|
||||
int width;
|
||||
int height;
|
||||
int x;
|
||||
int y;
|
||||
vga_colors fg_color;
|
||||
vga_colors bg_color;
|
||||
static char* screen;
|
||||
static int width;
|
||||
static int height;
|
||||
static int x;
|
||||
static int y;
|
||||
static vga_colors fg_color;
|
||||
static vga_colors bg_color;
|
||||
|
||||
void vga_set_char(int x,int y,char c) {
|
||||
static void set_char(int x,int y,char c) {
|
||||
screen[xy_to_indx(x,y)]=c;
|
||||
screen[xy_to_indx(x,y)+1]=(bg_color<<4)|fg_color;
|
||||
}
|
||||
@ -20,12 +20,12 @@ void vga_set_char(int x,int y,char c) {
|
||||
void vga_clear() {
|
||||
for (int y=0;y<height;y++) {
|
||||
for (int x=0;x<width;x++) {
|
||||
vga_set_char(x,y,' ');
|
||||
set_char(x,y,' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_cursor(int x,int y) {
|
||||
static void set_cursor(int x,int y) {
|
||||
int pos=(x+(y*width));
|
||||
port_byte_out(0x3D4,0xF);
|
||||
port_byte_out(0x3D5,pos&0xFF);
|
||||
@ -56,7 +56,7 @@ void vga_write_string(const char* string) {
|
||||
x=0;
|
||||
y++;
|
||||
} else {
|
||||
vga_set_char(x,y,c);
|
||||
set_char(x,y,c);
|
||||
x++;
|
||||
}
|
||||
if (x==width) {
|
||||
@ -74,3 +74,11 @@ void vga_write_string(const char* string) {
|
||||
}
|
||||
set_cursor(x,y);
|
||||
}
|
||||
|
||||
void vga_backspace() {
|
||||
if (x!=0) {
|
||||
x--;
|
||||
set_char(x,y,' ');
|
||||
set_cursor(x,y);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef PCI_H
|
||||
#define PCI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t vend_id;
|
||||
uint16_t dev_id;
|
||||
|
142
fs/devfs.c
142
fs/devfs.c
@ -1,71 +1,71 @@
|
||||
// #include "../kernel/vfs.h"
|
||||
// #include "../libc/stdlib.h"
|
||||
// #include "../libc/string.h"
|
||||
// #include "../libc/stdio.h"
|
||||
// #include "devfs.h"
|
||||
//
|
||||
// char** devices;
|
||||
// dev_drv* dev_drivers;
|
||||
// uint32_t num_devices;
|
||||
// uint32_t max_devices;
|
||||
//
|
||||
// char devfs_drv(fs_op op,FILE* stream,void* data1,void* data2) {
|
||||
// if (op==FSOP_MOUNT) {
|
||||
// return 1;
|
||||
// }
|
||||
// if (op==FSOP_OPEN) {
|
||||
// for (int i=0;i<num_devices;i++) {
|
||||
// if (strcmp(devices[i],stream->path)==0) {
|
||||
// return 1;
|
||||
// }
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
// if (op==FSOP_GETC) {
|
||||
// int i;
|
||||
// for (i=0;i<num_devices;i++) {
|
||||
// if (strcmp(devices[i],stream->path)==0) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// *((int*)data1)=dev_drivers[i]((char*)stream->path,0,stream->pos,0);
|
||||
// stream->pos+=1;
|
||||
// return 1;
|
||||
// }
|
||||
// if (op==FSOP_PUTC) {
|
||||
// int i;
|
||||
// for (i=0;i<num_devices;i++) {
|
||||
// if (strcmp(devices[i],stream->path)==0) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// dev_drivers[i]((char*)stream->path,*((int*)data1),stream->pos,1);
|
||||
// stream->pos+=1;
|
||||
// return 1;
|
||||
// }
|
||||
// if (op==FSOP_CLOSE) {
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// void init_devfs() {
|
||||
// devices=malloc(sizeof(char*)*32);
|
||||
// dev_drivers=malloc(sizeof(dev_drv)*32);
|
||||
// num_devices=0;
|
||||
// max_devices=0;
|
||||
// register_fs(devfs_drv,"devfs");
|
||||
// mount("/dev/","","devfs");
|
||||
// }
|
||||
//
|
||||
// void add_dev(dev_drv drv,char* name) {
|
||||
// if (num_devices==max_devices) {
|
||||
// devices=realloc(devices,sizeof(char*)*(max_devices+32));
|
||||
// dev_drivers=realloc(dev_drivers,sizeof(dev_drv)*(max_devices+32));
|
||||
// max_devices+=32;
|
||||
// }
|
||||
// dev_drivers[num_devices]=drv;
|
||||
// devices[num_devices]=malloc(sizeof(char)*(strlen(name)+1));
|
||||
// strcpy(devices[num_devices],name);
|
||||
// num_devices++;
|
||||
// }
|
||||
#include "../kernel/vfs.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "devfs.h"
|
||||
|
||||
static char** devices;
|
||||
static dev_drv* dev_drivers;
|
||||
static uint32_t num_devices;
|
||||
static uint32_t max_devices;
|
||||
|
||||
char devfs_drv(fs_op op,FILE* stream,void* data1,void* data2) {
|
||||
if (op==FSOP_MOUNT) {
|
||||
return 1;
|
||||
}
|
||||
if (op==FSOP_OPEN) {
|
||||
for (uint32_t i=0;i<num_devices;i++) {
|
||||
if (strcmp(devices[i],stream->path)==0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (op==FSOP_GETC) {
|
||||
uint32_t i;
|
||||
for (i=0;i<num_devices;i++) {
|
||||
if (strcmp(devices[i],stream->path)==0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*((int*)data1)=dev_drivers[i]((char*)stream->path,0,stream->pos,0);
|
||||
stream->pos+=1;
|
||||
return 1;
|
||||
}
|
||||
if (op==FSOP_PUTC) {
|
||||
uint32_t i;
|
||||
for (i=0;i<num_devices;i++) {
|
||||
if (strcmp(devices[i],stream->path)==0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev_drivers[i]((char*)stream->path,*((int*)data1),stream->pos,1);
|
||||
stream->pos+=1;
|
||||
return 1;
|
||||
}
|
||||
if (op==FSOP_CLOSE) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_devfs() {
|
||||
devices=malloc(sizeof(char*)*32);
|
||||
dev_drivers=malloc(sizeof(dev_drv)*32);
|
||||
num_devices=0;
|
||||
max_devices=32;
|
||||
register_fs(devfs_drv,"devfs");
|
||||
mount("/dev/","","devfs");
|
||||
}
|
||||
|
||||
void devfs_add(dev_drv drv,char* name) {
|
||||
if (num_devices==max_devices) {
|
||||
devices=realloc(devices,sizeof(char*)*(max_devices+32));
|
||||
dev_drivers=realloc(dev_drivers,sizeof(dev_drv)*(max_devices+32));
|
||||
max_devices+=32;
|
||||
}
|
||||
dev_drivers[num_devices]=drv;
|
||||
devices[num_devices]=malloc(sizeof(char)*(strlen(name)+1));
|
||||
strcpy(devices[num_devices],name);
|
||||
num_devices++;
|
||||
}
|
||||
|
@ -4,5 +4,6 @@
|
||||
typedef int (*dev_drv)(char* filename,int c,long pos,char wr);
|
||||
|
||||
void init_devfs();
|
||||
void add_dev(dev_drv drv,char* name);
|
||||
void devfs_add(dev_drv drv,char* name);
|
||||
|
||||
#endif
|
||||
|
170
fs/initrd.c
170
fs/initrd.c
@ -1,85 +1,85 @@
|
||||
// #include "../kernel/vfs.h"
|
||||
// #include "../cpu/halt.h"
|
||||
// #include "../libc/stdlib.h"
|
||||
// #include "../libc/stdio.h"
|
||||
// #include "../libc/string.h"
|
||||
//
|
||||
// char** names;
|
||||
// uint32_t* offsets;
|
||||
// uint32_t* sizes;
|
||||
// uint32_t num_files;
|
||||
// FILE* initrd_fd;
|
||||
//
|
||||
// char initrd_drv(fs_op op,FILE* stream,void* data1,void* data2) {
|
||||
// if (op==FSOP_MOUNT) {
|
||||
// return 1;
|
||||
// }
|
||||
// if (op==FSOP_OPEN) {
|
||||
// char file_exists=0;
|
||||
// for (int i=0;i<num_files;i++) {
|
||||
// if (strcmp(names[i],stream->path)==0) {
|
||||
// file_exists=1;
|
||||
// }
|
||||
// }
|
||||
// return file_exists;
|
||||
// }
|
||||
// if (op==FSOP_GETC) {
|
||||
// int i;
|
||||
// for (i=0;i<num_files;i++) {
|
||||
// if (strcmp(names[i],stream->path)==0) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (stream->pos>=sizes[i]) {
|
||||
// *((int*)data1)=EOF;
|
||||
// stream->eof=1;
|
||||
// return 1;
|
||||
// }
|
||||
// fseek(initrd_fd,offsets[i]+stream->pos,SEEK_SET);
|
||||
// *((int*)data1)=fgetc(initrd_fd);
|
||||
// stream->pos+=1;
|
||||
// return 1;
|
||||
// }
|
||||
// if (op==FSOP_CLOSE) {
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// void init_initrd() {
|
||||
// initrd_fd=fopen("/dev/initrd","r");
|
||||
// if (!initrd_fd) {
|
||||
// printf("PANIC: Cannot open initrd!");
|
||||
// halt();
|
||||
// }
|
||||
// uint32_t max_files=32;
|
||||
// num_files=0;
|
||||
// names=malloc(sizeof(char*)*32);
|
||||
// offsets=malloc(sizeof(uint32_t)*32);
|
||||
// sizes=malloc(sizeof(uint32_t)*32);
|
||||
// for (uint32_t i=0;;i++) {
|
||||
// if (i==max_files) {
|
||||
// names=realloc(names,sizeof(char*)*(max_files+32));
|
||||
// offsets=realloc(offsets,sizeof(uint32_t)*(max_files+32));
|
||||
// sizes=realloc(sizes,sizeof(uint32_t)*(max_files+32));
|
||||
// max_files+=32;
|
||||
// }
|
||||
// uint32_t name_size;
|
||||
// fread(&name_size,4,1,initrd_fd);
|
||||
// if (name_size==0) {
|
||||
// break;
|
||||
// }
|
||||
// char* name=malloc(sizeof(char)*(name_size+1));
|
||||
// fread(name,1,name_size+1,initrd_fd);
|
||||
// long contents_size;
|
||||
// fread(&contents_size,4,1,initrd_fd);
|
||||
// long datapos=ftell(initrd_fd);
|
||||
// fseek(initrd_fd,contents_size,SEEK_CUR);
|
||||
// names[i]=name;
|
||||
// offsets[i]=datapos;
|
||||
// sizes[i]=contents_size;
|
||||
// num_files++;
|
||||
// }
|
||||
// fseek(initrd_fd,0,SEEK_SET);
|
||||
// register_fs(initrd_drv,"initrd");
|
||||
// }
|
||||
#include "../kernel/vfs.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <klog.h>
|
||||
|
||||
static char** names;
|
||||
static uint32_t* offsets;
|
||||
static long* sizes;
|
||||
static uint32_t num_files;
|
||||
static FILE* initrd_fd;
|
||||
|
||||
static char drv(fs_op op,FILE* stream,void* data1,void* data2) {
|
||||
if (op==FSOP_MOUNT) {
|
||||
return 1;
|
||||
}
|
||||
if (op==FSOP_OPEN) {
|
||||
char file_exists=0;
|
||||
for (uint32_t i=0;i<num_files;i++) {
|
||||
if (strcmp(names[i],stream->path)==0) {
|
||||
file_exists=1;
|
||||
}
|
||||
}
|
||||
return file_exists;
|
||||
}
|
||||
if (op==FSOP_GETC) {
|
||||
uint32_t i;
|
||||
for (i=0;i<num_files;i++) {
|
||||
if (strcmp(names[i],stream->path)==0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stream->pos>=sizes[i]) {
|
||||
*((int*)data1)=EOF;
|
||||
stream->eof=1;
|
||||
return 1;
|
||||
}
|
||||
fseek(initrd_fd,offsets[i]+stream->pos,SEEK_SET);
|
||||
*((int*)data1)=fgetc(initrd_fd);
|
||||
stream->pos+=1;
|
||||
return 1;
|
||||
}
|
||||
if (op==FSOP_CLOSE) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initrd_init() {
|
||||
initrd_fd=fopen("/dev/initrd","r");
|
||||
if (!initrd_fd) {
|
||||
klog("PANIC","Cannot open initrd!");
|
||||
for(;;) {}
|
||||
}
|
||||
uint32_t max_files=32;
|
||||
num_files=0;
|
||||
names=malloc(sizeof(char*)*32);
|
||||
offsets=malloc(sizeof(uint32_t)*32);
|
||||
sizes=malloc(sizeof(long)*32);
|
||||
for (uint32_t i=0;;i++) {
|
||||
if (i==max_files) {
|
||||
names=realloc(names,sizeof(char*)*(max_files+32));
|
||||
offsets=realloc(offsets,sizeof(uint32_t)*(max_files+32));
|
||||
sizes=realloc(sizes,sizeof(long)*(max_files+32));
|
||||
max_files+=32;
|
||||
}
|
||||
uint32_t name_size;
|
||||
fread(&name_size,4,1,initrd_fd);
|
||||
if (name_size==0) {
|
||||
break;
|
||||
}
|
||||
char* name=malloc(sizeof(char)*(name_size+1));
|
||||
fread(name,1,name_size+1,initrd_fd);
|
||||
long contents_size;
|
||||
fread(&contents_size,4,1,initrd_fd);
|
||||
long datapos=ftell(initrd_fd);
|
||||
fseek(initrd_fd,contents_size,SEEK_CUR);
|
||||
names[i]=name;
|
||||
offsets[i]=datapos;
|
||||
sizes[i]=contents_size;
|
||||
num_files++;
|
||||
}
|
||||
fseek(initrd_fd,0,SEEK_SET);
|
||||
register_fs(drv,"initrd");
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef INITRD_H
|
||||
#define INITRD_H
|
||||
|
||||
uint32_t init_initrd();
|
||||
uint32_t initrd_init();
|
||||
|
||||
#endif
|
||||
|
BIN
iso/boot/initrd
BIN
iso/boot/initrd
Binary file not shown.
@ -37,10 +37,6 @@ boot_page_table1:
|
||||
.skip 4096
|
||||
boot_page_table2:
|
||||
.skip 4096
|
||||
boot_page_table3:
|
||||
.skip 4096
|
||||
boot_page_table4:
|
||||
.skip 4096
|
||||
# Further page tables may be required if the kernel grows beyond 3 MiB.
|
||||
|
||||
# The kernel entry point.
|
||||
@ -60,8 +56,8 @@ _start:
|
||||
# 1 MiB as it can be generally useful, and there's no need to
|
||||
# specially map the VGA buffer.
|
||||
movl $0, %esi
|
||||
# Map 4096 pages.
|
||||
movl $4096, %ecx
|
||||
# Map 2048 pages.
|
||||
movl $2048, %ecx
|
||||
|
||||
1:
|
||||
# Map physical address as "present, writable". Note that this maps
|
||||
@ -88,8 +84,6 @@ _start:
|
||||
movl $(boot_page_table1 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 0
|
||||
movl $(boot_page_table1 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 768 * 4
|
||||
movl $(boot_page_table2 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 769 * 4
|
||||
movl $(boot_page_table3 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 770 * 4
|
||||
movl $(boot_page_table4 - 0xC0000000 + 0x007), boot_page_directory - 0xC0000000 + 771 * 4
|
||||
# Set cr3 to the address of the boot_page_directory.
|
||||
movl $(boot_page_directory - 0xC0000000), %ecx
|
||||
movl %ecx, %cr3
|
||||
|
39
kernel/elf.h
Normal file
39
kernel/elf.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef ELF_H
|
||||
#define ELF_H
|
||||
#define ELF_MAGIC 0x464c457f
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
char type;
|
||||
char endian;
|
||||
char version;
|
||||
char abi;
|
||||
char padding[8];
|
||||
uint16_t type2;
|
||||
uint16_t iset;
|
||||
uint32_t version2;
|
||||
uint32_t entry;
|
||||
uint32_t prog_hdr;
|
||||
uint32_t section_hdr;
|
||||
uint32_t flags;
|
||||
uint16_t header_sz;
|
||||
uint16_t pheader_ent_sz;
|
||||
uint16_t pheader_ent_nm;
|
||||
uint16_t sheader_ent_sz;
|
||||
uint16_t sheader_ent_nm;
|
||||
uint16_t sheader_nm_idx;
|
||||
} __attribute__((packed)) elf_header;
|
||||
|
||||
typedef struct {
|
||||
uint32_t type;
|
||||
uint32_t offset;
|
||||
uint32_t vaddr;
|
||||
uint32_t unused;
|
||||
uint32_t filesz;
|
||||
uint32_t memsz;
|
||||
uint32_t flags;
|
||||
uint32_t alignment;
|
||||
} __attribute__((packed)) elf_pheader;
|
||||
|
||||
|
||||
#endif
|
139
kernel/kernel.c
139
kernel/kernel.c
@ -1,27 +1,125 @@
|
||||
#include "../cpu/cpu_init.h"
|
||||
#include "../cpu/i386/paging.h"
|
||||
#include "../drivers/vga.h"
|
||||
#include "../drivers/pci.h"
|
||||
#include "../drivers/serial.h"
|
||||
#include "../cpu/i386/ports.h"
|
||||
#include "../cpu/i386/pmem.h"
|
||||
#include "../cpu/memory.h"
|
||||
#include "vfs.h"
|
||||
#include "../fs/devfs.h"
|
||||
#include "../fs/initrd.h"
|
||||
#include <grub/text_fb_info.h>
|
||||
#include <stdlib.h>
|
||||
#include <tasking.h>
|
||||
#include <k_messages.h>
|
||||
#include <string.h>
|
||||
#include "multiboot.h"
|
||||
#include <grub/multiboot.h>
|
||||
#include "klog.h"
|
||||
#include "elf.h"
|
||||
|
||||
void init() {
|
||||
void* addr=get_paddr((void*)0xC0000001);
|
||||
vga_write_string("Physical address of 0xC0000001 is ");
|
||||
char str[11];
|
||||
str[0]='\0';
|
||||
hex_to_ascii((uint32_t)addr,str);
|
||||
static long initrd_sz;
|
||||
static char* initrd;
|
||||
static multiboot_info_t* mbd;
|
||||
|
||||
typedef int (*func_ptr)();
|
||||
|
||||
static int console_dev_drv(char* filename,int c,long pos,char wr) {
|
||||
if (wr) {
|
||||
if (c=='\f') {
|
||||
vga_clear();
|
||||
} else if (c=='\b') {
|
||||
vga_backspace();
|
||||
}
|
||||
char str[2];
|
||||
str[0]=(char)c;
|
||||
str[1]='\0';
|
||||
vga_write_string(str);
|
||||
vga_write_string("\n");
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
// return devbuf_get(kbd_buf);
|
||||
}
|
||||
}
|
||||
|
||||
static int initrd_dev_drv(char* filename,int c,long pos,char wr) {
|
||||
if (wr) {
|
||||
return 0;
|
||||
}
|
||||
if (pos>=initrd_sz) {
|
||||
return EOF;
|
||||
}
|
||||
return initrd[pos];
|
||||
}
|
||||
|
||||
static void read_initrd(multiboot_info_t* mbd) {
|
||||
if ((mbd->flags&MULTIBOOT_INFO_MODS)!=0) {
|
||||
uint32_t mods_count=mbd->mods_count;
|
||||
if (mods_count>0) {
|
||||
while (mods_count>0) {
|
||||
multiboot_module_t* mods_addr=(multiboot_module_t*)(mbd->mods_addr+0xC0000000);
|
||||
if (strcmp((char*)(mods_addr->cmdline+0xC0000000),"initrd")==0) {
|
||||
initrd=malloc(sizeof(char)*(mods_addr->mod_end-mods_addr->mod_start));
|
||||
initrd_sz=(mods_addr->mod_end-mods_addr->mod_start);
|
||||
memcpy(initrd,(void*)mods_addr->mod_start+0xC0000000,initrd_sz);
|
||||
};
|
||||
mods_count--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
klog("PANIC","Cannnot load initrd. No modules found!");
|
||||
for(;;) {}
|
||||
}
|
||||
if (!initrd) {
|
||||
klog("PANIC","Cannnot load initrd. Initrd module not found!");
|
||||
for(;;) {}
|
||||
}
|
||||
}
|
||||
|
||||
static void init() {
|
||||
init_vfs();
|
||||
init_devfs();
|
||||
devfs_add(console_dev_drv,"console");
|
||||
stdout=fopen("/dev/console","w");
|
||||
stdin=fopen("/dev/console","r");
|
||||
stderr=fopen("/dev/console","w");
|
||||
pmem_init(mbd);
|
||||
read_initrd(mbd);
|
||||
devfs_add(initrd_dev_drv,"initrd");
|
||||
initrd_init();
|
||||
mount("/initrd/","","initrd");
|
||||
// Detect PCI
|
||||
port_long_out(0xCF8,(1<<31));
|
||||
uint32_t word=port_long_in(0xCFC);
|
||||
port_long_out(0xCF8,(1<<31)|0x4);
|
||||
if (word!=port_long_in(0xCFC)) {
|
||||
pci_init();
|
||||
}
|
||||
// Detect and initailize serial ports
|
||||
serial_init();
|
||||
FILE* file=fopen("/initrd/prog.elf","r");
|
||||
elf_header header;
|
||||
fread(&header,sizeof(elf_header),1,file);
|
||||
if (header.magic!=ELF_MAGIC) {
|
||||
klog("INFO","Invalid magic number for prog.elf");
|
||||
fclose(file);
|
||||
} else {
|
||||
fseek(file,header.prog_hdr,SEEK_SET);
|
||||
elf_pheader pheader;
|
||||
fread(&pheader,sizeof(elf_pheader),1,file);
|
||||
alloc_memory_virt(1,(void*)pheader.vaddr);
|
||||
fseek(file,pheader.offset,SEEK_SET);
|
||||
fread((void*)pheader.vaddr,pheader.filesz,1,file);
|
||||
klog("INFO","VADDR:%x",pheader.vaddr);
|
||||
func_ptr prog=(func_ptr)header.entry;
|
||||
int val=prog();
|
||||
klog("INFO","RAN PROG:%d",val);
|
||||
}
|
||||
for(;;) {
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void kmain(multiboot_info_t* header) {
|
||||
mbd=header;
|
||||
cpu_init();
|
||||
text_fb_info info;
|
||||
if (header->flags&MULTIBOOT_INFO_FRAMEBUFFER_INFO&&header->framebuffer_type==2) {
|
||||
@ -36,27 +134,6 @@ void kmain(multiboot_info_t* header) {
|
||||
vga_init(info);
|
||||
createTask(init);
|
||||
for (;;) {
|
||||
uint32_t sender;
|
||||
char* msg;
|
||||
msg=get_msg(&sender);
|
||||
if (msg) {
|
||||
char* cmd=strtok(msg," ");
|
||||
if (strcmp(cmd,"GET_PADDR")==0) {
|
||||
uint32_t addr;
|
||||
addr=addr|msg[10];
|
||||
addr=addr|msg[11]<<8;
|
||||
addr=addr|msg[12]<<16;
|
||||
addr=addr|msg[13]<<24;
|
||||
addr=(uint32_t)virt_to_phys((void*)addr);
|
||||
char* addr_str=malloc(sizeof(char)*5);
|
||||
addr_str[4]=0;
|
||||
addr_str[0]=addr&0xFF;
|
||||
addr_str[1]=(addr&0xFF00)>>8;
|
||||
addr_str[2]=(addr&0xFF0000)>>16;
|
||||
addr_str[3]=(addr&0xFF0000)>>24;
|
||||
send_msg(sender,addr_str);
|
||||
}
|
||||
}
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
276
kernel/vfs.c
Normal file
276
kernel/vfs.c
Normal file
@ -0,0 +1,276 @@
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "vfs.h"
|
||||
typedef struct _vfs_mapping_struct {
|
||||
char* mntpnt;
|
||||
uint32_t type;
|
||||
struct _vfs_mapping_struct* next;
|
||||
} vfs_mapping;
|
||||
|
||||
static const char** drv_names;
|
||||
static fs_drv* drvs;
|
||||
static uint32_t max_drvs;
|
||||
static uint32_t next_drv_indx;
|
||||
static vfs_mapping* head_mapping;
|
||||
static vfs_mapping* tail_mapping;
|
||||
|
||||
FILE* stdin=NULL;
|
||||
FILE* stdout=NULL;
|
||||
FILE* stderr=NULL;
|
||||
|
||||
|
||||
static int vfsstrcmp(const char* s1,const char* s2) {
|
||||
int i;
|
||||
for (i = 0; s1[i] == s2[i]; i++) {
|
||||
if (s1[i] == '\0') return 0;
|
||||
}
|
||||
if (s1[i] == '\0') return 0;
|
||||
return s1[i] - s2[i];
|
||||
}
|
||||
|
||||
void init_vfs() {
|
||||
drvs=malloc(sizeof(fs_drv)*32);
|
||||
drv_names=malloc(sizeof(const char**)*32);
|
||||
max_drvs=32;
|
||||
next_drv_indx=0;
|
||||
head_mapping=NULL;
|
||||
tail_mapping=NULL;
|
||||
}
|
||||
|
||||
uint32_t register_fs(fs_drv drv,const char* type) {
|
||||
if (next_drv_indx==max_drvs) {
|
||||
drvs=realloc(drvs,sizeof(fs_drv)*(max_drvs+32));
|
||||
drv_names=realloc(drv_names,sizeof(char*)*(max_drvs+32));
|
||||
max_drvs+=32;
|
||||
}
|
||||
drvs[next_drv_indx]=drv;
|
||||
drv_names[next_drv_indx]=type;
|
||||
next_drv_indx++;
|
||||
return next_drv_indx-1;
|
||||
}
|
||||
|
||||
char mount(char* mntpnt,char* dev,char* type) {
|
||||
uint32_t i;
|
||||
for (i=0;i<next_drv_indx;i++) {
|
||||
const char* name=drv_names[i];
|
||||
if (strcmp(name,type)==0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
char ok=drvs[i](FSOP_MOUNT,NULL,mntpnt,dev);
|
||||
if (ok) {
|
||||
if (head_mapping==NULL) {
|
||||
vfs_mapping* mapping=malloc(sizeof(vfs_mapping));
|
||||
mapping->mntpnt=malloc(sizeof(char)*(strlen(mntpnt)+1));
|
||||
strcpy(mapping->mntpnt,mntpnt);
|
||||
mapping->type=i;
|
||||
mapping->next=NULL;
|
||||
head_mapping=mapping;
|
||||
tail_mapping=mapping;
|
||||
} else {
|
||||
vfs_mapping* mapping=malloc(sizeof(vfs_mapping));
|
||||
mapping->mntpnt=malloc(sizeof(char)*(strlen(mntpnt)+1));
|
||||
strcpy(mapping->mntpnt,mntpnt);
|
||||
mapping->type=i;
|
||||
mapping->next=NULL;
|
||||
tail_mapping->next=mapping;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FILE* fopen(const char* filename,const char* mode) {
|
||||
vfs_mapping* mnt=head_mapping;
|
||||
vfs_mapping* mntpnt=NULL;
|
||||
const char* path;
|
||||
uint32_t mntpnt_len=0;
|
||||
for (;mnt!=NULL;mnt=mnt->next) {
|
||||
char* root=mnt->mntpnt;
|
||||
if (strlen(root)>mntpnt_len) {
|
||||
if (vfsstrcmp(root,filename)==0) {
|
||||
mntpnt=mnt;
|
||||
mntpnt_len=strlen(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mntpnt) {
|
||||
path=filename+mntpnt_len;
|
||||
FILE* stream=malloc(sizeof(FILE));
|
||||
stream->mntpnt=mntpnt->mntpnt;
|
||||
stream->path=path;
|
||||
stream->type=mntpnt->type;
|
||||
stream->pos=0;
|
||||
stream->eof=0;
|
||||
char ok=drvs[mntpnt->type](FSOP_OPEN,stream,NULL,NULL);
|
||||
if (ok) {
|
||||
return stream;
|
||||
} else {
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fgetc(FILE* stream) {
|
||||
int c;
|
||||
drvs[stream->type](FSOP_GETC,stream,&c,NULL);
|
||||
return c;
|
||||
}
|
||||
|
||||
int getc() {
|
||||
return fgetc(stdin);
|
||||
}
|
||||
|
||||
char* fgets(char* str,int count,FILE* stream) {
|
||||
int i;
|
||||
for (i=0;i<count-1;i++) {
|
||||
char c=fgetc(stream);
|
||||
if (c==EOF) {
|
||||
break;
|
||||
} else if (c=='\n') {
|
||||
str[i]=c;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
str[i]=c;
|
||||
}
|
||||
str[i]='\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
size_t fread(void* buffer_ptr,size_t size,size_t count,FILE* stream) {
|
||||
char* buffer=(char*)buffer_ptr;
|
||||
size_t bytes=size*count;
|
||||
for (size_t i=0;i<bytes;i++) {
|
||||
int c=fgetc(stream);
|
||||
if (c==EOF) {
|
||||
return (size_t)((double)i/size);
|
||||
}
|
||||
buffer[i]=c;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int fputc(int c,FILE* stream) {
|
||||
char ok=drvs[stream->type](FSOP_PUTC,stream,&c,NULL);
|
||||
if (ok) {
|
||||
return c;
|
||||
} else {
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
int putc(int c) {
|
||||
return fputc(c,stdout);
|
||||
}
|
||||
|
||||
int fputs(const char* s,FILE* stream) {
|
||||
size_t len=strlen(s);
|
||||
for (size_t i=0;i<len;i++) {
|
||||
fputc(s[i],stream);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int puts(const char* s) {
|
||||
return fputs(s,stdout);
|
||||
}
|
||||
|
||||
int vfprintf(FILE* stream,const char* format,va_list arg) {
|
||||
for(;*format!='\0';format++) {
|
||||
if(*format!='%') {
|
||||
fputc(*format,stream);
|
||||
continue;
|
||||
}
|
||||
format++;
|
||||
switch(*format) {
|
||||
case 'c': {
|
||||
int i=va_arg(arg,int);
|
||||
fputc(i,stream);
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
int i=va_arg(arg,int); //Fetch Decimal/Integer argument
|
||||
if(i<0) {
|
||||
i=-i;
|
||||
fputc('-',stream);
|
||||
}
|
||||
char str[11];
|
||||
int_to_ascii(i,str);
|
||||
fputs(str,stream);
|
||||
break;
|
||||
}
|
||||
// case 'o': {
|
||||
// int i=va_arg(arg,unsigned int); //Fetch Octal representation
|
||||
// puts(convert(i,8));
|
||||
// break;
|
||||
// }
|
||||
case 's': {
|
||||
char* s=va_arg(arg,char*);
|
||||
fputs(s,stream);
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
uint32_t i=va_arg(arg,uint32_t);
|
||||
char str[11];
|
||||
str[0]='\0';
|
||||
hex_to_ascii(i,str);
|
||||
fputs(str,stream);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fprintf(FILE* stream,const char* format,...) {
|
||||
va_list arg;
|
||||
int code;
|
||||
va_start(arg,format);
|
||||
code=vfprintf(stream,format,arg);
|
||||
va_end(arg);
|
||||
if (code) {
|
||||
return strlen(format);
|
||||
} else {
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
int printf(const char* format,...) {
|
||||
va_list arg;
|
||||
int code;
|
||||
va_start(arg,format);
|
||||
code=vfprintf(stdout,format,arg);
|
||||
va_end(arg);
|
||||
if (code) {
|
||||
return strlen(format);
|
||||
} else {
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
int fseek(FILE* stream,long offset,int origin) {
|
||||
if (origin==SEEK_SET) {
|
||||
stream->pos=offset;
|
||||
}
|
||||
if (origin==SEEK_CUR) {
|
||||
stream->pos+=offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
long ftell(FILE* stream) {
|
||||
return stream->pos;
|
||||
}
|
||||
|
||||
int fclose(FILE* stream) {
|
||||
drvs[stream->type](FSOP_CLOSE,stream,NULL,NULL);
|
||||
free(stream);
|
||||
return 0;
|
||||
}
|
21
kernel/vfs.h
Normal file
21
kernel/vfs.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef VFS_H
|
||||
#define VFS_H
|
||||
#include <stdint.h>
|
||||
#include "../libc/stdio.h"
|
||||
|
||||
typedef enum {
|
||||
FSOP_MOUNT,
|
||||
FSOP_OPEN,
|
||||
FSOP_GETC,
|
||||
FSOP_PUTC,
|
||||
FSOP_CLOSE,
|
||||
FSOP_UMOUNT
|
||||
} fs_op;
|
||||
|
||||
typedef char (*fs_drv)(fs_op op,FILE* stream,void* data1,void* data2);
|
||||
|
||||
void init_vfs();
|
||||
uint32_t register_fs(fs_drv drv,const char* type);
|
||||
char mount(char* mntpnt,char* dev,char* type);
|
||||
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <tasking.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void* get_paddr(void* addr_arg) {
|
||||
uint32_t addr=(uint32_t)addr_arg;
|
||||
char msg[15];
|
||||
strcpy(msg,"GET_PADDR ");
|
||||
msg[14]=0;
|
||||
msg[10]=addr&0xFF;
|
||||
msg[11]=(addr&0xFF00)>>8;
|
||||
msg[12]=(addr&0xFF0000)>>16;
|
||||
msg[13]=(addr&0xFF000000)>>24;
|
||||
send_msg(0,msg);
|
||||
char* recv_msg=NULL;
|
||||
while (recv_msg==NULL) {
|
||||
uint32_t sender;
|
||||
recv_msg=get_msg(&sender);
|
||||
yield();
|
||||
}
|
||||
uint32_t recv_addr=recv_msg[0];
|
||||
recv_addr=recv_addr|recv_msg[1]<<8;
|
||||
recv_addr=recv_addr|recv_msg[2]<<16;
|
||||
recv_addr=recv_addr|recv_msg[3]<<24;
|
||||
return (void*)recv_addr;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef K_MESSAGES_H
|
||||
#define K_MESSAGES_H
|
||||
|
||||
void* get_paddr(void* addr);
|
||||
|
||||
#endif
|
15
libc/klog.c
Normal file
15
libc/klog.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int vfprintf(FILE* stream,const char* format,va_list arg);
|
||||
|
||||
void klog(char* level,char* s,...) {
|
||||
if (stdout!=NULL) {
|
||||
va_list arg;
|
||||
va_start(arg,s);
|
||||
printf("[%s] ",level);
|
||||
vfprintf(stdout,s,arg);
|
||||
printf("\n");
|
||||
va_end(arg);
|
||||
}
|
||||
}
|
6
libc/klog.h
Normal file
6
libc/klog.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef KLOG_H
|
||||
#define KLOG_H
|
||||
|
||||
void klog(char* level,char* s,...);
|
||||
|
||||
#endif
|
11
libc/stdio.h
11
libc/stdio.h
@ -9,20 +9,19 @@ typedef struct {
|
||||
uint32_t type;
|
||||
long pos;
|
||||
int eof;
|
||||
void* data;
|
||||
} FILE;
|
||||
|
||||
#define NO_FD 0xFFFFFFFF
|
||||
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#define SEEK_SET 3
|
||||
#define EOF -1
|
||||
|
||||
extern uint32_t stdin;
|
||||
extern uint32_t stdout;
|
||||
extern uint32_t stderr;
|
||||
extern FILE* stdin;
|
||||
extern FILE* stdout;
|
||||
extern FILE* stderr;
|
||||
|
||||
uint32_t fopen(const char* filename,const char* mode);
|
||||
FILE* fopen(const char* filename,const char* mode);
|
||||
int fgetc(FILE* stream);
|
||||
int getc();
|
||||
char* fgets(char* str,int count,FILE* stream);
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include "math.h"
|
||||
#include <stdint.h>
|
||||
#define MAX_BLOCKS 512
|
||||
#define MALLOC_DEBUG 1
|
||||
|
||||
typedef struct {
|
||||
uint8_t* bitmap;
|
||||
char* bitmap;
|
||||
uint32_t bitmap_byt_size;
|
||||
uint32_t bitmap_bit_size;
|
||||
uint32_t avail_data_size;
|
||||
@ -14,31 +14,35 @@ typedef struct {
|
||||
} heap_block;
|
||||
|
||||
|
||||
heap_block entries[MAX_BLOCKS];
|
||||
uint32_t num_used_entries;
|
||||
char get_bmap_bit(uint8_t* bmap,uint32_t index) {
|
||||
static heap_block entries[MAX_BLOCKS];
|
||||
static uint32_t num_used_entries=0;
|
||||
|
||||
static char get_bmap_bit(char* bmap,uint32_t index) {
|
||||
uint32_t byte=index/8;
|
||||
uint32_t bit=index%8;
|
||||
char entry=bmap[byte];
|
||||
return (entry&(1<<bit))>0;
|
||||
}
|
||||
void set_bmap_bit(uint8_t* bmap,uint32_t index) {
|
||||
|
||||
static void set_bmap_bit(char* bmap,uint32_t index) {
|
||||
uint32_t byte=index/8;
|
||||
uint32_t bit=index%8;
|
||||
bmap[byte]=bmap[byte]|(1<<bit);
|
||||
}
|
||||
void clear_bmap_bit(uint8_t* bmap,uint32_t index) {
|
||||
|
||||
static void clear_bmap_bit(char* bmap,uint32_t index) {
|
||||
uint32_t byte=index/8;
|
||||
uint32_t bit=index%8;
|
||||
bmap[byte]=bmap[byte]&(~(1<<bit));
|
||||
}
|
||||
void reserve_block(uint32_t mem_blks) {
|
||||
|
||||
static void reserve_block(uint32_t mem_blks) {
|
||||
uint32_t bmap_byts=((mem_blks*BLK_SZ)/4)/8;
|
||||
entries[num_used_entries].bitmap=alloc_memory((uint32_t)ceilf((double)bmap_byts/BLK_SZ));
|
||||
entries[num_used_entries].bitmap_byt_size=bmap_byts;
|
||||
entries[num_used_entries].bitmap_bit_size=bmap_byts*8;
|
||||
uint8_t* bmap=entries[num_used_entries].bitmap;
|
||||
char bmap_byt_sz=entries[num_used_entries].bitmap_byt_size;
|
||||
char* bmap=entries[num_used_entries].bitmap;
|
||||
uint32_t bmap_byt_sz=entries[num_used_entries].bitmap_byt_size;
|
||||
for(uint32_t i=0;i<bmap_byt_sz;i++) {
|
||||
bmap[i]=0;
|
||||
}
|
||||
@ -57,7 +61,7 @@ void* malloc(uint32_t size) {
|
||||
uint32_t remaining_blks;
|
||||
entry=entries[i];
|
||||
if (entry.avail_data_size>=size) {
|
||||
uint8_t* bmap=entry.bitmap;
|
||||
char* bmap=entry.bitmap;
|
||||
uint32_t bmap_byt_sz=entry.bitmap_byt_size;
|
||||
for(uint32_t i=0;i<bmap_byt_sz;i++) {
|
||||
if (bmap[i]!=0xFF) {
|
||||
|
@ -102,10 +102,10 @@ void backspace(char* s) {
|
||||
s[len-1] = '\0';
|
||||
}
|
||||
|
||||
char* strtok_str=NULL;
|
||||
size_t strtok_index;
|
||||
static char* strtok_str=NULL;
|
||||
static size_t strtok_index;
|
||||
|
||||
char strtok_delim_check(const char* delim) {
|
||||
static char strtok_delim_check(const char* delim) {
|
||||
for (size_t i=0;i<strlen(delim);i++) {
|
||||
if (strtok_str[strtok_index]==delim[i]||strtok_str[strtok_index]=='\0') {
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user