From e963f0f87166ded889f5d0649b4c80c00a34e67c Mon Sep 17 00:00:00 2001 From: rami Date: Thu, 27 Jun 2024 18:36:32 -0400 Subject: [PATCH] multiboot info, serial ports, logs --- .../index/kernel.c.77F67860B909D538.idx | Bin 0 -> 758 bytes .../index/kernel.h.2BB7B327DAB1C098.idx | Bin 0 -> 450 bytes .../index/multiboot.h.569D3E05B34DD4E9.idx | Bin 0 -> 2444 bytes .../index/serial.h.C96BAE791DAC37AC.idx | Bin 0 -> 680 bytes Makefile | 10 ++-- compile_commands.json | 20 ++++++++ include/kernel/io.h | 9 ++++ include/kernel/kernel.h | 15 ++++++ include/kernel/log.h | 13 ++++++ include/kernel/multiboot.h | 17 +++++++ include/kernel/serial.h | 21 +++++++++ kernel/io.c | 17 +++++++ kernel/kernel.c | 15 ++++-- kernel/log.c | 15 ++++++ kernel/serial.c | 44 ++++++++++++++++++ 15 files changed, 189 insertions(+), 7 deletions(-) create mode 100644 .cache/clangd/index/kernel.c.77F67860B909D538.idx create mode 100644 .cache/clangd/index/kernel.h.2BB7B327DAB1C098.idx create mode 100644 .cache/clangd/index/multiboot.h.569D3E05B34DD4E9.idx create mode 100644 .cache/clangd/index/serial.h.C96BAE791DAC37AC.idx create mode 100644 compile_commands.json create mode 100644 include/kernel/io.h create mode 100644 include/kernel/kernel.h create mode 100644 include/kernel/log.h create mode 100644 include/kernel/serial.h create mode 100644 kernel/io.c create mode 100644 kernel/log.c create mode 100644 kernel/serial.c diff --git a/.cache/clangd/index/kernel.c.77F67860B909D538.idx b/.cache/clangd/index/kernel.c.77F67860B909D538.idx new file mode 100644 index 0000000000000000000000000000000000000000..778b63eeaf008ce050ca7dc7348a75667fb2ca62 GIT binary patch literal 758 zcmWIYbaQ*h#K7R3;#rZKT9U}Zz`!5`#Kk2=ncIN$3`PcqiaEXgv0O}sJT1iwC29f% zZ5q@+?3|re-h5N+QkaJ9#9u$spu|_#?mACQ`irY6-d|d?lClHs{CfUBTb>rWd(P|s9)j0D ztbX))HamYgv!2`fp3}vZxk+|F*T*MIgz zA~0UbiRCPLHFCv3>v&jr_+ci+e6QaUFu`WYA_IBEf(?4y<<0> z({P>24*5>$0RQz0-@*<{-`io=b?W4;Z+Y8qP2#<`d#OMb!--QIrbUf1`YIZeR-EO~ z4y%0DZTSChv9k8$RkkNrJ8e>)k^JO9;cp3!qj#sxFrUOwT$!5`547um+YZJW*DeEY z2B1rrxR|*3zyt#)P>z9tk%=|w?P4!SCXb1H3~Y=HOq@KN;$VV-1FV4Iqt~Q95X}q>Fw=p;AfsWzFjIlTAR}SIrHQ%9 z8E3oK0EJmOSOsCiQVSGnk1WyL4HRbNV1ygOwdTWFn_2&!G4e2RGIMgntXj$I<5BaQ s>gPB7TW);w-If)<>i;I$r!DcWm5t_3!WN9`xBQpat%q|8709dwiN&o-= literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/multiboot.h.569D3E05B34DD4E9.idx b/.cache/clangd/index/multiboot.h.569D3E05B34DD4E9.idx new file mode 100644 index 0000000000000000000000000000000000000000..2be98b50b7f1c19ec402180c8ac93714a635899b GIT binary patch literal 2444 zcmYL}dr(wW9LLYH$7MPDI|p`Qmt7wF;3Z(bg2KXPG6lqOjBH3PCqo6)#4#2X6~_!Q zaU=^P%`nZdK}6KR2hOOCk2DPdA5&V*_=lnb_HdGhA+q1S_0yf%?=qk7IhT9SIiEW< zJ2P`_5M$%#W|tP_m*jEAm<_-FlH&OW17o-FTUuL`b8*obFWh={#ln#pFXUcmpTObZ zg5LF64ZS~%jJsYkt-JEmyk1w%Z|f?KBtCQUc6GyW&*_~T{qt)_e;*jrpIcCQb~0aJ zOH!}3>})(U??-F#x!%!HjxCETe$MjU*=${$*!*DPsCoMeD|c?LtS|H%FQ5OU!8mBF zjI62=eRb_8KialAp|&Od^tjclW~H=_x%EqS!rW`sAN(5qXSa2Bx_3!P+k?AH4m3}T zT{7cX*39^$W7C_bw$|^xvc5OJ%yFZou4rM;o3}@>EiHq?4sW_tYOFc3HTSwBr|0U| zH)?V=-EDaRs?!{oK5wrseRL{i?WH#gOKS(VrFVoM+RpsTi)L3E8SA?}Ph@q^vMA;? zFyWAnFg=(VR|`Kk6Q@*cxSt-aSQOS_GAvRLs?T*kj9t^}c3YU8F%c0EVbg=*(&NV< zhV02rZnk86lcZQE&Ibt*deHn6QLnFXOv)Ign9Iq8Te_`!Q2j;6hxrrtAIMb9h_y$0 z?0QiB+{cY|tJ?0pte6`w?v&0bJ*c*JuIbw~Fya-(qOo>Kmq!n(d#3LnR##q;tC$Dt za2Xz@2i4=;o-qOJ_%y{#SPLnfdQhD^FzMZtqsQM-%!jpI+MRk(J+_a3HBc5)qF6B2 zfilpp2h}tGTHP`=t8=MhR;-m&Et(y9m5n;OlT9sc{f6br-JA}vlmsBTNW+GTD(|D|F>unv+z;d)SgW8Z~)sbx+3 z6fWwdTGa*J5>z_6br)HAu`0J2i4n~LbmSq zzJFG+NSvK06Rmnsy{>B1&E>w1izXJ1XEiD?DpHRpXSKWJ+?{1RnmQE=!1-S3b?8C! zkA1h{v%P$U*NCD7gcI!*`t(I>r4hAhMI?ZbdxYhRK%L4gh^1unw^A6OvIX%gh@xl znu~-=r=(8r_TSwK_mw!$C3b~5zf^d zqB&Ep8+WfP<5v+I%!bFeOI9J)l%g9DjlZ{z-S$sc1PBv10c{3|KpqIRzaY%q474L4 zf_MD+$8Ntw6f~ z!p3bt#{fhq4+SzFL>LbPG8KfK+kuWQ2nTln$qgc$hXW}C!pWULx`A+U7m#Hj+}sT$ zE(j0z0Qm~S%e_GR0K&(8K*s_^437ai^B@v=BG7Kr4&q*D?=RX5dJM$cTZ?dU{=z)% cZ-4O|zkVpi(?3;P&L4Vqk-@?&G>Wl*0hiQU#{d8T literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/serial.h.C96BAE791DAC37AC.idx b/.cache/clangd/index/serial.h.C96BAE791DAC37AC.idx new file mode 100644 index 0000000000000000000000000000000000000000..8fed3a5321a66cb9d8dd51e019f349329b1d5f6f GIT binary patch literal 680 zcmWIYbaPw4#K7R3;#rZKT9U}Zz`!5`#Kk2=nJa;`5hDXb#hlh&N3KH#0@3)@3)U%6P~>I#O6J%C;Gi=UPY}tHuum2 zVec(gr+gp%n16_~@^<&uY4PjpDkC^UjvF;wOg83X$a%r*a#uK_)|~Ie;?r{*S9k6^ zk)o8jeXH^OU>0|Ehvk1+XZ@A&xHI*f(>|rQA@?S!&*Pt2xKVu~cYQ`APovdG7Hj$R zLkz{0xk<@D7nht^&XQLnSIon}1LT1Kry#4K00So*GXp;dBPZ*E;_P2ew3D_pp-Na*V9)J>5~?R{%cWiemT$(P7Y4EAuwG))!-#*}r9XhGIXF1rs*6%{5 + +uint8_t inb(uint16_t port); +void outb(uint16_t port, uint8_t byte); + +#endif diff --git a/include/kernel/kernel.h b/include/kernel/kernel.h new file mode 100644 index 0000000..77d2237 --- /dev/null +++ b/include/kernel/kernel.h @@ -0,0 +1,15 @@ +#ifndef HAZEL_KERNEL_H_ +#define HAZEL_KERNEL_H_ + +#include +#include + +#define cpu_relax asm volatile ("pause" ::) + +typedef struct { + multiboot_memory_map_t *mem_map; + uint32_t mem_map_len; + log_method_t log_method; +} kernel_ctx_t; + +#endif diff --git a/include/kernel/log.h b/include/kernel/log.h new file mode 100644 index 0000000..de05ef8 --- /dev/null +++ b/include/kernel/log.h @@ -0,0 +1,13 @@ +#ifndef HAZEL_LOG_H_ +#define HAZEL_LOG_H_ + +typedef enum { + LOG_COM1, + LOG_VGA, +} log_method_t; + +#define LOG(x) logs(x); + +void logs(const char *str); + +#endif diff --git a/include/kernel/multiboot.h b/include/kernel/multiboot.h index d14b7d2..5ebf77e 100644 --- a/include/kernel/multiboot.h +++ b/include/kernel/multiboot.h @@ -26,4 +26,21 @@ typedef struct { uint32_t vbeinterfacelength; } multiboot_info_t; +struct multiboot_mmap_entry +{ + uint32_t size; + uint32_t addr_low; + uint32_t addr_high; + uint32_t len_low; + uint32_t len_high; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + + #endif diff --git a/include/kernel/serial.h b/include/kernel/serial.h new file mode 100644 index 0000000..113142b --- /dev/null +++ b/include/kernel/serial.h @@ -0,0 +1,21 @@ +#ifndef HAZEL_SERIAL_H_ +#define HAZEL_SERIAL_H_ + +#include + +#define COM1 0x3F8 +#define COM2 0x2F8 +#define COM3 0x3E8 +#define COM4 0x2E8 +#define COM5 0x5F8 +#define COM6 0x4F8 +#define COM7 0x5E8 +#define COM8 0x4E8 + +#define IS_TRANSMIT_EMPTY(x) (inb(x + 5) & 0x20) + +uint8_t serial_port_init(int port); +void serial_putc(int port, const char c); +void serial_puts(int port, const char *str); + +#endif diff --git a/kernel/io.c b/kernel/io.c new file mode 100644 index 0000000..dcd1403 --- /dev/null +++ b/kernel/io.c @@ -0,0 +1,17 @@ +#include + +uint8_t inb(uint16_t port) { + uint8_t result; + + asm volatile ("in %%dx, %%al" + : "=a" (result) + : "d" (port)); + + return result; +} + +void outb(uint16_t port, uint8_t byte) { + asm volatile ("out %%al, %%dx" + : // no output + : "a" (byte), "d" (port)); +} diff --git a/kernel/kernel.c b/kernel/kernel.c index b9aaedb..363d192 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,10 +1,19 @@ +#include #include +#include + +kernel_ctx_t ctx = {0}; void kernel(multiboot_info_t *info) { - char *vmem = (char *)0xb8000; - vmem[0] = info->flags; - vmem[1] = 0x0f; + if (!(info->flags & (1<<6))) goto halt; + ctx.mem_map = (multiboot_memory_map_t *)info->memmapaddress; + ctx.mem_map_len = info->memmaplength; + if (serial_port_init(COM1)) + ctx.log_method = LOG_COM1; + + LOG("Kernel log being sent to COM1\n"); +halt: asm volatile ("cli" ::); for (;;) {} } diff --git a/kernel/log.c b/kernel/log.c new file mode 100644 index 0000000..cf53c8f --- /dev/null +++ b/kernel/log.c @@ -0,0 +1,15 @@ +#include +#include +#include + +extern kernel_ctx_t ctx; + +void logs(const char *str) { + switch (ctx.log_method) { + case LOG_COM1: + serial_puts(COM1, str); + break; + default: + break; + } +} diff --git a/kernel/serial.c b/kernel/serial.c new file mode 100644 index 0000000..2b50aef --- /dev/null +++ b/kernel/serial.c @@ -0,0 +1,44 @@ +#include +#include +#include + +uint8_t serial_port_init(int port) { + // Test port by seeing if scratch register can store a value + uint8_t old_scratch = inb(port + 7); + outb(port + 7, old_scratch + 1); + if (inb(port + 7) != old_scratch + 1) + return 0; + outb(port + 7, old_scratch); + + outb(port + 1, 0x00); // Disable all interrupts + outb(port + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + outb(port + 1, 0x00); // (hi byte) + outb(port + 3, 0x03); // 8 bits, no parity, one stop bit + outb(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + outb(port + 4, 0x0B); // IRQs enabled, RTS/DSR set + outb(port + 4, 0x1E); // Set in loopback mode, test the serial chip + outb(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) + + // Check if serial is faulty (i.e: not same byte as sent) + if(inb(port + 0) != 0xAE) + return 0; + + // If serial is not faulty set it in normal operation mode + // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) + outb(port + 4, 0x0F); + return 1; +} + +void serial_putc(int port, const char c) { + // Poll until transmit is empty + while(!IS_TRANSMIT_EMPTY(port)) cpu_relax; + outb(port, c); +} + +void serial_puts(int port, const char *str) { + while (*str) { + serial_putc(port, str[0]); + str++; + } +}