# HG changeset patch # User windel # Date 1326475097 -3600 # Node ID 3a6a9b929db0e0280b05ae75ffe9af3bb8c35652 # Parent 88590c42320ffb141c6ea1c6004ad9154ed48e54 Added initial ramdisk and some virtual file system functions diff -r 88590c42320f -r 3a6a9b929db0 cos/Makefile --- a/cos/Makefile Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/Makefile Fri Jan 13 18:18:17 2012 +0100 @@ -2,7 +2,9 @@ all: make -C kernel + python makeinitrd.py lcfosinitrd.img hello/hello.bin cp grub/emptybootdisk.img bootdisk.img mcopy -D o -i bootdisk.img kernel/lcfos.bin :: + mcopy -D o -i bootdisk.img lcfosinitrd.img :: mcopy -D o -i bootdisk.img grub/menu.lst ::/grub diff -r 88590c42320f -r 3a6a9b929db0 cos/grub/menu.lst --- a/cos/grub/menu.lst Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/grub/menu.lst Fri Jan 13 18:18:17 2012 +0100 @@ -3,4 +3,5 @@ title lcfos root (fd0) kernel /lcfos.bin +module /lcfosinitrd.img diff -r 88590c42320f -r 3a6a9b929db0 cos/hello/Makefile --- a/cos/hello/Makefile Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/hello/Makefile Fri Jan 13 18:18:17 2012 +0100 @@ -11,8 +11,8 @@ -Wextra \ -Werror -hello.bin: hello.o - ld -T hello.ld -s -o hello.bin hello.o +hello.bin: hello.o liblcfos.o + ld -T hello.ld -s -o hello.bin hello.o liblcfos.o %.o: %.c gcc $(CFLAGS) -o $@ -c $< diff -r 88590c42320f -r 3a6a9b929db0 cos/hello/hello.c --- a/cos/hello/hello.c Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/hello/hello.c Fri Jan 13 18:18:17 2012 +0100 @@ -2,6 +2,7 @@ int main() { + unsigned char * const screen = (unsigned char*)0xB8000; screen[0] = 'H'; screen[2] = 'o'; diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/Makefile --- a/cos/kernel/Makefile Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/Makefile Fri Jan 13 18:18:17 2012 +0100 @@ -8,7 +8,7 @@ -fno-builtin -mcmodel=large -Wall -Wextra -Werror OBJECTS = video.o snprintf.o kernel.o asmcode.o handlers.o keyboard.o \ - klib.o malloc.o task.o mm.o timer.o + klib.o malloc.o task.o mm.o timer.o fs.o initrd.o lcfos.bin: $(CRT0) $(OBJECTS) link.ld ld -T link.ld -s -o lcfos.bin $(CRT0) $(OBJECTS) @@ -20,5 +20,5 @@ gcc $(CFLAGS) -o $@ -c $< clean: - rm $(OBJECTS) $(CRT0) lcfosc.bin + rm $(OBJECTS) $(CRT0) lcfos.bin diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/asmcode.asm --- a/cos/kernel/asmcode.asm Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/asmcode.asm Fri Jan 13 18:18:17 2012 +0100 @@ -2,6 +2,9 @@ ; from 20 - 31 are reserved vectors. ; below are the custom ones! +; Calling convention AMD64 ABI: +; parameters in: rdi, rsi, rdx, rcx .... + section .text align 4 @@ -18,6 +21,11 @@ lidt [idtP] ret +global setCR3 +setCR3: + mov cr3, rdi ; Load cr3 + ret + ; ISR related assembler wrappers: %macro ISR_NOERRCODE 1 diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/fs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cos/kernel/fs.c Fri Jan 13 18:18:17 2012 +0100 @@ -0,0 +1,56 @@ + +#include "kernel.h" + +uint64_t read_fs(fs_node_t *node, uint64_t offset, uint64_t size, uint8_t *buffer) +{ + if (node->read != 0) + { + return node->read(node, offset, size, buffer); + } + else + { + return 0; + } +} + +uint64_t write_fs(fs_node_t *node, uint64_t offset, uint64_t size, uint8_t *buffer) +{ + if (node->write != 0) + { + return node->write(node, offset, size, buffer); + } + else + { + return 0; + } +} + +void open_fs(fs_node_t *node) +{ + if (node->open != 0) + { + node->open(node); + } +} + +void close_fs(fs_node_t *node) +{ + if (node->close != 0) + { + node->close(node); + } +} + +// TODO: why not return an fs_node_t* ? +fs_dirent_t* readdir_fs(fs_node_t *node, int i) +{ + if (node->readdir != 0) + { + return node->readdir(node, i); + } + else + { + return 0; + } +} + diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/goto64.asm --- a/cos/kernel/goto64.asm Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/goto64.asm Fri Jan 13 18:18:17 2012 +0100 @@ -18,15 +18,6 @@ ; 0x5000 - 0x6000 : IDT entries ; 0x6000 - 0xA000 : Stack -; panic macro to debug on real hardware -%macro DOPANIC 1 -mov al, %1 -mov edi, 0xb8000 -stosb -xchg bx,bx -hlt -%endmacro - bits 32 ; Start in 32 bits mode, as loaded by GRUB ; Multiboot header: @@ -103,6 +94,9 @@ ; Start of loader code: loader: +; here ebx contains the pointer to the multiboot header, store is for later use. +extern multiboot_info +mov [multiboot_info], ebx ; Check that the CPU supports long mode: mov eax, 80000000h @@ -220,6 +214,7 @@ lgdt [gdt64pointer] ; Reload GDT in 64 bits mode +; TODO: determine a good place for the kernel stack. mov rsp, 0xA000 ; Setup stack pointer. extern kmain diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/handlers.c --- a/cos/kernel/handlers.c Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/handlers.c Fri Jan 13 18:18:17 2012 +0100 @@ -128,23 +128,24 @@ // Hopefully, this function get called with the correct registers. void isr_handler(uint64_t* registers) { - uint64_t intnum = registers[7]; + // TODO: make a list with handler pointers: if (intnum == 32) { timerDriverUpdate(); } else if (intnum == 33) { - unsigned char scancode = inb(0x60); - keyboardDriverUpdate(scancode); + keyboardDriverUpdate(); } else { - printf("Interrupt %d called, registers at: %x\n", registers[7], registers); + // printf("Interrupt %d called, registers at: %x\n", registers[7], registers); } + // TODO: EOI to slave? + // TODO: replace this with APIC code? outb(0x20, 0x20); // EOI to master } @@ -170,26 +171,6 @@ panic("Unhandled exception!"); } -// remapped IRQ from master PIC: -void INT32handler() -{ - // System timer. - //printf("INT32 called!\n"); - // called very frequent, what is this? - timerDriverUpdate(); - // Acknowledge int: - outb(0x20, 0x20); // EOI to master -} - -void INT33handler() -{ - //printf("INT33 called, key pressed????\n"); - unsigned char scancode = inb(0x60); - //printf("Scancode = 0x%x\n", scancode); - keyboardDriverUpdate(scancode); - outb(0x20, 0x20); // EOI to master -} - void INTDEF_handler() { panic("Default int handler called\n"); diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/initrd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cos/kernel/initrd.c Fri Jan 13 18:18:17 2012 +0100 @@ -0,0 +1,25 @@ +/* + * Initial ramdisk filesystem driver. + * */ + +#include "kernel.h" + +fs_node_t *initrd_root = 0; + +typedef struct +{ + uint32_t magic; + uint32_t numfiles; +} initrd_header_t; + +fs_node_t* initialize_initrd(uint64_t location) +{ + // We need a valid malloc here! + initrd_root = (fs_node_t*)kmalloc(sizeof(fs_node_t)); + + initrd_header_t *header = (initrd_header_t*)location; + initrd_root->length = header->numfiles; + + return initrd_root; +} + diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/kernel.c --- a/cos/kernel/kernel.c Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/kernel.c Fri Jan 13 18:18:17 2012 +0100 @@ -15,6 +15,8 @@ kfree(a); } +multiboot_info_t *multiboot_info = 0; // Set by startup code. + /* This routine initializes the kernel. * We are left here in 64-bit long mode with the first 6 MB identity mapped. * */ @@ -22,14 +24,66 @@ { init_screen(); setupIDT(); - // init_heap(); + + uint64_t available_memory = 0; + + /* Display memory information from multiboot header */ + if ((multiboot_info->flags & (1<<6)) == (1<<6)) + { + multiboot_memory_map_t *mmap; + for (mmap = (multiboot_memory_map_t*)(uint64_t)multiboot_info->mmap_addr; + (uint64_t)mmap < multiboot_info->mmap_addr + multiboot_info->mmap_length; + mmap = (multiboot_memory_map_t*) ( (uint64_t)mmap + mmap->size + sizeof(mmap->size)) ) + { + printf("size: %d, start: 0x%x, length=0x%x, type=%d\n", mmap->size, mmap->base, mmap->length, mmap->type); + + if ( (mmap->type == 1) && (mmap->base == 0x100000) ) + { + available_memory = mmap->length; + } + } + } + + printf("Running with %d MB ram\n", available_memory / 1000000); + + fs_node_t *fs_root = 0; + + if ( (multiboot_info->flags & (1<<3)) == (1<<3)) + { + printf("Mod count: %d\n", multiboot_info->mods_count); + uint64_t i; + multiboot_module_t *mod; + for (i=0, mod=(multiboot_module_t*)(uint64_t)multiboot_info->mods_addr; imods_count; i++, mod++) + { + printf("Mod start: %x, end: %x\n", mod->mod_start, mod->mod_end); + if (i == 0) + { + uint64_t ramdisk_location = ((uint32_t*)((uint64_t)multiboot_info->mods_addr))[0]; + fs_root = initialize_initrd(ramdisk_location); + } + } + } + + if (fs_root != 0) + { + fs_dirent_t *node = 0; + int i = 0; + while ( (node = readdir_fs(fs_root, i)) != 0) + { + + } + } + + // TODO: Make sure that placement malloc does not overwrite the ramdisk. + printf("Mod size: "); // Assume first 16MB: // TODO: get size from grub init_memory(0x1000000); - // TODO: make below a user space program! - printf("Welcome!\n"); + // TODO: make below a user space program! + printf("Welcome!\n"); + while (1==1) { diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/kernel.h --- a/cos/kernel/kernel.h Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/kernel.h Fri Jan 13 18:18:17 2012 +0100 @@ -34,7 +34,8 @@ uint32_t strsize, addr, reserved; }; -struct multiboot_info { +typedef struct multiboot_info_tag +{ uint32_t flags; // Multiboot flags / version uint32_t mem_lower; // available memory from BIOS uint32_t mem_upper; @@ -48,14 +49,23 @@ uint32_t mmap_length; uint32_t mmap_addr; -}; +} multiboot_info_t; -struct memory_map { +typedef struct memory_map_tag +{ uint32_t size; - uint32_t baselow, basehigh; - uint32_t lenlow, lenhigh; + uint64_t base; + uint64_t length; uint32_t type; -}; +} __attribute__((packed)) multiboot_memory_map_t; + +typedef struct +{ + uint32_t mod_start; + uint32_t mod_end; + uint32_t cmdline; + uint32_t pad; +} multiboot_module_t; // Memory manager structures: typedef struct @@ -195,6 +205,48 @@ console_t *console; } task_t; +/* Filesystem related types: */ +struct fs_node_tag; +struct fs_dirent_tag; + +typedef uint64_t (*read_type_t)(struct fs_node_tag*, uint64_t, uint64_t, uint8_t*); +typedef uint64_t (*write_type_t)(struct fs_node_tag*, uint64_t, uint64_t, uint8_t*); +typedef void (*open_type_t)(struct fs_node_tag*); +typedef void (*close_type_t)(struct fs_node_tag*); +typedef struct fs_dirent_tag* (*readdir_type_t)(struct fs_node_tag*, int); + +typedef struct fs_node_tag +{ + char name[129]; + uint64_t flags; + uint64_t length; + uint64_t inode; + // Accessor functions: + read_type_t read; + write_type_t write; + open_type_t open; + close_type_t close; + readdir_type_t readdir; +} fs_node_t; + +typedef struct fs_dirent_tag +{ + char name[65]; + uint64_t inode; +} fs_dirent_t; + +#define FS_FILE 0x1 +#define FS_DIRECTORY 0x2 + +uint64_t read_fs(fs_node_t *node, uint64_t offset, uint64_t size, uint8_t *buffer); +uint64_t write_fs(fs_node_t *node, uint64_t offset, uint64_t size, uint8_t *buffer); +void open_fs(fs_node_t *node); +void close_fs(fs_node_t *node); +fs_dirent_t* readdir_fs(fs_node_t *node, int i); + +// Initial ramdisk functions: +fs_node_t* initialize_initrd(uint64_t location); + // Variable argument list things: #define va_start(v,l) __builtin_va_start(v,l) #define va_end(v) __builtin_va_end(v) @@ -261,7 +313,7 @@ void doCPUID(int eax, int *ebx, int *ecx, int *edx); // Keyboard driver: -void keyboardDriverUpdate(unsigned char scancode); +void keyboardDriverUpdate(void); void getline(char *buffer, int len); // Timer: diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/keyboard.c --- a/cos/kernel/keyboard.c Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/keyboard.c Fri Jan 13 18:18:17 2012 +0100 @@ -4,7 +4,9 @@ static volatile uint8_t charAvail = 0; static volatile char kbdchar = ' '; -static char keymap[128] = { +// TODO: move to user land: +static char keymap[128] = +{ '?','?','1','2', '3', '4', '5','6', '7', '8','9', '0', '-','=', 0xe, '?', 'q','w','e','r', 't', 'y', 'u','i', 'o', 'p','[', ']', '\n','?', 'a', 's', 'd','f','g','h', 'j', 'k', 'l',';', '\'', '?','?', '?', 'z','x', 'c', 'v', @@ -16,7 +18,8 @@ '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?' }; -static char keymapUPPER[128] = { +static char keymapUPPER[128] = +{ '?','?','!','@', '#', '$', '%','^', '&', '*','(', ')', '_','+', '?', '?', 'Q','W','E','R', 'T', 'Y', 'U','I', 'O', 'P','{', '}', '|','?', 'A', 'S', 'D','F','G','H', 'J', 'K', 'L',':', '"', '?','?', '?', 'Z','X', 'C', 'V', @@ -28,8 +31,10 @@ '?','?','?','?', '?', '?', '?','?', '?', '?','?', '?', '?','?', '?', '?' }; -void keyboardDriverUpdate(unsigned char scancode) +void keyboardDriverUpdate() { + unsigned char scancode = inb(0x60); + switch(scancode) { case 0x2a: shiftstate = 1; @@ -64,6 +69,7 @@ return c; } +// Move to user code: void getline(char *buffer, int len) { char c; diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/klib.c --- a/cos/kernel/klib.c Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/klib.c Fri Jan 13 18:18:17 2012 +0100 @@ -1,5 +1,6 @@ #include "kernel.h" +/* Panic and shutdown functions */ void magicBochsBreak() { asm volatile("xchg %bx, %bx"); @@ -28,7 +29,7 @@ asm volatile("hlt"); } -// IO port helpers: +/* IO port helpers: */ void outb(uint16_t port, uint8_t value) { asm volatile ("outb %1, %0" : : "dN" (port), "a" (value)); @@ -48,7 +49,7 @@ return ret; } -// string functions: +/* string functions: */ int strncmp(const char* s1, const char* s2, int size) { int i; @@ -59,7 +60,6 @@ return 1; } -// mem functions: void memset(void* data, uint8_t value, uint64_t size) { uint64_t i; diff -r 88590c42320f -r 3a6a9b929db0 cos/kernel/mm.c --- a/cos/kernel/mm.c Tue Jan 10 20:40:35 2012 +0100 +++ b/cos/kernel/mm.c Fri Jan 13 18:18:17 2012 +0100 @@ -58,8 +58,8 @@ // Memory manager functions: void init_memory(uint64_t total_mem_size) { - printf("Size of PT_t = %d\n", sizeof(PD_t)); - printf("Size of page_t = %d\n", sizeof(page_t)); + // Only here placement malloc is used! + // // Allocate and clear bits to remember which 4kb-frames are in use: nframes = (total_mem_size / 0x1000); frames = (uint64_t*)kmalloc_int( (nframes / 64) * sizeof(uint64_t) ); diff -r 88590c42320f -r 3a6a9b929db0 cos/makeinitrd.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cos/makeinitrd.py Fri Jan 13 18:18:17 2012 +0100 @@ -0,0 +1,34 @@ +#!/usr/bin/python + +# Script for generation of an initial ramdisk that contains +# the first programs to run. + +import struct +import sys + +if len(sys.argv) < 3: + print('Usage: {0} output file1 [file2] ...'.format(sys.argv[0])) + sys.exit(1) + +outputfilename = sys.argv[1] +inputFileNames = sys.argv[2:] + +with open(outputfilename, 'wb') as outputFile: + # Amount of files: + outputFile.write(struct.pack('