forked from PoliEcho-holding-org/kern
Did stuff...
This commit is contained in:
+5
-18
@@ -1,30 +1,17 @@
|
||||
#
|
||||
# kern. makefile defaults
|
||||
#
|
||||
|
||||
# Tools
|
||||
HOSTCC = cc
|
||||
CC = i686-elf-gcc
|
||||
LD = i686-elf-ld
|
||||
AS = nasm
|
||||
MAKE = make
|
||||
AR = i686-elf-ar
|
||||
OBJCOPY = i686-elf-objcopy
|
||||
|
||||
# Flags
|
||||
HOSTCFLAGS = -Wall -Wextra -Wpedantic -O2 -std=c17 -g
|
||||
CFLAGS = -Wall -Wextra -Wpedantic -Wno-pointer-arith\
|
||||
-ffreestanding -fno-stack-protector -fno-builtin -fno-pie -fcommon\
|
||||
-O2 -std=c17 -nostdinc -nostdlib -z notext -march=i386
|
||||
-O2 -std=c17 -nostdinc -nostdlib -z notext -march=i386 -g
|
||||
LDFLAGS = -melf_i386
|
||||
ASFLAGS =
|
||||
|
||||
# Directories
|
||||
KERNEL_DIR = ./kernel
|
||||
BOOT_DIR = ./boot
|
||||
LIBC_DIR = ./libc
|
||||
USER_DIR = ./user
|
||||
|
||||
# Modules
|
||||
MODULES = $(KERNEL_DIR) \
|
||||
$(BOOT_DIR) \
|
||||
$(LIBC_DIR) \
|
||||
$(USER_DIR)
|
||||
ARFLAGS =
|
||||
|
||||
|
||||
@@ -186,3 +186,13 @@ The prefered way of allocating memory for a struct is:
|
||||
Casting the returned void pointer is redundant since C converts void pointers
|
||||
to any other pointers.
|
||||
|
||||
Include Order
|
||||
*************
|
||||
The prefered way of ordering '#include' directives is as so:
|
||||
* Include path includes (ones in <>)
|
||||
* Local path includes (ones in "")
|
||||
* Header implementation include, if you're implementing a header, include it last
|
||||
|
||||
Directives should be ordered by lenght, descending. If two or more includes
|
||||
have the same length, order alphabetically.
|
||||
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
;
|
||||
; Kernel entry point
|
||||
;
|
||||
|
||||
MBH_MAGIC equ 0xe85250d6
|
||||
MBH_ARCH equ 0x00000000
|
||||
STACK_SIZE equ 4096
|
||||
global VIRT_BASE
|
||||
KERN_VIRT_BASE equ 0xC000000
|
||||
KERN_PAGE_NUM equ (KERN_VIRT_BASE >> 22)
|
||||
|
||||
bits 32
|
||||
|
||||
; Multiboot2 Header
|
||||
section .multiboot
|
||||
align 64
|
||||
mbh:
|
||||
; Magic fields
|
||||
.magic: dd MBH_MAGIC
|
||||
.arch: dd MBH_ARCH
|
||||
.size: dd (mbh.end - mbh)
|
||||
.checksum: dd 0x10000000 - (MBH_MAGIC + MBH_ARCH + (mbh.end - mbh))
|
||||
|
||||
; Framebuffer Tag
|
||||
align 8
|
||||
dw 5 ; Type - Framebuffer
|
||||
dw 1 ; Flags - Optional
|
||||
dd 20 ; Size
|
||||
dd 1920 ; Width
|
||||
dd 1080 ; Height
|
||||
dd 32 ; Depth
|
||||
|
||||
; Zero Tag
|
||||
align 8
|
||||
dw 0 ; Type - Zero
|
||||
dw 0 ; Flags
|
||||
dd 8 ; Size
|
||||
|
||||
.end:
|
||||
|
||||
; Stack
|
||||
section .bss
|
||||
align 16
|
||||
stack_bottom:
|
||||
resb 16384*8
|
||||
stack_top:
|
||||
|
||||
; Entry section
|
||||
section .boot
|
||||
global start
|
||||
|
||||
extern kmain
|
||||
start:
|
||||
; Init temporary paging
|
||||
mov eax, (initpd - 0xC0000000)
|
||||
mov cr3, eax
|
||||
|
||||
mov ecx, cr4
|
||||
or ecx, 0x10 ; Paging enable bit
|
||||
mov cr4, ecx
|
||||
|
||||
mov ecx, cr0
|
||||
or ecx, 0x8000000
|
||||
mov cr0, ecx
|
||||
|
||||
jmp higher_half
|
||||
|
||||
Shutdown:
|
||||
mov ax, 0x1000
|
||||
mov ss, ax
|
||||
mov sp, 0xf000
|
||||
mov ax, 0x5307
|
||||
mov bx, 0x0001
|
||||
mov cx, 0x0003
|
||||
int 0x15
|
||||
|
||||
section .text
|
||||
higher_half:
|
||||
mov esp, stack_top ; Stack Pointer
|
||||
|
||||
add ebx, KERN_VIRT_BASE ; Make address in EBX virtual
|
||||
push ebx ; Push multiboot mem info pointer
|
||||
|
||||
call kmain
|
||||
|
||||
; Halt on return
|
||||
cli
|
||||
h: hlt
|
||||
jmp h
|
||||
|
||||
section .data
|
||||
|
||||
; Inital Page Directory
|
||||
align 4096
|
||||
global initpd
|
||||
initpd:
|
||||
dd 0b10000011 ; Initial 4MB identity map
|
||||
|
||||
times 768-1 dd 0 ; Padding
|
||||
|
||||
; Higher half kernel start, map 16MB
|
||||
dd (0 << 22) | 0b10000011
|
||||
dd (1 << 22) | 0b10000011
|
||||
dd (2 << 22) | 0b10000011
|
||||
dd (3 << 22) | 0b10000011
|
||||
|
||||
times 256-4 dd 0 ; More padding
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "multiboot.h"
|
||||
|
||||
#define FLAGS (MBH_PAGE_ALIGN | MBH_GRAPH_INFO)
|
||||
|
||||
__attribute__ ((section(".multiboot")))
|
||||
struct multiboot_header mbh = {
|
||||
.magic = HEAD_MAGIC,
|
||||
.flags = FLAGS,
|
||||
.checksum = -(HEAD_MAGIC + FLAGS),
|
||||
// We don't need the a.out format fields
|
||||
.mode_type = 0,
|
||||
.width = 1920,
|
||||
.height = 1080,
|
||||
.depth = 32,
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define NULL ((void*)0)
|
||||
|
||||
// Naitive width
|
||||
// Naitive size
|
||||
typedef unsigned int size_t;
|
||||
typedef signed int ssize_t;
|
||||
|
||||
@@ -19,5 +19,4 @@ typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
|
||||
#endif
|
||||
+2
-198
@@ -1,200 +1,4 @@
|
||||
#include "stdint.h"
|
||||
#include "multiboot.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Constants */
|
||||
#define COLS 80
|
||||
#define ROWS 24
|
||||
#define ATTR 0x0f
|
||||
#define VID_MEM 0xb8000
|
||||
|
||||
/* Variables */
|
||||
static int xpos;
|
||||
static int ypos;
|
||||
static uint8_t* video;
|
||||
|
||||
/* Forward Declarations */
|
||||
void cls(void);
|
||||
void itoa(char* buf, int base, int d);
|
||||
void putc(int c);
|
||||
void printf(const char* fmt, ...);
|
||||
|
||||
/* Entry Point */
|
||||
void kmain(void) {
|
||||
uint32_t magic, addr;
|
||||
__asm__ volatile ("movl %%eax, %0; movl %%ebx, %1" : "=m"(magic), "=m"(addr));
|
||||
struct multiboot_info* mbi;
|
||||
video = (uint8_t*)VID_MEM;
|
||||
|
||||
// Clear Screen
|
||||
cls();
|
||||
|
||||
// Didn't boot with Multiboot
|
||||
if (magic != BOOT_MAGIC) {
|
||||
printf("Invalid Magic Number: 0x%x\n", magic);
|
||||
while (1);
|
||||
}
|
||||
|
||||
mbi = (struct multiboot_info*)addr;
|
||||
|
||||
printf("flags: 0x%x\n", mbi->flags);
|
||||
|
||||
if (mbi->flags & MBI_MEMORY) {
|
||||
printf("mem_lower: %ukB, mem_upper: %ukB\n",
|
||||
mbi->mem_lower, mbi->mem_upper);
|
||||
}
|
||||
|
||||
if (mbi->flags & MBI_BOOT_DEV) {
|
||||
printf("boot_device: 0x%x\n", mbi->boot_device);
|
||||
}
|
||||
|
||||
if (mbi->flags & MBI_CMDLINE) {
|
||||
printf("cmdline: %s\n", mbi->cmdline);
|
||||
}
|
||||
|
||||
if (mbi->flags & MBI_MODS) {
|
||||
printf("mods_count: %d, mods_addr: 0x%x\n",
|
||||
mbi->mods_count, mbi->mods_addr);
|
||||
|
||||
struct multiboot_module* mod =
|
||||
(struct multiboot_module*)mbi->mods_addr;
|
||||
|
||||
for (size_t i = 0; i < mbi->mods_count; i++) {
|
||||
printf(" start 0x%x, end: 0x%x, cmdline: %s\n",
|
||||
mod->start, mod->end, mod->cmdline);
|
||||
mod++;
|
||||
}
|
||||
}
|
||||
|
||||
if (mbi->flags & MBI_SYMBOLS &&
|
||||
mbi->flags & MBI_ELF_HEAD) {
|
||||
printf("Flag SYMBOLS and ELF HEADER are both set!\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
if (mbi->flags & MBI_MEMMAP) {
|
||||
printf("mmap_addr: 0x%x, mmap_length: 0x%x\n",
|
||||
mbi->mmap_addr, mbi->mmap_length);
|
||||
|
||||
struct multiboot_memmap* mmap =
|
||||
(struct multiboot_memmap*)mbi->mmap_addr;
|
||||
|
||||
while ((uint32_t)mmap < mbi->mmap_addr + mbi->mmap_length) {
|
||||
printf( " size: 0x%x, base: 0x%08x, "
|
||||
"length: 0x%08x, type: 0x%x\n",
|
||||
mmap->size, mmap->base, mmap->len, mmap->type);
|
||||
|
||||
mmap = (struct multiboot_memmap*)
|
||||
((uint32_t)mmap + mmap->size + (sizeof(mmap->size)));
|
||||
}
|
||||
}
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
void cls(void) {
|
||||
for (int i = 0; i < COLS * ROWS * 2; i++) video[i] = 0;
|
||||
xpos = 0;
|
||||
ypos = 0;
|
||||
}
|
||||
|
||||
void itoa(char* buf, int base, int d) {
|
||||
char* p = buf;
|
||||
char* p1;
|
||||
char* p2;
|
||||
uint32_t ud = d;
|
||||
int divisor = 10;
|
||||
|
||||
if (base == 'd' && d < 0) {
|
||||
*p++ = '-';
|
||||
buf++;
|
||||
ud = -d;
|
||||
} else if (base == 'x') divisor = 16;
|
||||
|
||||
do {
|
||||
int remainder = ud % divisor;
|
||||
*p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
|
||||
} while (ud /= divisor);
|
||||
|
||||
*p = 0;
|
||||
|
||||
p1 = buf;
|
||||
p2 = p - 1;
|
||||
while (p1 < p2) {
|
||||
char tmp = *p1;
|
||||
*p1 = *p2;
|
||||
*p2 = tmp;
|
||||
p1++;
|
||||
p2--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the character C on the screen. */
|
||||
void putc(int c) {
|
||||
if (c == '\n' || c == '\r') {
|
||||
newline:
|
||||
xpos = 0;
|
||||
ypos++;
|
||||
if (ypos >= ROWS)
|
||||
ypos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
video[(xpos + ypos * COLS) * 2] = c & 0xFF;
|
||||
video[(xpos + ypos * COLS) * 2 + 1] = ATTR;
|
||||
|
||||
xpos++;
|
||||
if (xpos >= COLS)
|
||||
goto newline;
|
||||
}
|
||||
|
||||
void printf(const char *format, ...) {
|
||||
char** arg = (char**)&format;
|
||||
int c;
|
||||
char buf[20];
|
||||
|
||||
arg++;
|
||||
|
||||
while ((c = *format++) != 0) {
|
||||
if (c != '%') {
|
||||
putc (c);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *p, *p2;
|
||||
int pad0 = 0, pad = 0;
|
||||
|
||||
c = *format++;
|
||||
|
||||
if (c == '0') {
|
||||
pad0 = 1;
|
||||
c = *format++;
|
||||
}
|
||||
|
||||
if (c >= '0' && c <= '9') {
|
||||
pad = c - '0';
|
||||
c = *format++;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
case 'u':
|
||||
case 'x':
|
||||
itoa(buf, c, *((int *) arg++));
|
||||
p = buf;
|
||||
goto string;
|
||||
break;
|
||||
case 's':
|
||||
p = *arg++;
|
||||
if (! p) p = "(null)";
|
||||
string:
|
||||
for (p2 = p; *p2; p2++);
|
||||
for (; p2 < p + pad; p2++) putc (pad0 ? '0' : ' ');
|
||||
while (*p) putc (*p++);
|
||||
break;
|
||||
default:
|
||||
putc(*((int *) arg++));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void kmain(uint32_t addr) {}
|
||||
|
||||
|
||||
+15
-6
@@ -1,34 +1,41 @@
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
ENTRY(kmain)
|
||||
ENTRY(start)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x00100000;
|
||||
kernel_start = .;
|
||||
|
||||
/* Multiboot Header */
|
||||
.multiboot ALIGN(4) : {
|
||||
.multiboot ALIGN(4K) : {
|
||||
*(.multiboot)
|
||||
}
|
||||
|
||||
.boot ALIGN(4K) : {
|
||||
*(.boot)
|
||||
}
|
||||
|
||||
. += 0xC000000;
|
||||
|
||||
/* Kernel Code */
|
||||
.text ALIGN(4) : {
|
||||
.text ALIGN(4) : AT(ADDR(.text) - 0xC000000) {
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
}
|
||||
|
||||
/* Read-Only Data */
|
||||
.rodata ALIGN(4) : {
|
||||
.rodata ALIGN(4) : AT(ADDR(.rodata) - 0xC000000) {
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
}
|
||||
|
||||
/* Read/Write Data */
|
||||
.data ALIGN(4) : {
|
||||
.data ALIGN(4) : AT(ADDR(.data) - 0xC000000) {
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
}
|
||||
|
||||
/* BSS Section */
|
||||
.bss ALIGN(4) : {
|
||||
.bss ALIGN(4) : AT(ADDR(.bss) - 0xC000000) {
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
@@ -40,4 +47,6 @@ SECTIONS {
|
||||
*(.note.*)
|
||||
*(.comment)
|
||||
}
|
||||
|
||||
kernel_end = .;
|
||||
}
|
||||
|
||||
+19
-9
@@ -1,19 +1,29 @@
|
||||
include defaults.mk
|
||||
include ../defaults.mk
|
||||
|
||||
SRCS = $(shell find $(SRC) -name '**.c')
|
||||
OBJS = $(patsubst $(SRC)/%.c, $(BIN)/%.o, $(SRCS))
|
||||
LINKER = $(SRC)/linker.ld
|
||||
OUT = $(BIN)/kernel.elf
|
||||
INC = ./include
|
||||
BIN = ./bin
|
||||
|
||||
SRCS_C = $(shell find . -name '*.c')
|
||||
SRCS_S = $(shell find . -name '*.s')
|
||||
OBJS = $(patsubst %.c, $(BIN)/%.o, $(SRCS_C)) \
|
||||
$(patsubst %.s, $(BIN)/%.s.o, $(SRCS_S))
|
||||
LINKER = ./linker.ld
|
||||
OUT = ./kernel.elf
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT)
|
||||
$(OUT): $(OBJS)
|
||||
$(LD) $(LDFLAGS) -T $(LINKER) -o $@ $^
|
||||
$(LD) $(LDFLAGS) -T$(LINKER) -o $@ $^
|
||||
|
||||
$(BIN)/%.o: $(SRC)/%.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
$(BIN)/%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) -I$(INC) -c -o $@ $<
|
||||
|
||||
$(BIN)/%.s.o: %.s
|
||||
@mkdir -p $(dir $@)
|
||||
$(AS) $(ASFLAGS) -felf32 -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -fr $(BIN)
|
||||
rm -fr $(BIN) $(OUT)
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
#ifndef _MULTIBOOT_H
|
||||
#define _MULTIBOOT_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
#define __packed __attribute__ ((packed))
|
||||
|
||||
#define HEAD_MAGIC 0x1BADB002
|
||||
#define BOOT_MAGIC 0x2BADB002
|
||||
|
||||
// Multiboot Header Flags
|
||||
enum {
|
||||
MBH_PAGE_ALIGN = (1<<0),
|
||||
MBH_MEMORY_INFO = (1<<1),
|
||||
MBH_GRAPH_INFO = (1<<2),
|
||||
MBH_ADDR_FIELDS = (1<<16),
|
||||
};
|
||||
|
||||
struct multiboot_header {
|
||||
uint32_t magic;
|
||||
uint32_t flags;
|
||||
uint32_t checksum;
|
||||
uint32_t header_addr;
|
||||
uint32_t load_addr;
|
||||
uint32_t load_end_addr;
|
||||
uint32_t bss_end_addr;
|
||||
uint32_t entry_addr;
|
||||
uint32_t mode_type;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t depth;
|
||||
} __packed;
|
||||
|
||||
// Multiboot Info Flags
|
||||
enum {
|
||||
MBI_MEMORY = (1<<0),
|
||||
MBI_BOOT_DEV = (1<<1),
|
||||
MBI_CMDLINE = (1<<2),
|
||||
MBI_MODS = (1<<3),
|
||||
MBI_SYMBOLS = (1<<4),
|
||||
MBI_ELF_HEAD = (1<<5),
|
||||
MBI_MEMMAP = (1<<6),
|
||||
MBI_DRIVES = (1<<7),
|
||||
MBI_CONF_TAB = (1<<8),
|
||||
MBI_BOOTLD_NAME = (1<<9),
|
||||
MBI_APM_TABLE = (1<<10),
|
||||
MBI_VBE_TABLE = (1<<11),
|
||||
MBI_FB_TABLE = (1<<12),
|
||||
};
|
||||
|
||||
struct multiboot_info {
|
||||
uint32_t flags;
|
||||
uint32_t mem_lower;
|
||||
uint32_t mem_upper;
|
||||
uint32_t boot_device;
|
||||
uint32_t cmdline;
|
||||
uint32_t mods_count;
|
||||
uint32_t mods_addr;
|
||||
uint32_t syms[4];
|
||||
uint32_t mmap_length;
|
||||
uint32_t mmap_addr;
|
||||
uint32_t drives_length;
|
||||
uint32_t drives_addr;
|
||||
uint32_t config_table;
|
||||
uint32_t bootloader_name;
|
||||
uint32_t apm_table;
|
||||
uint32_t vbe_control_info;
|
||||
uint32_t vbe_mode_info;
|
||||
uint32_t vbe_mode;
|
||||
uint32_t vbe_interface_seg;
|
||||
uint32_t vbe_interface_off;
|
||||
uint32_t vbe_interface_len;
|
||||
uint32_t framebuffer_addr;
|
||||
uint32_t framebuffer_pitch;
|
||||
uint32_t framebuffer_width;
|
||||
uint32_t framebuffer_height;
|
||||
uint32_t framebuffer_bpp;
|
||||
uint32_t framebuffer_type;
|
||||
uint32_t color_info;
|
||||
} __packed;
|
||||
|
||||
struct multiboot_module {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
uint32_t cmdline;
|
||||
uint32_t __reserved;
|
||||
} __packed;
|
||||
|
||||
struct multiboot_memmap {
|
||||
uint32_t size;
|
||||
uint64_t base;
|
||||
uint64_t len;
|
||||
uint32_t type;
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
@@ -1,40 +1,2 @@
|
||||
#
|
||||
# Root kern. makefile
|
||||
# (c) 2023-2025 Tomas Kubecek
|
||||
#
|
||||
|
||||
export VERSION = 0.3.0
|
||||
|
||||
# Configurable variables
|
||||
include defaults.mk
|
||||
|
||||
BIN = ./bin
|
||||
IMG = ./kern.img
|
||||
|
||||
.PHONY: all clean qemu msg $(MODULES)
|
||||
|
||||
all: msg $(IMG)
|
||||
$(IMG): $(MODULES)
|
||||
@echo "\nDone!\n"
|
||||
|
||||
# Build each module
|
||||
$(MODULES):
|
||||
mkdir -p $(BIN)/$@
|
||||
$(MAKE) BIN=$(BIN)/$@ SRC=$@ -f $@/makefile all
|
||||
|
||||
clean:
|
||||
for m in $(MODULES); do $(MAKE) BIN=$(BIN)/$$m SRC=$$m -C . -f $$m/makefile clean; done
|
||||
rm -fr $(BIN)
|
||||
rm -fr $(IMG)
|
||||
|
||||
msg:
|
||||
@echo "\x1b[36mBuilding \x1b[1mkern.\x1b[22m V$(VERSION)\x1b[0m\n"
|
||||
|
||||
# Core Audio only works on MacOS
|
||||
qemu:
|
||||
qemu-system-x86_64\
|
||||
-drive format=raw,file=$(IMG),index=0,media=disk\
|
||||
-m 256M -accel tcg -monitor stdio\
|
||||
-rtc base=localtime,clock=host,driftfix=slew\
|
||||
-audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0
|
||||
|
||||
all:
|
||||
@echo TODO
|
||||
|
||||
Reference in New Issue
Block a user