diff options
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | include/asm/io.h | 14 | ||||
| -rw-r--r-- | include/kernel/con.h | 14 | ||||
| -rw-r--r-- | include/kernel/vsprintf.h | 14 | ||||
| -rw-r--r-- | include/stdarg.h | 27 | ||||
| -rw-r--r-- | include/stdbool.h | 17 | ||||
| -rw-r--r-- | include/stdint.h | 19 | ||||
| -rw-r--r-- | kernel/Makefile | 33 | ||||
| -rw-r--r-- | kernel/boot.o | bin | 0 -> 3184 bytes | |||
| -rw-r--r-- | kernel/boot.s | 127 | ||||
| -rw-r--r-- | kernel/con.c | 96 | ||||
| -rw-r--r-- | kernel/con.o | bin | 0 -> 6496 bytes | |||
| -rwxr-xr-x | kernel/kernel | bin | 0 -> 14092 bytes | |||
| -rw-r--r-- | kernel/kmain.c | 10 | ||||
| -rw-r--r-- | kernel/kmain.o | bin | 0 -> 3288 bytes | |||
| -rw-r--r-- | kernel/link.ld | 11 | ||||
| -rw-r--r-- | kernel/vsprintf.c | 18 | ||||
| -rw-r--r-- | kernel/vsprintf.o | bin | 0 -> 3464 bytes |
18 files changed, 408 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4098be7 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: + make -C kernel + +run: + make -C kernel run + +clean: + make -C kernel clean diff --git a/include/asm/io.h b/include/asm/io.h new file mode 100644 index 0000000..6ca5bbc --- /dev/null +++ b/include/asm/io.h @@ -0,0 +1,14 @@ +/* + * asm/io.h + * + * Provides acces to x86 I/O functions + */ + +#define inb(port) ({ \ + unsigned char _val; \ + asm volatile ("inb %%dx, %%al" : "=a" (_val) : "d" (port)); \ + _val; \ + }) + +#define outb(port, val) \ + asm volatile ("outb %%al, %%dx" : : "d" (port), "a" (val)); diff --git a/include/kernel/con.h b/include/kernel/con.h new file mode 100644 index 0000000..4e564ed --- /dev/null +++ b/include/kernel/con.h @@ -0,0 +1,14 @@ +/* + * con.h + * + * Basic VGA text console + */ + +#ifndef _CON_H +#define _CON_H + +void con_init(void); + +void con_print(char*); + +#endif diff --git a/include/kernel/vsprintf.h b/include/kernel/vsprintf.h new file mode 100644 index 0000000..08297d6 --- /dev/null +++ b/include/kernel/vsprintf.h @@ -0,0 +1,14 @@ +/* + * vsprintf.h + * + * A very basic implmentation of thr vsprintf function + */ + +#ifndef _VSPRINTF_H +#define _VSPRINTF_H + +#include <stdarg.h> + +int vsprintf(char*, char*, va_list); + +#endif diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100644 index 0000000..8eb1341 --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,27 @@ +/* + * stdarg.h + * + * Provides va_list and associated functions + */ + +#ifndef _STDARG_H +#define _STDARG_H + +typedef char* va_list; + +#define __va_rounded_size(TYPE) \ + (((sizeof(TYPE) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) + +#define va_start(AP, LAST) \ + (AP = ((char*) &LAST + __va_rounded_size(LAST))) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size(TYPE), \ + *((TYPE*) (AP - __va_rounded_size(TYPE)))) + +#define va_end(AP) + +#define va_copy(DEST, SRC) \ + (DEST = SRC) + +#endif diff --git a/include/stdbool.h b/include/stdbool.h new file mode 100644 index 0000000..f96b223 --- /dev/null +++ b/include/stdbool.h @@ -0,0 +1,17 @@ +/* + * stdbool.h + * + * Defines bool, true and false + */ + +#ifndef _STDBOOL_H +#define _STDBOOL_H + +typedef char bool; + +#undef false +#define false 0 +#undef true +#define true 1 + +#endif diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..3dc068e --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,19 @@ +/* + * stdint.h + * + * Common integer types + */ + +#ifndef _STDINT_H +#define _STDINT_H + +typedef char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef long int64_t; +typedef unsigned long uint64_t; + +#endif diff --git a/kernel/Makefile b/kernel/Makefile new file mode 100644 index 0000000..0f3ac41 --- /dev/null +++ b/kernel/Makefile @@ -0,0 +1,33 @@ +TARGET = kernel + +SRCS = $(wildcard *.c) +ASMS = $(wildcard *.s) +OBJS = $(SRCS:.c=.o) $(ASMS:.s=.o) + +CFLAGS = -m32 -I../include -ffreestanding -nostdinc -nostdlib -fno-stack-protector -gstabs+ +LDFLAGS = -m elf_i386 -Tlink.ld +ASMFLAGS = -f elf32 + +CC = gcc $(CFLAGS) +LD = ld $(LDFLAGS) +ASM = nasm $(ASMFLAGS) + +all: build + +build: $(TARGET) + +.s.o: + $(ASM) -o $*.o $^ + +.c.o: + $(CC) -c -o $*.o $^ + +$(TARGET): $(OBJS) + $(LD) -o $(TARGET) $(OBJS) + +clean: + rm -f $(OBJS) + rm -f $(TARGET) + +run: $(TARGET) + qemu-system-x86_64 -s -kernel $(TARGET) diff --git a/kernel/boot.o b/kernel/boot.o Binary files differnew file mode 100644 index 0000000..41427be --- /dev/null +++ b/kernel/boot.o diff --git a/kernel/boot.s b/kernel/boot.s new file mode 100644 index 0000000..be68109 --- /dev/null +++ b/kernel/boot.s @@ -0,0 +1,127 @@ +global kboot +extern kmain + +; Multiboot header +section .mboothdr +mboot_hdr: + align 4 + dd 0x1BADB002 + dd 0x00 + dd - (0x1BADB002 + 0x00) + +section .text + +kboot: + cli + call flush_gdt + call flush_idt + call kmain + cli + hlt + +gdt: + ; null descriptor + dq 0 + ; kernel code segment + dw 0xFFFF ; limit (bits 0-15) + dw 0x0000 ; base (bits 0-15) + db 0x00 ; base (bits 16-23) + db 0x9A ; access byte + db 0xCF ; flags / limit (bits 16-19) + db 0x00 ; base (bits 24-31) + ; kernel data segment + dw 0xFFFF + dw 0x0000 + db 0x00 + db 0x92 + db 0xCF + db 0x00 + ; userspace code segment + dw 0xFFFF + dw 0x0000 + db 0x00 + db 0xFA + db 0xCF + db 0x00 + ; userspace data segment + dw 0xFFFF + dw 0x0000 + db 0x00 + db 0xF2 + db 0xCF + db 0x00 + +gdtp: + dw ($-gdt-1) + dd gdt + +flush_gdt: + push ebp + mov ebp, esp + lgdt [gdtp] + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + jmp 0x08:.end +.end: + pop ebp + ret + +idt: + times (256*8) db 0 + +idtp: + dw ($-idt-1) + dd idt + +int_handler: + iret + +flush_idt: + push ebp + mov ebp, esp + mov ecx, 256 + mov edx, idt +.loop: + mov eax, int_handler + mov [edx], ax + mov word [edx+2], 0x08 + mov byte [edx+4], 0 + mov byte [edx+5], 0x8E + shr eax, 16 + mov [edx+6], ax + add edx, 8 + dec ecx + jz .end + jmp .loop +.end: + lidt [idtp] + call pic_init + sti + pop ebp + ret + +pic_init: + push ebp + mov ebp, esp + mov al, 0x11 + out 0x20, al + out 0xA0, al + mov al, 0x20 + out 0x21, al + out 0xA1, al + mov al, 0x04 + out 0x21, al + mov al, 0x02 + out 0xA1, al + mov al, 0x01 + out 0x21, al + out 0xA1, al + mov al, 0xFF + out 0x21, al + out 0xA1, al + pop ebp + ret diff --git a/kernel/con.c b/kernel/con.c new file mode 100644 index 0000000..b3d2b9d --- /dev/null +++ b/kernel/con.c @@ -0,0 +1,96 @@ +/* + * con.c + * + * Basic VGA text console + */ + +#include <asm/io.h> +#include <kernel/vsprintf.h> +#include <stdarg.h> +#include <stdint.h> + +#define COLS 80 +#define ROWS 25 + +static uint8_t *vram = (uint8_t*) 0xB8000; +static int pos; + +static inline void cursorpos(int pos) { + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8_t) ((pos >> 9) & 0xFF)); + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8_t) ((pos >> 1) & 0xFF)); +} + +/* scrolls the console up one line */ +static void scroll_up(void) { + int n = (COLS * (ROWS - 1)) << 1; + uint8_t *p = vram; + + while(n--) { + *p = p[COLS << 1]; + p++; + } + + p = (uint8_t*) (vram + (COLS * (ROWS - 1) << 1)); + n = COLS; + while(n--) { + *p = ' '; + p += 2; + } + + pos -= COLS << 1; + cursorpos(pos); +} + +/* must be called before any console output */ +void con_init(void) { + int n = COLS * ROWS; + uint8_t *p = vram; + + while(n--) { + *(p++) = 0x20; + *(p++) = 0x07; + } + + pos = 0; + cursorpos(0); +} + +/* write a zero-terminated string to console */ +void con_print(char *s) { + uint8_t *p = &vram[pos]; + + while(*s) { + if(*s == '\n') { + pos = (int) (p - vram); + pos = ((pos / (COLS << 1)) + 1) * (COLS << 1); + p = &vram[pos]; + s++; + } else { + *p = *(s++); + p += 2; + } + + pos = (int) (p - vram); + + if(pos >= (COLS * ROWS) << 1) + scroll_up(); + } + + /* update the cursor position */ + cursorpos(pos); +} + +int printf(char *fmt, ...) { + int ret; + char buf[1024]; + va_list ap; + + va_start(ap, fmt); + ret = vsprintf(buf, fmt, ap); + va_end(ap); + + con_print(buf); + return ret; +} diff --git a/kernel/con.o b/kernel/con.o Binary files differnew file mode 100644 index 0000000..49168c9 --- /dev/null +++ b/kernel/con.o diff --git a/kernel/kernel b/kernel/kernel Binary files differnew file mode 100755 index 0000000..664108b --- /dev/null +++ b/kernel/kernel diff --git a/kernel/kmain.c b/kernel/kmain.c new file mode 100644 index 0000000..2dc9e76 --- /dev/null +++ b/kernel/kmain.c @@ -0,0 +1,10 @@ +#include <kernel/con.h> + +extern int printf(char *fmt, ...); + +void kmain(void) { + con_init(); + + printf("Kernel booting...\n"); + printf("Kernel booted!\n"); +} diff --git a/kernel/kmain.o b/kernel/kmain.o Binary files differnew file mode 100644 index 0000000..9a3a76d --- /dev/null +++ b/kernel/kmain.o diff --git a/kernel/link.ld b/kernel/link.ld new file mode 100644 index 0000000..67ae357 --- /dev/null +++ b/kernel/link.ld @@ -0,0 +1,11 @@ +OUTPUT_FORMAT(elf32-i386) +/* OUTPUT_FORMAT(binary) */ +ENTRY(kboot) +SECTIONS +{ + . = 0x100000; + .mboothdr : { *(.mboothdr) } + .text : { *(.text) } + .data : { *(.data) } + .bss : { *(.bss) } +} diff --git a/kernel/vsprintf.c b/kernel/vsprintf.c new file mode 100644 index 0000000..f3feb43 --- /dev/null +++ b/kernel/vsprintf.c @@ -0,0 +1,18 @@ +#include <stdarg.h> + +int vsprintf(char *str, char *fmt, va_list ap) { + char *start = str; + + while(*fmt) { + if(*fmt != '%') { + *str++ = *fmt++; + continue; + } + + fmt++; + } + + *str = 0; + + return (str - start); +} diff --git a/kernel/vsprintf.o b/kernel/vsprintf.o Binary files differnew file mode 100644 index 0000000..b5359fe --- /dev/null +++ b/kernel/vsprintf.o |
