init
This commit is contained in:
commit
884d0f4c7d
BIN
.cache/clangd/index/acpi.h.DEF797BDB8217123.idx
Normal file
BIN
.cache/clangd/index/acpi.h.DEF797BDB8217123.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/kmain.c.9B04FE5F8A3537CE.idx
Normal file
BIN
.cache/clangd/index/kmain.c.9B04FE5F8A3537CE.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/multiboot.h.DC0E53CEA67FC33F.idx
Normal file
BIN
.cache/clangd/index/multiboot.h.DC0E53CEA67FC33F.idx
Normal file
Binary file not shown.
49
Makefile
Normal file
49
Makefile
Normal 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
39
acpi.c
Normal 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
45
acpi.h
Normal 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
BIN
build/acpi.o
Normal file
Binary file not shown.
BIN
build/io.o
Normal file
BIN
build/io.o
Normal file
Binary file not shown.
BIN
build/kernel.bin
Executable file
BIN
build/kernel.bin
Executable file
Binary file not shown.
BIN
build/kmain.o
Normal file
BIN
build/kmain.o
Normal file
Binary file not shown.
BIN
build/multiboot.o
Normal file
BIN
build/multiboot.o
Normal file
Binary file not shown.
7
compile_commands.json
Normal file
7
compile_commands.json
Normal 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
17
io.c
Normal 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
9
io.h
Normal 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
28
kernel.ld
Normal 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
81
kmain.c
Normal 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
71
multiboot.asm
Normal 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
31
multiboot.h
Normal 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
|
Loading…
Reference in New Issue
Block a user