15 Commits

Author SHA1 Message Date
03f87723d1 Splash 2026-03-20 10:04:16 +01:00
3607a7179c printf spinlock + remove DEPRECATED stuff + begin separating x86 stuff 2026-03-20 09:01:57 +01:00
424b4c4632 Use MSR to map framebuffer as WC (write-combining) = huge speed diff on real HW 2026-03-19 19:34:31 +01:00
6a82d581fb Fix PMM for real HW + serial lock 2026-03-19 16:54:23 +01:00
b77c53ae99 Keyboard buffer + getline 2026-03-18 13:07:26 +01:00
f7735eb3a4 Move headers to include/ 2026-03-18 11:48:33 +01:00
a1e8aacd01 improve README.md 2026-03-17 10:33:10 +01:00
ccc8985d4c Merge pull request 'Improve Makefile' (#15) from furtest/pepperOS:makefile into main
Reviewed-on: #15
2026-03-15 21:17:44 +01:00
0482f594ef Flanterm back to bump alloc (allows earlier use for real hw debugging) 2026-03-15 21:11:47 +01:00
b02a4b5284 Fix build-iso prerequisites 2026-03-15 18:05:24 +01:00
32f3889565 Move PHONY tags and fix clean
Move the PHONY tags to make them clearer to read.
Fix the clean rule so it deletes the build directory.
2026-03-15 18:01:35 +01:00
803ac0879b Auto find source files check for changes
Previously the build process removed everything and did all the build
again on each make invocation.
This fixes this behaviour with two changes.
First dynamically find the list of files to build using find instead of
a manually written list.
Then use implicit rules to only build files that need to be built again
instead of recompiling everything.
2026-03-15 17:56:26 +01:00
9fc55f98d8 Use variables for build and pepperk and rename build target.
Instead of hardcoding the names set them using a variable.
Also rename the target build to the name of the file it builds which is
in the ELFFILE variable.
2026-03-15 16:58:04 +01:00
11bd628821 Extract CC and LD to variables.
This allows to change the name of the compiler or linker when calling
make.
2026-03-15 16:57:29 +01:00
80d8b49560 Merge pull request 'spinlock' (#14) from spinlock into main
Reviewed-on: #14
2026-03-15 09:55:45 +01:00
51 changed files with 522 additions and 253 deletions

View File

@@ -1,31 +1,41 @@
SOURCES = src/sched/spinlock.c src/debug/misc.c src/io/term/flanterm_backends/fb.c src/io/term/flanterm.c src/debug/panic.c src/debug/stacktrace.c src/boot/boot.c src/sched/scheduler.c src/sched/process.c src/mem/heap/kheap.c src/mem/paging/vmm.c src/mem/paging/paging.c src/mem/paging/pmm.c src/string/string.c src/io/kbd/ps2.c src/io/serial/serial.c src/io/term/term.c src/idt/idt.c src/mem/gdt/gdt.c src/mem/misc/utils.c src/time/timer.c src/kmain.c
BUILDDIR := build
ELFFILE := pepperk
SRC := src
SOURCES := $(shell find src -name '*.c')
OBJFILES := $(patsubst $(SRC)/%.c, $(BUILDDIR)/%.o, $(SOURCES))
CC := x86_64-elf-gcc
CC_FLAGS=-Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-omit-frame-pointer -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel CC_FLAGS=-Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fno-stack-protector -fno-omit-frame-pointer -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel
CC_PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable CC_PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
.PHONY: build build-iso debug debug2 run clean LD := x86_64-elf-ld
build: $(ELFFILE): $(BUILDDIR) $(OBJFILES)
mkdir -p build nasm -f elf64 src/arch/x86/idt.S -o $(BUILDDIR)/idt_stub.o
rm -f *.o build/*.o $(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o
x86_64-elf-gcc -g -c -Isrc $(SOURCES) $(CC_PROBLEMATIC_FLAGS) $(CC_FLAGS) # Get the symbols for debugging
mv *.o build/ nm -n $(ELFFILE) | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
nasm -f elf64 src/idt/idt.S -o build/idt_stub.o
x86_64-elf-ld -o pepperk -T linker.ld build/*.o
nm -n pepperk | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
python3 symbols.py python3 symbols.py
nasm -f elf64 symbols.S -o build/symbols.o nasm -f elf64 symbols.S -o $(BUILDDIR)/symbols.o
x86_64-elf-ld -o pepperk -T linker.ld build/*.o $(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o $(BUILDDIR)/symbols.o
$(BUILDDIR):
@mkdir -p $(BUILDDIR)
$(BUILDDIR)/%.o: $(SRC)/%.c
mkdir -p $(dir $@)
$(CC) -g -c -Iinclude $< $(CC_PROBLEMATIC_FLAGS) $(CC_FLAGS) -o $@
limine/limine: limine/limine:
rm -rf limine rm -rf limine
git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1
$(MAKE) -C limine $(MAKE) -C limine
build-iso: limine/limine build build-iso: limine/limine $(ELFFILE)
rm -rf iso_root rm -rf iso_root
mkdir -p iso_root/boot mkdir -p iso_root/boot
cp -v pepperk iso_root/boot cp -v $(ELFFILE) iso_root/boot
mkdir -p iso_root/boot/limine mkdir -p iso_root/boot/limine
cp -v limine.conf iso_root/boot/limine cp -v limine.conf iso_root/boot/limine
mkdir -p iso_root/EFI/BOOT mkdir -p iso_root/EFI/BOOT
@@ -39,16 +49,20 @@ build-iso: limine/limine build
iso_root -o pepper.iso iso_root -o pepper.iso
./limine/limine bios-install pepper.iso ./limine/limine bios-install pepper.iso
.PHONY: debug
debug: debug:
/usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -D qemu.log -no-reboot -no-shutdown & /usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -D qemu.log -no-reboot -no-shutdown &
gdb pepperk --command=debug.gdb gdb $(ELFFILE) --command=debug.gdb
.PHONY: debug2
debug2: debug2:
/usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -no-reboot -no-shutdown & /usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -no-reboot -no-shutdown &
pwndbg pepperk --command=debug.gdb pwndbg $(ELFFILE) --command=debug.gdb
.PHONY: run
run: build-iso run: build-iso
/usr/bin/qemu-system-x86_64 -cdrom pepper.iso -serial stdio /usr/bin/qemu-system-x86_64 -cdrom pepper.iso -serial stdio
.PHONY: clean
clean: clean:
rm -rf *.o symbols.map symbols.S pepperk iso_root pepper.iso limine build/*.o rm -rf $(BUILDDIR) symbols.map symbols.S $(ELFFILE) iso_root pepper.iso limine

View File

@@ -1,17 +1,38 @@
# <img width="40" height="40" alt="red-pepper" src="https://i.ibb.co/mrHH6d1m/pixil-frame-0-4.png" /> pepperOS: "will never be done" # <img width="40" height="40" alt="red-pepper" src="https://i.ibb.co/mrHH6d1m/pixil-frame-0-4.png" /> pepperOS: "will never be done"
## Trying the kernel ## Description
First install the dependencies: `sudo apt install python3 xorriso make qemu-system` PepperOS is a 64-bit freely-licensed monolithic kernel for x86 processors, with round-robin preemptive scheduling and 4-level paging. See the [manual](docs/MANUAL.md) for more.
Also, you have to get an x86_64 toolchain for compilation. The easiest way to do that on most systems is to install it from Homebrew: ## Trying the kernel in QEMU
### Debian-based distributions
First, install the dependencies: `sudo apt install nasm python3 xorriso make qemu-system`
Then, you can get an x86_64 toolchain for compilation. The easiest way to do that on most systems is to install it from Homebrew:
``` ```
brew install x86_64-elf-gcc brew install x86_64-elf-gcc
``` ```
Then, to compile the kernel and make an ISO image file: `make build-iso` If you're already on a 64-bit machine (which you probably are), and don't want to install a cross-compiler, you can just override `CC` and `LD` variables in the Makefile, like so:
To run it with QEMU, `make run`
```
CC := gcc
LD := ld
```
Then, to compile the kernel and make an ISO image file, run: `make build-iso`
To run it with QEMU, do: `make run`
## Trying the kernel on real hardware
Compile the kernel and generate an ISO image like described above, then burn the image to a USB stick, `/dev/sdX` being the device name (you can get it using `lsblk`):
```
sudo dd if=pepper.iso of=/dev/sdX
```
## TODO ## TODO
@@ -44,7 +65,7 @@ In the future, maybe?
PepperOS wouldn't be possible without the following freely-licensed software: PepperOS wouldn't be possible without the following freely-licensed software:
- the [Limine](https://codeberg.org/Limine/Limine) portable bootloader - the [Limine](https://codeberg.org/Limine/Limine) portable bootloader
- Marco Paland's freestanding [printf implementation](https://github.com/mpaland) - Charles Nicholson's [nanoprintf](https://github.com/charlesnicholson/nanoprintf)
- Mintuski's [Flanterm](https://codeberg.org/Mintsuki/Flanterm) terminal emulator - Mintuski's [Flanterm](https://codeberg.org/Mintsuki/Flanterm) terminal emulator
...and without these amazing resources: ...and without these amazing resources:
@@ -52,3 +73,4 @@ PepperOS wouldn't be possible without the following freely-licensed software:
- the [OSDev](https://osdev.org) wiki & forums - the [OSDev](https://osdev.org) wiki & forums
- Intel 64 and IA-32 Architectures Software Developer's Manual - Intel 64 and IA-32 Architectures Software Developer's Manual
- Documentation for the [GNU Compiler Collection](https://gcc.gnu.org/onlinedocs/gcc/) - Documentation for the [GNU Compiler Collection](https://gcc.gnu.org/onlinedocs/gcc/)
- dreamos82's [OSDev Notes](https://github.com/dreamportdev/Osdev-Notes/tree/master)

40
docs/MANUAL.md Normal file
View File

@@ -0,0 +1,40 @@
# PepperOS Manual
# Table of Contents
- [Overview](#i-overview)
- [Supported Hardware](#a-supported-hardware)
- [Features](#b-features)
- [Kernel architecture](#ii-kernel-architecture)
- [Boot process](#a-boot-process)
- [Memory management](#b-memory-management)
- [Scheduling](#c-scheduling)
- [Input/output](#d-inputoutput)
- [Syscall table](#iii-syscall-table)
## I. Overview
## a. Supported Hardware
The recommended hardware to run PepperOS is the following:
- UEFI/BIOS
- Any x86 processor, 64-bits only
- PS/2 Keyboard
- Minimum 128MB of memory
## b. Features
## II. Kernel architecture
### a. Boot process
### b. Memory management
### c. Scheduling
### d. Input/Output
## III. Syscall table
Not yet implemented.

View File

@@ -1,14 +1,17 @@
/* #ifndef X86_H
* @author xamidev <xamidev@riseup.net> #define X86_H
* @brief Interrupt Descriptor Table setup and dispatching
* @license GPL-3.0-only
*/
#ifndef IDT_H
#define IDT_H
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
uint64_t rdmsr(uint32_t msr);
void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx);
void wrmsr(uint32_t msr, uint64_t value);
bool x86_has_msr();
void x86_arch_init();
/* Interrupt Descriptor Table */
void idt_init(void); void idt_init(void);
struct interrupt_descriptor { struct interrupt_descriptor {

View File

@@ -11,7 +11,14 @@
#define PEPPEROS_VERSION_MAJOR "0" #define PEPPEROS_VERSION_MAJOR "0"
#define PEPPEROS_VERSION_MINOR "0" #define PEPPEROS_VERSION_MINOR "0"
#define PEPPEROS_VERSION_PATCH "58" #define PEPPEROS_VERSION_PATCH "58"
#define PEPPEROS_SPLASH "\x1b[38;5;196mPepperOS\x1b[0m version "PEPPEROS_VERSION_MAJOR"."PEPPEROS_VERSION_MINOR"."PEPPEROS_VERSION_PATCH"\n" #define PEPPEROS_SPLASH \
"\x1b[38;5;196m \x1b[38;5;231m____ _____\r\n\x1b[0m"\
"\x1b[38;5;196m ____ ___ ____ ____ ___ _____\x1b[38;5;231m/ __ \\/ ___/\r\n\x1b[0m"\
"\x1b[38;5;196m / __ \\/ _ \\/ __ \\/ __ \\/ _ \\/ ___\x1b[38;5;231m/ / / /\\__ \\ \r\n\x1b[0m"\
"\x1b[38;5;196m / /_/ / __/ /_/ / /_/ / __/ / \x1b[38;5;231m/ /_/ /___/ / \r\n\x1b[0m"\
"\x1b[38;5;196m / .___/\\___/ .___/ .___/\\___/_/ \x1b[38;5;231m\\____//____/ \r\n\x1b[0m"\
"\x1b[38;5;196m/_/ /_/ /_/ \r\n\x1b[0m"\
" --- version \x1b[38;5;220m"PEPPEROS_VERSION_MAJOR"."PEPPEROS_VERSION_MINOR"."PEPPEROS_VERSION_PATCH"\x1b[0m built on \x1b[38;5;40m"__DATE__" "__TIME__"\x1b[0m\r\n"
/* process */ /* process */
#define PROCESS_NAME_MAX 64 #define PROCESS_NAME_MAX 64
@@ -31,7 +38,7 @@
#define KERNEL_IDT_ENTRIES 33 #define KERNEL_IDT_ENTRIES 33
/* paging */ /* paging */
#define PAGING_MAX_PHYS 0x100000000 #define PAGING_MAX_PHYS 0x200000000
/* heap */ /* heap */
#define KHEAP_SIZE (32*1024*1024) #define KHEAP_SIZE (32*1024*1024)
@@ -39,6 +46,9 @@
/* term */ /* term */
#define TERM_HISTORY_MAX_LINES 256 #define TERM_HISTORY_MAX_LINES 256
/* kbd */
#define KBD_BUFFER_MAX 256
/* time */ /* time */
#define TIMER_FREQUENCY 1000 #define TIMER_FREQUENCY 1000

View File

@@ -7,7 +7,12 @@
#ifndef PS2_H #ifndef PS2_H
#define PS2_H #define PS2_H
#include <stddef.h>
void keyboard_handler(void); void keyboard_handler(void);
char keyboard_getchar();
int keyboard_putchar(char c);
int keyboard_getline(char* output, size_t size);
#define SHIFT_PRESSED_BIT 0b00000001 #define SHIFT_PRESSED_BIT 0b00000001
#define ALT_PRESSED_BIT 0b00000010 #define ALT_PRESSED_BIT 0b00000010

View File

@@ -8,8 +8,8 @@
#define TERM_H #define TERM_H
void kputs(const char* str); void kputs(const char* str);
void _putchar(char character);
void term_init(void); void term_init(void);
int printf(const char* fmt, ...); int printf(const char* fmt, ...);
void internal_putc(int c, void *_);
#endif #endif

View File

@@ -15,9 +15,9 @@ enum ErrorCodes {
#define CLEAR_INTERRUPTS __asm__ volatile("cli") #define CLEAR_INTERRUPTS __asm__ volatile("cli")
#define SET_INTERRUPTS __asm__ volatile("sti") #define SET_INTERRUPTS __asm__ volatile("sti")
#include "io/serial/serial.h" #include <io/serial/serial.h>
#include "io/term/term.h" #include <io/term/term.h>
#include "idt/idt.h" #include <arch/x86.h>
#include <stdbool.h> #include <stdbool.h>
extern volatile uint64_t ticks; extern volatile uint64_t ticks;

View File

@@ -11,7 +11,7 @@
#include <stdint.h> #include <stdint.h>
#include <limine.h> #include <limine.h>
#include "mem/heap/kheap.h" #include <mem/kheap.h>
#include <kernel.h> #include <kernel.h>
void paging_init(struct boot_context boot_ctx); void paging_init(struct boot_context boot_ctx);

View File

@@ -8,7 +8,7 @@
#define PROCESS_H #define PROCESS_H
#include <stddef.h> #include <stddef.h>
#include "config.h" #include <config.h>
#include <stdint.h> #include <stdint.h>
typedef enum { typedef enum {

View File

@@ -1,6 +1,8 @@
timeout: 3 timeout: 3
interface_branding: Welcome to the PepperOS disk!
/PepperOS /PepperOS
protocol: limine protocol: limine
comment: Default configuration (warning: spicy)
path: boot():/boot/pepperk path: boot():/boot/pepperk

21
src/arch/x86/cpuid.c Normal file
View File

@@ -0,0 +1,21 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief x86 CPU identification
* @license GPL-3.0-only
*/
#include <stdint.h>
#include <stddef.h>
/*
* cpuid - Wrapper for CPUID instruction
* @leaf: Requested leaf (input EAX)
* @eax: EAX register value (output)
* @ebx: EBX register value (output)
* @ecx: ECX register value (output)
* @edx: EDX register value (output)
*/
void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx)
{
__asm__ volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf));
}

View File

@@ -4,16 +4,16 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "idt.h" #include <arch/x86.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include "io/serial/serial.h" #include <io/serial/serial.h>
#include "io/kbd/ps2.h" #include <io/kbd/ps2.h>
#include <kernel.h> #include <kernel.h>
#include <stdbool.h> #include <stdbool.h>
#include "sched/scheduler.h" #include <sched/scheduler.h>
#include "config.h" #include <config.h>
#include "sched/process.h" #include <sched/process.h>
struct interrupt_descriptor idt[256]; struct interrupt_descriptor idt[256];
struct idtr idt_reg; struct idtr idt_reg;

46
src/arch/x86/init.c Normal file
View File

@@ -0,0 +1,46 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief x86 architecture-dependant initialization
* @license GPL-3.0-only
*/
#include <mem/gdt.h>
#include <stdint.h>
#include <arch/x86.h>
#include <kernel.h>
/*
* x86_overwrite_pat - Set PAT to WC
*
* This function overwrites the 1st Page Attribute
* Table entry, to enable the Write-Combining property
* when we map memory regions later on.
* The framebuffer will be mapped with WC, which makes
* memory access significantly faster by using burst
* operations.
*/
static void x86_overwrite_pat()
{
uint64_t pat = rdmsr(0x277);
pat &= ~(0xFFULL << 8); // Clear PAT1
pat |= (0x01ULL << 8); // PAT1 = 0x01 (WC)
wrmsr(0x277, pat);
}
/*
* x86_arch_init - Initialize x86 CPU structures
*
* This function is responsible for overriding a PAT entry
* (to put the framebuffer area in WC mode) only.
*
* Later, all architecture-dependant init (GDT, IDT, TSS, ...)
* should be initialized here, and separate function pointers
* should be set up for each arch.
*/
void x86_arch_init()
{
x86_overwrite_pat();
idt_init();
gdt_init();
}

66
src/arch/x86/msr.c Normal file
View File

@@ -0,0 +1,66 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief x86 MSR C wrappers
* @description
* Wrapper functions to access Model Specific Registers
*
* @license GPL-3.0-only
*/
#include <stdint.h>
#include <stdbool.h>
#include <arch/x86.h>
/*
* rdmsr - Read from MSR
* @msr: model specific register number
*
* Read a 64-bit word from a Model Specific Register.
* Wrapper for the "rdmsr" instruction. It originally
* outputs to two 32-bit registers (EDX:EAX), so the
* function does the job of uniting them as a 64-bit
* value for us.
*
* Return:
* <value> - value read from MSR
*/
uint64_t rdmsr(uint32_t msr)
{
uint32_t low;
uint32_t high;
__asm__ volatile("rdmsr" : "=a"(low), "=d"(high) : "c"(msr));
return ((uint64_t)high << 32) | low;
}
/*
* wrmsr - Write to MSR
* @msr: model specific register number
*
* Write a 64-bit value to a Model Specific Register.
*/
void wrmsr(uint32_t msr, uint64_t value)
{
uint32_t low = (uint32_t)(value & 0xFFFFFFFF);
uint32_t high = (uint32_t)(value >> 32);
__asm__ volatile("wrmsr" : : "c"(msr), "a"(low), "d"(high) : "memory");
}
/*
* x86_has_msr - Test for MSR support
*
* Checks if CPU supports Model Specific Registers
* using CPUID.01h:EDX[bit 5].
*
* Return:
* true - MSR are supported
* false - MSR are not supported
*/
bool x86_has_msr()
{
uint32_t eax, ebx, ecx, edx;
cpuid(1, &eax, &ebx, &ecx, &edx);
return (edx & (1 << 5)) != 0;
}

View File

@@ -5,8 +5,8 @@
*/ */
#include <kernel.h> #include <kernel.h>
#include "limine.h" #include <limine.h>
#include "string/string.h" #include <string/string.h>
#include <stddef.h> #include <stddef.h>
extern struct boot_context boot_ctx; extern struct boot_context boot_ctx;

View File

@@ -5,9 +5,9 @@
*/ */
#include <stddef.h> #include <stddef.h>
#include "idt/idt.h" #include <arch/x86.h>
#include "io/serial/serial.h" #include <io/serial/serial.h>
#include "kernel.h" #include <kernel.h>
extern struct init_status init; extern struct init_status init;
extern int panic_count; extern int panic_count;
@@ -36,27 +36,6 @@ void read_rflags(uint64_t rflags)
CHECK_BIT(rflags, 19) ? "VIF " : "", /*virtual interrupt flag*/ CHECK_BIT(rflags, 19) ? "VIF " : "", /*virtual interrupt flag*/
CHECK_BIT(rflags, 20) ? "VIP " : "", /*virtual interrupt pending*/ CHECK_BIT(rflags, 20) ? "VIP " : "", /*virtual interrupt pending*/
CHECK_BIT(rflags, 21) ? "ID " : ""); /*id flag*/ CHECK_BIT(rflags, 21) ? "ID " : ""); /*id flag*/
if (init.terminal) {
printf("\x1b[38;5;226m%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1b[38;5;231m\r\n",
CHECK_BIT(rflags, 0) ? "CF " : "",
CHECK_BIT(rflags, 2) ? "PF " : "",
CHECK_BIT(rflags, 4) ? "AF " : "",
CHECK_BIT(rflags, 6) ? "ZF " : "",
CHECK_BIT(rflags, 7) ? "SF " : "",
CHECK_BIT(rflags, 8) ? "TF " : "",
CHECK_BIT(rflags, 9) ? "IF " : "",
CHECK_BIT(rflags, 10) ? "DF " : "",
CHECK_BIT(rflags, 11) ? "OF " : "",
(CHECK_BIT(rflags, 12) && CHECK_BIT(rflags, 13)) ? "IOPL3 " : "IOPL0 ",
CHECK_BIT(rflags, 14) ? "NT " : "",
CHECK_BIT(rflags, 16) ? "RF " : "",
CHECK_BIT(rflags, 17) ? "VM " : "",
CHECK_BIT(rflags, 18) ? "AC " : "",
CHECK_BIT(rflags, 19) ? "VIF " : "",
CHECK_BIT(rflags, 20) ? "VIP " : "",
CHECK_BIT(rflags, 21) ? "ID " : "");
}
} }
/* /*

View File

@@ -5,7 +5,7 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include "kernel.h" #include <kernel.h>
#include <stddef.h> #include <stddef.h>
extern struct init_status init; extern struct init_status init;

View File

@@ -4,10 +4,11 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "io/serial/serial.h" #include "config.h"
#include "ps2.h" #include <io/serial/serial.h>
#include <io/kbd/ps2.h>
#include <stdint.h> #include <stdint.h>
#include "io/term/term.h" #include <io/term/term.h>
#include <kernel.h> #include <kernel.h>
#include <stddef.h> #include <stddef.h>
@@ -18,6 +19,11 @@ uint8_t key_status = 0b00000000;
unsigned char* keymap; unsigned char* keymap;
unsigned char* keymap_shifted; unsigned char* keymap_shifted;
// Keyboard buffer
char keyboard_buffer[KBD_BUFFER_MAX] = {0};
int write_index = 0;
int read_index = 0;
extern struct init_status init; extern struct init_status init;
unsigned char kbdus[128] = unsigned char kbdus[128] =
@@ -210,10 +216,11 @@ void keyboard_handler()
if (c) { if (c) {
if (c == '\n') { if (c == '\n') {
_putchar('\r'); internal_putc('\r', NULL);
} }
// Should probably have a keyboard buffer here... instead of this
_putchar(c); internal_putc(c, NULL);
keyboard_putchar(c);
} }
} }
} }
@@ -221,6 +228,79 @@ void keyboard_handler()
} }
} }
/*
* keyboard_getchar - Get a character from keyboard
*
* This function reads one character from the keyboard buffer.
* If the keyboard buffer is empty, it will block until a key
* is pressed.
*
* Return:
* <char> - character from keyboard buffer
*/
char keyboard_getchar()
{
while (read_index == write_index); // Empty buffer
char c = keyboard_buffer[read_index];
read_index = (read_index+1) % KBD_BUFFER_MAX;
return c;
}
/*
* keyboard_putchar - Puts a character in the keyboard buffer
* @c: character to add
*
* This function is used in the keyboard handler to add new
* characters to the keyboard buffer.
*
* Return:
* %-1 - keyboard buffer is full
* %0 - operation completed successfully
*/
int keyboard_putchar(char c)
{
if ((write_index+1) % KBD_BUFFER_MAX == read_index) {
// Full buffer
return -1;
}
keyboard_buffer[write_index] = c;
write_index = (write_index+1) % KBD_BUFFER_MAX;
return 0;
}
/*
* keyboard_getline - Gets a line of input from keyboard
* @output: Output string
* @size: Size of output string
*
* Read a line of characters from the keyboard, until the
* buffer fills or a newline character is read.
* The output string is NULL-terminated.
*
* Return:
* <num> - the number of characters read
*/
int keyboard_getline(char* output, size_t size)
{
char c;
size_t index = 0;
// Read until Enter is pressed
while ((c = keyboard_getchar()) != 0x0A) {
if (index == size-1) {
output[index] = c;
output[index+1] = '\0';
return index;
}
output[index] = c;
index++;
}
output[index+1] = '\0';
return index;
}
/* /*
* keyboard_init - Keyboard initialization * keyboard_init - Keyboard initialization
* @layout: Desired layout * @layout: Desired layout

View File

@@ -5,10 +5,14 @@
*/ */
#include <kernel.h> #include <kernel.h>
#include "serial.h" #include <io/serial/serial.h>
#include <sched/spinlock.h>
extern struct init_status init; extern struct init_status init;
extern int panic_count;
struct spinlock_t serial_lock = {0};
/* /*
* outb - Writes a byte to a CPU port * outb - Writes a byte to a CPU port
* @port: CPU port to write to * @port: CPU port to write to
@@ -61,8 +65,8 @@ int serial_init()
// Set normal operation mode // Set normal operation mode
outb(PORT + 4, 0x0F); outb(PORT + 4, 0x0F);
DEBUG("*** Welcome to PepperOS! ***");
init.serial = true; init.serial = true;
DEBUG("*** Welcome to PepperOS! (built @ %s %s) ***", __DATE__, __TIME__);
return 0; return 0;
} }
@@ -85,9 +89,15 @@ static int is_transmit_empty()
*/ */
void skputc(char c) void skputc(char c)
{ {
// TODO: Spinlock here (serial access) if (panic_count == 0) {
spinlock_acquire(&serial_lock);
while (!is_transmit_empty()); // wait for free spot while (!is_transmit_empty()); // wait for free spot
outb(PORT, c); outb(PORT, c);
spinlock_release(&serial_lock);
} else {
while (!is_transmit_empty());
outb(PORT, c);
}
} }
/* /*

View File

@@ -41,7 +41,7 @@
#define FLANTERM_IN_FLANTERM #define FLANTERM_IN_FLANTERM
#endif #endif
#include "flanterm.h" #include <io/term/flanterm.h>
// Tries to implement this standard for terminfo // Tries to implement this standard for terminfo
// https://man7.org/linux/man-pages/man4/console_codes.4.html // https://man7.org/linux/man-pages/man4/console_codes.4.html

View File

@@ -51,8 +51,8 @@
#define FLANTERM_IN_FLANTERM #define FLANTERM_IN_FLANTERM
#endif #endif
#include "../flanterm.h" #include <io/term/flanterm.h>
#include "fb.h" #include <io/term/flanterm_backends/fb.h>
void *memset(void *, int, size_t); void *memset(void *, int, size_t);
void *memcpy(void *, const void *, size_t); void *memcpy(void *, const void *, size_t);

View File

@@ -13,36 +13,27 @@ because this shitty implementation will be replaced one day by Flanterm
#include <stddef.h> #include <stddef.h>
#include <kernel.h> #include <kernel.h>
#include "term.h" #include <io/term/term.h>
#include "config.h" #include <config.h>
#include "flanterm.h" #include <io/term/flanterm.h>
#include "flanterm_backends/fb.h" #include <io/term/flanterm_backends/fb.h>
#include "mem/heap/kheap.h" #include <mem/kheap.h>
#include "limine.h" #include <limine.h>
#include <stdarg.h> #include <stdarg.h>
#include "sched/spinlock.h" #include <sched/spinlock.h>
#include "io/serial/serial.h" #include <io/serial/serial.h>
#define NANOPRINTF_IMPLEMENTATION #define NANOPRINTF_IMPLEMENTATION
#include "nanoprintf.h" #include <io/term/nanoprintf.h>
extern struct flanterm_context* ft_ctx; extern struct flanterm_context* ft_ctx;
extern struct init_status init; extern struct init_status init;
struct spinlock_t term_lock = {0}; struct spinlock_t term_lock = {0};
struct spinlock_t printf_lock = {0};
extern int panic_count; extern int panic_count;
/*
* _putchar - Writes a character to terminal (DEPRECATED)
* @character: character to write
*/
void _putchar(char character)
{
// TODO: Spinlock here (terminal access)
flanterm_write(ft_ctx, &character, 1);
}
/* /*
* internal_putc - Internal putchar function * internal_putc - Internal putchar function
* @c: char to print * @c: char to print
@@ -83,15 +74,27 @@ void internal_putc(int c, void *_)
* *
* Return: * Return:
* <ret> - number of characters sent to the callback * <ret> - number of characters sent to the callback
* %-1 - error
*/ */
int printf(const char* fmt, ...) int printf(const char* fmt, ...)
{ {
if (panic_count == 0) {
spinlock_acquire(&printf_lock);
va_list args;
va_start(args, fmt);
int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
va_end(args);
spinlock_release(&printf_lock);
return ret;
} else {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
int ret = npf_vpprintf(internal_putc, NULL, fmt, args); int ret = npf_vpprintf(internal_putc, NULL, fmt, args);
va_end(args); va_end(args);
return ret; return ret;
} }
return -1;
}
/* /*
* kputs - Kernel puts * kputs - Kernel puts
@@ -103,30 +106,14 @@ void kputs(const char* str)
{ {
size_t i=0; size_t i=0;
while (str[i] != 0) { while (str[i] != 0) {
_putchar(str[i]); internal_putc(str[i], NULL);
i++; i++;
} }
_putchar('\r');
} }
extern struct flanterm_context* ft_ctx; extern struct flanterm_context* ft_ctx;
extern struct boot_context boot_ctx; extern struct boot_context boot_ctx;
/*
* flanterm_free_wrapper - free() wrapper for Flanterm
* @ptr: pointer to free
* @size: amount of bytes to free
*
* This function exists solely because the Flanterm initialization
* function only accepts a free() function with a size parameter,
* and the default one doesn't have it.
*/
void flanterm_free_wrapper(void* ptr, size_t size)
{
(void)size;
kfree(ptr);
}
/* /*
* term_init - Video output/terminal initialization * term_init - Video output/terminal initialization
* *
@@ -136,8 +123,8 @@ void term_init()
{ {
uint32_t bgColor = 0x252525; uint32_t bgColor = 0x252525;
ft_ctx = flanterm_fb_init( ft_ctx = flanterm_fb_init(
kmalloc, NULL,
flanterm_free_wrapper, NULL,
boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch, boot_ctx.fb->address, boot_ctx.fb->width, boot_ctx.fb->height, boot_ctx.fb->pitch,
boot_ctx.fb->red_mask_size, boot_ctx.fb->red_mask_shift, boot_ctx.fb->red_mask_size, boot_ctx.fb->red_mask_shift,
boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift, boot_ctx.fb->green_mask_size, boot_ctx.fb->green_mask_shift,

View File

@@ -4,27 +4,27 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "arch/x86.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <limine.h> #include <limine.h>
#include "io/term/term.h" #include <io/term/term.h>
#include "io/term/term.h" #include <io/serial/serial.h>
#include "io/serial/serial.h" #include <mem/gdt.h>
#include "mem/gdt/gdt.h" #include <mem/utils.h>
#include "mem/misc/utils.h" #include <kernel.h>
#include "idt/idt.h" #include <time/timer.h>
#include "kernel.h" #include <io/kbd/ps2.h>
#include "time/timer.h" #include <mem/pmm.h>
#include "io/kbd/ps2.h" #include <mem/paging.h>
#include "mem/paging/pmm.h" #include <mem/vmm.h>
#include "mem/paging/paging.h" #include <mem/kheap.h>
#include "mem/paging/vmm.h" #include <sched/process.h>
#include "mem/heap/kheap.h" #include <sched/scheduler.h>
#include "sched/process.h" #include <config.h>
#include "sched/scheduler.h" #include <io/term/flanterm.h>
#include "config.h" #include <io/term/flanterm_backends/fb.h>
#include "io/term/flanterm.h" #include <arch/x86.h>
#include "io/term/flanterm_backends/fb.h"
// Limine version used // Limine version used
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
@@ -69,7 +69,7 @@ struct process_t* idle_proc;
// Never gets executed although pedicel is scheduled? // Never gets executed although pedicel is scheduled?
void pedicel_main(void* arg) void pedicel_main(void* arg)
{ {
printf("\n\nWelcome to PepperOS! Pedicel speaking.\r\nNothing left to do, let's go idle!"); printf("\n\n\rWelcome to PepperOS! Pedicel speaking.\r\nNothing left to do, let's go idle!\r\n");
} }
void idle_main(void* arg) void idle_main(void* arg)
@@ -79,6 +79,14 @@ void idle_main(void* arg)
} }
} }
void thing_main(void* arg)
{
printf("What's your name, pal? ");
char name[10];
keyboard_getline(name, 10);
printf("\r\n{%s} is such a nice name!\r\n", name);
}
extern uintptr_t kheap_start; extern uintptr_t kheap_start;
/* /*
@@ -94,37 +102,33 @@ void kmain()
CLEAR_INTERRUPTS; CLEAR_INTERRUPTS;
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf(); if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
serial_init();
timer_init();
// Populate boot context // Populate boot context
boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL; boot_ctx.fb = framebuffer_request.response ? framebuffer_request.response->framebuffers[0] : NULL;
boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL; boot_ctx.mmap = memmap_request.response ? memmap_request.response : NULL;
boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL; boot_ctx.hhdm = hhdm_request.response ? hhdm_request.response : NULL;
boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL; boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL;
term_init();
serial_init();
timer_init();
x86_arch_init();
boot_mem_display(); boot_mem_display();
pmm_init(boot_ctx); pmm_init(boot_ctx);
// Remap kernel , HHDM and framebuffer
paging_init(boot_ctx); paging_init(boot_ctx);
kheap_init(); kheap_init();
keyboard_init(FR); keyboard_init(FR);
term_init();
gdt_init();
idt_init();
process_init(); process_init();
idle_proc = process_create("idle", (void*)idle_main, 0); idle_proc = process_create("idle", (void*)idle_main, 0);
struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0); process_create("pedicel", (void*)pedicel_main, 0);
process_create("thing", thing_main, NULL);
process_display_list(processes_list);
scheduler_init(); scheduler_init();
kputs(PEPPEROS_SPLASH); printf(PEPPEROS_SPLASH);
idle(); idle();
} }

View File

@@ -4,9 +4,9 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "gdt.h" #include <mem/gdt.h>
#include <stdint.h> #include <stdint.h>
#include "io/serial/serial.h" #include <io/serial/serial.h>
#include <kernel.h> #include <kernel.h>
// Descriptors are 8-byte wide (64bits) // Descriptors are 8-byte wide (64bits)

View File

@@ -4,13 +4,13 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "kheap.h" #include <mem/kheap.h>
#include "mem/paging/paging.h" #include <mem/paging.h>
#include "mem/paging/pmm.h" #include <mem/pmm.h>
#include <stddef.h> #include <stddef.h>
#include <kernel.h> #include <kernel.h>
#include "sched/process.h" #include <sched/process.h>
#include "config.h" #include <config.h>
extern uint64_t kernel_phys_base; extern uint64_t kernel_phys_base;
extern uint64_t kernel_virt_base; extern uint64_t kernel_virt_base;

View File

@@ -4,12 +4,12 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "paging.h" #include <mem/paging.h>
#include "pmm.h" #include <mem/pmm.h>
#include <kernel.h> #include <kernel.h>
#include <stddef.h> #include <stddef.h>
#include <limine.h> #include <limine.h>
#include "config.h" #include <config.h>
/* /*
Paging on x86 uses four different page table levels: Paging on x86 uses four different page table levels:
@@ -173,9 +173,9 @@ void paging_init(struct boot_context boot_ctx)
} }
} }
// 4GB // 8GB
if (max_phys > PAGING_MAX_PHYS) { if (max_phys > PAGING_MAX_PHYS) {
DEBUG("WARNING: max_phys capped to 4GB (%x) (from max_phys=%p)", PAGING_MAX_PHYS, max_phys); DEBUG("WARNING: max_phys capped to PAGING_MAX_PHYS (from max_phys=%p)", max_phys);
max_phys = PAGING_MAX_PHYS; max_phys = PAGING_MAX_PHYS;
} }
@@ -202,9 +202,9 @@ void paging_init(struct boot_context boot_ctx)
uint64_t fb_size = fb->pitch * fb->height; uint64_t fb_size = fb->pitch * fb->height;
uint64_t fb_pages = (fb_size + PAGE_SIZE-1)/PAGE_SIZE; uint64_t fb_pages = (fb_size + PAGE_SIZE-1)/PAGE_SIZE;
// Map the framebuffer (with cache-disable & write-through) // Map the framebuffer (PWT set, and no PCD means PAT1 [Write-Combining] for this region)
for (uint64_t i=0; i<fb_pages; i++) { for (uint64_t i=0; i<fb_pages; i++) {
paging_map_page(kernel_pml4, fb_virt+i*PAGE_SIZE, fb_phys+i*PAGE_SIZE, PTE_WRITABLE | PTE_PCD | PTE_PWT); paging_map_page(kernel_pml4, fb_virt+i*PAGE_SIZE, fb_phys+i*PAGE_SIZE, PTE_WRITABLE | PTE_PWT);
page_count++; page_count++;
} }
DEBUG("Mapped %u pages for framebuffer", page_count); DEBUG("Mapped %u pages for framebuffer", page_count);

View File

@@ -11,55 +11,20 @@ it will probably need to get some info from Limine,
to see which pages are used by kernel/bootloader/mmio/fb etc. to see which pages are used by kernel/bootloader/mmio/fb etc.
*/ */
#include "paging.h" #include "config.h"
#include <mem/paging.h>
#include <limine.h> #include <limine.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <kernel.h> #include <kernel.h>
#include "mem/misc/utils.h" #include <mem/utils.h>
#include "pmm.h" #include <mem/pmm.h>
/* /*
First we'll have to discover the physical memory layout, First we'll have to discover the physical memory layout,
and for that we can use a Limine request. and for that we can use a Limine request.
*/ */
struct limine_memmap_entry* biggest_entry;
/*
* pmm_find_biggest_usable_region - Finding the biggest free memory region
* @memmap: Limine memory map
* @hhdm: Limine HHDM offset
*
* This function uses the memory map provided by the bootloader
* to find the single biggest free memory region we can use.
*/
static void pmm_find_biggest_usable_region(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm)
{
// Max length of a usable memory region
uint64_t length_max = 0;
uint64_t offset = hhdm->offset;
DEBUG("Usable Memory:");
for (size_t i=0; i<memmap->entry_count; i++) {
struct limine_memmap_entry* entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE) {
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", entry->base, entry->base+entry->length,
entry->base+offset, entry->base+entry->length+offset);
if (entry->length > length_max)
{
length_max = entry->length;
biggest_entry = entry;
}
}
}
DEBUG("Biggest usable memory region:");
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", biggest_entry->base, biggest_entry->base + biggest_entry->length,
biggest_entry->base+offset, biggest_entry->base+biggest_entry->length+offset);
}
// Offset from Higher Half Direct Map // Offset from Higher Half Direct Map
uint64_t hhdm_off; uint64_t hhdm_off;
@@ -99,19 +64,32 @@ void pmm_free(uintptr_t addr)
* This function marks the biggest memory region as * This function marks the biggest memory region as
* free, so we can use it in pmm_alloc. * free, so we can use it in pmm_alloc.
*/ */
static void pmm_init_freelist() static void pmm_init_freelist(struct limine_memmap_response* memmap)
{ {
// We simply call pmm_free() on each page that is marked USABLE uint64_t total_pages = 0;
// in our big memory region.
uint64_t base = ALIGN_UP(biggest_entry->base, PAGE_SIZE); for (size_t i=0; i<memmap->entry_count; i++) {
uint64_t end = ALIGN_DOWN(biggest_entry->base + biggest_entry->length, PAGE_SIZE); struct limine_memmap_entry* entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE) {
uint64_t base = ALIGN_UP(entry->base, PAGE_SIZE);
uint64_t end = ALIGN_DOWN(entry->base + entry->length, PAGE_SIZE);
if (end > PAGING_MAX_PHYS) {
end = PAGING_MAX_PHYS;
}
// Region above PAGING_MAX_PHYS
if (base >= end) continue;
uint64_t page_count=0;
for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) { for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) {
pmm_free(addr); pmm_free(addr);
page_count++; total_pages++;
} }
DEBUG("%u frames in freelist, available for use (%u bytes)", page_count, page_count*PAGE_SIZE); }
}
DEBUG("%u frames in freelist, %u bytes available (%u MB)", total_pages, total_pages*PAGE_SIZE, total_pages*PAGE_SIZE/1000000);
} }
/* /*
@@ -124,9 +102,9 @@ static void pmm_init_freelist()
void pmm_init(struct boot_context boot_ctx) void pmm_init(struct boot_context boot_ctx)
{ {
hhdm_off = boot_ctx.hhdm->offset; hhdm_off = boot_ctx.hhdm->offset;
pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm); //pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm);
// Now we have biggest USABLE region, // Now we have biggest USABLE region,
// so to populate the free list we just iterate through it // so to populate the free list we just iterate through it
pmm_init_freelist(); pmm_init_freelist(boot_ctx.mmap);
} }

View File

@@ -7,8 +7,8 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <limine.h> #include <limine.h>
#include "kernel.h" #include <kernel.h>
#include "string/string.h" #include <string/string.h>
// We won't be linked to standard library, but still need the basic mem* functions // We won't be linked to standard library, but still need the basic mem* functions
// so everything goes allright with the compiler // so everything goes allright with the compiler

View File

@@ -13,10 +13,10 @@ in a specified virtual space
compared to the PMM which allocs/frees 4kb frames ("physical pages"). compared to the PMM which allocs/frees 4kb frames ("physical pages").
*/ */
#include "vmm.h" #include <mem/vmm.h>
#include "paging.h" #include <mem/paging.h>
#include <stddef.h> #include <stddef.h>
#include "pmm.h" #include <mem/pmm.h>
#include <kernel.h> #include <kernel.h>
void* vmm_pt_root = 0; void* vmm_pt_root = 0;

View File

@@ -5,15 +5,15 @@
*/ */
#include <stddef.h> #include <stddef.h>
#include "process.h" #include <sched/process.h>
#include "mem/heap/kheap.h" #include <mem/kheap.h>
#include "kernel.h" #include <kernel.h>
#include "string/string.h" #include <string/string.h>
#include "mem/gdt/gdt.h" #include <mem/gdt.h>
#include "config.h" #include <config.h>
#include "io/serial/serial.h" #include <io/serial/serial.h>
#include "io/term/flanterm.h" #include <io/term/flanterm.h>
extern struct flanterm_context* ft_ctx; extern struct flanterm_context* ft_ctx;
struct process_t* processes_list; struct process_t* processes_list;

View File

@@ -4,11 +4,11 @@
* @license GPL-3.0-only * @license GPL-3.0-only
*/ */
#include "kernel.h" #include <kernel.h>
#include "process.h" #include <sched/process.h>
#include "mem/paging/paging.h" #include <mem/paging.h>
#include <stdint.h> #include <stdint.h>
#include "io/serial/serial.h" #include <io/serial/serial.h>
extern struct process_t* processes_list; extern struct process_t* processes_list;
extern struct process_t* current_process; extern struct process_t* current_process;
@@ -49,7 +49,6 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
} }
current_process->context = context; current_process->context = context;
//current_process->status = READY;
for (;;) { for (;;) {
struct process_t* prev_process = current_process; struct process_t* prev_process = current_process;
@@ -65,14 +64,17 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
return idle_proc->context; return idle_proc->context;
} else { } else {
current_process->status = RUNNING; current_process->status = RUNNING;
/* if (prev_process != current_process) {
DEBUG("Changed from {pid=%u, name=%s} to {pid=%u, name=%s}", prev_process->pid, prev_process->name, current_process->pid, current_process->name);
} */
break; break;
} }
} }
DEBUG("current_process={pid=%u, name='%s', root_page_table[virt]=%p}", current_process->pid, current_process->name, current_process->root_page_table); //DEBUG("current_process={pid=%u, name='%s', root_page_table[virt]=%p}", current_process->pid, current_process->name, current_process->root_page_table);
load_cr3(VIRT_TO_PHYS((uint64_t)current_process->root_page_table)); load_cr3(VIRT_TO_PHYS((uint64_t)current_process->root_page_table));
DEBUG("Loaded process PML4 into CR3"); //DEBUG("Loaded process PML4 into CR3");
return current_process->context; return current_process->context;
} }

View File

@@ -6,8 +6,8 @@
#include <stdatomic.h> #include <stdatomic.h>
#include <stdbool.h> #include <stdbool.h>
#include "kernel.h" #include <kernel.h>
#include "spinlock.h" #include <sched/spinlock.h>
/* /*
* spinlock_acquire - Lock a lock * spinlock_acquire - Lock a lock

View File

@@ -5,9 +5,9 @@
*/ */
#include <stdint.h> #include <stdint.h>
#include "io/serial/serial.h" #include <io/serial/serial.h>
#include <kernel.h> #include <kernel.h>
#include "config.h" #include <config.h>
/* /*
For now, the timer module will be using the PIC. For now, the timer module will be using the PIC.