From 4aa74dbe2a35a45668b33d688f17b680c2232572 Mon Sep 17 00:00:00 2001 From: EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> Date: Sun, 5 May 2024 01:08:00 -0400 Subject: improved makefile somewhat --- libc/README.txt | 5 ++ libc/abort.c | 11 +++ libc/include/stdio.h | 18 +++++ libc/include/stdlib.h | 15 ++++ libc/include/string.h | 20 +++++ libc/include/sys/cdefs.h | 6 ++ libc/makefile | 79 ++++++++++++++++++++ libc/memcmp.c | 13 ++++ libc/memcpy.c | 9 +++ libc/memmove.c | 14 ++++ libc/memset.c | 8 ++ libc/printf.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++ libc/putchar.c | 9 +++ libc/puts.c | 5 ++ libc/strlen.c | 9 +++ 15 files changed, 412 insertions(+) create mode 100644 libc/README.txt create mode 100644 libc/abort.c create mode 100644 libc/include/stdio.h create mode 100644 libc/include/stdlib.h create mode 100644 libc/include/string.h create mode 100644 libc/include/sys/cdefs.h create mode 100644 libc/makefile create mode 100644 libc/memcmp.c create mode 100644 libc/memcpy.c create mode 100644 libc/memmove.c create mode 100644 libc/memset.c create mode 100644 libc/printf.c create mode 100644 libc/putchar.c create mode 100644 libc/puts.c create mode 100644 libc/strlen.c (limited to 'libc') diff --git a/libc/README.txt b/libc/README.txt new file mode 100644 index 0000000..6806bd4 --- /dev/null +++ b/libc/README.txt @@ -0,0 +1,5 @@ +a temporary(?) libc for the kernel + +code based off meaty skeleton from osdev.org + +todo: \ No newline at end of file diff --git a/libc/abort.c b/libc/abort.c new file mode 100644 index 0000000..83873e8 --- /dev/null +++ b/libc/abort.c @@ -0,0 +1,11 @@ +#include +#include + +__attribute__((__noreturn__)) +void abort(void) { + // TODO: Add proper kernel panic. + printf("kernel: panic: abort()\n"); + asm volatile("hlt"); + while (1) { } + __builtin_unreachable(); +} \ No newline at end of file diff --git a/libc/include/stdio.h b/libc/include/stdio.h new file mode 100644 index 0000000..eb4e45b --- /dev/null +++ b/libc/include/stdio.h @@ -0,0 +1,18 @@ +#ifndef _STDIO_H +#define _STDIO_H 1 + +#define EOF (-1) + +#ifdef __cplusplus +extern "C" { +#endif + +int printf(const char* __restrict, ...); +int putchar(int); +int puts(const char*); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h new file mode 100644 index 0000000..1d1ee32 --- /dev/null +++ b/libc/include/stdlib.h @@ -0,0 +1,15 @@ +#ifndef _STDLIB_H +#define _STDLIB_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((__noreturn__)) +void abort(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libc/include/string.h b/libc/include/string.h new file mode 100644 index 0000000..4f6b5bd --- /dev/null +++ b/libc/include/string.h @@ -0,0 +1,20 @@ +#ifndef _STRING_H +#define _STRING_H 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int memcmp(const void*, const void*, size_t); +void* memcpy(void* __restrict, const void* __restrict, size_t); +void* memmove(void*, const void*, size_t); +void* memset(void*, int, size_t); +size_t strlen(const char*); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h new file mode 100644 index 0000000..1e2c277 --- /dev/null +++ b/libc/include/sys/cdefs.h @@ -0,0 +1,6 @@ +#ifndef _SYS_CDEFS_H +#define _SYS_CDEFS_H 1 + + + +#endif \ No newline at end of file diff --git a/libc/makefile b/libc/makefile new file mode 100644 index 0000000..2e1912e --- /dev/null +++ b/libc/makefile @@ -0,0 +1,79 @@ +# libck makefile + +ifndef AR + AR = i686-elf-ar +endif + +ifndef CFLAGS + CFLAGS = -ffreestanding -Wall -Wextra -g -std=gnu11 -O2 -Iinclude + CFLAGS += --sysroot="$(SYSROOT)" + CFLAGS += -isystem="/usr/include" +endif + +ifndef CXXFLAGS + CXXFLAGS = -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -D__is_kernel -g -O2 -Iinclude + CXXFLAGS += -Iinclude + CXXFLAGS += --sysroot="$(SYSROOT)" + CXXFLAGS += -isystem="/usr/include" +endif + +ifndef LDFLAGS + LDFLAGS = -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude + LDFLAGS += --sysroot="$(SYSROOT)" + LDFLAGS += -isystem="/usr/include" +endif + +ifndef SYSROOT + $(error No sysroot specified) +endif + + +LIBS = -nostdlib -lgcc + +#Find all the source files +C_SOURCES := $(shell find $(PWD) -type f -name '*.c') +#CPP_SOURCES := $(shell find $(PWD)/kernel -type f -name '*.cpp') +HEADERS := $(shell find $(PWD) -type f -name '*.h') +#ASMFILES := $(shell find $(PWD) -type f -name '*.asm') + +OBJECTS := $(patsubst %.c,%.o,$(C_SOURCES)) +# OBJECTS += $(patsubst %.cpp,%.o,$(CPP_SOURCES)) +# OBJECTS += $(patsubst %.asm,%.o,$(ASMFILES)) + +DEPFILES := $(patsubst %.c,%.d,$(C_SOURCES)) +# DEPFILES += $(patsubst %.cpp,%.d,$(CPP_SOURCES)) + +LINKLST += $(OBJECTS) +LINKLST += $(LIBS) + +-include $(DEPFILES) + +.PHONY: all install-headers install-lib clean + +all: libc.a install-lib + +libc.a: ${OBJECTS} + $(info [INFO] Linking $<) + $(AR) rcs $@ $(OBJECTS) + +%.o: %.cpp + $(info [INFO] Compiling $<) + $(CXX) ${CXXFLAGS} -MMD -MP -c $< -o $@ + +%.o: %.c + $(info [INFO] Compiling $<) + $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ + +%.o: %.asm + $(info [INFO] Assembling $<) + $(NASM) $< -felf32 -o $@ -g + +install-headers: + cp -r --preserve=timestamps include/. $(SYSROOT)/usr/include + +install-lib: libck.a + cp -r $< $(SYSROOT)/usr/lib/. + +clean: + $(info [INFO] Cleaning) + $(RM) ${OBJECTS} $(DEPFILES) \ No newline at end of file diff --git a/libc/memcmp.c b/libc/memcmp.c new file mode 100644 index 0000000..93141e1 --- /dev/null +++ b/libc/memcmp.c @@ -0,0 +1,13 @@ +#include + +int memcmp(const void* aptr, const void* bptr, size_t size) { + const unsigned char* a = (const unsigned char*) aptr; + const unsigned char* b = (const unsigned char*) bptr; + for (size_t i = 0; i < size; i++) { + if (a[i] < b[i]) + return -1; + else if (b[i] < a[i]) + return 1; + } + return 0; +} \ No newline at end of file diff --git a/libc/memcpy.c b/libc/memcpy.c new file mode 100644 index 0000000..7e09be7 --- /dev/null +++ b/libc/memcpy.c @@ -0,0 +1,9 @@ +#include + +void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) { + unsigned char* dst = (unsigned char*) dstptr; + const unsigned char* src = (const unsigned char*) srcptr; + for (size_t i=0; i < size; i++) + dst[i] = src[i]; + return dstptr; +} \ No newline at end of file diff --git a/libc/memmove.c b/libc/memmove.c new file mode 100644 index 0000000..98c787f --- /dev/null +++ b/libc/memmove.c @@ -0,0 +1,14 @@ +#include + +void* memmove(void* dstptr, const void* srcptr, size_t size) { + unsigned char* dst = (unsigned char*) dstptr; + const unsigned char* src = (const unsigned char*) srcptr; + if (dst < src) { + for (size_t i = 0; i < size; i++) + dst[i] = src[i]; + } else { + for (size_t i = size; i != 0; i--) + dst[i-1] = src[i-1]; + } + return dstptr; +} \ No newline at end of file diff --git a/libc/memset.c b/libc/memset.c new file mode 100644 index 0000000..67dadfe --- /dev/null +++ b/libc/memset.c @@ -0,0 +1,8 @@ +#include + +void* memset(void* bufptr, int value, size_t size) { + unsigned char* buf = (unsigned char*) bufptr; + for (size_t i = 0; i < size; i++) + buf[i] = (unsigned char) value; + return bufptr; +} \ No newline at end of file diff --git a/libc/printf.c b/libc/printf.c new file mode 100644 index 0000000..72a4749 --- /dev/null +++ b/libc/printf.c @@ -0,0 +1,191 @@ +#include +#include +#include +#include +#include +#include + +static bool print(const char* data, size_t length) { + const unsigned char* bytes = (const unsigned char*) data; + for (size_t i = 0; i < length; i++) + if (putchar(bytes[i]) == EOF) + return false; + return true; +} + +// for %d and %x. +static const char* itoa(unsigned int num, char* str, unsigned int base) { + int cou = 0; // nt + + if (num == 0) { // 0 + str[cou] = '0'; + str[++cou] = '\0'; + return str; + } + + while (num) + { + unsigned int rem = (num % base); + // brings the number up to ascii 0 + the digit + if (rem > 9) { + str[cou] = rem + '7'; // 7 = 55 + 10(A) = 65 + } else { + str[cou] = rem + '0'; + } + num /= base; + ++cou; + } + + // reverse the string + for (int i = 0; i < cou; i++) { + char temp = str[i]; + str[i] = str[cou - i - 1]; + str[cou - 1] = temp; + } + + str[cou] = '\0'; + return str; +} + +// have no idea if there's a better way to do this. for %lx +static const char* itoa_u64(unsigned long long num, char* str, int base) { + int cou = 0; // nt + + if (num == 0) { // 0 + str[cou] = '0'; + str[++cou] = '\0'; + return str; + } + + while (num) + { + unsigned long long rem = num % base; + // brings the number up to ascii 0 + the digit + if (rem > 9) { + str[cou] = rem + '7'; // 7 = 55 + 10(A) = 65 + } else { + str[cou] = rem + '0'; + } + num /= base; + ++cou; + } + + // reverse the string + for (int i = 0; i < cou; i++) { + char temp = str[i]; + str[i] = str[cou - i - 1]; + str[cou - 1] = temp; + } + + str[cou] = '\0'; + return str; +} + +int printf(const char* restrict format, ...) { + va_list parameters; + va_start(parameters, format); + + int written = 0; + + while (*format != '\0') { + size_t maxrem = INT_MAX - written; + + if (format[0] != '%' || format[1] == '%') { + if (format[0] == '%') + format++; + size_t amount = 1; + while (format[amount] && format[amount] != '%') + amount++; + if (maxrem < amount) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(format, amount)) + return -1; + format += amount; + written += amount; + continue; + } + + const char* format_begun_at = format++; + + if (*format == 'c') { + format++; + char c = (char) va_arg(parameters, int /* char promotes to int */); + if (!maxrem) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(&c, sizeof(c))) + return -1; + written++; + } else if (*format == 'd') { + format++; + char str[20]; // probably a long enough buffer + unsigned int d = va_arg(parameters, unsigned int); + itoa(d, str, 10); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } else if (*format == 'x') { + format++; + char str[20]; // probably a long enough buffer + unsigned int d = va_arg(parameters, unsigned int); + itoa(d, str, 16); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } else if (*format == 'l') { // for %lx and others that start with l + format++; + if (*format == 'x') { + format++; + char str[20]; // probably a long enough buffer + unsigned long long d = va_arg(parameters, unsigned long long); + itoa_u64(d, str, 16); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } + } else if (*format == 's') { + format++; + const char* str = va_arg(parameters, const char*); + size_t len = strlen(str); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(str, len)) + return -1; + written += len; + } else { + format = format_begun_at; + size_t len = strlen(format); + if (maxrem < len) { + // TODO: Set errno to EOVERFLOW. + return -1; + } + if (!print(format, len)) + return -1; + written += len; + format += len; + } + } + + va_end(parameters); + return written; +} \ No newline at end of file diff --git a/libc/putchar.c b/libc/putchar.c new file mode 100644 index 0000000..c5a7976 --- /dev/null +++ b/libc/putchar.c @@ -0,0 +1,9 @@ +#include + +#include + +int putchar(int ic) { + char c = (char) ic; + terminal_write(&c, sizeof(c)); + return ic; +} \ No newline at end of file diff --git a/libc/puts.c b/libc/puts.c new file mode 100644 index 0000000..8c8c036 --- /dev/null +++ b/libc/puts.c @@ -0,0 +1,5 @@ +#include + +int puts(const char* string) { + return printf("%s\n", string); +} \ No newline at end of file diff --git a/libc/strlen.c b/libc/strlen.c new file mode 100644 index 0000000..441622a --- /dev/null +++ b/libc/strlen.c @@ -0,0 +1,9 @@ +#include + +size_t strlen(const char* str) { + size_t len = 0; + while (str[len]) { + ++len; + } + return len; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 33bc3446d237a95f1bbf9d5d70a170fa4c4241cd Mon Sep 17 00:00:00 2001 From: EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> Date: Mon, 6 May 2024 23:00:36 -0400 Subject: Improved makefile a bit more and got it working with the other files --- kernel/arch/x86_64/limine.cpp | 6 ++-- kernel/arch/x86_64/limine.h | 2 +- kernel/arch/x86_64/linker.ld | 78 +++++++++++++++++++++++++++++++++++++++++++ kernel/dev/ps2kbd.cpp | 34 +++++++++---------- kernel/kernel.cpp | 6 ++-- kernel/makefile | 68 ++++++++++++++++++------------------- libc/makefile | 4 +-- libc/putchar.c | 4 +-- makefile | 25 +++++++------- run-qemu.bat | 2 +- setup_sysroot.sh | 9 +++++ 11 files changed, 163 insertions(+), 75 deletions(-) create mode 100644 kernel/arch/x86_64/linker.ld create mode 100644 setup_sysroot.sh (limited to 'libc') diff --git a/kernel/arch/x86_64/limine.cpp b/kernel/arch/x86_64/limine.cpp index 84f8642..8c67c52 100644 --- a/kernel/arch/x86_64/limine.cpp +++ b/kernel/arch/x86_64/limine.cpp @@ -1,4 +1,3 @@ -#include #include #include #include "limine.h" @@ -37,6 +36,7 @@ void hcf() { extern void (*__init_array[])(); extern void (*__init_array_end[])(); +extern "C" void kernel_main(); extern "C" void _start() { if (!LIMINE_BASE_REVISION_SUPPORTED) { @@ -58,11 +58,13 @@ extern "C" void _start() { limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; // Note: we assume the framebuffer model is RGB with 32-bit pixels. - for (std::size_t i = 0; i < 100; i++) { + for (size_t i = 0; i < 100; i++) { volatile uint32_t *fb_ptr = static_cast(framebuffer->address); fb_ptr[i * (framebuffer->pitch / 4) + i] = 0xffffff; } + + // We're done, just hang... hcf(); } \ No newline at end of file diff --git a/kernel/arch/x86_64/limine.h b/kernel/arch/x86_64/limine.h index 0e7e87a..b4afb43 100644 --- a/kernel/arch/x86_64/limine.h +++ b/kernel/arch/x86_64/limine.h @@ -584,4 +584,4 @@ struct limine_dtb_request { } #endif -#endif \ No newline at end of file +#endif diff --git a/kernel/arch/x86_64/linker.ld b/kernel/arch/x86_64/linker.ld new file mode 100644 index 0000000..5724ecf --- /dev/null +++ b/kernel/arch/x86_64/linker.ld @@ -0,0 +1,78 @@ +OUTPUT_FORMAT(elf64-x86-64) +OUTPUT_ARCH(i386:x86-64) + +/* Excecution entry point symbol */ +ENTRY(_start) + +PHDRS +{ + requests PT_LOAD FLAGS((1 << 1) | (1 << 2)); /* Write + Read */ + text PT_LOAD FLAGS((1 << 0) | (1 << 2)); /* Execute + Read */ + rodata PT_LOAD FLAGS((1 << 2)); /* Read only */ + data PT_LOAD FLAGS((1 << 1) | (1 << 2)); /* Write + Read */ + dynamic PT_DYNAMIC FLAGS((1 << 1) | (1 << 2)); /* Dynamic PHDR for relocations */ +} + +SECTIONS +{ + /* Places kernel in the top 2GiB of the address space */ + . = 0xffffffff80000000; + + /* Used to get the beginning and end address of the kernel */ + __kernel_begin = .; + + .requests : { + KEEP(*(.requests_start_marker)) + KEEP(*(.requests)) + KEEP(*(.requests_end_marker)) + } :requests + + . += CONSTANT(MAXPAGESIZE); + + /* code. multiboot header comes first */ + .text : { + *(.text .text.*) + } :text + + . += CONSTANT(MAXPAGESIZE); + + /* read only data */ + .rodata : { + *(. .rodata.*) + } :rodata + + /* init array symbols used to get start and end address of the array */ + .init_array : { + __init_array = .; + *(.init_array .init_array.*) + __init_array_end = .; + } :rodata + + . += CONSTANT(MAXPAGESIZE); + + /* read write data (initialized) */ + .data : { + *(.data .data.*) + } :data + + /* Dynamic section for relocations, both in its own PHDR and inside data PHDR */ + .dynamic : { + *(.dynamic) + } :data :dynamic + + . += CONSTANT(MAXPAGESIZE); + + /* read write data (uninitialized) and stack */ + .bss : { + *(.bss .bss.*) + *(COMMON) + } :data + + /* Discard .note.* and .eh_frame since they may cause issues on some hosts */ + /DISCARD/ : { + *(.eh_frame) + *(.note .note.*) + } + + __kernel_end = .; +} \ No newline at end of file diff --git a/kernel/dev/ps2kbd.cpp b/kernel/dev/ps2kbd.cpp index ee282b6..ffb1189 100644 --- a/kernel/dev/ps2kbd.cpp +++ b/kernel/dev/ps2kbd.cpp @@ -1,25 +1,25 @@ #include -#include -#include +//#include +//#include #include // Keycodes are sorted from left to right, up to down starting with esc // 0x80 is reserved for nonexistant scancodes // used for scan code set 2 -constexpr uint8_t scancodes[] = { - 9, 0x80, 5, 3, 1, 2, 12, 0x80, - 10, 8, 6, 4, 27, -}; +// constexpr uint8_t scancodes[] = { +// 9, 0x80, 5, 3, 1, 2, 12, 0x80, +// 10, 8, 6, 4, 27, +// }; -void keyboard_init() { - irq_clear_mask(1); - outb(0x60, 0xF4); - inb(0x60); -} +// void keyboard_init() { +// irq_clear_mask(1); +// outb(0x60, 0xF4); +// inb(0x60); +// } -void keyboard_write(uint8_t scancode) { - printf("a\n"); - /*for (int i = 0; i < 7; i++) { - inputbuffer |= inb(PS2_DATA) << (i * 8); // lsb is the first scan code - }*/ -} \ No newline at end of file +// void keyboard_write(uint8_t scancode) { +// printf("a\n"); +// /*for (int i = 0; i < 7; i++) { +// inputbuffer |= inb(PS2_DATA) << (i * 8); // lsb is the first scan code +// }*/ +// } \ No newline at end of file diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index f8f36b5..a0394ea 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -1,7 +1,7 @@ #include -#include -#include -#include +//#include +//#include +//#include //#include //#include diff --git a/kernel/makefile b/kernel/makefile index b2a2660..8c2832d 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,14 +1,14 @@ # Kernel makefile -CFLAGS := -ffreestanding -Wall -Wextra -g -std=gnu99 -O2 -Iinclude -CXXFLAGS := -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -g -O2 -Iinclude -LDFLAGS := -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude +CFLAGS := -ffreestanding -Wall -Wextra -g -std=gnu99 -O2 -Iinclude --sysroot=$(SYSROOT) +CXXFLAGS := -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -g -O2 -Iinclude --sysroot=$(SYSROOT) +LDFLAGS := -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude --sysroot=$(SYSROOT) ASMFLAGS := ifeq ($(ARCH),x86_64) -CFLAGS += -mno-red-zone -CXXFLAGS += -mno-red-zone -LDFLAGS += -mno-red-zone +CFLAGS += -mno-red-zone -mcmodel=kernel -mno-sse -mno-sse2 -mno-mmx +CXXFLAGS += -mno-red-zone -mcmodel=kernel -mno-sse -mno-sse2 -mno-mmx +LDFLAGS += -mno-red-zone -mcmodel=kernel -mno-sse -mno-sse2 -mno-mmx ASMFLAGS += -felf64 endif @@ -16,38 +16,36 @@ ifndef SYSROOT $(error No sysroot specified) endif - -LIBS = -nostdlib -lck -lgcc +LIBS = -nostdlib -lc -lgcc #Find all the source files -C_SOURCES := $(shell find $(PWD)/kernel -type f -name '*.c') -CPP_SOURCES := $(shell find $(PWD)/kernel -type f -name '*.cpp') -HEADERS := $(shell find $(PWD) -type f -name '*.h') -ASMFILES := $(shell find $(PWD) -type f -name '*.asm' ! -name 'crti.asm' ! -name 'crtn.asm') -CRTBEGIN := $(shell $(CXX) $(CXXFLAGS) -print-file-name=crtbegin.o) -CRTEND := $(shell $(CXX) $(CXXFLAGS) -print-file-name=crtend.o) - -OBJECTS := $(patsubst %.c,%.o,$(C_SOURCES)) -OBJECTS += $(patsubst %.cpp,%.o,$(CPP_SOURCES)) -OBJECTS += $(patsubst %.asm,%.o,$(ASMFILES)) - -DEPFILES := $(patsubst %.c,%.d,$(C_SOURCES)) -DEPFILES += $(patsubst %.cpp,%.d,$(CPP_SOURCES)) - -LINKLST := crti.o -LINKLST += $(CRTBEGIN) -LINKLST += $(OBJECTS) +CPP_SRCS := $(shell find . -type f -name '*.cpp' -not -path './arch/*') \ + $(shell find $(PWD)/kernel/arch/$(ARCH) -type f -name '*.cpp') +#HEADERS := $(shell find $(PWD) -type f -name '*.h') +#ASMFILES := $(shell find $(PWD) -type f -name '*.asm' -prune $(PWD)/arch) \ + $(shell find $(PWD)/kernel/arch/$(ARCH) -type f -name '*.asm') + +#OBJS := $(patsubst %.c,%.o,$(C_SOURCES)) +OBJS := $(patsubst %.cpp,%.o,$(CPP_SRCS)) +OBJS += $(patsubst %.asm,%.o,$(ASMFILES)) + +#DEPFILES := $(patsubst %.c,%.d,$(C_SOURCES)) +DEPFILES := $(patsubst %.cpp,%.d,$(CPP_SRCS)) + +# LINKLST := crti.o +# LINKLST += $(CRTBEGIN) +LINKLST += $(OBJS) LINKLST += $(LIBS) -LINKLST += $(CRTEND) -LINKLST += crtn.o +# LINKLST += $(CRTEND) +# LINKLST += crtn.o -include $(DEPFILES) -.PHONY: all crt clean kernel.bin +.PHONY: all clean -all: crti.o crtn.o kernel.bin +all: kernel.bin -kernel.bin: ${OBJECTS} +kernel.bin: ${OBJS} $(info [INFO] Linking kernel) $(CXX) ${LDFLAGS} -o $@ $(LINKLST) @@ -63,15 +61,15 @@ kernel.bin: ${OBJECTS} $(info [INFO] Assembling $<) $(NASM) $< $(ASMFLAGS) -o $@ -g -crti.o: - $(NASM) arch/$(ARCH)/crti.asm $(ASMFLAGS) -o $@ +# crti.o: +# $(NASM) arch/$(ARCH)/crti.asm $(ASMFLAGS) -o $@ -crtn.o: - $(NASM) arch/$(ARCH)/crtn.asm $(ASMFLAGS) -o $@ +# crtn.o: +# $(NASM) arch/$(ARCH)/crtn.asm $(ASMFLAGS) -o $@ install-headers: cp -r --preserve=timestamps include/. $(SYSROOT)/usr/include clean: $(info [INFO] Cleaning) - $(RM) ${OBJECTS} $(DEPFILES) crti.o crtn.o \ No newline at end of file + $(RM) ${OBJS} $(DEPFILES) \ No newline at end of file diff --git a/libc/makefile b/libc/makefile index 2e1912e..560efb7 100644 --- a/libc/makefile +++ b/libc/makefile @@ -1,4 +1,4 @@ -# libck makefile +# libc makefile ifndef AR AR = i686-elf-ar @@ -71,7 +71,7 @@ libc.a: ${OBJECTS} install-headers: cp -r --preserve=timestamps include/. $(SYSROOT)/usr/include -install-lib: libck.a +install-lib: libc.a cp -r $< $(SYSROOT)/usr/lib/. clean: diff --git a/libc/putchar.c b/libc/putchar.c index c5a7976..48147bf 100644 --- a/libc/putchar.c +++ b/libc/putchar.c @@ -1,9 +1,9 @@ #include -#include +//#include int putchar(int ic) { char c = (char) ic; - terminal_write(&c, sizeof(c)); + //terminal_write(&c, sizeof(c)); return ic; } \ No newline at end of file diff --git a/makefile b/makefile index 21c698c..2581e21 100644 --- a/makefile +++ b/makefile @@ -1,24 +1,24 @@ # The makefile -OS_NAME := emuos -ARCH ?= x86_64 -export SYSROOT = $(PWD)/sysroot +OS_NAME := emuos +export ARCH ?= x86_64 +export SYSROOT = $(PWD)/sysroot # Variables for easy access of tools like gcc and nasm export CC = $(ARCH)-elf-gcc export CXX = $(ARCH)-elf-g++ export AR = $(ARCH)-elf-ar export NASM = nasm -QEMU = qemu-system-x86_64 +QEMU = qemu-system-$(ARCH) #ASMFLAGS = -felf32 #CXXFLAGS := -ffreestanding -O2 -Wall -Wextra -fno-exceptions -fno-rtti #LDFLAGS := -ffreestanding -O2 -nostdlib -.PHONY: all grub clean build-all +.PHONY: all limine clean build-all -all: build-all grub +all: build-all limine -build-all: kernel/kernel.bin libc.a +build-all: kernel/kernel.bin libc/libc.a libc/libc.a: install-headers $(info [INFO] Building libc) @@ -28,26 +28,27 @@ kernel/kernel.bin: libc/libc.a install-headers $(info [INFO] Building kernel) $(MAKE) -C ./kernel/ ARCH=$(ARCH) PREFIX=$(PWD) -grub: build-all grub.cfg +limine: build-all + cp kernel/kernel.bin isodir/boot xorriso -as mkisofs -b boot/limine/limine-bios-cd.bin \ -no-emul-boot -boot-load-size 4 -boot-info-table \ --efi-boot boot/limine/limine-uefi-cd.bin \ -efi-boot-part --efi-boot-image --protective-msdos-label \ isodir -o emuos.iso -qemu: grub +qemu: limine $(QEMU) -no-shutdown -no-reboot --serial stdio -s -m 512 -hda $(OS_NAME).iso install: install-headers install-libraries install-headers: $(MAKE) -C ./kernel/ install-headers - $(MAKE) -C ./libs/libc/ install-headers + $(MAKE) -C ./libc/ install-headers install-libraries: - $(MAKE) -C ./libs/libc/ install-lib + $(MAKE) -C ./libc/ install-lib clean: -@$(MAKE) -C ./kernel/ clean - -@$(MAKE) -C ./libs/libc/ clean + -@$(MAKE) -C ./libc/ clean -@$(RM) $(wildcard *.bin *.a) diff --git a/run-qemu.bat b/run-qemu.bat index 19a5ae8..ddf7afa 100644 --- a/run-qemu.bat +++ b/run-qemu.bat @@ -1,2 +1,2 @@ @echo off -qemu-system-i386 -m 128 -drive format=raw,media=cdrom,file=emuos.iso \ No newline at end of file +qemu-system-x86_64 -m 128 -drive format=raw,media=cdrom,file=emuos.iso \ No newline at end of file diff --git a/setup_sysroot.sh b/setup_sysroot.sh new file mode 100644 index 0000000..5c48677 --- /dev/null +++ b/setup_sysroot.sh @@ -0,0 +1,9 @@ +# Copies include/ header files to sysroot/ + +# creates the needed sysroot folders if non existant +mkdir -p sysroot/usr/include +mkdir -p sysroot/usr/lib + +# copies all needed header files for compiling +cp -r kernel/include/* sysroot/usr/include +cp -r libc/include/* sysroot/usr/include \ No newline at end of file -- cgit v1.2.3-70-g09d2 From abaab98bd757cd0818cfcddc983eee25ab7672ed Mon Sep 17 00:00:00 2001 From: EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> Date: Tue, 7 May 2024 11:07:03 -0400 Subject: Made framebuffer class, serial write functions, and finally got makefile to build without having to make clean --- .gitignore | 1 + kernel/arch/x86_64/limine.cpp | 8 ++++++++ kernel/arch/x86_64/serial.cpp | 23 +++++++++++++++++++++++ kernel/framebuffer.cpp | 22 ++++++++++++++++++++++ kernel/include/arch/x86_64/serial.h | 19 +++++++++++++++++++ kernel/include/framebuffer.h | 18 ++++++++++++++++++ kernel/makefile | 19 +++++++++++-------- libc/makefile | 14 +++++++------- libc/putchar.c | 2 ++ makefile | 4 ++-- run-qemu.bat | 2 +- 11 files changed, 114 insertions(+), 18 deletions(-) create mode 100644 kernel/arch/x86_64/serial.cpp create mode 100644 kernel/framebuffer.cpp create mode 100644 kernel/include/arch/x86_64/serial.h create mode 100644 kernel/include/framebuffer.h (limited to 'libc') diff --git a/.gitignore b/.gitignore index ce75dcb..2d6918b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,6 @@ misc/ # not important make.png +.clangd .vscode/ diff --git a/kernel/arch/x86_64/limine.cpp b/kernel/arch/x86_64/limine.cpp index 8c67c52..9ea2bbc 100644 --- a/kernel/arch/x86_64/limine.cpp +++ b/kernel/arch/x86_64/limine.cpp @@ -1,6 +1,9 @@ #include #include +#include +#include #include "limine.h" +#include namespace { __attribute__((used, section(".requests"))) @@ -63,7 +66,12 @@ extern "C" void _start() { fb_ptr[i * (framebuffer->pitch / 4) + i] = 0xffffff; } + Framebuffer fb((uint32_t*)framebuffer->address, framebuffer->width, framebuffer->height); + fb.drawpixel(727, 727, 0x9528fd); + printf("video modes: %lx", framebuffer->mode_count); + + kernel_main(); // We're done, just hang... hcf(); diff --git a/kernel/arch/x86_64/serial.cpp b/kernel/arch/x86_64/serial.cpp new file mode 100644 index 0000000..e90bcde --- /dev/null +++ b/kernel/arch/x86_64/serial.cpp @@ -0,0 +1,23 @@ +#include +#include + +#define PORT 0x3f8 + +int is_transmit_empty() { + return inb(PORT + 5) & 0x20; +} + +extern "C" void serial_putchar(char c) { + while (is_transmit_empty() == 0); + outb(PORT, c); +} + +void serial_write(const char* data, size_t size) { + for (size_t i = 0; i < size; i++) { + serial_putchar(data[i]); + } +} + +void serial_writestring(const char* data) { + serial_write(data, strlen(data)); +} \ No newline at end of file diff --git a/kernel/framebuffer.cpp b/kernel/framebuffer.cpp new file mode 100644 index 0000000..a07d61a --- /dev/null +++ b/kernel/framebuffer.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +Framebuffer::Framebuffer(uint32_t* addr, const uint64_t width, const uint64_t height) + : addr {addr}, width {width}, height {height} { + clear(); +} + +void Framebuffer::clear() { + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) { + const size_t i = y * width + x; + addr[i] = 0x000000; + } + } +} + +void Framebuffer::drawpixel(const uint64_t x, const uint64_t y, const uint32_t color) { + const size_t pos = y * width + x; + addr[pos] = color; +} \ No newline at end of file diff --git a/kernel/include/arch/x86_64/serial.h b/kernel/include/arch/x86_64/serial.h new file mode 100644 index 0000000..2ee63c5 --- /dev/null +++ b/kernel/include/arch/x86_64/serial.h @@ -0,0 +1,19 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +void serial_putchar(char c); +void serial_write(const char* data, size_t size); +void serial_writestring(const char* data); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/kernel/include/framebuffer.h b/kernel/include/framebuffer.h new file mode 100644 index 0000000..6080810 --- /dev/null +++ b/kernel/include/framebuffer.h @@ -0,0 +1,18 @@ +#ifndef FRAMEBUFFER_H +#define FRAMEBUFFER_H + +#include + +class Framebuffer { + private: + uint32_t* addr; + const uint64_t width; + const uint64_t height; + + public: + Framebuffer(uint32_t* addr, const uint64_t width, const uint64_t height); + void clear(); + void drawpixel(const uint64_t x, const uint64_t y, const uint32_t color); +}; + +#endif \ No newline at end of file diff --git a/kernel/makefile b/kernel/makefile index 8c2832d..33ab941 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,8 +1,11 @@ # Kernel makefile -CFLAGS := -ffreestanding -Wall -Wextra -g -std=gnu99 -O2 -Iinclude --sysroot=$(SYSROOT) -CXXFLAGS := -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -g -O2 -Iinclude --sysroot=$(SYSROOT) -LDFLAGS := -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude --sysroot=$(SYSROOT) +CFLAGS := -ffreestanding -Wall -Wextra -g -std=gnu99 -O2 -Iinclude --sysroot=$(SYSROOT) \ + -isystem="/usr/include" +CXXFLAGS := -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -g -O2 -Iinclude --sysroot=$(SYSROOT) \ + -isystem="/usr/include" +LDFLAGS := -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude --sysroot=$(SYSROOT) \ + -isystem="/usr/include" ASMFLAGS := ifeq ($(ARCH),x86_64) @@ -21,7 +24,7 @@ LIBS = -nostdlib -lc -lgcc #Find all the source files CPP_SRCS := $(shell find . -type f -name '*.cpp' -not -path './arch/*') \ $(shell find $(PWD)/kernel/arch/$(ARCH) -type f -name '*.cpp') -#HEADERS := $(shell find $(PWD) -type f -name '*.h') +HEADERS := $(shell find ./include -type f -name '*.h') #ASMFILES := $(shell find $(PWD) -type f -name '*.asm' -prune $(PWD)/arch) \ $(shell find $(PWD)/kernel/arch/$(ARCH) -type f -name '*.asm') @@ -50,11 +53,11 @@ kernel.bin: ${OBJS} $(CXX) ${LDFLAGS} -o $@ $(LINKLST) %.o: %.cpp - $(info [INFO] Compiling $<) +# $(info [INFO] Compiling $<) $(CXX) ${CXXFLAGS} -MMD -MP -c $< -o $@ %.o: %.c - $(info [INFO] Compiling $<) +# $(info [INFO] Compiling $<) $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ %.o: %.asm @@ -67,9 +70,9 @@ kernel.bin: ${OBJS} # crtn.o: # $(NASM) arch/$(ARCH)/crtn.asm $(ASMFLAGS) -o $@ -install-headers: +install-headers: $(HEADERS) cp -r --preserve=timestamps include/. $(SYSROOT)/usr/include clean: $(info [INFO] Cleaning) - $(RM) ${OBJS} $(DEPFILES) \ No newline at end of file + $(RM) ${OBJS} $(DEPFILES) kernel.bin \ No newline at end of file diff --git a/libc/makefile b/libc/makefile index 560efb7..aec21ef 100644 --- a/libc/makefile +++ b/libc/makefile @@ -6,21 +6,21 @@ endif ifndef CFLAGS CFLAGS = -ffreestanding -Wall -Wextra -g -std=gnu11 -O2 -Iinclude - CFLAGS += --sysroot="$(SYSROOT)" - CFLAGS += -isystem="/usr/include" + CFLAGS += --sysroot=$(SYSROOT) + CFLAGS += -isystem $(SYSROOT)/usr/include endif ifndef CXXFLAGS CXXFLAGS = -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -D__is_kernel -g -O2 -Iinclude CXXFLAGS += -Iinclude - CXXFLAGS += --sysroot="$(SYSROOT)" - CXXFLAGS += -isystem="/usr/include" + CXXFLAGS += --sysroot=$(SYSROOT) + CXXFLAGS += -isystem $(SYSROOT)/usr/include endif ifndef LDFLAGS LDFLAGS = -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude - LDFLAGS += --sysroot="$(SYSROOT)" - LDFLAGS += -isystem="/usr/include" + LDFLAGS += --sysroot=$(SYSROOT) + LDFLAGS += -isystem $(SYSROOT)/usr/include endif ifndef SYSROOT @@ -76,4 +76,4 @@ install-lib: libc.a clean: $(info [INFO] Cleaning) - $(RM) ${OBJECTS} $(DEPFILES) \ No newline at end of file + $(RM) ${OBJECTS} $(DEPFILES) libc.a \ No newline at end of file diff --git a/libc/putchar.c b/libc/putchar.c index 48147bf..f0f5783 100644 --- a/libc/putchar.c +++ b/libc/putchar.c @@ -1,9 +1,11 @@ #include //#include +#include int putchar(int ic) { char c = (char) ic; + serial_putchar(c); //terminal_write(&c, sizeof(c)); return ic; } \ No newline at end of file diff --git a/makefile b/makefile index 2581e21..d8535bc 100644 --- a/makefile +++ b/makefile @@ -22,11 +22,11 @@ build-all: kernel/kernel.bin libc/libc.a libc/libc.a: install-headers $(info [INFO] Building libc) - $(MAKE) -C ./libc/ ARCH=$(ARCH) PREFIX=$(PWD) + $(MAKE) -C ./libc/ all kernel/kernel.bin: libc/libc.a install-headers $(info [INFO] Building kernel) - $(MAKE) -C ./kernel/ ARCH=$(ARCH) PREFIX=$(PWD) + $(MAKE) -C ./kernel/ all limine: build-all cp kernel/kernel.bin isodir/boot diff --git a/run-qemu.bat b/run-qemu.bat index ddf7afa..b9c277b 100644 --- a/run-qemu.bat +++ b/run-qemu.bat @@ -1,2 +1,2 @@ @echo off -qemu-system-x86_64 -m 128 -drive format=raw,media=cdrom,file=emuos.iso \ No newline at end of file +qemu-system-x86_64 -m 128 -drive format=raw,media=cdrom,file=emuos.iso -serial stdio \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 1bd17dce9a8297f86f3bb34b3f440490b601eca6 Mon Sep 17 00:00:00 2001 From: EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> Date: Fri, 31 May 2024 21:08:22 -0400 Subject: started working on pmm and fixed printf doing weird things to the numbers --- .bochsrc | 8 +- kernel/arch/x86_64/limine.cpp | 45 +++- kernel/arch/x86_64/limine.h | 587 ------------------------------------------ kernel/include/limine.h | 587 ++++++++++++++++++++++++++++++++++++++++++ kernel/include/mm/pmm.h | 27 ++ kernel/kernel.cpp | 2 +- kernel/makefile | 11 +- kernel/mm/pmm.cpp | 55 ++++ libc/printf.c | 26 +- makefile | 5 +- 10 files changed, 740 insertions(+), 613 deletions(-) delete mode 100644 kernel/arch/x86_64/limine.h create mode 100644 kernel/include/limine.h create mode 100644 kernel/include/mm/pmm.h create mode 100644 kernel/mm/pmm.cpp (limited to 'libc') diff --git a/.bochsrc b/.bochsrc index 8cd280b..924ea32 100644 --- a/.bochsrc +++ b/.bochsrc @@ -3,13 +3,15 @@ boot: cdrom megs: 256 -display_library: sdl2 -#display_library: sdl2, options="gui_debug" +#display_library: sdl2 +display_library: sdl2, options="gui_debug" vga: extension=vbe magic_break: enabled=1 -clock: sync=none, time0=local +clock: sync=realtime, time0=local cpu: reset_on_triple_fault=0 + +com1: enabled=1, mode=file, dev=misc/bochs.txt \ No newline at end of file diff --git a/kernel/arch/x86_64/limine.cpp b/kernel/arch/x86_64/limine.cpp index 6d7984e..b592592 100644 --- a/kernel/arch/x86_64/limine.cpp +++ b/kernel/arch/x86_64/limine.cpp @@ -2,10 +2,11 @@ #include #include #include -#include "limine.h" +#include #include "gdt.h" #include "idt.h" #include +#include namespace { __attribute__((used, section(".requests"))) @@ -21,6 +22,24 @@ volatile limine_framebuffer_request framebuffer_request = { }; } +namespace { +__attribute__((used, section(".requests"))) +volatile limine_memmap_request memmap_request = { + .id = LIMINE_MEMMAP_REQUEST, + .revision = 0, + .response = nullptr +}; +} + +namespace { +__attribute__((used, section(".requests"))) +volatile limine_hhdm_request hhdm_request = { + .id = LIMINE_HHDM_REQUEST, + .revision = 0, + .response = nullptr +}; +} + namespace { __attribute__((used, section(".requests_start_marker"))) volatile LIMINE_REQUESTS_START_MARKER; @@ -30,7 +49,7 @@ volatile LIMINE_REQUESTS_END_MARKER; } namespace { -void hcf() { +[[noreturn]] void hcf() { asm("cli"); for (;;) { asm("hlt"); @@ -41,7 +60,7 @@ void hcf() { extern void (*__init_array[])(); extern void (*__init_array_end[])(); -extern "C" void kernel_main(); +void kernel_main(); extern "C" void _start() { asm("cli"); @@ -75,8 +94,12 @@ extern "C" void _start() { hcf(); } + if (memmap_request.response == nullptr) { + hcf(); + } + // Fetch the first framebuffer. - limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; + limine_framebuffer* framebuffer = framebuffer_request.response->framebuffers[0]; // Note: we assume the framebuffer model is RGB with 32-bit pixels. // for (size_t i = 0; i < 100; i++) { @@ -84,11 +107,10 @@ extern "C" void _start() { // fb_ptr[i * (framebuffer->pitch / 4) + i] = 0xffffff; // } - asm("xchgw %bx, %bx"); fb_init((uint32_t*)framebuffer->address, framebuffer->width, framebuffer->height); draw_pixel(727, 727, 0x9528fd); draw_pixel(0, 0, 0xff0000); - draw_pixel(1919, 1079, 0x00ff00); + draw_pixel(framebuffer->width - 1, framebuffer->height - 1, 0x00ff00); // for (size_t i = 0; i < framebuffer->mode_count; i++) { // printf("Mode %d\n", i); // printf("Pitch %d\nWidth %d\nHeight %d\nbpp %d\nmem_model %d\n", @@ -100,6 +122,17 @@ extern "C" void _start() { printf("Pitch %d\nWidth %d\nHeight %d\nbpp %d\nmem_model %d\n", framebuffer->pitch, framebuffer->width, framebuffer->height, framebuffer->bpp, framebuffer->memory_model); + + limine_memmap_response* memmap = memmap_request.response; + for (int i = 0; i < memmap->entry_count; i++) { + printf("base: %lx\nlength: %lx\ntype: %d\n\n", + memmap->entries[i]->base, memmap->entries[i]->length, memmap->entries[i]->type); + } + + // broken printf mirroring 64 bit values for some reason + //uint64_t tester = 0xFFFE0000000000AE + 1; + //printf("aaaa: %lx\n", tester); + pmm_init(memmap_request.response, hhdm_request.response->offset); kernel_main(); diff --git a/kernel/arch/x86_64/limine.h b/kernel/arch/x86_64/limine.h deleted file mode 100644 index b4afb43..0000000 --- a/kernel/arch/x86_64/limine.h +++ /dev/null @@ -1,587 +0,0 @@ -/* BSD Zero Clause License */ - -/* Copyright (C) 2022-2024 mintsuki and contributors. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef LIMINE_H -#define LIMINE_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* Misc */ - -#ifdef LIMINE_NO_POINTERS -# define LIMINE_PTR(TYPE) uint64_t -#else -# define LIMINE_PTR(TYPE) TYPE -#endif - -#ifdef __GNUC__ -# define LIMINE_DEPRECATED __attribute__((__deprecated__)) -# define LIMINE_DEPRECATED_IGNORE_START \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -# define LIMINE_DEPRECATED_IGNORE_END \ - _Pragma("GCC diagnostic pop") -#else -# define LIMINE_DEPRECATED -# define LIMINE_DEPRECATED_IGNORE_START -# define LIMINE_DEPRECATED_IGNORE_END -#endif - -#define LIMINE_REQUESTS_START_MARKER \ - uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ - 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; -#define LIMINE_REQUESTS_END_MARKER \ - uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; - -#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER - -#define LIMINE_BASE_REVISION(N) \ - uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; - -#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) - -#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b - -struct limine_uuid { - uint32_t a; - uint16_t b; - uint16_t c; - uint8_t d[8]; -}; - -#define LIMINE_MEDIA_TYPE_GENERIC 0 -#define LIMINE_MEDIA_TYPE_OPTICAL 1 -#define LIMINE_MEDIA_TYPE_TFTP 2 - -struct limine_file { - uint64_t revision; - LIMINE_PTR(void *) address; - uint64_t size; - LIMINE_PTR(char *) path; - LIMINE_PTR(char *) cmdline; - uint32_t media_type; - uint32_t unused; - uint32_t tftp_ip; - uint32_t tftp_port; - uint32_t partition_index; - uint32_t mbr_disk_id; - struct limine_uuid gpt_disk_uuid; - struct limine_uuid gpt_part_uuid; - struct limine_uuid part_uuid; -}; - -/* Boot info */ - -#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } - -struct limine_bootloader_info_response { - uint64_t revision; - LIMINE_PTR(char *) name; - LIMINE_PTR(char *) version; -}; - -struct limine_bootloader_info_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_bootloader_info_response *) response; -}; - -/* Stack size */ - -#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } - -struct limine_stack_size_response { - uint64_t revision; -}; - -struct limine_stack_size_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_stack_size_response *) response; - uint64_t stack_size; -}; - -/* HHDM */ - -#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } - -struct limine_hhdm_response { - uint64_t revision; - uint64_t offset; -}; - -struct limine_hhdm_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_hhdm_response *) response; -}; - -/* Framebuffer */ - -#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } - -#define LIMINE_FRAMEBUFFER_RGB 1 - -struct limine_video_mode { - uint64_t pitch; - uint64_t width; - uint64_t height; - uint16_t bpp; - uint8_t memory_model; - uint8_t red_mask_size; - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; -}; - -struct limine_framebuffer { - LIMINE_PTR(void *) address; - uint64_t width; - uint64_t height; - uint64_t pitch; - uint16_t bpp; - uint8_t memory_model; - uint8_t red_mask_size; - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; - uint8_t unused[7]; - uint64_t edid_size; - LIMINE_PTR(void *) edid; - /* Response revision 1 */ - uint64_t mode_count; - LIMINE_PTR(struct limine_video_mode **) modes; -}; - -struct limine_framebuffer_response { - uint64_t revision; - uint64_t framebuffer_count; - LIMINE_PTR(struct limine_framebuffer **) framebuffers; -}; - -struct limine_framebuffer_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_framebuffer_response *) response; -}; - -/* Terminal */ - -#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } - -#define LIMINE_TERMINAL_CB_DEC 10 -#define LIMINE_TERMINAL_CB_BELL 20 -#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 -#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 -#define LIMINE_TERMINAL_CB_POS_REPORT 50 -#define LIMINE_TERMINAL_CB_KBD_LEDS 60 -#define LIMINE_TERMINAL_CB_MODE 70 -#define LIMINE_TERMINAL_CB_LINUX 80 - -#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) -#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) -#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) -#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) - -/* Response revision 1 */ -#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) -#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) - -#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) -#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) -#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) -#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) -#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) -#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) -#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) -#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) - -LIMINE_DEPRECATED_IGNORE_START - -struct LIMINE_DEPRECATED limine_terminal; - -typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); -typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); - -struct LIMINE_DEPRECATED limine_terminal { - uint64_t columns; - uint64_t rows; - LIMINE_PTR(struct limine_framebuffer *) framebuffer; -}; - -struct LIMINE_DEPRECATED limine_terminal_response { - uint64_t revision; - uint64_t terminal_count; - LIMINE_PTR(struct limine_terminal **) terminals; - LIMINE_PTR(limine_terminal_write) write; -}; - -struct LIMINE_DEPRECATED limine_terminal_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_terminal_response *) response; - LIMINE_PTR(limine_terminal_callback) callback; -}; - -LIMINE_DEPRECATED_IGNORE_END - -/* Paging mode */ - -#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } - -#if defined (__x86_64__) || defined (__i386__) -#define LIMINE_PAGING_MODE_X86_64_4LVL 0 -#define LIMINE_PAGING_MODE_X86_64_5LVL 1 -#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL -#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL -#elif defined (__aarch64__) -#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 -#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 -#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL -#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL -#elif defined (__riscv) && (__riscv_xlen == 64) -#define LIMINE_PAGING_MODE_RISCV_SV39 0 -#define LIMINE_PAGING_MODE_RISCV_SV48 1 -#define LIMINE_PAGING_MODE_RISCV_SV57 2 -#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 -#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 -#else -#error Unknown architecture -#endif - -struct limine_paging_mode_response { - uint64_t revision; - uint64_t mode; - uint64_t flags; -}; - -struct limine_paging_mode_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_paging_mode_response *) response; - uint64_t mode; - uint64_t flags; -}; - -/* 5-level paging */ - -#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } - -LIMINE_DEPRECATED_IGNORE_START - -struct LIMINE_DEPRECATED limine_5_level_paging_response { - uint64_t revision; -}; - -struct LIMINE_DEPRECATED limine_5_level_paging_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_5_level_paging_response *) response; -}; - -LIMINE_DEPRECATED_IGNORE_END - -/* SMP */ - -#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } - -struct limine_smp_info; - -typedef void (*limine_goto_address)(struct limine_smp_info *); - -#if defined (__x86_64__) || defined (__i386__) - -#define LIMINE_SMP_X2APIC (1 << 0) - -struct limine_smp_info { - uint32_t processor_id; - uint32_t lapic_id; - uint64_t reserved; - LIMINE_PTR(limine_goto_address) goto_address; - uint64_t extra_argument; -}; - -struct limine_smp_response { - uint64_t revision; - uint32_t flags; - uint32_t bsp_lapic_id; - uint64_t cpu_count; - LIMINE_PTR(struct limine_smp_info **) cpus; -}; - -#elif defined (__aarch64__) - -struct limine_smp_info { - uint32_t processor_id; - uint32_t gic_iface_no; - uint64_t mpidr; - uint64_t reserved; - LIMINE_PTR(limine_goto_address) goto_address; - uint64_t extra_argument; -}; - -struct limine_smp_response { - uint64_t revision; - uint64_t flags; - uint64_t bsp_mpidr; - uint64_t cpu_count; - LIMINE_PTR(struct limine_smp_info **) cpus; -}; - -#elif defined (__riscv) && (__riscv_xlen == 64) - -struct limine_smp_info { - uint64_t processor_id; - uint64_t hartid; - uint64_t reserved; - LIMINE_PTR(limine_goto_address) goto_address; - uint64_t extra_argument; -}; - -struct limine_smp_response { - uint64_t revision; - uint64_t flags; - uint64_t bsp_hartid; - uint64_t cpu_count; - LIMINE_PTR(struct limine_smp_info **) cpus; -}; - -#else -#error Unknown architecture -#endif - -struct limine_smp_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_smp_response *) response; - uint64_t flags; -}; - -/* Memory map */ - -#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } - -#define LIMINE_MEMMAP_USABLE 0 -#define LIMINE_MEMMAP_RESERVED 1 -#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 -#define LIMINE_MEMMAP_ACPI_NVS 3 -#define LIMINE_MEMMAP_BAD_MEMORY 4 -#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 -#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 -#define LIMINE_MEMMAP_FRAMEBUFFER 7 - -struct limine_memmap_entry { - uint64_t base; - uint64_t length; - uint64_t type; -}; - -struct limine_memmap_response { - uint64_t revision; - uint64_t entry_count; - LIMINE_PTR(struct limine_memmap_entry **) entries; -}; - -struct limine_memmap_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_memmap_response *) response; -}; - -/* Entry point */ - -#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } - -typedef void (*limine_entry_point)(void); - -struct limine_entry_point_response { - uint64_t revision; -}; - -struct limine_entry_point_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_entry_point_response *) response; - LIMINE_PTR(limine_entry_point) entry; -}; - -/* Kernel File */ - -#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } - -struct limine_kernel_file_response { - uint64_t revision; - LIMINE_PTR(struct limine_file *) kernel_file; -}; - -struct limine_kernel_file_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_kernel_file_response *) response; -}; - -/* Module */ - -#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } - -#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) -#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) - -struct limine_internal_module { - LIMINE_PTR(const char *) path; - LIMINE_PTR(const char *) cmdline; - uint64_t flags; -}; - -struct limine_module_response { - uint64_t revision; - uint64_t module_count; - LIMINE_PTR(struct limine_file **) modules; -}; - -struct limine_module_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_module_response *) response; - - /* Request revision 1 */ - uint64_t internal_module_count; - LIMINE_PTR(struct limine_internal_module **) internal_modules; -}; - -/* RSDP */ - -#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } - -struct limine_rsdp_response { - uint64_t revision; - LIMINE_PTR(void *) address; -}; - -struct limine_rsdp_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_rsdp_response *) response; -}; - -/* SMBIOS */ - -#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } - -struct limine_smbios_response { - uint64_t revision; - LIMINE_PTR(void *) entry_32; - LIMINE_PTR(void *) entry_64; -}; - -struct limine_smbios_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_smbios_response *) response; -}; - -/* EFI system table */ - -#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } - -struct limine_efi_system_table_response { - uint64_t revision; - LIMINE_PTR(void *) address; -}; - -struct limine_efi_system_table_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_efi_system_table_response *) response; -}; - -/* EFI memory map */ - -#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } - -struct limine_efi_memmap_response { - uint64_t revision; - LIMINE_PTR(void *) memmap; - uint64_t memmap_size; - uint64_t desc_size; - uint64_t desc_version; -}; - -struct limine_efi_memmap_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_efi_memmap_response *) response; -}; - -/* Boot time */ - -#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } - -struct limine_boot_time_response { - uint64_t revision; - int64_t boot_time; -}; - -struct limine_boot_time_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_boot_time_response *) response; -}; - -/* Kernel address */ - -#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } - -struct limine_kernel_address_response { - uint64_t revision; - uint64_t physical_base; - uint64_t virtual_base; -}; - -struct limine_kernel_address_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_kernel_address_response *) response; -}; - -/* Device Tree Blob */ - -#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } - -struct limine_dtb_response { - uint64_t revision; - LIMINE_PTR(void *) dtb_ptr; -}; - -struct limine_dtb_request { - uint64_t id[4]; - uint64_t revision; - LIMINE_PTR(struct limine_dtb_response *) response; -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/include/limine.h b/kernel/include/limine.h new file mode 100644 index 0000000..b4afb43 --- /dev/null +++ b/kernel/include/limine.h @@ -0,0 +1,587 @@ +/* BSD Zero Clause License */ + +/* Copyright (C) 2022-2024 mintsuki and contributors. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIMINE_H +#define LIMINE_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Misc */ + +#ifdef LIMINE_NO_POINTERS +# define LIMINE_PTR(TYPE) uint64_t +#else +# define LIMINE_PTR(TYPE) TYPE +#endif + +#ifdef __GNUC__ +# define LIMINE_DEPRECATED __attribute__((__deprecated__)) +# define LIMINE_DEPRECATED_IGNORE_START \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define LIMINE_DEPRECATED_IGNORE_END \ + _Pragma("GCC diagnostic pop") +#else +# define LIMINE_DEPRECATED +# define LIMINE_DEPRECATED_IGNORE_START +# define LIMINE_DEPRECATED_IGNORE_END +#endif + +#define LIMINE_REQUESTS_START_MARKER \ + uint64_t limine_requests_start_marker[4] = { 0xf6b8f4b39de7d1ae, 0xfab91a6940fcb9cf, \ + 0x785c6ed015d3e316, 0x181e920a7852b9d9 }; +#define LIMINE_REQUESTS_END_MARKER \ + uint64_t limine_requests_end_marker[2] = { 0xadc0e0531bb10d03, 0x9572709f31764c62 }; + +#define LIMINE_REQUESTS_DELIMITER LIMINE_REQUESTS_END_MARKER + +#define LIMINE_BASE_REVISION(N) \ + uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) }; + +#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0) + +#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b + +struct limine_uuid { + uint32_t a; + uint16_t b; + uint16_t c; + uint8_t d[8]; +}; + +#define LIMINE_MEDIA_TYPE_GENERIC 0 +#define LIMINE_MEDIA_TYPE_OPTICAL 1 +#define LIMINE_MEDIA_TYPE_TFTP 2 + +struct limine_file { + uint64_t revision; + LIMINE_PTR(void *) address; + uint64_t size; + LIMINE_PTR(char *) path; + LIMINE_PTR(char *) cmdline; + uint32_t media_type; + uint32_t unused; + uint32_t tftp_ip; + uint32_t tftp_port; + uint32_t partition_index; + uint32_t mbr_disk_id; + struct limine_uuid gpt_disk_uuid; + struct limine_uuid gpt_part_uuid; + struct limine_uuid part_uuid; +}; + +/* Boot info */ + +#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 } + +struct limine_bootloader_info_response { + uint64_t revision; + LIMINE_PTR(char *) name; + LIMINE_PTR(char *) version; +}; + +struct limine_bootloader_info_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_bootloader_info_response *) response; +}; + +/* Stack size */ + +#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d } + +struct limine_stack_size_response { + uint64_t revision; +}; + +struct limine_stack_size_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_stack_size_response *) response; + uint64_t stack_size; +}; + +/* HHDM */ + +#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b } + +struct limine_hhdm_response { + uint64_t revision; + uint64_t offset; +}; + +struct limine_hhdm_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_hhdm_response *) response; +}; + +/* Framebuffer */ + +#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b } + +#define LIMINE_FRAMEBUFFER_RGB 1 + +struct limine_video_mode { + uint64_t pitch; + uint64_t width; + uint64_t height; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; +}; + +struct limine_framebuffer { + LIMINE_PTR(void *) address; + uint64_t width; + uint64_t height; + uint64_t pitch; + uint16_t bpp; + uint8_t memory_model; + uint8_t red_mask_size; + uint8_t red_mask_shift; + uint8_t green_mask_size; + uint8_t green_mask_shift; + uint8_t blue_mask_size; + uint8_t blue_mask_shift; + uint8_t unused[7]; + uint64_t edid_size; + LIMINE_PTR(void *) edid; + /* Response revision 1 */ + uint64_t mode_count; + LIMINE_PTR(struct limine_video_mode **) modes; +}; + +struct limine_framebuffer_response { + uint64_t revision; + uint64_t framebuffer_count; + LIMINE_PTR(struct limine_framebuffer **) framebuffers; +}; + +struct limine_framebuffer_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_framebuffer_response *) response; +}; + +/* Terminal */ + +#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 } + +#define LIMINE_TERMINAL_CB_DEC 10 +#define LIMINE_TERMINAL_CB_BELL 20 +#define LIMINE_TERMINAL_CB_PRIVATE_ID 30 +#define LIMINE_TERMINAL_CB_STATUS_REPORT 40 +#define LIMINE_TERMINAL_CB_POS_REPORT 50 +#define LIMINE_TERMINAL_CB_KBD_LEDS 60 +#define LIMINE_TERMINAL_CB_MODE 70 +#define LIMINE_TERMINAL_CB_LINUX 80 + +#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1)) +#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2)) +#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3)) +#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4)) + +/* Response revision 1 */ +#define LIMINE_TERMINAL_OOB_OUTPUT_GET ((uint64_t)(-10)) +#define LIMINE_TERMINAL_OOB_OUTPUT_SET ((uint64_t)(-11)) + +#define LIMINE_TERMINAL_OOB_OUTPUT_OCRNL (1 << 0) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFDEL (1 << 1) +#define LIMINE_TERMINAL_OOB_OUTPUT_OFILL (1 << 2) +#define LIMINE_TERMINAL_OOB_OUTPUT_OLCUC (1 << 3) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLCR (1 << 4) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONLRET (1 << 5) +#define LIMINE_TERMINAL_OOB_OUTPUT_ONOCR (1 << 6) +#define LIMINE_TERMINAL_OOB_OUTPUT_OPOST (1 << 7) + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_terminal; + +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); +typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); + +struct LIMINE_DEPRECATED limine_terminal { + uint64_t columns; + uint64_t rows; + LIMINE_PTR(struct limine_framebuffer *) framebuffer; +}; + +struct LIMINE_DEPRECATED limine_terminal_response { + uint64_t revision; + uint64_t terminal_count; + LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; +}; + +struct LIMINE_DEPRECATED limine_terminal_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_terminal_response *) response; + LIMINE_PTR(limine_terminal_callback) callback; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* Paging mode */ + +#define LIMINE_PAGING_MODE_REQUEST { LIMINE_COMMON_MAGIC, 0x95c1a0edab0944cb, 0xa4e5cb3842f7488a } + +#if defined (__x86_64__) || defined (__i386__) +#define LIMINE_PAGING_MODE_X86_64_4LVL 0 +#define LIMINE_PAGING_MODE_X86_64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_X86_64_5LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_X86_64_4LVL +#elif defined (__aarch64__) +#define LIMINE_PAGING_MODE_AARCH64_4LVL 0 +#define LIMINE_PAGING_MODE_AARCH64_5LVL 1 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_AARCH64_5LVL +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_AARCH64_4LVL +#elif defined (__riscv) && (__riscv_xlen == 64) +#define LIMINE_PAGING_MODE_RISCV_SV39 0 +#define LIMINE_PAGING_MODE_RISCV_SV48 1 +#define LIMINE_PAGING_MODE_RISCV_SV57 2 +#define LIMINE_PAGING_MODE_MAX LIMINE_PAGING_MODE_RISCV_SV57 +#define LIMINE_PAGING_MODE_DEFAULT LIMINE_PAGING_MODE_RISCV_SV48 +#else +#error Unknown architecture +#endif + +struct limine_paging_mode_response { + uint64_t revision; + uint64_t mode; + uint64_t flags; +}; + +struct limine_paging_mode_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_paging_mode_response *) response; + uint64_t mode; + uint64_t flags; +}; + +/* 5-level paging */ + +#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 } + +LIMINE_DEPRECATED_IGNORE_START + +struct LIMINE_DEPRECATED limine_5_level_paging_response { + uint64_t revision; +}; + +struct LIMINE_DEPRECATED limine_5_level_paging_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_5_level_paging_response *) response; +}; + +LIMINE_DEPRECATED_IGNORE_END + +/* SMP */ + +#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 } + +struct limine_smp_info; + +typedef void (*limine_goto_address)(struct limine_smp_info *); + +#if defined (__x86_64__) || defined (__i386__) + +#define LIMINE_SMP_X2APIC (1 << 0) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint32_t flags; + uint32_t bsp_lapic_id; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__aarch64__) + +struct limine_smp_info { + uint32_t processor_id; + uint32_t gic_iface_no; + uint64_t mpidr; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_mpidr; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#elif defined (__riscv) && (__riscv_xlen == 64) + +struct limine_smp_info { + uint64_t processor_id; + uint64_t hartid; + uint64_t reserved; + LIMINE_PTR(limine_goto_address) goto_address; + uint64_t extra_argument; +}; + +struct limine_smp_response { + uint64_t revision; + uint64_t flags; + uint64_t bsp_hartid; + uint64_t cpu_count; + LIMINE_PTR(struct limine_smp_info **) cpus; +}; + +#else +#error Unknown architecture +#endif + +struct limine_smp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smp_response *) response; + uint64_t flags; +}; + +/* Memory map */ + +#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 } + +#define LIMINE_MEMMAP_USABLE 0 +#define LIMINE_MEMMAP_RESERVED 1 +#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2 +#define LIMINE_MEMMAP_ACPI_NVS 3 +#define LIMINE_MEMMAP_BAD_MEMORY 4 +#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5 +#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6 +#define LIMINE_MEMMAP_FRAMEBUFFER 7 + +struct limine_memmap_entry { + uint64_t base; + uint64_t length; + uint64_t type; +}; + +struct limine_memmap_response { + uint64_t revision; + uint64_t entry_count; + LIMINE_PTR(struct limine_memmap_entry **) entries; +}; + +struct limine_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_memmap_response *) response; +}; + +/* Entry point */ + +#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a } + +typedef void (*limine_entry_point)(void); + +struct limine_entry_point_response { + uint64_t revision; +}; + +struct limine_entry_point_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_entry_point_response *) response; + LIMINE_PTR(limine_entry_point) entry; +}; + +/* Kernel File */ + +#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 } + +struct limine_kernel_file_response { + uint64_t revision; + LIMINE_PTR(struct limine_file *) kernel_file; +}; + +struct limine_kernel_file_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_file_response *) response; +}; + +/* Module */ + +#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee } + +#define LIMINE_INTERNAL_MODULE_REQUIRED (1 << 0) +#define LIMINE_INTERNAL_MODULE_COMPRESSED (1 << 1) + +struct limine_internal_module { + LIMINE_PTR(const char *) path; + LIMINE_PTR(const char *) cmdline; + uint64_t flags; +}; + +struct limine_module_response { + uint64_t revision; + uint64_t module_count; + LIMINE_PTR(struct limine_file **) modules; +}; + +struct limine_module_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_module_response *) response; + + /* Request revision 1 */ + uint64_t internal_module_count; + LIMINE_PTR(struct limine_internal_module **) internal_modules; +}; + +/* RSDP */ + +#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c } + +struct limine_rsdp_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_rsdp_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_rsdp_response *) response; +}; + +/* SMBIOS */ + +#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee } + +struct limine_smbios_response { + uint64_t revision; + LIMINE_PTR(void *) entry_32; + LIMINE_PTR(void *) entry_64; +}; + +struct limine_smbios_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_smbios_response *) response; +}; + +/* EFI system table */ + +#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc } + +struct limine_efi_system_table_response { + uint64_t revision; + LIMINE_PTR(void *) address; +}; + +struct limine_efi_system_table_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_system_table_response *) response; +}; + +/* EFI memory map */ + +#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 } + +struct limine_efi_memmap_response { + uint64_t revision; + LIMINE_PTR(void *) memmap; + uint64_t memmap_size; + uint64_t desc_size; + uint64_t desc_version; +}; + +struct limine_efi_memmap_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_efi_memmap_response *) response; +}; + +/* Boot time */ + +#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 } + +struct limine_boot_time_response { + uint64_t revision; + int64_t boot_time; +}; + +struct limine_boot_time_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_boot_time_response *) response; +}; + +/* Kernel address */ + +#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 } + +struct limine_kernel_address_response { + uint64_t revision; + uint64_t physical_base; + uint64_t virtual_base; +}; + +struct limine_kernel_address_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_kernel_address_response *) response; +}; + +/* Device Tree Blob */ + +#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 } + +struct limine_dtb_response { + uint64_t revision; + LIMINE_PTR(void *) dtb_ptr; +}; + +struct limine_dtb_request { + uint64_t id[4]; + uint64_t revision; + LIMINE_PTR(struct limine_dtb_response *) response; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/include/mm/pmm.h b/kernel/include/mm/pmm.h new file mode 100644 index 0000000..bfe21c5 --- /dev/null +++ b/kernel/include/mm/pmm.h @@ -0,0 +1,27 @@ +#ifndef PMM_H +#define PMM_H + +#include +#include +#include + +enum mm_type { + MEM_USABLE, + MEM_RESERVED +}; + +struct MMEntry { + uint64_t base; + uint64_t length; + mm_type type; +}; + +struct PBitmap { + uint64_t* addr; + size_t size; + MMEntry entry; +}; + +void pmm_init(limine_memmap_response* memmap, uint64_t hhdm_offset); + +#endif \ No newline at end of file diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index a0394ea..e72500e 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -12,7 +12,7 @@ unsigned int _kernel_begin; unsigned int _kernel_end; -extern "C" void kernel_main(void) { +void kernel_main(void) { // Initialize terminal //terminal_initialize(); diff --git a/kernel/makefile b/kernel/makefile index dfced86..030caaa 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -3,15 +3,16 @@ CFLAGS := -ffreestanding -Wall -Wextra -g -std=gnu99 -O2 -Iinclude --sysroot=$(SYSROOT) \ -isystem="/usr/include" CXXFLAGS := -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -g -O2 -Iinclude --sysroot=$(SYSROOT) \ - -isystem="/usr/include" + -isystem="/usr/include" -std=gnu++20 LDFLAGS := -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude --sysroot=$(SYSROOT) \ -isystem="/usr/include" ASMFLAGS := ifeq ($(ARCH),x86_64) -CFLAGS += -mno-red-zone -mcmodel=kernel -mno-sse -mno-sse2 -mno-mmx -CXXFLAGS += -mno-red-zone -mcmodel=kernel -mno-sse -mno-sse2 -mno-mmx -LDFLAGS += -mno-red-zone -mcmodel=kernel -mno-sse -mno-sse2 -mno-mmx +CFLAGS += -mno-red-zone -mcmodel=kernel -mno-80387 -mno-sse -mno-sse2 -mno-mmx +CXXFLAGS += -mno-red-zone -mcmodel=kernel -mno-80387 -mno-sse -mno-sse2 -mno-mmx +LDFLAGS += -mno-red-zone -mcmodel=kernel -mno-80387 -mno-sse -mno-sse2 -mno-mmx \ + -z max-page-size=0x1000 ASMFLAGS += -felf64 endif @@ -75,4 +76,4 @@ install-headers: $(HEADERS) clean: $(info [INFO] Cleaning) - $(RM) ${OBJS} $(DEPFILES) kernel.bin \ No newline at end of file + $(RM) ${OBJS} $(DEPFILES) kernel.bin diff --git a/kernel/mm/pmm.cpp b/kernel/mm/pmm.cpp new file mode 100644 index 0000000..bd8f12c --- /dev/null +++ b/kernel/mm/pmm.cpp @@ -0,0 +1,55 @@ +#include +#include + +PBitmap bitmap; + +// Finds the biggest chunk of memory +static MMEntry find_mem_chunk(limine_memmap_response* memmap) { + uint64_t highestmem = 0; + size_t highestindex = 0; + limine_memmap_entry* entries = memmap->entries[0]; + for (size_t i = 0; i < memmap->entry_count; i++) { + if (entries[i].type == LIMINE_MEMMAP_USABLE && entries[i].length > highestmem) { + highestmem = entries[i].length; + highestindex = i; + } + } + + return MMEntry{ + entries[highestindex].base, + entries[highestindex].length, + MEM_USABLE + }; +} + +void pmm_init(limine_memmap_response* memmap, uint64_t hhdm_offset) { + MMEntry mem_entry = find_mem_chunk(memmap); + + // Round any numbers needed to 4K boudaries + //mem_entry.base += 4096 - (mem_entry.base % 4096); + mem_entry.length -= mem_entry.length % 4096; + + // setup bitmap at the beginning of the chunk + bitmap.entry = mem_entry; + bitmap.addr = (uint64_t*)(bitmap.entry.base + hhdm_offset); + // divided by byte size since size is for iterating over the bitmap + bitmap.size = mem_entry.length / 4096 / sizeof(uint64_t); + + printf("addr: %lx\nsize: %lx\n", (uint64_t)bitmap.addr, bitmap.size); + printf("hhdm offset: %lx\n", hhdm_offset); + + // write test + for (size_t i = 0; i < 100; i++) { + bitmap.addr[i] = i; + //printf("value %d: %lx\n", i, bitmap.addr[i]); + } + + // read test + for (size_t i = 0; i < bitmap.size; i++) { + //printf("value %d: %lx\n"); + } +} + +uint64_t get_phys_page() { + +} \ No newline at end of file diff --git a/libc/printf.c b/libc/printf.c index 72a4749..0bb5506 100644 --- a/libc/printf.c +++ b/libc/printf.c @@ -37,10 +37,14 @@ static const char* itoa(unsigned int num, char* str, unsigned int base) { } // reverse the string - for (int i = 0; i < cou; i++) { - char temp = str[i]; - str[i] = str[cou - i - 1]; - str[cou - 1] = temp; + size_t start = 0; + size_t end = cou - 1; + while (start < end) { + char temp = str[start]; + str[start] = str[end]; + str[end] = temp; + ++start; + --end; } str[cou] = '\0'; @@ -49,7 +53,7 @@ static const char* itoa(unsigned int num, char* str, unsigned int base) { // have no idea if there's a better way to do this. for %lx static const char* itoa_u64(unsigned long long num, char* str, int base) { - int cou = 0; // nt + size_t cou = 0; // nt if (num == 0) { // 0 str[cou] = '0'; @@ -71,10 +75,14 @@ static const char* itoa_u64(unsigned long long num, char* str, int base) { } // reverse the string - for (int i = 0; i < cou; i++) { - char temp = str[i]; - str[i] = str[cou - i - 1]; - str[cou - 1] = temp; + size_t start = 0; + size_t end = cou - 1; + while (start < end) { + char temp = str[start]; + str[start] = str[end]; + str[end] = temp; + ++start; + --end; } str[cou] = '\0'; diff --git a/makefile b/makefile index d8535bc..8717518 100644 --- a/makefile +++ b/makefile @@ -34,10 +34,11 @@ limine: build-all -no-emul-boot -boot-load-size 4 -boot-info-table \ --efi-boot boot/limine/limine-uefi-cd.bin \ -efi-boot-part --efi-boot-image --protective-msdos-label \ - isodir -o emuos.iso + isodir -o $(OS_NAME).iso + limine bios-install $(OS_NAME).iso qemu: limine - $(QEMU) -no-shutdown -no-reboot --serial stdio -s -m 512 -hda $(OS_NAME).iso + $(QEMU) -no-shutdown -no-reboot --serial stdio -s -m 1024 -hda $(OS_NAME).iso install: install-headers install-libraries -- cgit v1.2.3-70-g09d2