This commit is contained in:
rami 2024-05-20 05:59:07 -04:00
commit 884d0f4c7d
18 changed files with 377 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

49
Makefile Normal file
View File

@ -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

39
acpi.c Normal file
View File

@ -0,0 +1,39 @@
#include <acpi.h>
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;
}

45
acpi.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef ACPI_H_
#define ACPI_H_
#include <stdint.h>
#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

BIN
build/acpi.o Normal file

Binary file not shown.

BIN
build/io.o Normal file

Binary file not shown.

BIN
build/kernel.bin Executable file

Binary file not shown.

BIN
build/kmain.o Normal file

Binary file not shown.

BIN
build/multiboot.o Normal file

Binary file not shown.

7
compile_commands.json Normal file
View File

@ -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"
}
]

17
io.c Normal file
View File

@ -0,0 +1,17 @@
#include <io.h>
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));
}

9
io.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef IO_H_
#define IO_H_
#include <stdint.h>
uint8_t inportb(uint16_t port);
void outportb(uint16_t port, uint8_t byte);
#endif

28
kernel.ld Normal file
View File

@ -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)
}
}

81
kmain.c Normal file
View File

@ -0,0 +1,81 @@
#include <multiboot.h>
#include <acpi.h>
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 (;;) {}
}

71
multiboot.asm Normal file
View File

@ -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:

31
multiboot.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef MULTIBOOT_H_
#define MULTIBOOT_H_
#include <stdint.h>
#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