From 99d7fed783680f9f4c0a0f6caaf4188bed3ac89e Mon Sep 17 00:00:00 2001 From: pjht Date: Mon, 11 Mar 2019 09:32:55 -0500 Subject: [PATCH] Work and cleanup --- .gitignore | 1 + Makefile | 7 +- cpu/i386/cpu_init.c | 2 +- cpu/i386/gdt.c | 10 +- cpu/i386/idt.c | 35 +++- cpu/i386/idt.h | 33 +--- cpu/i386/interrupt.h | 56 ++++++ cpu/i386/isr.c | 107 ++++++------ cpu/i386/isr.h | 20 ++- cpu/i386/memory.c | 6 +- cpu/i386/memory.h | 1 + cpu/i386/paging.c | 142 +++++++++------ cpu/i386/paging.h | 14 +- cpu/i386/pmem.c | 117 +++++++++++++ cpu/i386/pmem.h | 10 ++ cpu/i386/ports.c | 20 ++- cpu/i386/ports.h | 14 +- cpu/i386/tasking.c | 18 +- drivers/i386/pci.c | 98 +++++++++++ drivers/i386/pci.h | 13 ++ drivers/i386/serial.c | 159 +++++++++++++++++ drivers/i386/vga.c | 30 ++-- drivers/pci.h | 2 + fs/devfs.c | 142 +++++++-------- fs/devfs.h | 3 +- fs/initrd.c | 170 +++++++++--------- fs/initrd.h | 2 +- iso/boot/initrd | Bin 1548 -> 0 bytes kernel/boot.s | 10 +- kernel/elf.h | 39 +++++ kernel/kernel.c | 141 +++++++++++---- kernel/vfs.c | 276 ++++++++++++++++++++++++++++++ kernel/vfs.h | 21 +++ {kernel => libc/grub}/multiboot.h | 0 libc/k_messages.c | 26 --- libc/k_messages.h | 6 - libc/klog.c | 15 ++ libc/klog.h | 6 + libc/stdio.h | 11 +- libc/stdlib.c | 26 +-- libc/string.c | 6 +- 41 files changed, 1356 insertions(+), 459 deletions(-) create mode 100644 cpu/i386/interrupt.h create mode 100644 cpu/i386/pmem.c create mode 100644 cpu/i386/pmem.h create mode 100644 drivers/i386/pci.c create mode 100644 drivers/i386/pci.h create mode 100644 drivers/i386/serial.c delete mode 100644 iso/boot/initrd create mode 100644 kernel/elf.h create mode 100644 kernel/vfs.c create mode 100644 kernel/vfs.h rename {kernel => libc/grub}/multiboot.h (100%) delete mode 100644 libc/k_messages.c delete mode 100644 libc/k_messages.h create mode 100644 libc/klog.c create mode 100644 libc/klog.h diff --git a/.gitignore b/.gitignore index 5d76e48..239e010 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ stuff/* cpu/memory.h os.iso disk.img +iso/boot/initrd diff --git a/Makefile b/Makefile index 323fb71..1cb03ee 100644 --- a/Makefile +++ b/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 diff --git a/cpu/i386/cpu_init.c b/cpu/i386/cpu_init.c index a624487..ff94da4 100644 --- a/cpu/i386/cpu_init.c +++ b/cpu/i386/cpu_init.c @@ -6,7 +6,7 @@ void cpu_init() { gdt_init(); isr_install(); - //asm volatile("sti"); + asm volatile("sti"); paging_init(); tasking_init(); } diff --git a/cpu/i386/gdt.c b/cpu/i386/gdt.c index 874e7e6..9e92654 100644 --- a/cpu/i386/gdt.c +++ b/cpu/i386/gdt.c @@ -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); diff --git a/cpu/i386/idt.c b/cpu/i386/idt.c index 11fb823..7b7c06d 100644 --- a/cpu/i386/idt.c +++ b/cpu/i386/idt.c @@ -1,10 +1,41 @@ #include "idt.h" #include +/* 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 */ diff --git a/cpu/i386/idt.h b/cpu/i386/idt.h index 9796723..9cc8812 100644 --- a/cpu/i386/idt.h +++ b/cpu/i386/idt.h @@ -3,37 +3,8 @@ #include -/* 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 diff --git a/cpu/i386/interrupt.h b/cpu/i386/interrupt.h new file mode 100644 index 0000000..93adba5 --- /dev/null +++ b/cpu/i386/interrupt.h @@ -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 diff --git a/cpu/i386/isr.c b/cpu/i386/isr.c index 33abed8..c6a868c 100644 --- a/cpu/i386/isr.c +++ b/cpu/i386/isr.c @@ -5,47 +5,48 @@ #include "../halt.h" #include "../drivers/vga.h" #include "../tasking.h" +#include "interrupt.h" #include #include 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; } diff --git a/cpu/i386/isr.h b/cpu/i386/isr.h index fa63adf..6cab517 100644 --- a/cpu/i386/isr.h +++ b/cpu/i386/isr.h @@ -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 diff --git a/cpu/i386/memory.c b/cpu/i386/memory.c index 8546a0b..1e1fafb 100644 --- a/cpu/i386/memory.c +++ b/cpu/i386/memory.c @@ -2,5 +2,9 @@ #include 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); } diff --git a/cpu/i386/memory.h b/cpu/i386/memory.h index 204a502..15dba19 100644 --- a/cpu/i386/memory.h +++ b/cpu/i386/memory.h @@ -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 diff --git a/cpu/i386/paging.c b/cpu/i386/paging.c index e85cdf1..eb02f43 100644 --- a/cpu/i386/paging.c +++ b/cpu/i386/paging.c @@ -1,70 +1,116 @@ #include +#include #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 #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(); diff --git a/cpu/i386/pmem.c b/cpu/i386/pmem.c new file mode 100644 index 0000000..dac95a4 --- /dev/null +++ b/cpu/i386/pmem.c @@ -0,0 +1,117 @@ +#include +#include "../halt.h" +#include +#include +#include + +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<0; +} + +static void set_bmap_bit(int index) { + int byte=index/8; + int bit=index%8; + bmap[byte]=bmap[byte]|(1<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 + +void pmem_init(multiboot_info_t* mbd); +void* pmem_alloc(int num_pages); +void pmem_free(int start_page,int num_pages); + +#endif diff --git a/cpu/i386/ports.c b/cpu/i386/ports.c index 769be8b..5991314 100644 --- a/cpu/i386/ports.c +++ b/cpu/i386/ports.c @@ -1,29 +1,31 @@ -unsigned char port_byte_in(unsigned short port) { - unsigned char result; +#include + +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)); } diff --git a/cpu/i386/ports.h b/cpu/i386/ports.h index 33bcca1..4f5c6e1 100644 --- a/cpu/i386/ports.h +++ b/cpu/i386/ports.h @@ -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 + +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 diff --git a/cpu/i386/tasking.c b/cpu/i386/tasking.c index 544388e..a32c3a2 100644 --- a/cpu/i386/tasking.c +++ b/cpu/i386/tasking.c @@ -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) { diff --git a/drivers/i386/pci.c b/drivers/i386/pci.c new file mode 100644 index 0000000..80f2034 --- /dev/null +++ b/drivers/i386/pci.c @@ -0,0 +1,98 @@ +#include +#include "../../cpu/i386/ports.h" +#include +#include "pci.h" +#include "../vga.h" +#include + +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); + } + } +} diff --git a/drivers/i386/pci.h b/drivers/i386/pci.h new file mode 100644 index 0000000..76ecc97 --- /dev/null +++ b/drivers/i386/pci.h @@ -0,0 +1,13 @@ +#ifndef PCI_INTERN_H +#define PCI_INTERN_H + +#include +#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 diff --git a/drivers/i386/serial.c b/drivers/i386/serial.c new file mode 100644 index 0000000..e2dd302 --- /dev/null +++ b/drivers/i386/serial.c @@ -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 +#include + +#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"); + } + } + } +} diff --git a/drivers/i386/vga.c b/drivers/i386/vga.c index b748aad..8922232 100644 --- a/drivers/i386/vga.c +++ b/drivers/i386/vga.c @@ -4,15 +4,15 @@ #include #include #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 + typedef struct { uint16_t vend_id; uint16_t dev_id; diff --git a/fs/devfs.c b/fs/devfs.c index 9000c1d..554878a 100644 --- a/fs/devfs.c +++ b/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;ipath)==0) { -// return 1; -// } -// } -// return 0; -// } -// if (op==FSOP_GETC) { -// int i; -// for (i=0;ipath)==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;ipath)==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 +#include +#include +#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;ipath)==0) { + return 1; + } + } + return 0; + } + if (op==FSOP_GETC) { + uint32_t i; + for (i=0;ipath)==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;ipath)==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++; +} diff --git a/fs/devfs.h b/fs/devfs.h index 6c13539..439e3f7 100644 --- a/fs/devfs.h +++ b/fs/devfs.h @@ -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 diff --git a/fs/initrd.c b/fs/initrd.c index 3a20a22..01789ae 100644 --- a/fs/initrd.c +++ b/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;ipath)==0) { -// file_exists=1; -// } -// } -// return file_exists; -// } -// if (op==FSOP_GETC) { -// int i; -// for (i=0;ipath)==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 +#include +#include +#include + +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;ipath)==0) { + file_exists=1; + } + } + return file_exists; + } + if (op==FSOP_GETC) { + uint32_t i; + for (i=0;ipath)==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"); +} diff --git a/fs/initrd.h b/fs/initrd.h index e421fa2..6637845 100644 --- a/fs/initrd.h +++ b/fs/initrd.h @@ -1,6 +1,6 @@ #ifndef INITRD_H #define INITRD_H -uint32_t init_initrd(); +uint32_t initrd_init(); #endif diff --git a/iso/boot/initrd b/iso/boot/initrd deleted file mode 100644 index e090dff5d61c3c6d5fe8b00e5891fa2e9f207741..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1548 zcma)6OK;Oa5FS5LLfl4uAfOb4BOWS3by`}rRjU?gpaltmgy;dJDs_@|Vj4Sa13^vD%eNc;^BNJyMGa|qwq-qtD{m}ETj&3wCF&(3b1h`K?iX^FN&dpV-l zcOR@Oih^(=Drv;1`$o^t!0u~Fe1=TK$Elx;I3GvBA?QBypqP$mkRL~~{{H)?0^r7h zv&X+5KYP920nw?HqP%=e%B#FG*01aD@Z$4`vwj7Q$INXSAqv7mThjEI(DlZ+mJWxs>K{4t{HA)qJ=nXvLv({rvLAwHyB zDUKLgajZC`4EGJ5AyO^6IjR*Gj78)A2nTPS{jf4hq+KS%ST?jgCb|Jt=|Vj5@8STa zkIRfjDCF6$Z`F~4aQ*yL?B4TT!Q5#*RN1^(ZWNz`*Xy_wzE6Mf~;THE}TM z2BMuqoD^FQ(7?!wmKIyaw4^H}1iSChXGfzG$8i3rzmU=CS1(>j%3^#GKKCbw2EjfD zyT2!~N>_np8w?|V{aBuNCd-%Q*b;#++T}Wm8bp>IdQ`2}!mt|Sm_$|4up=ABZxC7G zt{2%g*eFPBOL~#miO3SIsuS3rAgkW-Jb`Ai8ltw{tlEL?H$^C+>pLCk+qGICUP#n- zeT+^9VQwt^KV=L&?su*>*J2a)G*pT_rX>WJ$GggVyaUUpLrQXVD6S#%Ces9;_aRAw zqj{JF^><>s@oRkRDoCL?K%K)hBsUewf#=i5`oFdQhY)F E0ZMSkQ2+n{ diff --git a/kernel/boot.s b/kernel/boot.s index ee514c1..11eb2a2 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -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 diff --git a/kernel/elf.h b/kernel/elf.h new file mode 100644 index 0000000..2a59138 --- /dev/null +++ b/kernel/elf.h @@ -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 diff --git a/kernel/kernel.c b/kernel/kernel.c index 435cefa..6cfe418 100644 --- a/kernel/kernel.c +++ b/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 #include #include -#include #include -#include "multiboot.h" +#include +#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(); } } diff --git a/kernel/vfs.c b/kernel/vfs.c new file mode 100644 index 0000000..8fa24a1 --- /dev/null +++ b/kernel/vfs.c @@ -0,0 +1,276 @@ +#include +#include +#include +#include +#include +#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;imntpnt=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;itype](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;ipos=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; +} diff --git a/kernel/vfs.h b/kernel/vfs.h new file mode 100644 index 0000000..3deaa34 --- /dev/null +++ b/kernel/vfs.h @@ -0,0 +1,21 @@ +#ifndef VFS_H +#define VFS_H +#include +#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 diff --git a/kernel/multiboot.h b/libc/grub/multiboot.h similarity index 100% rename from kernel/multiboot.h rename to libc/grub/multiboot.h diff --git a/libc/k_messages.c b/libc/k_messages.c deleted file mode 100644 index 9746864..0000000 --- a/libc/k_messages.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include -#include - -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; -} diff --git a/libc/k_messages.h b/libc/k_messages.h deleted file mode 100644 index 73f255f..0000000 --- a/libc/k_messages.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef K_MESSAGES_H -#define K_MESSAGES_H - -void* get_paddr(void* addr); - -#endif diff --git a/libc/klog.c b/libc/klog.c new file mode 100644 index 0000000..741ba63 --- /dev/null +++ b/libc/klog.c @@ -0,0 +1,15 @@ +#include +#include + +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); + } +} diff --git a/libc/klog.h b/libc/klog.h new file mode 100644 index 0000000..910dd9a --- /dev/null +++ b/libc/klog.h @@ -0,0 +1,6 @@ +#ifndef KLOG_H +#define KLOG_H + +void klog(char* level,char* s,...); + +#endif diff --git a/libc/stdio.h b/libc/stdio.h index cde815a..12ecb61 100644 --- a/libc/stdio.h +++ b/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); diff --git a/libc/stdlib.c b/libc/stdlib.c index 537d14f..9f1431b 100644 --- a/libc/stdlib.c +++ b/libc/stdlib.c @@ -4,9 +4,9 @@ #include "math.h" #include #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<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<=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