summaryrefslogtreecommitdiff
path: root/kernel.cc
diff options
context:
space:
mode:
authorRichard Qin <richard.qin.x@gmail.com>2025-12-08 22:25:48 +0800
committerRichard Qin <richard.qin.x@gmail.com>2025-12-08 22:25:48 +0800
commit8cf8be522133548ee25fdcb0258ddf3950a68bcf (patch)
tree17d97abd848638d44de41e202d891dcaf4bb68c0 /kernel.cc
downloadlume-8cf8be522133548ee25fdcb0258ddf3950a68bcf.tar.gz
lume-8cf8be522133548ee25fdcb0258ddf3950a68bcf.tar.xz
The start of the project -- A MicroDOS
feat: Initial bare-metal RISC-V boot with UART
Diffstat (limited to 'kernel.cc')
-rw-r--r--kernel.cc69
1 files changed, 69 insertions, 0 deletions
diff --git a/kernel.cc b/kernel.cc
new file mode 100644
index 0000000..f9cacba
--- /dev/null
+++ b/kernel.cc
@@ -0,0 +1,69 @@
+extern "C" void kernel_main();
+
+#define UART_ADDR 0x10000000UL
+
+#define THR_OFFSET 0x0
+#define LSR_OFFSET 0x5
+#define FCR_OFFSET 0x2
+#define LCR_OFFSET 0x3
+#define DLL_OFFSET 0x0
+#define DLH_OFFSET 0x1
+
+static void
+write_byte(unsigned long addr, char byte)
+{
+ *((volatile char *)addr) = byte;
+}
+
+static int
+is_tx_empty()
+{
+ return *((volatile char *)(UART_ADDR + LSR_OFFSET)) & (1 << 5);
+}
+
+void uart_init()
+{
+ write_byte(UART_ADDR + LCR_OFFSET, 0x80);
+
+ write_byte(UART_ADDR + DLL_OFFSET, 0x01);
+ write_byte(UART_ADDR + DLH_OFFSET, 0x00);
+
+ write_byte(UART_ADDR + LCR_OFFSET, 0x03);
+
+ write_byte(UART_ADDR + FCR_OFFSET, 0x07);
+}
+
+void put_char(char c)
+{
+ if (c == '\n')
+ {
+ put_char('\r');
+ }
+
+ while (!is_tx_empty())
+ {
+ }
+ write_byte(UART_ADDR + THR_OFFSET, c);
+}
+
+void print_str(const char *s)
+{
+ while (*s != '\0')
+ {
+ put_char(*s++);
+ }
+}
+
+void kernel_main()
+{
+ uart_init();
+
+ print_str("Modern DOS 1.0\n");
+ print_str("Hello OS! Running on RISC-V 64.\n");
+ print_str("Hello Ziyi Yang! Love from RUC");
+
+ while (1)
+ {
+
+ }
+} \ No newline at end of file