summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenji Dial <benji3.141@gmail.com>2020-05-24 11:02:43 -0400
committerBenji Dial <benji3.141@gmail.com>2020-05-24 11:02:43 -0400
commit02f14113cbf14c6f842fb43ecbc68d0c851ef3b0 (patch)
tree75d2d943d9822b3f945fd947e9b91eec1d68e900
parent31d8ae388a7ded576abd3e3d99c3d9193ea6d704 (diff)
downloadportland-os-02f14113cbf14c6f842fb43ecbc68d0c851ef3b0.tar.gz
very basic vga, ata, serial drivers. start of fat and fs drivers
-rw-r--r--doc/internal/mem.txt8
-rw-r--r--makefile30
-rw-r--r--src/boot.asm9
-rw-r--r--src/kernel/ata.c113
-rw-r--r--src/kernel/ata.h6
-rw-r--r--src/kernel/fat.c21
-rw-r--r--src/kernel/fat.h17
-rw-r--r--src/kernel/fs.c82
-rw-r--r--src/kernel/fs.h10
-rw-r--r--src/kernel/link.ld4
-rw-r--r--src/kernel/main.c28
-rw-r--r--src/kernel/panic.c31
-rw-r--r--src/kernel/panic.h4
-rw-r--r--src/kernel/serial.c100
-rw-r--r--src/kernel/serial.h10
-rw-r--r--src/kernel/util.asm37
-rw-r--r--src/kernel/util.c100
-rw-r--r--src/kernel/util.h13
-rw-r--r--src/kernel/vga.c58
-rw-r--r--src/kernel/vga.h6
-rw-r--r--src/kernel/vga.inc11
21 files changed, 633 insertions, 65 deletions
diff --git a/doc/internal/mem.txt b/doc/internal/mem.txt
index d3b7696..cc5d301 100644
--- a/doc/internal/mem.txt
+++ b/doc/internal/mem.txt
@@ -1,4 +1,8 @@
-0x0001.0000 - 0x0002.ffff: unused
+0x0001.0000 - 0x0002.5fff: unused
+0x0002.6000 - 0x0002.bfff: fat
+0x0002.c000 - 0x0002.ffff: file buffers
0x0003.0000 - 0x0003.7fff: kernel
0x0003.8000 - 0x0003.ffff: stack
-0x0004.0000 - 0x0007.ffff: unused \ No newline at end of file
+0x0004.0000 - 0x0007.ffff: unused
+0x0008.0000 - 0x000d.9fff: ramd
+0x000d.a000 - 0xffff.ffff: unused \ No newline at end of file
diff --git a/makefile b/makefile
index 0de951a..503fcca 100644
--- a/makefile
+++ b/makefile
@@ -1,20 +1,32 @@
-qemu: floppy
- qemu-system-i386 out/floppy.img
-
-floppy: kernel boot
+disk: kernel boot
mkdir -p obj out
- /sbin/mkfs.fat -C -R 17 -n "PORTLAND OS" obj/shadow.img 1440
+ /sbin/mkfs.fat -C -f 1 -F 12 -n "PORTLAND OS" -R 17 obj/shadow.img 8192
echo -n -e '\xeb\x3c' > obj/jmp.bin
dd if=obj/jmp.bin of=obj/shadow.img obs=2 conv=notrunc
dd if=out/boot.bin of=obj/shadow.img obs=1 seek=62 conv=notrunc
dd if=out/kernel.bin of=obj/shadow.img seek=1 conv=notrunc
- mv obj/shadow.img out/floppy.img
+ mv obj/shadow.img out/disk.img
+
+vbox-image: disk
+ VBoxManage convertfromraw out/disk.img out/disk.vdi --uuid a61929ed-3bf2-45ff-b98a-44f87c616dba
+
+kdump: kernel
+ objdump -M intel -d obj/kernel.elf > out/kernel.dasm
+kgccargs = -m32 -ffreestanding -fno-asynchronous-unwind-tables
kernel:
mkdir -p obj/kernel out
- gcc -m32 -ffreestanding -c src/kernel/main.c -o obj/kernel/main.o
- gcc -m32 -ffreestanding -c src/kernel/vga.c -o obj/kernel/vga.o
- ld -T src/kernel/link.ld obj/kernel/main.o obj/kernel/vga.o -o out/kernel.bin
+ gcc ${kgccargs} -c src/kernel/main.c -o obj/kernel/main.o
+ gcc ${kgccargs} -c src/kernel/vga.c -o obj/kernel/vga.o
+ gcc ${kgccargs} -c src/kernel/fat.c -o obj/kernel/fat.o
+ gcc ${kgccargs} -c src/kernel/fs.c -o obj/kernel/fs.o
+ gcc ${kgccargs} -c src/kernel/ata.c -o obj/kernel/ata.o
+ gcc ${kgccargs} -c src/kernel/util.c -o obj/kernel/utilc.o
+ gcc ${kgccargs} -c src/kernel/panic.c -o obj/kernel/panic.o
+ gcc ${kgccargs} -c src/kernel/serial.c -o obj/kernel/serial.o
+ nasm -f elf32 src/kernel/util.asm -o obj/kernel/utila.o
+ ld -T src/kernel/link.ld obj/kernel/main.o obj/kernel/vga.o obj/kernel/fat.o obj/kernel/fs.o obj/kernel/ata.o obj/kernel/utilc.o obj/kernel/panic.o obj/kernel/utila.o obj/kernel/serial.o -o obj/kernel.elf
+ objcopy -O binary -j .entry -j .bin obj/kernel.elf out/kernel.bin
boot:
mkdir -p out
diff --git a/src/boot.asm b/src/boot.asm
index fecf466..f8ff1c8 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -41,9 +41,14 @@ pmode:
mov ds, ax
mov ax, 0x18
mov ss, ax
- mov sp, 0x7ffc
+ mov esp, 0x00008000
+
+ xor ebp, ebp
+ call kernel_segment * 16
- jmp kernel_segment * 16
+halt:
+ hlt
+ jmp halt
gdt:
dw .e - .t
diff --git a/src/kernel/ata.c b/src/kernel/ata.c
new file mode 100644
index 0000000..0e6cc4e
--- /dev/null
+++ b/src/kernel/ata.c
@@ -0,0 +1,113 @@
+#include <stdint.h>
+#include "panic.h"
+#include "util.h"
+#include "ata.h"
+
+enum {
+ AP_PRIMARY = 0x01f0,
+ AP_SECONDARY = 0x0170,
+
+ AP_DATA = 0x0,
+ AP_ERROR = 0x1,
+ AP_FEAT = 0x1,
+ AP_COUNT = 0x2,
+ AP_SEC = 0x3,
+ AP_CYL_L = 0x4,
+ AP_CYL_H = 0x5,
+ AP_HD_DR = 0x6,
+ AP_LBA0 = 0x3,
+ AP_LBA1 = 0x4,
+ AP_LBA2 = 0x5,
+ AP_L3_DR = 0x6,
+ AP_STAT = 0x7,
+ AP_CMD = 0x7,
+
+ APC_STAT = 0x0206,
+ APC_CTRL = 0x0206,
+ APC_ADDR = 0x0207
+};
+
+enum {
+ ADR_BASE = 0xa0,
+ ADR_CASCD = 0x10,
+ ADR_LBA = 0x40
+};
+
+enum {
+ AS_ERROR = 0x01,
+ AS_INDEX = 0x02,
+ AS_CORRECT = 0x04,
+ AS_DREADY = 0x08,
+ AS_SERVICE = 0x10,
+ AS_FAULT = 0x20,
+ AS_READY = 0x40,
+ AS_BUSY = 0x80
+};
+
+enum {
+ AC_READ = 0x20,
+ AC_WRITE = 0x30,
+ AC_FLUSH = 0xe7
+};
+
+void ata_ldelay() {
+ uint16_t i = 65535;
+ while (i--)
+ ;
+}
+
+void ata_sdelay() {
+ uint8_t i = 255;
+ while (i--)
+ ;
+}
+
+void ata_dpoll() {
+ uint8_t s;
+ while ((s = inb(AP_PRIMARY | AP_STAT) & (AS_BUSY | AS_DREADY)) != AS_DREADY)
+ if (s & (AS_ERROR | AS_FAULT))
+ panic("ATA controller error or fault.");
+}
+
+uint8_t read_sectors(uint16_t start, uint8_t count, void *buffer) {
+ outb(AP_PRIMARY | AP_L3_DR, ADR_BASE | ADR_LBA);
+ outb(AP_PRIMARY | AP_LBA2, 0);
+ outb(AP_PRIMARY | AP_LBA1, start >> 8);
+ outb(AP_PRIMARY | AP_LBA0, start & 0xff);
+ outb(AP_PRIMARY | AP_COUNT, count);
+ outb(AP_PRIMARY | AP_CMD, AC_READ);
+ uint8_t i = count - 1;
+ uint16_t *ptr = buffer;
+ do {
+ ata_dpoll();
+ uint8_t j = 255;
+ do
+ *(ptr++) = inw(AP_PRIMARY | AP_DATA);
+ while (j--);
+ ata_ldelay();
+ } while (i--);
+ return count;//TODO: return early if necessary
+}
+
+uint8_t write_sectors(uint16_t start, uint8_t count, void *buffer) {
+ outb(AP_PRIMARY | AP_L3_DR, ADR_BASE | ADR_LBA);
+ outb(AP_PRIMARY | AP_LBA2, 0);
+ outb(AP_PRIMARY | AP_LBA1, start >> 8);
+ outb(AP_PRIMARY | AP_LBA0, start & 0xff);
+ outb(AP_PRIMARY | AP_COUNT, count);
+ outb(AP_PRIMARY | AP_CMD, AC_WRITE);
+ uint8_t i = 0;
+ uint16_t *ptr = buffer;
+ do {
+ ata_dpoll();
+ uint8_t j = 0;
+ do {
+ ata_sdelay();
+ outw(AP_PRIMARY | AP_DATA, *(ptr++));
+ }
+ while (++j);
+ ata_ldelay();
+ } while (++i != count);
+ outb(AP_PRIMARY | AP_CMD, AC_FLUSH);
+ return count;//TODO: return early if necessary
+} \ No newline at end of file
diff --git a/src/kernel/ata.h b/src/kernel/ata.h
new file mode 100644
index 0000000..605f991
--- /dev/null
+++ b/src/kernel/ata.h
@@ -0,0 +1,6 @@
+#include <stdint.h>
+
+void init_ata();
+
+uint8_t read_sectors(uint16_t start, uint8_t count, void *buffer);
+uint8_t write_sectors(uint16_t start, uint8_t count, void *buffer); \ No newline at end of file
diff --git a/src/kernel/fat.c b/src/kernel/fat.c
new file mode 100644
index 0000000..00fa61f
--- /dev/null
+++ b/src/kernel/fat.c
@@ -0,0 +1,21 @@
+#include "fat.h"
+#include "ata.h"
+#include "panic.h"
+
+void load_fat() {
+ read_sectors(FAT_INFO->reserved_sectors, FAT_INFO->sectors_per_fat, FAT);
+}
+
+uint16_t get_cluster(uint16_t n) {
+ uint32_t t = *(uint32_t *)(FAT + (n / 2) * 3);
+ return (n % 2 ? (t >> 12) : t) & 0xfff;
+}
+
+void set_cluster(uint16_t n, uint16_t v) {
+ uint32_t *t = (uint32_t *)(FAT + (n / 2) * 3);
+ *t = (*t & (n % 2 ? 0xff000fff : 0xfffff000)) | (n % 2 ? v << 12 : v);
+}
+
+uint16_t get_start_cluster(uint8_t *path) {
+ panic("Not implemented (get_start_cluster).");
+} \ No newline at end of file
diff --git a/src/kernel/fat.h b/src/kernel/fat.h
index e7aa956..0fbf59f 100644
--- a/src/kernel/fat.h
+++ b/src/kernel/fat.h
@@ -4,12 +4,12 @@
struct fat_info {
uint8_t oem[8];
- uint16_t bytes_per_sector;
- uint8_t sectors_per_cluster;
+ uint16_t bytes_per_sector;//Assumed to be 512
+ uint8_t sectors_per_cluster;//Assumed to be 1
uint16_t reserved_sectors;
- uint8_t fats;
+ uint8_t fats;//Assumed to be 1
uint16_t root_entries;
- uint16_t sectors;
+ uint16_t sectors;//Assumed not to be 0
uint8_t media_type;
uint16_t sectors_per_fat;
uint16_t sectors_per_track;
@@ -22,4 +22,11 @@ struct fat_info {
uint32_t volume_id;
uint8_t label[11];
uint8_t fs_type[8];
-} __attribute__ ((packed)); \ No newline at end of file
+} __attribute__ ((packed));
+
+#define FAT ((void *)0x00026000)
+void load_fat();
+uint16_t get_cluster(uint16_t n);
+void set_cluster(uint16_t n, uint16_t v);
+
+uint16_t get_start_cluster(uint8_t *path); \ No newline at end of file
diff --git a/src/kernel/fs.c b/src/kernel/fs.c
new file mode 100644
index 0000000..129e631
--- /dev/null
+++ b/src/kernel/fs.c
@@ -0,0 +1,82 @@
+#include <stdint.h>
+#include "fs.h"
+#include "ata.h"
+#include "fat.h"
+#include <stdbool.h>
+#include "panic.h"
+
+#define MAX_HANDLES 32
+#define FILE_BUFFER(h) ((void *)(0x0002be00 + (h << 9)))
+#define HANDLE(h) ((handles - 1)[h])
+#define HEAD(h) (FILE_BUFFER(h) + HANDLE(h).seek % 512)
+
+struct handle_info {
+ uint16_t start_cluster;
+ uint16_t seek;
+ uint16_t loaded_cluster;
+ bool dirty;
+};
+
+struct handle_info handles[MAX_HANDLES];
+
+void clear_fs_handles() {
+ struct handle_info *f = handles;
+ while (f < handles + MAX_HANDLES)
+ (f++)->start_cluster = 0;
+}
+
+fs_handle next_handle() {
+ fs_handle r = 0;
+ while (HANDLE(++r).start_cluster)
+ if (r == MAX_HANDLES)
+ return 0;
+ return r;
+}
+
+void write_buffer(fs_handle handle) {
+ HANDLE(handle).dirty = false;
+ panic("Not implemented (write_buffer).");
+}
+
+void read_buffer(fs_handle handle) {
+ if (HANDLE(handle).dirty)
+ write_buffer(handle);
+ HANDLE(handle).loaded_cluster = HANDLE(handle).seek >> 9;
+ panic("Not implemented (read_buffer).");
+}
+
+fs_handle fs_open(uint8_t *path) {
+ fs_handle next = next_handle();
+ if (!next)
+ return 0;
+ uint16_t s = get_start_cluster(path);
+ if (!s)
+ return 0;
+ HANDLE(next).start_cluster = s;
+ HANDLE(next).seek = 0;
+ HANDLE(next).dirty = false;
+ read_buffer(next);
+ return next;
+}
+
+int16_t fs_seek(fs_handle handle, int16_t by) {
+ uint16_t old = HANDLE(handle).seek;
+ uint16_t to = -by > old ? 0 : old + by;
+ HANDLE(handle).seek = to;
+ if ((to ^ old) & 0xfe00)
+ read_buffer(handle);
+}
+
+uint16_t fs_read(fs_handle handle, uint16_t max, void *buffer) {
+ panic("Not implemented (fs_read).");
+}
+
+uint16_t fs_write(fs_handle handle, uint16_t max, void *buffer) {
+ panic("Not implemented (fs_write).");
+}
+
+void fs_close(fs_handle handle) {
+ if (HANDLE(handle).dirty)
+ write_buffer(handle);
+ HANDLE(handle).start_cluster = 0;
+} \ No newline at end of file
diff --git a/src/kernel/fs.h b/src/kernel/fs.h
new file mode 100644
index 0000000..821d810
--- /dev/null
+++ b/src/kernel/fs.h
@@ -0,0 +1,10 @@
+#include <stdint.h>
+
+void clear_fs_handles();
+
+typedef uint8_t fs_handle;
+fs_handle fs_open(uint8_t *path);
+int16_t fs_seek(fs_handle handle, int16_t by);
+uint16_t fs_read(fs_handle handle, uint16_t max, void *buffer);
+uint16_t fs_write(fs_handle handle, uint16_t max, void *buffer);
+void fs_close(fs_handle handle); \ No newline at end of file
diff --git a/src/kernel/link.ld b/src/kernel/link.ld
index 1fcff40..1fc64fd 100644
--- a/src/kernel/link.ld
+++ b/src/kernel/link.ld
@@ -1,4 +1,4 @@
-OUTPUT_FORMAT(binary)
+OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386)
SECTIONS {
@@ -10,6 +10,8 @@ SECTIONS {
*(.text)
*(.rodata)
*(.data)
+ }
+ /DISCARD/ : {
*(.bss)
}
} \ No newline at end of file
diff --git a/src/kernel/main.c b/src/kernel/main.c
index dbeb11b..877a276 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -1,14 +1,36 @@
#include <stdint.h>
#include "vga.h"
#include "fat.h"
+#include "fs.h"
+#include "ata.h"
+#include "panic.h"
+#include "serial.h"
+#include "util.h"
+
+uint8_t nbuf[11];
void main() {
vga_blank();
- vga_printsz("In kernel-land\n\nDisk label: ");
+ vga_printsz("Initializing drivers...");
+ sinit();
+ vga_printsz("\n Serial ready.");
+ load_fat();
+ clear_fs_handles();
+ vga_printsz("\n File system ready.\n\nDisk label: ");
vga_printsn(FAT_INFO->label, 11);
vga_printsz("\nDisk size: ");
- vga_printu32((FAT_INFO->sectors * FAT_INFO->bytes_per_sector) >> 10);
- vga_printsz("k\n\nHalting...");
+ u32_dec(FAT_INFO->sectors >> 1, nbuf);
+ vga_printsz(nbuf);
+ vga_printsz("k\n\nFAT start:\n");
+ nbuf[3] = 0;
+ for (uint8_t r = 0; r < 192; r += 24) {
+ for (uint8_t c = 0; c < 24; ++c) {
+ u8_hex(*(uint8_t *)(FAT + r + c), nbuf);
+ nbuf[2] = ' ';
+ vga_printsz(nbuf);
+ }
+ vga_printch('\n');
+ }
while (1)
asm ("hlt");
} \ No newline at end of file
diff --git a/src/kernel/panic.c b/src/kernel/panic.c
new file mode 100644
index 0000000..49d4a27
--- /dev/null
+++ b/src/kernel/panic.c
@@ -0,0 +1,31 @@
+#include <stdint.h>
+#include "vga.h"
+#include "serial.h"
+#include "util.h"
+
+void halt() {
+ while (1)
+ asm volatile ("hlt");
+}
+
+void panic(uint8_t *message) {
+ uint32_t frame;
+ asm (
+ "movl %%ebp, %0"
+ : "=r" (frame));
+ vga_set_color(0x4f);
+ vga_blank();
+ vga_printsz("Kernel panic: ");
+ vga_printsz(message);
+ vga_printsz("\n\nStack trace:");
+ uint8_t stb[6];
+ while (1) {
+ uint32_t ip = *(uint32_t *)(0x38000 + frame + 4);
+ if (!ip)
+ halt();
+ vga_printsz("\n 0x");
+ u16_hex(ip - 0x30000 - 5, stb);//assumes would return to just after a call instruction
+ vga_printsz(stb);
+ frame = *(uint32_t *)(0x38000 + frame);
+ }
+} \ No newline at end of file
diff --git a/src/kernel/panic.h b/src/kernel/panic.h
new file mode 100644
index 0000000..8972814
--- /dev/null
+++ b/src/kernel/panic.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+
+void panic(uint8_t *message) __attribute__ ((noreturn));
+void halt() __attribute__ ((noreturn)); \ No newline at end of file
diff --git a/src/kernel/serial.c b/src/kernel/serial.c
new file mode 100644
index 0000000..b88c7ec
--- /dev/null
+++ b/src/kernel/serial.c
@@ -0,0 +1,100 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include "util.h"
+
+enum {
+ CP_DATA = 0x0,
+ CP_INT = 0x1,
+ CP_FIFO = 0x2,
+ CP_LINE = 0x3,
+ CP_MODEM = 0x4,
+ CP_LINE_S = 0x5,
+ CP_MODEM_S = 0x6,
+
+ CP_DIVLOW = 0x0,
+ CP_DIVHIGH = 0x1,
+
+ CP_1 = 0x03f8,
+ CP_2 = 0x02f8,
+ CP_3 = 0x03e8,
+ CP_4 = 0x02e8
+};
+
+enum {
+ CL_BAUD = 0x80,
+
+ CL_PODD = 0x08,
+ CL_PEVEN = 0x0c,
+ CL_PON = 0x18,
+ CL_POFF = 0x1c,
+
+ CL_LSTOP = 0x4,
+
+ CL_5BIT = 0x0,
+ CL_6BIT = 0x1,
+ CL_7BIT = 0x2,
+ CL_8BIT = 0x3
+};
+
+enum {
+ CLS_B_ERR = 0x80,
+ CLS_IDLE = 0x40,
+ CLS_WRITE = 0x20,
+ CLS_BREAK = 0x10,
+ CLS_FRAME = 0x08,
+ CLS_PAR = 0x04,
+ CLS_OVER = 0x02,
+ CLS_READ = 0x01
+};
+
+bool error;
+#define SERIAL_SPIN_LIMIT 65535
+
+bool serr() {
+ return error;
+}
+
+void sinit() {
+ error = false;
+ outb(CP_1 | CP_INT, 0);
+ outb(CP_1 | CP_LINE, CL_BAUD);
+ outb(CP_1 | CP_DIVLOW, 0x03);//38400
+ outb(CP_1 | CP_DIVHIGH, 0x00);//baud
+ outb(CP_1 | CP_LINE, CL_8BIT);
+ outb(CP_1 | CP_FIFO, 0xc7);//?
+}
+
+void sout(uint8_t b) {
+ if (error)
+ return;
+ uint16_t s = SERIAL_SPIN_LIMIT;
+ while (!(inb(CP_1 | CP_LINE_S) & CLS_WRITE))
+ if (!--s) {
+ error = true;
+ return;
+ }
+ outb(CP_1 | CP_DATA, b);
+}
+
+void soutsz(uint8_t *s) {
+ while (*s)
+ sout(*(s++));
+}
+
+void soutsn(uint8_t *s, uint8_t n) {
+ while (n--)
+ sout(*(s++));
+}
+
+uint8_t sin() {
+ if (error)
+ return 0;
+ while (!(inb(CP_1 | CP_LINE_S) & CLS_READ))
+ ;//spin
+ return inb(CP_1 | CP_DATA);
+}
+
+void sinsn(uint8_t *s, uint8_t n) {
+ while (n--)
+ *(s++) = sin();
+} \ No newline at end of file
diff --git a/src/kernel/serial.h b/src/kernel/serial.h
new file mode 100644
index 0000000..f0465d0
--- /dev/null
+++ b/src/kernel/serial.h
@@ -0,0 +1,10 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+bool serr();
+void sinit();
+void sout(uint8_t b);
+void soutsz(uint8_t *s);
+void soutsn(uint8_t *s, uint8_t n);
+uint8_t sin();
+void sinsn(uint8_t *s, uint8_t n); \ No newline at end of file
diff --git a/src/kernel/util.asm b/src/kernel/util.asm
new file mode 100644
index 0000000..acac17f
--- /dev/null
+++ b/src/kernel/util.asm
@@ -0,0 +1,37 @@
+bits 32
+
+global outb
+global inb
+global outw
+global inw
+
+section .text
+outb:
+ ;word [esp + 4] = port
+ ;byte [esp + 8] = value
+ mov dx, word [esp + 4]
+ mov al, byte [esp + 8]
+ out dx, al
+ ret
+
+inb:
+ ;word [esp + 4] = port
+ ;al out = value
+ mov dx, word [esp + 4]
+ in al, dx
+ ret
+
+outw:
+ ;word [esp + 4] = port
+ ;word [esp + 8] = value
+ mov dx, word [esp + 4]
+ mov ax, word [esp + 8]
+ out dx, ax
+ ret
+
+inw:
+ ;word [esp + 4] = port
+ ;ax out = value
+ mov dx, word [esp + 4]
+ in ax, dx
+ ret \ No newline at end of file
diff --git a/src/kernel/util.c b/src/kernel/util.c
new file mode 100644
index 0000000..df6e7d8
--- /dev/null
+++ b/src/kernel/util.c
@@ -0,0 +1,100 @@
+#include <stdint.h>
+#include "panic.h"
+#include <stdbool.h>
+
+void memcpy(void *from, void *to, uint32_t n) {
+ panic("Not implemented (memcpy).");
+}
+
+void u32_dec(uint32_t n, uint8_t *b) {
+ if (!n) {
+ *(uint16_t *)b = '0';
+ return;
+ }
+ bool zero = false;
+ for (uint32_t m = 1000000000; m; m /= 10) {
+ uint8_t d = (n / m) % 10;
+ if (zero)
+ *(b++) = d + '0';
+ else if (d) {
+ zero = true;
+ *(b++) = d + '0';
+ }
+ }
+ *b = 0;
+}
+
+void u16_dec(uint16_t n, uint8_t *b) {
+ if (!n) {
+ *(uint16_t *)b = '0';
+ return;
+ }
+ bool zero = false;
+ for (uint32_t m = 10000; m; m /= 10) {
+ uint8_t d = (n / m) % 10;
+ if (zero)
+ *(b++) = d + '0';
+ else if (d) {
+ zero = true;
+ *(b++) = d + '0';
+ }
+ }
+ *b = 0;
+}
+
+void u8_dec(uint8_t n, uint8_t *b) {
+ if (!n) {
+ *(uint16_t *)b = '0';
+ return;
+ }
+ bool zero = false;
+ for (uint32_t m = 100; m; m /= 10) {
+ uint8_t d = (n / m) % 10;
+ if (zero)
+ *(b++) = d + '0';
+ else if (d) {
+ zero = true;
+ *(b++) = d + '0';
+ }
+ }
+ *b = 0;
+}
+
+void u32_hex(uint32_t n, uint8_t *b) {
+ uint8_t m = 28;
+ while (1) {
+ uint8_t d = (n >> m) & 0xf;
+ *(b++) = d >= 10 ? 'a' + d - 10 : '0' + d;
+ if (!m) {
+ *b = 0;
+ return;
+ }
+ m -= 4;
+ }
+}
+
+void u16_hex(uint16_t n, uint8_t *b) {
+ uint8_t m = 12;
+ while (1) {
+ uint8_t d = (n >> m) & 0xf;
+ *(b++) = d >= 10 ? 'a' + d - 10 : '0' + d;
+ if (!m) {
+ *b = 0;
+ return;
+ }
+ m -= 4;
+ }
+}
+
+void u8_hex(uint8_t n, uint8_t *b) {
+ uint8_t m = 4;
+ while (1) {
+ uint8_t d = (n >> m) & 0xf;
+ *(b++) = d >= 10 ? 'a' + d - 10 : '0' + d;
+ if (!m) {
+ *b = 0;
+ return;
+ }
+ m -= 4;
+ }
+} \ No newline at end of file
diff --git a/src/kernel/util.h b/src/kernel/util.h
new file mode 100644
index 0000000..08b3e4a
--- /dev/null
+++ b/src/kernel/util.h
@@ -0,0 +1,13 @@
+#include <stdint.h>
+
+void memcpy(void *from, void *to, uint32_t n);
+void outb(uint16_t port, uint8_t value);
+uint8_t inb(uint16_t port);
+void outw(uint16_t port, uint16_t value);
+uint16_t inw(uint16_t port);
+void u32_dec(uint32_t n, uint8_t *b);
+void u16_dec(uint16_t n, uint8_t *b);
+void u8_dec(uint8_t n, uint8_t *b);
+void u32_hex(uint32_t n, uint8_t *b);
+void u16_hex(uint16_t n, uint8_t *b);
+void u8_hex(uint8_t n, uint8_t *b); \ No newline at end of file
diff --git a/src/kernel/vga.c b/src/kernel/vga.c
index 8e438a8..c387b22 100644
--- a/src/kernel/vga.c
+++ b/src/kernel/vga.c
@@ -1,6 +1,12 @@
#include <stdint.h>
#include <stdbool.h>
+#define VGA_COM_MIRROR
+
+#ifdef VGA_COM_MIRROR
+#include "serial.h"
+#endif
+
#define VGA_COLUMNS 80
#define VGA_LINES 25
#define VGA_START (uint16_t *)0x000b8000
@@ -8,11 +14,18 @@
uint16_t *cursor = VGA_START;
uint16_t color = 0x1f00;
+void vga_set_color(uint8_t new_color) {
+ color = new_color << 8;
+}
+
void vga_scroll() {
cursor = VGA_START;
}
void vga_blank() {
+#ifdef VGA_COM_MIRROR
+ soutsz("\r\n\r\n<CLEAR>\r\n\r\n");
+#endif
uint32_t f = (color << 16) | color | 0x00200020;
uint32_t *p = (uint32_t *)VGA_START;
while (p < (uint32_t *)VGA_END)
@@ -22,10 +35,16 @@ void vga_blank() {
void vga_printch(uint8_t ch) {
if (ch == '\n') {
+#ifdef VGA_COM_MIRROR
+ soutsz("\r\n");
+#endif
if ((cursor = cursor - (cursor - VGA_START) % VGA_COLUMNS + VGA_COLUMNS) == VGA_END)
vga_scroll();
return;
}
+#ifdef VGA_COM_MIRROR
+ sout(ch);
+#endif
*(cursor++) = color | ch;
if (cursor == VGA_END)
vga_scroll();
@@ -39,43 +58,4 @@ void vga_printsz(uint8_t *sz) {
void vga_printsn(uint8_t *sn, uint8_t n) {
while (n--)
vga_printch(*(sn++));
-}
-
-void vga_printu32(uint32_t n) {
- bool zero = false;
- for (uint32_t m = 1000000000; m; m /= 10) {
- uint8_t d = (n / m) % 10;
- if (zero)
- vga_printch(d + '0');
- else if (d) {
- zero = true;
- vga_printch(d + '0');
- }
- }
-}
-
-void vga_printu16(uint16_t n) {
- bool zero = false;
- for (uint16_t m = 10000; m; m /= 10) {
- uint8_t d = (n / m) % 10;
- if (zero)
- vga_printch(d + '0');
- else if (d) {
- zero = true;
- vga_printch(d + '0');
- }
- }
-}
-
-void vga_printu8(uint8_t n) {
- bool zero = false;
- for (uint8_t m = 100; m; m /= 10) {
- uint8_t d = (n / m) % 10;
- if (zero)
- vga_printch(d + '0');
- else if (d) {
- zero = true;
- vga_printch(d + '0');
- }
- }
} \ No newline at end of file
diff --git a/src/kernel/vga.h b/src/kernel/vga.h
index 95c6335..1e041df 100644
--- a/src/kernel/vga.h
+++ b/src/kernel/vga.h
@@ -1,10 +1,8 @@
#include <stdint.h>
+void vga_set_color(uint8_t color);
void vga_blank();
void vga_scroll();
void vga_printch(uint8_t ch);
void vga_printsz(uint8_t *sz);
-void vga_printsn(uint8_t *sn, uint8_t n);
-void vga_printu32(uint32_t n);
-void vga_printu16(uint16_t n);
-void vga_printu8(uint8_t n); \ No newline at end of file
+void vga_printsn(uint8_t *sn, uint8_t n); \ No newline at end of file
diff --git a/src/kernel/vga.inc b/src/kernel/vga.inc
new file mode 100644
index 0000000..c7244e1
--- /dev/null
+++ b/src/kernel/vga.inc
@@ -0,0 +1,11 @@
+extern vga_set_color
+extern vga_blank
+extern vga_scroll
+extern vga_printch
+extern vga_printsz
+extern vga_printsn
+extern vga_printu32
+extern vga_printu16
+extern vga_printu8
+extern vga_printu32h
+extern vga_printu8h \ No newline at end of file