From 884d0f4c7d80af81e0db072060347ff11ff97912 Mon Sep 17 00:00:00 2001 From: rami Date: Mon, 20 May 2024 05:59:07 -0400 Subject: [PATCH] init --- .../clangd/index/acpi.h.DEF797BDB8217123.idx | Bin 0 -> 2086 bytes .../clangd/index/kmain.c.9B04FE5F8A3537CE.idx | Bin 0 -> 1464 bytes .../index/multiboot.h.DC0E53CEA67FC33F.idx | Bin 0 -> 1768 bytes Makefile | 49 +++++++++++ acpi.c | 39 +++++++++ acpi.h | 45 ++++++++++ build/acpi.o | Bin 0 -> 1000 bytes build/io.o | Bin 0 -> 624 bytes build/kernel.bin | Bin 0 -> 9300 bytes build/kmain.o | Bin 0 -> 1364 bytes build/multiboot.o | Bin 0 -> 1024 bytes compile_commands.json | 7 ++ io.c | 17 ++++ io.h | 9 ++ kernel.ld | 28 ++++++ kmain.c | 81 ++++++++++++++++++ multiboot.asm | 71 +++++++++++++++ multiboot.h | 31 +++++++ 18 files changed, 377 insertions(+) create mode 100644 .cache/clangd/index/acpi.h.DEF797BDB8217123.idx create mode 100644 .cache/clangd/index/kmain.c.9B04FE5F8A3537CE.idx create mode 100644 .cache/clangd/index/multiboot.h.DC0E53CEA67FC33F.idx create mode 100644 Makefile create mode 100644 acpi.c create mode 100644 acpi.h create mode 100644 build/acpi.o create mode 100644 build/io.o create mode 100755 build/kernel.bin create mode 100644 build/kmain.o create mode 100644 build/multiboot.o create mode 100644 compile_commands.json create mode 100644 io.c create mode 100644 io.h create mode 100644 kernel.ld create mode 100644 kmain.c create mode 100644 multiboot.asm create mode 100644 multiboot.h diff --git a/.cache/clangd/index/acpi.h.DEF797BDB8217123.idx b/.cache/clangd/index/acpi.h.DEF797BDB8217123.idx new file mode 100644 index 0000000000000000000000000000000000000000..db9abac5ee252c43aa87b3bd45b14553639aaeac GIT binary patch literal 2086 zcmYL}3rtgI6vw}owzv1*kK6WAO6do!yet%PA#*e8lIZ}EqMP`_$B>8*h61vJL$~-C zpiISV>eS6JWx?mRsPnb4u!yg0W@sjaI7f(r@qvlroSTZ7?%azC!^EYYXZOYbxZo_(L3|C#ph zsjn6pyZbDs^SzCQ$wikU{yKHIV`}B~hCLS^zm~tnH21^(-`7ptbgN+Y^VS{5Is{+! zG}_Z-SzWZ@)&u*^g0V3VR?K|#_Tedlr|I_@3&kJ)*}%@!e}3uBweE>?8bgjhJlk_H z;2FKRYl1&9k(NX4g(v znloR&%mPF-jKG`vJ^0wPQRb@^e)98F<^4_Ig%bKR$7*{mv&ZO;I z?|+f9{BlP?VY!X=xBfViIc{;E;a<8U`s$b~>FS9&a$fSO@Eaq$n-8(-*rV_7YR{H? z*R?p39+QZt#ci2WC@HuC^Xj~&`a^x)I)y~X5f&E_=j1|Q z%-U1+Y}cw^hu0WPWC$Tl5fqsV5xG~#jN>MGOEb@=CM!gWAfVIm z3ZWul9@*pKg6x^8E>$ zd^1fX7UE-tSeeVq_$|hp zUZ)TR;+eoG7mP1@y{&&~Zss;h>=^HJ_!5XHgphbA#8-9|ZvUVlxj`Woh>w<|9b7P; z7;ksZ=ob$t#0KM0scPqf?(E;3;oWIv2jOxc+9kPEF6iFTMy_w&zw#s{5m-IRkmM$! zQ8&>2`V71Oo5H>(g{Y7|EHuo?1>@^_+~DdW1Gi1IDO}KfuKUH8PEYB1g~(9d zExYYp(495=D}PJ-qE>~3g4-!OZCub@DtuOzU3TQ2LOigT@p8PK3%XkapRPRrW7-RN zbBKE$}fbx+;5%4_Zk-l_c}xx*yrH;Q|1-C^5D|2L~mj;-f`i^D9rzWIn-X$Gt*)Ag{&_c7apSO9QwJ=JlocQZW{% zpc4m>2_CAS5y<-`{cs_q6wRUyTSbn*tU-jG51C+TJ8;Aq05dgHgoGegVAhzz)3r~| z^-jxqTw|cjYOu;UL&{WxD&wwG7O9UE@%|}u>0Kf&I^GrZ%sC8phZI6N4M8l2ZwjY5 zb-~lf9GupG!_!zF%o=DoODqj$4KO^t#+!KRVqw-H7_r%GM!E@QmN1J4hlZC14RG*+ zcEk=+YRq9J#0|_EYiLHyz^pNb4b-e1+w}4L#TUSAGMfh16{!QWh8&)jzI$--jh)YL znJ5c0gi-8(GN;}tVGL!_`e+HqLz!FemasZy9=%7x^`e&y+UQZv9#pMWS$|g!~V4pB!2M literal 0 HcmV?d00001 diff --git a/.cache/clangd/index/kmain.c.9B04FE5F8A3537CE.idx b/.cache/clangd/index/kmain.c.9B04FE5F8A3537CE.idx new file mode 100644 index 0000000000000000000000000000000000000000..0e86f2cb8f959506f35fb9f4fcf7b9e410dbf978 GIT binary patch literal 1464 zcmWIYbaUIl%D~{9;#rZKT9U}Zz`!5`#Kk2=nXiHLBt`~?iaEIf7qbo<@Lb{7T$Gcd zdZFD=;!AFRwNBsTB}$uQM5>>Bp59Wrc(H=t9a$?*MkR%`bmtT5>-tUEUNW8+WvsKB zDB2vkX|4WEnFZ``s<{)-`B`6MG+>OH5o{>GA=x@`W^YTh(9f=tiiOjru6niJ?0om- zMAOD~nruemGjsN&o46g1s=OgQJ-K$}{K8KfYf=w7a^KZkcCh-+HJN#JrZJ`&+}__O zPd@ORwQAZ0fxG%eb&p>Cy0KgK)rQ3rxVIOP=RHo1@~b!owg5l;&aK;RX{h>68onLaNs-%=j22 zfQGXRvWtQVnDm^erhP}SktV76lV9Y0eXGv@(S&{_!vf1EuBIKzfq;Q1OcgA6fkuMD7Up&yK{Z}A5t!p( zfy~SW4qSx2_B{4*dwB%i<=mBE=E4G=l?x@nfllSHo}YEZ$7wn~DroEnS&;1XcM}Wnk_F^0ZXV5j-0M8(Wx3Fs(oj zgW?hFjK|w(U!LygPmxtLhiPd42 z&fnk^pnFZ^OpIW{uHizFnlBFI0)^Ei)D&TQ-Mo$eyCwY32MX&6=_$ZeD|ql8y}l+m@to^y{^3ljOQ6O*XzLLv@<}xiqeX3 z$HPJp7@(jW0&^vgAQwBAC@dM|u}^67F4*uEs8`id)eGivuUDaJmyytI_hWl<0 zEUn*nN7)yH@4a2vaiyiVtgg9#=bjzs>#P5m-IAAB-Zxga@vDQ4z1{xR-Lvub-%9>| zEfC)`UKg)@%e`pqm~AMZ4Ls&8{%H5DZAIHQ_D!6)=H4(ou%f*>=Kd?^*`dZ6>yc-= zM{1%kC3_M#hJN|%hi}jP==k$U?7)TN1s9{gkNiB9e0_boW%7;Osnyw8>rR$0JN?1g z@?)0|mc|yoS*6A%$7fsSJcBu{pZ|3A=)!l>1vB!YU9A-?{q**#S27rTE@yxB;jK#? zie-^Bh@H~uHbMB2?;Bf7zdRgQ3=q4dD{O*r*xNK*e6goUF$ZF|bVp1OUOQ2dJoCV= zQpJ3TqcWOff-ryeYgyh=Tc%hDaZmc)v$_!Y1hcYY$g;<(@c;*o!zI15p!%_wmvc zoVwJdSO9TYhOR*h=13~Q|z)npgeS}m%{ zDy+3qRFh3uYn7-bi?G%TQBC$>t<|BL&RA<@j4K%A3f5W_x{4gZS_?uoxq-D7gKBaD zYb^xT6!wpcAb8Yev$)_VWY)v4MiD)lAlRCU^nUd-P&Rds)8 M{W**EzwL$mUod~+m;e9( literal 0 HcmV?d00001 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b807197 --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +CC = i686-elf-gcc +INCLUDE = -I./ +CFLAGS = -Wall -Wextra -Werror -ffreestanding $(INCLUDE) +LDFLAGS = -T kernel.ld -ffreestanding -O3 -nostdlib -lgcc -mpreferred-stack-boundary=4 + +BUILDDIR = build + +KERNELSRC := $(shell find . -name '*.c' -o -name '*.asm') +KERNELOBJ := $(addprefix $(BUILDDIR)/, \ + $(notdir \ + $(patsubst %.c,%.o,\ + $(patsubst %.asm,%.o,$(KERNELSRC))))) + +LIBSRC := $(shell find ./lib -name '*.c') +LIBOBJ := $(addprefix $(BUILDDIR)/, \ + $(notdir \ + $(patsubst %.c,%.o,$(LIBSRC)))) + +KERNELIMG := $(BUILDDIR)/kernel.bin + +QEMUFLAGS = -d int -s \ + -kernel $(KERNELIMG) + +.PHONY: all kernel qemu clean docs + +all: qemu + +qemu: kernel + +kernel: $(KERNELIMG) + +$(KERNELIMG): $(KERNELOBJ) $(LIBOBJ) + $(CC) $^ -o $@ $(LDFLAGS) +$(BUILDDIR)/%.o: %.c + $(CC) $(CFLAGS) -c $^ -o $@ +$(BUILDDIR)/%.o: %.asm + nasm -felf32 $^ -o $@ + +qemu: kernel + qemu-system-i386 $(QEMUFLAGS) + +iso: kernel + cp $(BUILDDIR)/kernel.bin iso/boot/kernel.bin + grub-mkrescue -o $(BUILDDIR)/andewOS.iso iso/ + +clean: + rm -rf build/*.o build/*.bin iso/boot/*.bin +docs: + doxygen diff --git a/acpi.c b/acpi.c new file mode 100644 index 0000000..419a004 --- /dev/null +++ b/acpi.c @@ -0,0 +1,39 @@ +#include + +struct rsdp *acpi_search_for_rsdp() { + char *ptr = (char *)BIOS_START; + char *str = RSDP_SIG; + + while ((uint32_t)ptr <= (uint32_t)BIOS_END - RSDP_SIG_LEN) { + int i; + for (i = 0; i < RSDP_SIG_LEN; i++) { + if (ptr[i] != str[i]) + break; + } + if (i == RSDP_SIG_LEN) { + return (struct rsdp *)ptr; + } + ptr++; + } + + return 0; +} + +int acpi_validate_rsdp_checksum(struct rsdp *s) { + uint8_t *bytes = (uint8_t *)s; + uint8_t sum = 0; + for (int i = 0; i < RSDP_SIZE; i++) { + sum += bytes[i]; + } + + return (sum & 0x0F) == 0; +} + +int acpi_validate_sdt_checksum(struct ACPISDTHeader *s) { + uint8_t sum = 0; + for (uint32_t i = 0; i < s->Length; i++) { + sum += ((char *)s)[i]; + } + + return sum == 0; +} diff --git a/acpi.h b/acpi.h new file mode 100644 index 0000000..ba29712 --- /dev/null +++ b/acpi.h @@ -0,0 +1,45 @@ +#ifndef ACPI_H_ +#define ACPI_H_ + +#include + +#define BIOS_START 0x000E0000 +#define BIOS_END 0x000FFFFF +#define RSDP_SIG "RSD PTR " +#define RSDP_SIG_LEN 8 +#define RSDP_SIZE 20 + +#define ACPI_VER_1 0 +#define ACPI_VER_OTHER 2 + +struct rsdp { + char Signature[RSDP_SIG_LEN]; + uint8_t Checksum; + char OEMID[6]; + uint8_t Revision; + uint32_t RsdtAddress; +} __attribute__ ((packed)); + +struct ACPISDTHeader { + char Signature[4]; + uint32_t Length; + uint8_t Revision; + uint8_t Checksum; + char OEMID[6]; + char OEMTableID[8]; + uint32_t OEMRevision; + uint32_t CreatorID; + uint32_t CreatorRevision; +}; + +struct rsdt { + struct ACPISDTHeader h; + uint32_t other_sdt[]; +}; + +struct rsdp *acpi_search_for_rsdp(); +int acpi_validate_rsdp_checksum(struct rsdp *s); +int acpi_validate_sdt_checksum(struct ACPISDTHeader *s); +struct ACPISDTHeader *acpi_find_table(struct rsdt *root, const char *signature); + +#endif diff --git a/build/acpi.o b/build/acpi.o new file mode 100644 index 0000000000000000000000000000000000000000..5294589ae3f7d1a33db21cb7ed4b82a380226106 GIT binary patch literal 1000 zcma)5L2DCH5S}%uO{KW8^&p749)yapBxwt6QLNTyFA7py=xyC@wxrm&VRuvNp;ZVT z%3eJ9Bm4!i$Dm;J<`3{7s363P5O5EL^_zYBY{*3iCi8tW^S(Ekmpl{q?rNGw$~4N+ zF(X<(AuBU!n4(iOMr#M(TR)3kaYS^Qx}wje-p#IvQ*bd_iz9KQebU>-=ssXy`=GaJ z?rn3tC1S0$7mx0L?rARp3e6F8_9k0s2e|P&(P`(+AqE7m8XlL5(AN09&ERQ0v^Nk#U&fk3zPoLP?rumXv~4msf`Clllf?1rb?gZW|81Ah z$-6n3o#5Zuw+wSodpi$22494;jbl#U*(jWQ@^I!?GM+8VaLF9i%a;_;?T3lI2@)4q%g}(>C1K*)$1EfRrtun}rwb;(U P2m8)K{8n0#AFA&U>PohW literal 0 HcmV?d00001 diff --git a/build/io.o b/build/io.o new file mode 100644 index 0000000000000000000000000000000000000000..653e94b23a6cee2083ad1720aefab1bf07db16dc GIT binary patch literal 624 zcmb<-^>JflWMqH=Mh0dE1doBi0Ln1|E6`xzU|?qm?R?t&Mx@)7Bdyc*4gYr6H=T#x zbh!TK-{$)NLb5(tAquedU|Bryp{mlQ$h3>d25?T1@Lp^Uw#OJ_NL|xQj$s=u%?G@61oK1Rs17gnN>i zbG~!VJ@?#iZXRZGKhRz~B1sbY5}+Pp6eWfBK<{|QjqD+n0@P0->T}`C3 zb^ndyzr`wd%+?M|3uP)=OP<$Sm4()ia=YF1Bo@>l4{cgY&qVMRWLMIwO;5)&+cJnWP zrM3<0{7rK7CpYO4GLi1gt1N1(_{KnsTALJwnlCSE9Uj(v(u#E~ZB<&5Yl`(c%(ir0 zuF>-g<*=!BBy+OUckY*_RD}^L_ad{o-9$Q!19xqiPS0QFGT!PGEWM(&f7EPD#xQp{y}rY?V0muq#u!iKRRtJ6Ie6Idg`7qm|C*QrUHy2duqZ%8t= zuw>>G^sSKb7_u?#blu>_c!65jS(|Z-uGNx~#Cw@v(4^rdcecMJ&b8>~`>F*Ih8M!thPuI(7vlX_>D~)NS znAa2@`K6n1kvGR;ZxDAD46#NOWJeq4{aoX$>%AC4(gnUb@vzgcg1u`_wy6A2Gv>{= zKhS*D!fw_YmWBrhO4_r0`zRW493#>!48WiZ10LMu!k*bc^MPu!ui6Y&v6ZUpJJ#t? z+yn!H0l|P^KrkQ}5DW+g1OtKr!NC86f#W9*tI;=)t90bxp(q_abm&F3|7bdI=(;+z zJ2D&@iWi0lhxZKb9o(%JhV~A4Ue$O0(<;~g|Bqmh{=|DW5x@DnA`u@cnCim)!2GK3 z$A>rIeZW>%{21`3UHENa{@CD(MDYzc#R1ii_fVek$#r~|u_xT`ln?OM zPe5X)4eH%FG z;h&(70q^(l9q2ybS3JzeH(m-Tbl1a_D^D2NQC&A8iBgW@B_mNZBIQy#p43z6cqx5~ z#u5_-ok|&Q%(3$2i3!ITPZ#q}<~m9xjD&;I`4sB{p=NSCZs@)>svCx$qpTiDQX*N% zLXGDV**tVMU(k!jsN=@uiDGgrp3#f(VkuRiq;ZDyvf*ZwjAA~SD^MnzPdWRME5%PI zCbDP%jicY>SUNdgD(Bp4Yay<+9&=_Uij>~V8HrJ7qv+}}-!jr?42l$WXJL`iQi&o- zJ(t7A2Z#Sw_`@0Rb?00QKTrJb?dclrK4RMG${3EI#58#8qe?f?J) literal 0 HcmV?d00001 diff --git a/build/kmain.o b/build/kmain.o new file mode 100644 index 0000000000000000000000000000000000000000..da543992e1159300387de261099b0163f4bed2f6 GIT binary patch literal 1364 zcma)6OKTHR6h1SVw6Ug4>H|bUv#8P{4CxE%3sUNBL0ohbcM{S`N@AM_GZU$3u`nq# z3_@0}EBynmg1V4c3)Nj01-C8~B9ldgfFhB2&dj|ubmbxUe&;){`#O{7?EZozNgzam z030)b{ebV8_FxQ#;1ndP-`%jyLXyqGlAVu8_C^G(iw+B^b*MC~h^OHkMn1b|9g)90 z_>M}r=ln3We(3wvdSiUAdid}oR<&D{T4lc-{KXZ!Ir^a~S6SzPb-mme*%MuRFXY^< zDOJ{XSo@KZCErrB+w1l0{qRU*FZ?vF1>?Zhnw`KR9!&+6=bXZfZt62Rj8{LSdtVy0jfi_wWGZBm;^mL_A9)3KS@ zRJ1fPGtRA1VWb0{l>XjO;AgMjAAlfshc97-5l~>5^9P7$u(Qr1lCE=p8SyQSU!0F3 z3W=a{Ll8vbi4z=F^Ql}x(?Pe^!L*Emo-e^lu8{T)?KvT(mvTunlQQ&da;0b_4KrQx zjgM1nxpd0Pc&4PD&FHIUIe)@urmbUF4cC`sfR~6ezWNu!L4ZGm__o7%K@xs5XE|O& zl<`t#Ilsekf$Tv{(#$7$E47Sh89ru(W@OehE3qbwrrZ98AYGy#e5#$5-a?- zT){|O76y0*ebcYWz(uH+kkdQHxjlyG!3F|6rk796PHlXZb98(1O%&i<(Cf%4zCVuo zLx}izVrZZoyk1YJ9$k?TQEwIvq*FY}4ekvc-Z+!R|pQ6ckp4U{Oy}x=<9sN@)wdE{TcjvdKm_v(VB*d+aHQ zNB={iM-LwQ57uLk9(s^^X`v^n#_vsLHqo08UcT>p@6DSxlli>%YTdFdGG>uYg(7O| z#InK$RjFc1?}glxUFcO`ARd-Fn64b-x^bO5fOu1?t7-lSScThK|KUYVEdZup9o*D# zmg`oTXyavUPvK@Z){77|BzcZWIQQed=iudjO^C0E88iK!A@INifv2cz0LS3G5BKBw z#rJR10J?tt_7~&jb3_&fjY(^26LROcM(L0AXL^>Nr>DPX5USD%AN1Y%|18Tc|6N=m zrYy?OD-9+}K>w$fYa@4vXgn41P%ZQuv za-c$gd4!SOeo1_9Wgsd5vv2*RG5pcRnf7=m8h(Hqdk{}l8d`XxL!K|Tmy zWNv~&kh0!4DTOwDVr(jbkFEZ_Q8mmzZv;@i#nE*-ZW2)|k#1jVa0W@x+K&C8l>}|- zMsBA^yKX3{?Mq$AtTzZl73v24o~kdD?@CvxpyxC05jNQFwq$IW7fTsOqp2pqEWEWR S8fO_RL<>NHfwy!VpzH=llzGtr literal 0 HcmV?d00001 diff --git a/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000..bb46126 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,7 @@ +[ + { + "directory": "/home/rami/rk", + "file": "kmain.c", + "command": "i686-elf-gcc -Wall -Wextra -Werror -ffreestanding -I./ -c kmain.c -o build/kmain.o" + } +] diff --git a/io.c b/io.c new file mode 100644 index 0000000..e3dc4ad --- /dev/null +++ b/io.c @@ -0,0 +1,17 @@ +#include + +uint8_t inportb(uint16_t port) { + uint8_t result; + + asm volatile ("in %%dx, %%al" + : "=a" (result) + : "d" (port)); + + return result; +} + +void outportb(uint16_t port, uint8_t byte) { + asm volatile ("out %%al, %%dx" + : // no output + : "a" (byte), "d" (port)); +} diff --git a/io.h b/io.h new file mode 100644 index 0000000..62474ca --- /dev/null +++ b/io.h @@ -0,0 +1,9 @@ +#ifndef IO_H_ +#define IO_H_ + +#include + +uint8_t inportb(uint16_t port); +void outportb(uint16_t port, uint8_t byte); + +#endif diff --git a/kernel.ld b/kernel.ld new file mode 100644 index 0000000..d6ca5c9 --- /dev/null +++ b/kernel.ld @@ -0,0 +1,28 @@ +ENTRY(_start) + +SECTIONS +{ + . = 1M; + + .text BLOCK(4K) : ALIGN(4K) + { + *(.multiboot) + *(.text) + } + + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } +} diff --git a/kmain.c b/kmain.c new file mode 100644 index 0000000..b9e2580 --- /dev/null +++ b/kmain.c @@ -0,0 +1,81 @@ +#include +#include + +struct kernel_context { + struct rsdp *rsdp; + struct xsdp *xsdp; + + struct rsdt *rsdt; +}; + +struct kernel_context ctx = {0}; + +int strncmp( const char * s1, const char * s2, int n ) +{ + while ( n && *s1 && ( *s1 == *s2 ) ) + { + ++s1; + ++s2; + --n; + } + if ( n == 0 ) + { + return 0; + } + else + { + return ( *(unsigned char *)s1 - *(unsigned char *)s2 ); + } +} + +void *findFACP(void *RootSDT) +{ + struct rsdt *rsdt = (struct rsdt *) RootSDT; + int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4; + + for (int i = 0; i < entries; i++) + { + struct ACPISDTHeader *h = (struct ACPISDTHeader *) rsdt->other_sdt[i]; + if (!strncmp(h->Signature, "FACP", 4)) + return (void *) h; + } + + // No FACP found + return 0; +} + +void kmain(struct multiboot_info *info) { + // Check if the bootloader gave us the upper and lower memory + if (!(info->flags & 0x1)) goto halt; + + char *vmem = (char *)0xb8000; + + struct rsdp *found_rsdp = acpi_search_for_rsdp(); + if (!found_rsdp) goto halt; + if (found_rsdp->Revision == ACPI_VER_1) { + // ACPI v1.0 is being used + if (!acpi_validate_rsdp_checksum(found_rsdp)) goto halt; + ctx.rsdp = found_rsdp; + ctx.xsdp = 0; + + if (!acpi_validate_sdt_checksum((struct ACPISDTHeader *)found_rsdp->RsdtAddress)) + goto halt; + + ctx.rsdt = (struct rsdt*)found_rsdp->RsdtAddress; + + } else if (found_rsdp->Revision == ACPI_VER_OTHER) { + // ACPI v2.0+ is being used + // not supported yet.... + goto halt; + } else goto halt; + + void *fadt = findFACP(ctx.rsdt); + if (!fadt) goto halt; + char *next_sig = (char *)fadt; + vmem[0] = next_sig[0]; + vmem[2] = next_sig[1]; + vmem[4] = next_sig[2]; + vmem[6] = next_sig[3]; +halt: + for (;;) {} +} diff --git a/multiboot.asm b/multiboot.asm new file mode 100644 index 0000000..510a1ed --- /dev/null +++ b/multiboot.asm @@ -0,0 +1,71 @@ +%define MAGIC 0x1BADB002 +%define FLAGS 0 + +; Multiboot v1 Specification +; https://www.gnu.org/software/grub/manual/multiboot/multiboot.html +section .multiboot +align 4 +dd MAGIC +dd FLAGS +dd -(MAGIC + FLAGS) + +section .text +global _start +_start: + cli + + ; Check if EAX contains the multiboot magic number the bootloader is supposed to give us + cmp eax, 0x2BADB002 + jne halt + + lgdt [gdtp] + mov ax, 0x10 ; Offset to kernel data descriptor + mov es, ax + mov ds, ax + mov fs, ax + mov gs, ax + mov ss, ax + jmp 0x8:.use_code_seg ; Offset to kernel code descriptor +.use_code_seg: + mov esp, stack_bottom + push ebx + extern kmain + call kmain + +; If the kernel function somehow returns, disable interrupts and hang + cli +halt: + hlt + jmp halt + +; GDT for a flat memory layout +; We get access to all memory and can utilize paging +gdt_start: +gdt_null: + dq 0 +gdt_kern_code: + dw 0xffff + dw 0x0000 + db 0x00 + db 0b10011010 + db 0b11001111 + db 0x00 +gdt_kern_data: + dw 0xffff + dw 0x0000 + db 0x00 + db 0b10010010 + db 0b11001111 + db 0x00 +gdt_end: + +gdtp: + dw gdt_end - gdt_start - 1 + dd gdt_start + +; Reserve 16KiB of kernel stack space +section .bss +align 4 +stack_top: + resb 16384 +stack_bottom: diff --git a/multiboot.h b/multiboot.h new file mode 100644 index 0000000..aca2ecf --- /dev/null +++ b/multiboot.h @@ -0,0 +1,31 @@ +#ifndef MULTIBOOT_H_ +#define MULTIBOOT_H_ + +#include + +#define MULTIBOOT_MAGIC 0x2BADB002 + +struct multiboot_info { + uint32_t flags; //required + uint32_t memLower; //if bit 0 in flags are set + uint32_t memUpper; //if bit 0 in flags are set + uint32_t bootDevice; //if bit 1 in flags are set + uint32_t commandLine; //if bit 2 in flags are set + uint32_t moduleCount; //if bit 3 in flags are set + uint32_t moduleAddress; //if bit 3 in flags are set + uint32_t syms[4]; //if bits 4 or 5 in flags are set + uint32_t memMapLength; //if bit 6 in flags is set + uint32_t memMapAddress; //if bit 6 in flags is set + uint32_t drivesLength; //if bit 7 in flags is set + uint32_t drivesAddress; //if bit 7 in flags is set + uint32_t configTable; //if bit 8 in flags is set + uint32_t apmTable; //if bit 9 in flags is set + uint32_t vbeControlInfo; //if bit 10 in flags is set + uint32_t vbeModeInfo; //if bit 11 in flags is set + uint32_t vbeMode; // all vbe_* set if bit 12 in flags are set + uint32_t vbeInterfaceSeg; + uint32_t vbeInterfaceOff; + uint32_t vbeInterfaceLength; +}; + +#endif