Work and cleanup

This commit is contained in:
pjht 2019-03-11 09:32:55 -05:00
parent 7131f4ae5a
commit 99d7fed783
41 changed files with 1356 additions and 459 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ stuff/*
cpu/memory.h
os.iso
disk.img
iso/boot/initrd

View File

@ -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

View File

@ -6,7 +6,7 @@
void cpu_init() {
gdt_init();
isr_install();
//asm volatile("sti");
asm volatile("sti");
paging_init();
tasking_init();
}

View File

@ -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);

View File

@ -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 */

View File

@ -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
View 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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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));
}

View File

@ -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
View 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
View 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

View File

@ -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));
}

View File

@ -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

View File

@ -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
View 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
View 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
View 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");
}
}
}
}

View File

@ -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);
}
}

View File

@ -1,6 +1,8 @@
#ifndef PCI_H
#define PCI_H
#include <stdint.h>
typedef struct {
uint16_t vend_id;
uint16_t dev_id;

View File

@ -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++;
}

View File

@ -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

View File

@ -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");
}

View File

@ -1,6 +1,6 @@
#ifndef INITRD_H
#define INITRD_H
uint32_t init_initrd();
uint32_t initrd_init();
#endif

Binary file not shown.

View File

@ -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
View 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

View File

@ -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);
vga_write_string(str);
vga_write_string("\n");
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);
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
View 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
View 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

View File

@ -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;
}

View File

@ -1,6 +0,0 @@
#ifndef K_MESSAGES_H
#define K_MESSAGES_H
void* get_paddr(void* addr);
#endif

15
libc/klog.c Normal file
View 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
View File

@ -0,0 +1,6 @@
#ifndef KLOG_H
#define KLOG_H
void klog(char* level,char* s,...);
#endif

View File

@ -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);

View File

@ -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) {

View File

@ -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;