From 48410e65809731e4aa5b027fed82bf481ae9b21d Mon Sep 17 00:00:00 2001 From: jasonp019 Date: Sun, 8 May 2022 01:20:27 -0700 Subject: [PATCH 1/6] Update stdio.c added basic support for field widths in the format string for numbers, including left-justifying them. not yet implemented changing the prefix from ' '. also, not implemented for non-numbers. --- src/bootloader/stage2/stdio.c | 356 ++++++++++++++++++++++++---------- 1 file changed, 256 insertions(+), 100 deletions(-) diff --git a/src/bootloader/stage2/stdio.c b/src/bootloader/stage2/stdio.c index 13fb464..303c251 100644 --- a/src/bootloader/stage2/stdio.c +++ b/src/bootloader/stage2/stdio.c @@ -1,39 +1,38 @@ -#include "stdio.h" -#include "x86.h" - +#include #include -#include +#include "x86.h" -const unsigned SCREEN_WIDTH = 80; -const unsigned SCREEN_HEIGHT = 25; +const unsigned int SCREEN_WIDTH = 80; +const unsigned int SCREEN_HEIGHT = 25; const uint8_t DEFAULT_COLOR = 0x7; uint8_t* g_ScreenBuffer = (uint8_t*)0xB8000; -int g_ScreenX = 0, g_ScreenY = 0; +int g_ScreenX = 0; +int g_ScreenY = 0; -void putchr(int x, int y, char c) +char getchr(int x, int y) { - g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x)] = c; + return (char)g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x)]; } -void putcolor(int x, int y, uint8_t color) +void putchr(int x, int y, char c) { - g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x) + 1] = color; + g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x)] = c; } -char getchr(int x, int y) +uint8_t getcolor(int x, int y) { - return g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x)]; + return g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x) + 1]; } -uint8_t getcolor(int x, int y) +void putcolor(int x, int y, uint8_t color) { - return g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x) + 1]; + g_ScreenBuffer[2 * (y * SCREEN_WIDTH + x) + 1] = color; } void setcursor(int x, int y) { - int pos = y * SCREEN_WIDTH + x; + uint16_t pos = y * SCREEN_WIDTH + x; x86_outb(0x3D4, 0x0F); x86_outb(0x3D5, (uint8_t)(pos & 0xFF)); @@ -46,92 +45,162 @@ void clrscr() for (int y = 0; y < SCREEN_HEIGHT; y++) for (int x = 0; x < SCREEN_WIDTH; x++) { - putchr(x, y, '\0'); + putchr(x, y, 0); putcolor(x, y, DEFAULT_COLOR); } g_ScreenX = 0; g_ScreenY = 0; - setcursor(g_ScreenX, g_ScreenY); + setcursor(0, 0); } -void scrollback(int lines) +void scrollback() { - for (int y = lines; y < SCREEN_HEIGHT; y++) + for (int y = 1; y < SCREEN_HEIGHT; y++) for (int x = 0; x < SCREEN_WIDTH; x++) { - putchr(x, y - lines, getchr(x, y)); - putcolor(x, y - lines, getcolor(x, y)); + putchr(x, y - 1, getchr(x, y)); + putcolor(x, y - 1, getcolor(x, y)); } - for (int y = SCREEN_HEIGHT - lines; y < SCREEN_HEIGHT; y++) - for (int x = 0; x < SCREEN_WIDTH; x++) - { - putchr(x, y, '\0'); - putcolor(x, y, DEFAULT_COLOR); - } + for (int x = 0; x < SCREEN_WIDTH; x++) + { + putchr(x, SCREEN_HEIGHT - 1, 0); + putcolor(x, SCREEN_HEIGHT - 1, DEFAULT_COLOR); + } - g_ScreenY -= lines; + g_ScreenY -= 1; } void putc(char c) { switch (c) { - case '\n': - g_ScreenX = 0; - g_ScreenY++; - break; + case '\n': g_ScreenX = 0; g_ScreenY++; + break; - case '\t': - for (int i = 0; i < 4 - (g_ScreenX % 4); i++) - putc(' '); - break; + case '\t': for (int i = 0; i < 4 - (g_ScreenX % 4); i++) + putc(' '); + break; - case '\r': - g_ScreenX = 0; - break; + case '\r': g_ScreenX = 0; + break; - default: - putchr(g_ScreenX, g_ScreenY, c); - g_ScreenX++; - break; + default: putchr(g_ScreenX, g_ScreenY, c); + g_ScreenX += 1; + break; } - if (g_ScreenX >= SCREEN_WIDTH) - { + if (g_ScreenX >= SCREEN_WIDTH) { + g_ScreenX -= SCREEN_WIDTH; g_ScreenY++; - g_ScreenX = 0; } + if (g_ScreenY >= SCREEN_HEIGHT) - scrollback(1); + scrollback(); setcursor(g_ScreenX, g_ScreenY); } void puts(const char* str) { - while(*str) + while (*str) { putc(*str); - str++; + ++str; + } +} + +unsigned long long pow(const unsigned long base, const unsigned long exp) +{ + unsigned long long r = 1; + unsigned long count = exp; + + while (count > 0) { + r *= base; + count--; + } + + return r; +} + +unsigned int num_digits(const unsigned long long num, const unsigned int radix) + { + unsigned int count = 0; + unsigned long long t_num = num; + + if (num == 0) { return 1; } + + while (1) { + unsigned long long q, r; + + q = t_num / radix; + r = t_num % radix; + + if ((q == r) && (q == 0)) { + break; + } + + t_num = q; + count++; } + + return count; +} + +unsigned long long abs(const long long num) +{ + return (num >= 0) ? num : (-1 * num); } +#define PRINTF_STATE_NORMAL 0 +#define PRINTF_STATE_WIDTH 1 +#define PRINTF_STATE_LENGTH 2 +#define PRINTF_STATE_LENGTH_SHORT 3 +#define PRINTF_STATE_LENGTH_LONG 4 +#define PRINTF_STATE_SPEC 5 + +#define PRINTF_LENGTH_DEFAULT 0 +#define PRINTF_WIDTH_DEFAULT 0 +#define PRINTF_LENGTH_SHORT_SHORT 1 +#define PRINTF_LENGTH_SHORT 2 +#define PRINTF_LENGTH_LONG 3 +#define PRINTF_LENGTH_LONG_LONG 4 + + const char g_HexChars[] = "0123456789abcdef"; +void printf_unsigned(unsigned long long, int); + +void printf_print_width(unsigned long long number, unsigned long long width, unsigned int radix) +{ + unsigned long long t_number = number; + unsigned long long n_digs = num_digits(number, radix); + unsigned long long t_width; + + // if no width calculated or # has more digits than the width, just + // return without printing the padding to the width + if ((width <= 0) || (width <= n_digs)) { return; } + + t_width = width - n_digs; + + while (t_width-- > 0) { + putc(' '); + } +} + void printf_unsigned(unsigned long long number, int radix) { + unsigned long long num = number; char buffer[32]; int pos = 0; - // convert number to ASCII do { - unsigned long long rem = number % radix; - number /= radix; + unsigned long long rem = num % radix; + num /= radix; buffer[pos++] = g_HexChars[rem]; - } while (number > 0); + } while (num > 0); // print number in reverse order while (--pos >= 0) @@ -143,23 +212,14 @@ void printf_signed(long long number, int radix) if (number < 0) { putc('-'); - printf_unsigned(-number, radix); + printf_unsigned((unsigned long long)(-number), radix); + } + else + { + printf_unsigned((unsigned long long)number, radix); } - else printf_unsigned(number, radix); } -#define PRINTF_STATE_NORMAL 0 -#define PRINTF_STATE_LENGTH 1 -#define PRINTF_STATE_LENGTH_SHORT 2 -#define PRINTF_STATE_LENGTH_LONG 3 -#define PRINTF_STATE_SPEC 4 - -#define PRINTF_LENGTH_DEFAULT 0 -#define PRINTF_LENGTH_SHORT_SHORT 1 -#define PRINTF_LENGTH_SHORT 2 -#define PRINTF_LENGTH_LONG 3 -#define PRINTF_LENGTH_LONG_LONG 4 - void printf(const char* fmt, ...) { va_list args; @@ -167,9 +227,11 @@ void printf(const char* fmt, ...) int state = PRINTF_STATE_NORMAL; int length = PRINTF_LENGTH_DEFAULT; - int radix = 10; - bool sign = false; + int width = PRINTF_WIDTH_DEFAULT; + bool left_align_width = false; bool number = false; + bool sign = false; + int radix = 10; while (*fmt) { @@ -178,13 +240,64 @@ void printf(const char* fmt, ...) case PRINTF_STATE_NORMAL: switch (*fmt) { - case '%': state = PRINTF_STATE_LENGTH; + case '%': state = PRINTF_STATE_WIDTH; break; default: putc(*fmt); break; } break; + case PRINTF_STATE_WIDTH: + { + switch (*fmt) { + case '-': + left_align_width = true; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + char *wptr = fmt; + char w_chars[10]; + int num_width_chars = 0; + + while (1) { + if (*wptr < '0' || *wptr > '9') { + int pwr = 0; + + // compute the width + for (--num_width_chars; num_width_chars >= 0; num_width_chars--) { + width += pow(10, pwr) * w_chars[num_width_chars]; + pwr++; + } + + // no longer in the width calculation mode + fmt = wptr; + break; + } + + w_chars[num_width_chars++] = (*wptr) - '0'; + wptr++; + } + state = PRINTF_STATE_LENGTH; + continue; + + default: + state = PRINTF_STATE_LENGTH; + continue; + } + + break; + } + break; + case PRINTF_STATE_LENGTH: switch (*fmt) { @@ -223,64 +336,106 @@ void printf(const char* fmt, ...) case 'c': putc((char)va_arg(args, int)); break; - case 's': - puts(va_arg(args, const char*)); + case 's': puts(va_arg(args, const char*)); break; case '%': putc('%'); break; case 'd': - case 'i': radix = 10; sign = true; number = true; + case 'i': number = true; radix = 10; sign = true; break; - case 'u': radix = 10; sign = false; number = true; + case 'u': number = true; radix = 10; sign = false; break; case 'X': case 'x': - case 'p': radix = 16; sign = false; number = true; + case 'p': number = true; radix = 16; sign = false; break; - case 'o': radix = 8; sign = false; number = true; + case 'o': number = true; radix = 8; sign = false; break; // ignore invalid spec default: break; } + // handle numbers if (number) { - if (sign) + if (sign) { switch (length) { - case PRINTF_LENGTH_SHORT_SHORT: - case PRINTF_LENGTH_SHORT: - case PRINTF_LENGTH_DEFAULT: printf_signed(va_arg(args, int), radix); - break; - - case PRINTF_LENGTH_LONG: printf_signed(va_arg(args, long), radix); - break; - - case PRINTF_LENGTH_LONG_LONG: printf_signed(va_arg(args, long long), radix); - break; + case PRINTF_LENGTH_SHORT_SHORT: + case PRINTF_LENGTH_SHORT: + case PRINTF_LENGTH_DEFAULT: int si = va_arg(args, int); + if (left_align_width == true) { + printf_signed(si, radix); + } + printf_print_width(abs(si), width, radix); + if (left_align_width == false) { + printf_signed(si, radix); + } + break; + + case PRINTF_LENGTH_LONG: long sl = va_arg(args, long); + if (left_align_width == true) { + printf_signed(sl, radix); + } + printf_print_width(abs(sl), width, radix); + if (left_align_width == false) { + printf_signed(sl, radix); + } + break; + + case PRINTF_LENGTH_LONG_LONG: long long sll = va_arg(args, long long); + if (left_align_width == true) { + printf_signed(sll, radix); + } + printf_print_width(abs(sll), width, radix); + if (left_align_width == false) { + printf_signed(sll, radix); + } + break; } } else { switch (length) { - case PRINTF_LENGTH_SHORT_SHORT: - case PRINTF_LENGTH_SHORT: - case PRINTF_LENGTH_DEFAULT: printf_unsigned(va_arg(args, unsigned int), radix); - break; - - case PRINTF_LENGTH_LONG: printf_unsigned(va_arg(args, unsigned long), radix); - break; - - case PRINTF_LENGTH_LONG_LONG: printf_unsigned(va_arg(args, unsigned long long), radix); - break; + case PRINTF_LENGTH_SHORT_SHORT: + case PRINTF_LENGTH_SHORT: + case PRINTF_LENGTH_DEFAULT: unsigned int ui = va_arg(args, unsigned int); + if (left_align_width == true) { + printf_unsigned(ui, radix); + } + printf_print_width(ui, width, radix); + if (left_align_width == false) { + printf_unsigned(ui, radix); + } + break; + + case PRINTF_LENGTH_LONG: unsigned long ul = va_arg(args, unsigned long); + if (left_align_width == true) { + printf_unsigned(ul, radix); + } + printf_print_width(ul, width, radix); + if (left_align_width == false) { + printf_unsigned(ul, radix); + } + break; + + case PRINTF_LENGTH_LONG_LONG: unsigned long long ull = va_arg(args, unsigned long long); + if (left_align_width == true) { + printf_unsigned(ull, radix); + } + printf_print_width(ull, width, radix); + if (left_align_width == false) { + printf_unsigned(ull, radix); + } + break; } } } @@ -288,6 +443,7 @@ void printf(const char* fmt, ...) // reset state state = PRINTF_STATE_NORMAL; length = PRINTF_LENGTH_DEFAULT; + width = PRINTF_WIDTH_DEFAULT; radix = 10; sign = false; number = false; @@ -296,11 +452,11 @@ void printf(const char* fmt, ...) fmt++; } - va_end(args); } -void print_buffer(const char* msg, const void* buffer, uint32_t count) + +void print_buffer(const char* msg, const void* buffer, uint16_t count) { const uint8_t* u8Buffer = (const uint8_t*)buffer; From 88ee732b9d85faa1b6db7e6e8fd481b11c326674 Mon Sep 17 00:00:00 2001 From: WoffleTbh Date: Fri, 2 Sep 2022 20:50:57 +0200 Subject: [PATCH 2/6] Various fixes --- README.md | 12 ++++-------- requirements.txt | 2 ++ scripts/install_deps.sh | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) create mode 100644 requirements.txt diff --git a/README.md b/README.md index 081a60c..a6155f4 100644 --- a/README.md +++ b/README.md @@ -10,21 +10,17 @@ First, install the following dependencies: sudo apt install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo wget \ nasm mtools python3 python3-pip python3-parted scons dosfstools libguestfs-tools qemu-system-x86 -sudo pip3 install sh - # Fedora: sudo dnf install gcc gcc-c++ make bison flex gmp-devel libmpc-devel mpfr-devel texinfo wget \ nasm mtools python3 python3-pip python3-pyparted python3-scons dosfstools guestfs-tools qemu-system-x86 -sudo pip3 install sh - # Arch & Arch-based: -paru -S gcc make bison flex libgmp-static libmpc mpfr texinfo nasm mtools qemu-system-x86 python3 python3-scons - -sudo pip3 install sh +paru -S gcc make bison flex libgmp-static libmpc mpfr texinfo nasm mtools qemu-system-x86 python3 scons ``` NOTE: to install all the required packages on Arch, you need an [AUR helper](https://wiki.archlinux.org/title/AUR_helpers). +Then you must run `python3 -m pip install -r requirements.txt` + After that, run `scons toolchain`, this should download and build the required tools (binutils and GCC). If you encounter errors during this step, you might have to modify `build_scripts/config.mk` and try a different version of **binutils** and **gcc**. Using the same version as the one bundled with your distribution is your best bet. Finally, you should be able to run `scons`. Use `scons run` to test your OS using qemu. @@ -32,4 +28,4 @@ Finally, you should be able to run `scons`. Use `scons run` to test your OS usin ## Links * [Discord channel](https://discord.gg/RgHc5XrCEw) -* [Patreon](https://www.patreon.com/nanobyte) \ No newline at end of file +* [Patreon](https://www.patreon.com/nanobyte) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9586fdc --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +sh +pyparted diff --git a/scripts/install_deps.sh b/scripts/install_deps.sh index dc82fd7..baf032e 100755 --- a/scripts/install_deps.sh +++ b/scripts/install_deps.sh @@ -61,7 +61,7 @@ DEPS_ARCH=( mtools qemu-system-x86 python3-pip - python3-scons + scons ) DEPS_SUSE=() @@ -120,4 +120,4 @@ case "$choice" in esac $PACKAGE_UPDATE -$PACKAGE_INSTALL ${DEPS[@]} \ No newline at end of file +$PACKAGE_INSTALL ${DEPS[@]} From 810dcce1b207400e74433eb02e1ac23ee0a4d08d Mon Sep 17 00:00:00 2001 From: Tiberiu Chibici Date: Tue, 4 Oct 2022 14:38:15 +0300 Subject: [PATCH 3/6] Memory detection --- SConstruct | 4 ++ src/bootloader/stage2/SConscript | 10 +++-- src/bootloader/stage2/main.c | 12 +++++- src/bootloader/stage2/memdetect.c | 35 +++++++++++++++ src/bootloader/stage2/memdetect.h | 5 +++ src/bootloader/stage2/x86.asm | 71 +++++++++++++++++++++++++++++++ src/bootloader/stage2/x86.h | 56 ++++++++++++++++-------- src/kernel/SConscript | 6 ++- src/kernel/main.c | 15 ++++++- src/libs/boot/bootparams.h | 19 +++++++++ 10 files changed, 207 insertions(+), 26 deletions(-) create mode 100644 src/bootloader/stage2/memdetect.c create mode 100644 src/bootloader/stage2/memdetect.h create mode 100644 src/libs/boot/bootparams.h diff --git a/SConstruct b/SConstruct index 235224f..dc312b8 100644 --- a/SConstruct +++ b/SConstruct @@ -56,6 +56,10 @@ HOST_ENVIRONMENT = Environment(variables=VARS, STRIP = 'strip', ) +HOST_ENVIRONMENT.Append( + PROJECTDIR = HOST_ENVIRONMENT.Dir('.').srcnode() +) + if HOST_ENVIRONMENT['config'] == 'debug': HOST_ENVIRONMENT.Append(CCFLAGS = ['-O0']) else: diff --git a/src/bootloader/stage2/SConscript b/src/bootloader/stage2/SConscript index 64a0708..8b2a257 100644 --- a/src/bootloader/stage2/SConscript +++ b/src/bootloader/stage2/SConscript @@ -12,9 +12,13 @@ env.Append( '-Wl,-T', env.File('linker.ld').srcnode().path, '-Wl,-Map=' + env.File('stage2.map').path ], - CPATH = [ env.Dir('.').srcnode() ], - CPPPATH = [ env.Dir('.').srcnode() ], - ASFLAGS = [ '-I', env.Dir('.').srcnode() ] + CPPPATH = [ + env.Dir('.').srcnode(), + env['PROJECTDIR'].Dir('src/libs') + ], + ASFLAGS = [ + '-I', env.Dir('.').srcnode(), + ] ) sources = GlobRecursive(env, '*.c') + \ diff --git a/src/bootloader/stage2/main.c b/src/bootloader/stage2/main.c index fdfbf50..fd9cd98 100644 --- a/src/bootloader/stage2/main.c +++ b/src/bootloader/stage2/main.c @@ -9,11 +9,15 @@ #include "stdlib.h" #include "string.h" #include "elf.h" +#include "memdetect.h" +#include uint8_t* KernelLoadBuffer = (uint8_t*)MEMORY_LOAD_KERNEL; uint8_t* Kernel = (uint8_t*)MEMORY_KERNEL_ADDR; -typedef void (*KernelStart)(); +BootParams g_BootParams; + +typedef void (*KernelStart)(BootParams* bootParams); void __attribute__((cdecl)) start(uint16_t bootDrive, void* partition) { @@ -35,6 +39,10 @@ void __attribute__((cdecl)) start(uint16_t bootDrive, void* partition) goto end; } + // prepare boot params + g_BootParams.BootDevice = bootDrive; + Memory_Detect(&g_BootParams.Memory); + // load kernel KernelStart kernelEntry; if (!ELF_Read(&part, "/boot/kernel.elf", (void**)&kernelEntry)) @@ -44,7 +52,7 @@ void __attribute__((cdecl)) start(uint16_t bootDrive, void* partition) } // execute kernel - kernelEntry(); + kernelEntry(&g_BootParams); end: for (;;); diff --git a/src/bootloader/stage2/memdetect.c b/src/bootloader/stage2/memdetect.c new file mode 100644 index 0000000..fd6b349 --- /dev/null +++ b/src/bootloader/stage2/memdetect.c @@ -0,0 +1,35 @@ +#include "x86.h" +#include "stdio.h" +#include + +#define MAX_REGIONS 256 + +MemoryRegion g_MemRegions[MAX_REGIONS]; +int g_MemRegionCount; + +void Memory_Detect(MemoryInfo* memoryInfo) +{ + E820MemoryBlock block; + uint32_t continuation = 0; + int ret; + + g_MemRegionCount = 0; + ret = x86_E820GetNextBlock(&block, &continuation); + + while (ret > 0 && continuation != 0) + { + g_MemRegions[g_MemRegionCount].Begin = block.Base; + g_MemRegions[g_MemRegionCount].Length = block.Length; + g_MemRegions[g_MemRegionCount].Type = block.Type; + g_MemRegions[g_MemRegionCount].ACPI = block.ACPI; + ++g_MemRegionCount; + + printf("E820: base=0x%llx length=0x%llx type=0x%x\n", block.Base, block.Length, block.Type); + + ret = x86_E820GetNextBlock(&block, &continuation); + } + + // fill meminfo structure + memoryInfo->RegionCount = g_MemRegionCount; + memoryInfo->Regions = g_MemRegions; +} diff --git a/src/bootloader/stage2/memdetect.h b/src/bootloader/stage2/memdetect.h new file mode 100644 index 0000000..3015c8f --- /dev/null +++ b/src/bootloader/stage2/memdetect.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +void Memory_Detect(MemoryInfo* memoryInfo); \ No newline at end of file diff --git a/src/bootloader/stage2/x86.asm b/src/bootloader/stage2/x86.asm index 0f7ca73..800eb20 100644 --- a/src/bootloader/stage2/x86.asm +++ b/src/bootloader/stage2/x86.asm @@ -245,3 +245,74 @@ x86_Disk_Read: mov esp, ebp pop ebp ret + + +; +; int ASMCALL x86_E820GetNextBlock(E820MemoryBlock* block, uint32_t* continuationId); +; +E820Signature equ 0x534D4150 + +global x86_E820GetNextBlock +x86_E820GetNextBlock: + + ; make new call frame + push ebp ; save old call frame + mov ebp, esp ; initialize new call frame + + x86_EnterRealMode + + ; save modified regs + push ebx + push ecx + push edx + push esi + push edi + push ds + push es + + ; setup params + LinearToSegOffset [bp + 8], es, edi, di ; es:di pointer to structure + + LinearToSegOffset [bp + 12], ds, esi, si ; ebx - pointer to continuationId + mov ebx, ds:[si] + + mov eax, 0xE820 ; eax - function + mov edx, E820Signature ; edx - signature + mov ecx, 24 ; ecx - size of structure + + ; call interrupt + int 0x15 + + ; test results + cmp eax, E820Signature + jne .Error + + .IfSuccedeed: + mov eax, ecx ; return size + mov ds:[si], ebx ; fill continuation parameter + jmp .EndIf + + .Error: + mov eax, -1 + + .EndIf: + + ; restore regs + pop es + pop ds + pop edi + pop esi + pop edx + pop ecx + pop ebx + + push eax + + x86_EnterProtectedMode + + pop eax + + ; restore old call frame + mov esp, ebp + pop ebp + ret \ No newline at end of file diff --git a/src/bootloader/stage2/x86.h b/src/bootloader/stage2/x86.h index 0b5e7f4..48464db 100644 --- a/src/bootloader/stage2/x86.h +++ b/src/bootloader/stage2/x86.h @@ -2,20 +2,42 @@ #include #include -void __attribute__((cdecl)) x86_outb(uint16_t port, uint8_t value); -uint8_t __attribute__((cdecl)) x86_inb(uint16_t port); - -bool __attribute__((cdecl)) x86_Disk_GetDriveParams(uint8_t drive, - uint8_t* driveTypeOut, - uint16_t* cylindersOut, - uint16_t* sectorsOut, - uint16_t* headsOut); - -bool __attribute__((cdecl)) x86_Disk_Reset(uint8_t drive); - -bool __attribute__((cdecl)) x86_Disk_Read(uint8_t drive, - uint16_t cylinder, - uint16_t sector, - uint16_t head, - uint8_t count, - void* lowerDataOut); +#define ASMCALL __attribute__((cdecl)) + +void ASMCALL x86_outb(uint16_t port, uint8_t value); +uint8_t ASMCALL x86_inb(uint16_t port); + +bool ASMCALL x86_Disk_GetDriveParams(uint8_t drive, + uint8_t* driveTypeOut, + uint16_t* cylindersOut, + uint16_t* sectorsOut, + uint16_t* headsOut); + +bool ASMCALL x86_Disk_Reset(uint8_t drive); + +bool ASMCALL x86_Disk_Read(uint8_t drive, + uint16_t cylinder, + uint16_t sector, + uint16_t head, + uint8_t count, + void* lowerDataOut); + +typedef struct +{ + uint64_t Base; + uint64_t Length; + uint32_t Type; + uint32_t ACPI; + +} E820MemoryBlock; + +enum E820MemoryBlockType +{ + E820_USABLE = 1, + E820_RESERVED = 2, + E820_ACPI_RECLAIMABLE = 3, + E820_ACPI_NVS = 4, + E820_BAD_MEMORY = 5, +}; + +int ASMCALL x86_E820GetNextBlock(E820MemoryBlock* block, uint32_t* continuationId); \ No newline at end of file diff --git a/src/kernel/SConscript b/src/kernel/SConscript index 1e97f0a..f19bf1e 100644 --- a/src/kernel/SConscript +++ b/src/kernel/SConscript @@ -13,8 +13,10 @@ env.Append( '-Wl,-T', env.File('linker.ld').srcnode().path, '-Wl,-Map=' + env.File('kernel.map').path ], - CPATH = [ env.Dir('.').srcnode() ], - CPPPATH = [ env.Dir('.').srcnode() ], + CPPPATH = [ + env.Dir('.').srcnode(), + env['PROJECTDIR'].Dir('src/libs') + ], ASFLAGS = [ '-I', env.Dir('.').srcnode(), '-f', 'elf' ] ) diff --git a/src/kernel/main.c b/src/kernel/main.c index a06e6a8..ced6167 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -4,6 +4,7 @@ #include #include #include +#include extern void _init(); @@ -14,14 +15,24 @@ void timer(Registers* regs) printf("."); } -void start(uint16_t bootDrive) +void start(BootParams* bootParams) { // call global constructors _init(); HAL_Initialize(); - log_debug("Main", "This is a debug msg!"); + log_debug("Main", "Boot device: %x", bootParams->BootDevice); + log_debug("Main", "Memory region count: %d", bootParams->Memory.RegionCount); + for (int i = 0; i < bootParams->Memory.RegionCount; i++) + { + log_debug("Main", "MEM: start=0x%llx length=0x%llx type=%x", + bootParams->Memory.Regions[i].Begin, + bootParams->Memory.Regions[i].Length, + bootParams->Memory.Regions[i].Type); + } + + log_info("Main", "This is an info msg!"); log_warn("Main", "This is a warning msg!"); log_err("Main", "This is an error msg!"); diff --git a/src/libs/boot/bootparams.h b/src/libs/boot/bootparams.h new file mode 100644 index 0000000..4d44ef0 --- /dev/null +++ b/src/libs/boot/bootparams.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +typedef struct { + uint64_t Begin, Length; + uint32_t Type; + uint32_t ACPI; +} MemoryRegion; + +typedef struct { + int RegionCount; + MemoryRegion* Regions; +} MemoryInfo; + +typedef struct { + MemoryInfo Memory; + uint8_t BootDevice; +} BootParams; \ No newline at end of file From ec11326fd822e1c9daf29088d19466cca2957fa1 Mon Sep 17 00:00:00 2001 From: makaroneder <83035759+makaroneder@users.noreply.github.com> Date: Sun, 11 Dec 2022 16:38:49 +0100 Subject: [PATCH 4/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a6155f4..060a9a1 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ NOTE: to install all the required packages on Arch, you need an [AUR helper](htt Then you must run `python3 -m pip install -r requirements.txt` -After that, run `scons toolchain`, this should download and build the required tools (binutils and GCC). If you encounter errors during this step, you might have to modify `build_scripts/config.mk` and try a different version of **binutils** and **gcc**. Using the same version as the one bundled with your distribution is your best bet. +After that, run `scons toolchain`, this should download and build the required tools (binutils and GCC). If you encounter errors during this step, you might have to modify `scripts/setup_toolchain.sh` and try a different version of **binutils** and **gcc**. Using the same version as the one bundled with your distribution is your best bet. Finally, you should be able to run `scons`. Use `scons run` to test your OS using qemu. From fe61d210896d05c98a731b2d77cded21c4d2c45f Mon Sep 17 00:00:00 2001 From: chibicitiberiu Date: Wed, 29 Mar 2023 21:12:04 +0300 Subject: [PATCH 5/6] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 060a9a1..3d2df4f 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ NOTE: to install all the required packages on Arch, you need an [AUR helper](htt Then you must run `python3 -m pip install -r requirements.txt` +Next, modify the configuration in `build_scripts/config.py`. The most important is the `toolchain='../.toolchains'` option which sets where the toolchain will be downloaded and built. The default option is in the directory above where the repo is cloned, in a .toolchains directory, but you will get an error if this directory doesn't exist. + After that, run `scons toolchain`, this should download and build the required tools (binutils and GCC). If you encounter errors during this step, you might have to modify `scripts/setup_toolchain.sh` and try a different version of **binutils** and **gcc**. Using the same version as the one bundled with your distribution is your best bet. Finally, you should be able to run `scons`. Use `scons run` to test your OS using qemu. From 933529c8959de11e0111966220106bdaf10f0343 Mon Sep 17 00:00:00 2001 From: ajh123 Date: Wed, 7 Jun 2023 08:37:20 +0100 Subject: [PATCH 6/6] Fix errors in x86.asm again --- src/bootloader/stage2/x86.asm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootloader/stage2/x86.asm b/src/bootloader/stage2/x86.asm index 800eb20..f343eb9 100644 --- a/src/bootloader/stage2/x86.asm +++ b/src/bootloader/stage2/x86.asm @@ -274,7 +274,7 @@ x86_E820GetNextBlock: LinearToSegOffset [bp + 8], es, edi, di ; es:di pointer to structure LinearToSegOffset [bp + 12], ds, esi, si ; ebx - pointer to continuationId - mov ebx, ds:[si] + mov ebx, [ds:si] mov eax, 0xE820 ; eax - function mov edx, E820Signature ; edx - signature @@ -289,7 +289,7 @@ x86_E820GetNextBlock: .IfSuccedeed: mov eax, ecx ; return size - mov ds:[si], ebx ; fill continuation parameter + mov [ds:si], ebx ; fill continuation parameter jmp .EndIf .Error: