Mon, 01 Jan 2018 21:37:18 +0100
38 files changed,
287 insertions(+),
203 deletions(-)
jump to
M
boot/makefile
→
boot/makefile
@@ -1,5 +1,16 @@
.RECIPEPREFIX = > +S_OBJECTS = $(patsubst %.s,$(LOCAL_BUILD)/%.s.o,$(wildcard *.s)) +C_OBJECTS = $(patsubst %.c,$(LOCAL_BUILD)/%.c.o,$(wildcard *.c)) +OBJECTS = $(S_OBJECTS) $(C_OBJECTS) + +LOCAL_BUILD = $(GLOBAL_BUILD) + +SUBDIRS = $(wildcard */.) + .PHONY: build -build: boot.s -> $(GCC_PREFIX)as -o $(GLOBAL_BUILD)/boot.o boot.s +build: $(SUBDIRS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): +> make -C $@ GLOBAL_BUILD=$(LOCAL_BUILD) build
A
boot/stage1/makefile
@@ -0,0 +1,5 @@
+.RECIPEPREFIX = > + +.PHONY: build +build: boot.s +> $(GCC_PREFIX)as -o $(GLOBAL_BUILD)/boot_stage1.o boot.s
A
boot/stage2/linker.h
@@ -0,0 +1,25 @@
+/*! \file + * Wrapper for symbols defined in the linker. + */ +#ifndef LINKER_H +#define LINKER_H + +#include <stdint.h> + +extern uint8_t __SS_VMA; +extern uint8_t __SS_LMA; +extern uint8_t __SS_SIZE; + +extern uint8_t __KERNEL_VMA; +extern uint8_t __KERNEL_LMA; +extern uint8_t __KERNEL_SIZE; + +#define SS_VMA (&__SS_VMA) +#define SS_LMA (&__SS_LMA) +#define SS_SIZE (uint32_t)(&__SS_SIZE) + +#define KERNEL_VMA (&__KERNEL_VMA) +#define KERNEL_LMA (&__KERNEL_LMA) +#define KERNEL_SIZE (uint32_t)(&__KERNEL_SIZE) + +#endif
A
include/cedos/drivers/console.h
@@ -0,0 +1,51 @@
+/*! \file + * Driver for VGA textmode output + */ +#ifndef TEXT_H +#define TEXT_H + +#include <stdint.h> + +/*! + * Interface for a console device. + */ +typedef struct { + /*! + * Name of the keyboard. + */ + const char* name; + + /*! + * Initializes the console + * \return 1 on success, 0 on fail + */ + int (*init)(void); + + /*! + * Prints a single character to the display. + * \param c Character to print. + */ + void (*write_c)(const char c); + void (*write_n)(const char *string, uint32_t num); + void (*write_s)(const char *string); + + /*! + * Clears the entire display and resets the cursor. + */ + void (*clear)(void); + + /*! + * Moves the cursor to the next line. + */ + void (*newline)(void); + + /*! + * Deletes a single character of the display and moves the cursor back. + */ + void (*backspace)(void); +} CON_DRIVER; + +//! VGA console driver (default driver) +CON_DRIVER vga_con; + +#endif
A
include/cedos/drivers/keyboard.h
@@ -0,0 +1,34 @@
+/*! \file + * Driver for PS/2 keyboard + */ +#ifndef OS_KEYBOARD_H +#define OS_KEYBOARD_H + +#include <stdint.h> + +/*! + * Interface for a keyboard device. + */ +typedef struct { + /*! + * Name of the keyboard. + */ + const char* name; + + /*! + * Initializes the keyboard. + * \return 1 on success, 0 on fail + */ + int (*init)(void); + + /*! + * Reads a single character from the keyboard + * \return A single char corresponding to a key press. + */ + uint32_t (*read)(void); +} KB_DRIVER; + +//! PS/2 keyboard driver (default driver) +KB_DRIVER ps2_kb; + +#endif
D
kernel/drivers/keyboard.c
@@ -1,28 +0,0 @@
-#include "keyboard.h" -#include "../os_interrupts.h" -#include "pic.h" -#include "assembly.h" - - - -/*! - * Initializes the keyboard. - * \return 1 on success, 0 on fail - */ -int keyboard_init(void) { - -} - -/*! - * Reads a single character from the keyboard - * \return A single char corresponding to a key press. - */ -uint8_t keyboard_read_c(void) { - static uint32_t keycode = 0; - - keycode <<= 8; -} - -__attribute__((interrupt)) volatile void keyboard_int_handler(INTERRUPT_FRAME *frame) { - -}
D
kernel/drivers/keyboard.h
@@ -1,21 +0,0 @@
-/*! \file - * Driver for PS/2 keyboard - */ -#ifndef OS_KEYBOARD_H -#define OS_KEYBOARD_H - -#include <stdint.h> - -/*! - * Initializes the keyboard. - * \return 1 on success, 0 on fail - */ -int keyboard_init(void); - -/*! - * Reads a single character from the keyboard - * \return A single char corresponding to a key press. - */ -uint8_t keyboard_read_c(void); - -#endif
M
kernel/drivers/pic.c
→
kernel/pic.c
@@ -1,4 +1,4 @@
-#include "pic.h" +#include "cedos/pic.h" #include "assembly.h" #include "common.h"
M
kernel/drivers/pic.h
→
include/cedos/pic.h
@@ -1,8 +1,8 @@
/*! \file * Interface for accessing the programmable interrupt contoller (PIC). */ -#ifndef OS_PIC_H -#define OS_PIC_H +#ifndef PIC_H +#define PIC_H #define PIC1_COMMAND 0x20 #define PIC1_DATA 0x21
A
kernel/drivers/ps2_keyboard.c
@@ -0,0 +1,35 @@
+#include "cedos/drivers/keyboard.h" +#include "cedos/interrupts.h" +#include "cedos/pic.h" +#include "assembly.h" + +/*! + * Initializes the PS/2 keyboard. + * \return 1 on success, 0 on fail + */ +int ps2_kb_init(void); + +/*! + * Reads a single character from the PS/2 keyboard + * \return A single char corresponding to a key press. + */ +uint8_t ps2_kb_read(void); + +//! PS/2 keyboard driver (default driver) +KB_DRIVER ps2_kb = { + "PS/2 keyboard driver", + ps2_kb_init, + ps2_kb_read +}; + +__attribute__((interrupt)) volatile void keyboard_int_handler(INTERRUPT_FRAME *frame) { + +} + +int ps2_kb_init(void) { + +} + +uint8_t ps2_kb_read(void) { + +}
M
kernel/drivers/text.c
→
kernel/drivers/vga_console.c
@@ -1,3 +1,4 @@
+#include "cedos/drivers/console.h" #include "linker.h" #include "assembly.h" #include "string.h"@@ -20,6 +21,25 @@
uint32_t line = 0; uint32_t column = 0; uint8_t color = 0x0F; + +int vga_con_init(void); +void vga_con_write_c(const char c); +void vga_con_write_n(const char *string, uint32_t num); +void vga_con_write_s(const char *string); +void vga_con_clear(void); +void vga_con_newline(void); +void vga_con_backspace(void); + +CON_DRIVER vga_con = { + "VGA console", + vga_con_init, + vga_con_write_c, + vga_con_write_n, + vga_con_write_s, + vga_con_clear, + vga_con_newline, + vga_con_backspace +}; __attribute((always_inline)) inline void set_char(char value) { VGA_MEM_VALUE(line, column) = value;@@ -70,64 +90,68 @@ outb(0x0E, VGA_INDEX_REG);
outb((uint8_t)(pos >> 8), VGA_DATA_REG); } -void text_backspace(void) { - if (column == 0 && line > 0) { - line--; - column = VGA_TEXTMODE_COLUMNS - 1; - } else if (column > 0) { - column--; +void enable_cursor(void) { + outb(0x0A, VGA_INDEX_REG); + outb((inb(VGA_DATA_REG) & 0x0C) | 0x00, VGA_DATA_REG); + outb(0x0B, VGA_INDEX_REG); + outb((inb(VGA_DATA_REG) & 0xE0) | 0x0F, VGA_DATA_REG); +} + +int vga_con_init(void) { + vga_con_clear(); + + enable_cursor(); + set_cursor(line, column); + + for (uint32_t i = 0; i < 320 * 200; i++) { + uint8_t* disp = (uint8_t*)0xA0000; + disp[i] = (uint8_t)i; } + + return 1; +} - set_char(0); +void vga_con_write_c(const char c) { + write_char(c); set_cursor(line, column); } -void text_write_n(const char *string, uint32_t num) { +void vga_con_write_n(const char *string, uint32_t num) { for (uint32_t i = 0; i < num; i++) { write_char(string[0]); } set_cursor(line, column); } -void text_write(const char *string) { +void vga_con_write_s(const char *string) { while (*string) { write_char(*(string++)); } set_cursor(line, column); } -void text_write_c(const char c) { - write_char(c); - set_cursor(line, column); -} - -void enable_cursor(void) { - outb(0x0A, VGA_INDEX_REG); - outb((inb(VGA_DATA_REG) & 0x0C) | 0x00, VGA_DATA_REG); - outb(0x0B, VGA_INDEX_REG); - outb((inb(VGA_DATA_REG) & 0xE0) | 0x0F, VGA_DATA_REG); -} - -void text_clear(void) { +void vga_con_clear(void) { for (int i = 0; i < VGA_TEXTMODE_CELLS; i++) { VGA_TEXTMODE_MEM[2 * i] = 0; VGA_TEXTMODE_MEM[2 * i + 1] = 0; } - + line = 0; column = 0; } -int text_init(void) { - text_clear(); - - enable_cursor(); - set_cursor(line, column); +void vga_con_newline(void) { + lfcr(); +} - for (uint32_t i = 0; i < 320 * 200; i++) { - uint8_t* disp = (uint8_t*)0xA0000; - disp[i] = (uint8_t)i; +void vga_con_backspace(void) { + if (column == 0 && line > 0) { + line--; + column = VGA_TEXTMODE_COLUMNS - 1; + } else if (column > 0) { + column--; } - return 1; + set_char(0); + set_cursor(line, column); }
D
kernel/drivers/text.h
@@ -1,44 +0,0 @@
-/*! \file - * Driver for VGA textmode output - */ -#ifndef TEXT_H -#define TEXT_H - -#include <stdint.h> - -/*! - * Prints a number of characters of a string to the display. - * \param string String from which to print characters. - * \param num Number of characters to print - */ -void text_write_n(const char *string, uint32_t num); - -/*! - * Prints a single character to the display. - * \param c Character to print. - */ -void text_write_c(const char c); - -/*! - * Prints a null-terminated string to the display. - * \param string Null-terminated string to print. - */ -void text_write(const char *string); - -/*! - * Initializes VGA textmode - * \return 1 on success, 0 on fail - */ -int text_init(void); - -/*! - * Clears the entire display and resets the cursor. - */ -void text_clear(void); - -/*! - * Deletes a single character of the display and moves the cursor back. - */ -void text_backspace(void); - -#endif
A
kernel/main.c
@@ -0,0 +1,29 @@
+#include "cedos/drivers/console.h" +#include "cedos/interrupts.h" +#include "cedos/pic.h" +#include "cedos/scheduler.h" + +int os_init(void) { + vga_con.init(); + vga_con.write_s("TTY output initialized.\n"); + + vga_con.write_s("Initializing PIC..."); + pic_init(); + vga_con.write_s("done.\n"); + + vga_con.write_s("Initializing interrupts..."); + interrupts_init(); + vga_con.write_s("done.\n"); + + vga_con.write_s("Initialization finished.\n--------------\n"); +} + +int os_main(void) { + //const char* string[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + + vga_con.write_s("Starting scheduler.\n"); + sched_exec(); + + vga_con.write_s("Main procedure terminating.\n"); + return 0; +}
M
kernel/makefile
→
kernel/makefile
@@ -10,7 +10,7 @@ SUBDIRS = $(wildcard */.)
.PHONY: build build: folder $(SUBDIRS) $(OBJECTS) -> $(GCC_PREFIX)ld $(LOCAL_BUILD)/*.o -r -e _kernel_start -Map=$(DEBUG_DIR)/kernel_map.txt -o $(GLOBAL_BUILD)/kernel.o --oformat elf32-i386 +> $(GCC_PREFIX)ld $(LOCAL_BUILD)/*.o -r -e _kernel_start -o $(GLOBAL_BUILD)/kernel.o --oformat elf32-i386 .PHONY: folder folder:
M
kernel/os_interrupts.c
→
kernel/interrupts.c
@@ -1,5 +1,5 @@
-#include "os_interrupts.h" -#include "drivers/text.h" +#include "cedos/interrupts.h" +#include "cedos/drivers/console.h" #define HARDWARE_INTERRUPT (0b10001110) #define SYSCALL_INTERRUPT (0b11101110)@@ -15,16 +15,16 @@ (uint16_t)(0xC000) \
} __attribute__((interrupt)) volatile void default_isr(INTERRUPT_FRAME *frame) { - text_write("interrupt was issued\n"); + vga_con.write_s("interrupt was issued\n"); } __attribute__((interrupt)) volatile void breakpoint_isr(INTERRUPT_FRAME *frame) { - text_write("BREAKPOINT WAS HIT\n"); + vga_con.write_s("BREAKPOINT WAS HIT\n"); // dump registers to stdout } __attribute__((interrupt)) volatile void double_fault_isr(INTERRUPT_FRAME *frame) { - text_write("CRITICAL: DOUBLE FAULT\n"); + vga_con.write_s("CRITICAL: DOUBLE FAULT\n"); //while (1) {} }
D
kernel/os_main.c
@@ -1,29 +0,0 @@
-#include "drivers/text.h" -#include "os_interrupts.h" -#include "drivers/pic.h" -#include "os_scheduler.h" - -int os_init(void) { - text_init(); - text_write("TTY output initialized.\n"); - - text_write("Initializing PIC..."); - pic_init(); - text_write("done.\n"); - - text_write("Initializing interrupts..."); - interrupts_init(); - text_write("done.\n"); - - text_write("Initialization finished.\n--------------\n"); -} - -int os_main(void) { - //const char* string[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - - text_write("Starting scheduler.\n"); - sched_exec(); - - text_write("Main procedure terminating.\n"); - return 0; -}
M
kernel/os_memory.c
→
kernel/memory.c
@@ -1,4 +1,4 @@
-#include "os_memory.h" +#include "cedos/memory.h" /*! * Allocates a block of \p size bytes of memory. (KERNEL MODE)
M
kernel/os_memory.h
→
include/cedos/memory.h
@@ -1,8 +1,8 @@
/*! \file * Provides functions for memory allocation. */ -#ifndef OS_MEMORY_H -#define OS_MEMORY_H +#ifndef MEMORY_H +#define MEMORY_H #include <stdint.h>
M
kernel/os_page_allocator.c
→
kernel/page_allocator.c
@@ -1,5 +1,5 @@
-#include "os_page_allocator.h" -#include "os_paging.h" +#include "cedos/page_allocator.h" +#include "cedos/paging.h" uint8_t* first_free = (uint8_t*)0x00200000;
M
kernel/os_paging.c
→
kernel/paging.c
@@ -1,6 +1,6 @@
-#include "os_paging.h" +#include "cedos/paging.h" +#include "cedos/page_allocator.h" #include "linker.h" -#include "os_page_allocator.h" #include "string.h" #define MAKE_PAGE_ENTRY(addr, flags) (uint32_t)(((uint32_t)(addr) & 0xFFFFF000) | (flags))
M
kernel/os_scheduler.c
→
kernel/scheduler.c
@@ -1,6 +1,6 @@
-#include "os_scheduler.h" -#include "os_paging.h" -#include "drivers/text.h" +#include "cedos/scheduler.h" +#include "cedos/paging.h" +#include "cedos/drivers/console.h" /*! * Executes a task.@@ -12,7 +12,7 @@
map_range_to(page_dir, (VIRT_ADDR)0x00000000, (PHYS_ADDR)0x00000000, PAGE_ENTRY_COUNT, 0b000000000011); // will not work because lower memory not mapped - text_write("Successfully switched to new page directory.\n"); + vga_con.write_s("Successfully switched to new page directory.\n"); return 0; }
M
kernel/os_scheduler.h
→
include/cedos/scheduler.h
@@ -1,8 +1,8 @@
/*! \file * Manages the distribution of processing time among processes. */ -#ifndef OS_SCHEDULER_H -#define OS_SCHEDULER_H +#ifndef SCHEDULER_H +#define SCHEDULER_H #include <stdint.h>
M
link.txt
→
link.txt
@@ -5,28 +5,28 @@ PAGE_SIZE = 1 << 12;
MEMORY { - BOOT : ORIGIN = 0x00007C00, LENGTH = 0x00000200 - SECOND_STAGE : ORIGIN = 0x00010000, LENGTH = 0x00090000 + BOOT_STAGE1 : ORIGIN = 0x00007C00, LENGTH = 0x00000200 + BOOT_STAGE2 : ORIGIN = 0x00010000, LENGTH = 0x00090000 KERNEL : ORIGIN = 0xC0000000, LENGTH = 0x30000000 APPLICATION : ORIGIN = 0x10000000, LENGTH = 0xB0000000 } SECTIONS { - BOOT : AT(0x0000) + BOOT_STAGE1 : AT(0x0000) { - */boot.o(.*) + */boot_stage1.o(.*) . = 510; BYTE(0x55) BYTE(0xAA) - } >BOOT + } >BOOT_STAGE1 - SECOND_STAGE : AT(LOADADDR(BOOT) + SIZEOF(BOOT)) + BOOT_STAGE2 : AT(LOADADDR(BOOT_STAGE1) + SIZEOF(BOOT_STAGE1)) { - */second_stage.o(.*) - } >SECOND_STAGE + */boot_stage2.o(.*) + } >BOOT_STAGE2 - KERNEL : AT(LOADADDR(SECOND_STAGE) + SIZEOF(SECOND_STAGE)) + KERNEL : AT(LOADADDR(BOOT_STAGE2) + SIZEOF(BOOT_STAGE2)) { */kernel.o(.*) */kernel.o(.bss)@@ -43,9 +43,9 @@
} >KERNEL } -__SS_LMA = LOADADDR(SECOND_STAGE); -__SS_VMA = ADDR(SECOND_STAGE); -__SS_SIZE = SIZEOF(SECOND_STAGE); +__SS_LMA = LOADADDR(BOOT_STAGE2); +__SS_VMA = ADDR(BOOT_STAGE2); +__SS_SIZE = SIZEOF(BOOT_STAGE2); __KERNEL_LMA = LOADADDR(KERNEL); __KERNEL_VMA = ADDR(KERNEL);
M
makefile
→
makefile
@@ -22,7 +22,6 @@ .PHONY: build
build: > @mkdir $(GLOBAL_BUILD) 2> /dev/null; true > $(MAKE) GLOBAL_BUILD=$(LOCAL_BUILD) -C boot build -> $(MAKE) GLOBAL_BUILD=$(LOCAL_BUILD) -C second_stage build > $(MAKE) GLOBAL_BUILD=$(LOCAL_BUILD) -C kernel build > $(GCC_PREFIX)ld $(GLOBAL_BUILD)/*.o -T link.txt -Map=$(DEBUG_DIR)/mapfile.txt -o build/base.o > $(GCC_PREFIX)objcopy --only-keep-debug build/base.o $(DEBUG_DIR)/base.sym@@ -35,15 +34,6 @@
.PHONY: run run: > ./run.sh - -.PHONY: rebuild -rebuild: -> $(MAKE) $(MAKEFLAGS) clear -> $(MAKE) $(MAKEFLAGS) build - -.PHONY: objdump -objdump: -> $(GCC_PREFIX)objdump -D $(FILE) > debug/objdump.txt .PHONY: debug debug:
M
second_stage/makefile
→
boot/stage2/makefile
@@ -4,11 +4,13 @@ S_OBJECTS = $(patsubst %.s,$(LOCAL_BUILD)/%.s.o,$(wildcard *.s))
C_OBJECTS = $(patsubst %.c,$(LOCAL_BUILD)/%.c.o,$(wildcard *.c)) OBJECTS = $(S_OBJECTS) $(C_OBJECTS) -LOCAL_BUILD = $(GLOBAL_BUILD)/second_stage +LOCAL_BUILD = $(GLOBAL_BUILD)/boot_stage2 + +SUBDIRS = $(wildcard */.) .PHONY: build build: folder $(SUBDIRS) $(OBJECTS) -> $(GCC_PREFIX)ld $(wildcard $(LOCAL_BUILD)/*.o) -r -T link.txt -o $(GLOBAL_BUILD)/second_stage.o --oformat elf32-i386 +> $(GCC_PREFIX)ld $(wildcard $(LOCAL_BUILD)/*.o) -r -T link.txt -o $(GLOBAL_BUILD)/boot_stage2.o --oformat elf32-i386 .PHONY: folder folder:@@ -22,4 +24,4 @@ $(LOCAL_BUILD)/%.s.o: %.s
> $(GCC_PREFIX)as -o $@ $< $(LOCAL_BUILD)/%.c.o: %.c $(wildcard *.h) -> $(GCC_PREFIX)gcc -c -I$(INCLUDE_DIR) --prefix=$(GCC_PREFIX) $(GCC_OPTIONS) -o $@ $<+> $(GCC_PREFIX)gcc -c --prefix=$(GCC_PREFIX) $(GCC_OPTIONS) -o $@ $<