Compare commits
8 Commits
flanterm
...
1dd4e728d4
| Author | SHA1 | Date | |
|---|---|---|---|
|
1dd4e728d4
|
|||
|
b9c77a316a
|
|||
| 6fc28806e2 | |||
|
3f9b78b05e
|
|||
|
42c7a55d3f
|
|||
|
5e9c582833
|
|||
| 77d9df6f48 | |||
| 95c801b991 |
+2
-1
@@ -10,4 +10,5 @@ iso_root
|
|||||||
.gdb_history
|
.gdb_history
|
||||||
symbols.map
|
symbols.map
|
||||||
symbols.S
|
symbols.S
|
||||||
*.log
|
*.log
|
||||||
|
build/
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
up to doom:
|
|
||||||
|
|
||||||
- Return from pedicel_main() normally (to idle)
|
|
||||||
|
|
||||||
** Checkpoint: ring0 process working
|
|
||||||
|
|
||||||
- VFS layer (open/read/write/...) with USTar filesystem (for initrd)
|
|
||||||
|
|
||||||
** Checkpoint: files not linked to but accessible by the kernel
|
|
||||||
|
|
||||||
- Ring3 memory mappings
|
|
||||||
- Ring3 privilege switch
|
|
||||||
|
|
||||||
** Checkpoint: welcome to userland
|
|
||||||
|
|
||||||
- Syscall interface
|
|
||||||
- Implement syscalls needed for doom
|
|
||||||
|
|
||||||
** Checkpoint: can run simple programs, ring 3, loaded from filesystem
|
|
||||||
|
|
||||||
- Properly handle the keyboard interrupt (keyboard buffer)
|
|
||||||
- Port DOOMgeneric (few functions with Framebuffer/ticks/etc.)
|
|
||||||
|
|
||||||
** Achievement: It runs doom!
|
|
||||||
@@ -1,16 +1,21 @@
|
|||||||
SOURCES = 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/printf.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
|
SOURCES = 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/printf.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
|
||||||
|
|
||||||
PROBLEMATIC_FLAGS=-Wno-unused-parameter -Wno-unused-variable
|
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
|
||||||
|
|
||||||
|
.PHONY: build build-iso debug debug2 run clean
|
||||||
|
|
||||||
build:
|
build:
|
||||||
rm -f *.o
|
mkdir -p build
|
||||||
x86_64-elf-gcc -g -c -Isrc $(SOURCES) $(PROBLEMATIC_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
|
rm -f *.o build/*.o
|
||||||
nasm -f elf64 src/idt/idt.S -o idt_stub.o
|
x86_64-elf-gcc -g -c -Isrc $(SOURCES) $(CC_PROBLEMATIC_FLAGS) $(CC_FLAGS)
|
||||||
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
mv *.o build/
|
||||||
|
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
|
nm -n pepperk | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
|
||||||
python3 symbols.py
|
python3 symbols.py
|
||||||
nasm -f elf64 symbols.S -o symbols.o
|
nasm -f elf64 symbols.S -o build/symbols.o
|
||||||
x86_64-elf-ld -o pepperk -T linker.ld *.o
|
x86_64-elf-ld -o pepperk -T linker.ld build/*.o
|
||||||
|
|
||||||
limine/limine:
|
limine/limine:
|
||||||
rm -rf limine
|
rm -rf limine
|
||||||
@@ -46,4 +51,4 @@ 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
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o symbols.map symbols.S pepperk iso_root pepper.iso limine
|
rm -rf *.o symbols.map symbols.S pepperk iso_root pepper.iso limine build/*.o
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ 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)
|
- Marco Paland's freestanding [printf implementation](https://github.com/mpaland)
|
||||||
- the [ZAP](https://www.zap.org.au/projects/console-fonts-zap/) PSF console fonts
|
- Mintuski's [Flanterm](https://codeberg.org/Mintsuki/Flanterm) terminal emulator
|
||||||
|
|
||||||
...and without these amazing resources:
|
...and without these amazing resources:
|
||||||
|
|
||||||
- the [OSDev](https://osdev.org) wiki & forums
|
- the [OSDev](https://osdev.org) wiki & forums
|
||||||
|
- Intel 64 and IA-32 Architectures Software Developer's Manual
|
||||||
|
- Documentation for the [GNU Compiler Collection](https://gcc.gnu.org/onlinedocs/gcc/)
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# Pepper kernel coding style
|
||||||
|
|
||||||
|
This document describes the coding style for the Pepper kernel. It is used as a guideline across all source files.
|
||||||
|
|
||||||
|
## Indentation
|
||||||
|
|
||||||
|
Indentations should be 4 characters long.
|
||||||
|
|
||||||
|
## Line length
|
||||||
|
|
||||||
|
Lines should not be more than 100 characters long.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
Variables should be declared at most once per line.
|
||||||
|
|
||||||
|
## Braces
|
||||||
|
|
||||||
|
Non-function statement blocks should have an opening brace last on the line, and a closing brace first. Exception is made for `else`, `else if` statements and the like:
|
||||||
|
|
||||||
|
```c
|
||||||
|
if (something) {
|
||||||
|
do_something();
|
||||||
|
} else if (something_else) {
|
||||||
|
do_something_else();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Functions should have their opening brace on a separate line, and the same goes for the closing brace:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void function()
|
||||||
|
{
|
||||||
|
do_something();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Spaces
|
||||||
|
|
||||||
|
Use a space after `if, switch, case, for, do, while` keywords, but not for `sizeof, typeof, alignof, __attribute__` and the like.
|
||||||
|
|
||||||
|
For pointers, the asterisk should always be placed adjacent to the type name, like `char* str;`.
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
|
||||||
|
Functions should be named with whole words, beginning with the corresponding name of the module in the kernel (the parent folder). Words should be spaced with underscores, like so:
|
||||||
|
|
||||||
|
```c
|
||||||
|
serial_init(void* ptr, char* str, int foo);
|
||||||
|
```
|
||||||
|
|
||||||
|
Constants should be named in all caps, separated by underscores:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define MAX_HEAP_SIZE 0x1000
|
||||||
|
```
|
||||||
|
|
||||||
|
Global variables need to have descriptive names. Local variables can be kept short (especially for loop counters).
|
||||||
|
|
||||||
|
## Typedefs
|
||||||
|
|
||||||
|
Structures should not be `typedef`'d.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
Functions should be short, simple, and only do one thing.
|
||||||
|
|
||||||
|
Function prototypes should include parameter names and their data types.
|
||||||
|
|
||||||
|
## Commenting
|
||||||
|
|
||||||
|
Comments should describe what a function does and why, not how it does it.
|
||||||
|
|
||||||
|
```c
|
||||||
|
/*
|
||||||
|
* This is the preferred style for multi-line
|
||||||
|
* comments in the Pepper kernel
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Resources
|
||||||
|
|
||||||
|
Some of the elements here are inspired by the [Linux kernel coding style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html).
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
#include "io/serial/serial.h"
|
#include "io/serial/serial.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
|
extern struct init_status init;
|
||||||
|
|
||||||
void panic(struct cpu_status_t* ctx, const char* str)
|
void panic(struct cpu_status_t* ctx, const char* str)
|
||||||
{
|
{
|
||||||
CLEAR_INTERRUPTS;
|
CLEAR_INTERRUPTS;
|
||||||
@@ -15,6 +17,13 @@ void panic(struct cpu_status_t* ctx, const char* str)
|
|||||||
skputc('\r');
|
skputc('\r');
|
||||||
skputc('\n');
|
skputc('\n');
|
||||||
DEBUG("\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m");
|
DEBUG("\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m");
|
||||||
|
|
||||||
|
if (init.terminal)
|
||||||
|
{
|
||||||
|
printf("\r\n\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m Something went horribly wrong! (no cpu ctx)");
|
||||||
|
printf("\r\n%s\r\n\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m", str);
|
||||||
|
}
|
||||||
|
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m at rip=%p\r\nSomething went horribly wrong! (%s) vect=0x%.2x errcode=0x%x\n\rrax=%p rbx=%p rcx=%p rdx=%p\n\rrsi=%p rdi=%p r8=%p r9=%p\n\rr10=%p r11=%p r12=%p r13=%p\n\rr14=%p r15=%p\n\n\rflags=%p\n\rHalting...",
|
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m at rip=%p\r\nSomething went horribly wrong! (%s) vect=0x%.2x errcode=0x%x\n\rrax=%p rbx=%p rcx=%p rdx=%p\n\rrsi=%p rdi=%p r8=%p r9=%p\n\rr10=%p r11=%p r12=%p r13=%p\n\rr14=%p r15=%p\n\n\rflags=%p\n\rHalting...",
|
||||||
@@ -22,6 +31,17 @@ void panic(struct cpu_status_t* ctx, const char* str)
|
|||||||
str,
|
str,
|
||||||
ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi,
|
ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi,
|
||||||
ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags);
|
ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags);
|
||||||
|
|
||||||
|
if (init.terminal)
|
||||||
|
{
|
||||||
|
printf("\r\n\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m at rip=%p\r\nSomething went horribly wrong! (%s) vect=0x%.2x errcode=0x%x\n\rrax=%p rbx=%p rcx=%p rdx=%p\n\rrsi=%p rdi=%p r8=%p r9=%p\n\rr10=%p r11=%p r12=%p r13=%p\n\rr14=%p r15=%p\n\n\rflags=%p\n\rHalting...",
|
||||||
|
ctx->iret_rip,
|
||||||
|
str,
|
||||||
|
ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi,
|
||||||
|
ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags);
|
||||||
|
}
|
||||||
|
|
||||||
debug_stack_trace(100);
|
debug_stack_trace(100);
|
||||||
|
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
|
extern struct init_status init;
|
||||||
|
|
||||||
void debug_stack_trace(unsigned int max_frames)
|
void debug_stack_trace(unsigned int max_frames)
|
||||||
{
|
{
|
||||||
DEBUG("*** begin stack trace ***");
|
DEBUG("*** begin stack trace ***");
|
||||||
|
if (init.terminal)
|
||||||
|
{
|
||||||
|
printf("\r\n*** begin stack trace ***\r\n");
|
||||||
|
}
|
||||||
// Thanks GCC :)
|
// Thanks GCC :)
|
||||||
uintptr_t* rbp = (uintptr_t*)__builtin_frame_address(0);
|
uintptr_t* rbp = (uintptr_t*)__builtin_frame_address(0);
|
||||||
|
|
||||||
@@ -15,6 +21,11 @@ void debug_stack_trace(unsigned int max_frames)
|
|||||||
const char* name = debug_find_symbol(rip, &offset);
|
const char* name = debug_find_symbol(rip, &offset);
|
||||||
DEBUG("[%u] <0x%p> (%s+0x%x)", frame, (void*)rip, name, offset);
|
DEBUG("[%u] <0x%p> (%s+0x%x)", frame, (void*)rip, name, offset);
|
||||||
|
|
||||||
|
if (init.terminal)
|
||||||
|
{
|
||||||
|
printf("[%u] <0x%p> (%s+0x%x)\r\n", frame, (void*)rip, name, offset);
|
||||||
|
}
|
||||||
|
|
||||||
uintptr_t* next_rbp = (uintptr_t*)rbp[0];
|
uintptr_t* next_rbp = (uintptr_t*)rbp[0];
|
||||||
|
|
||||||
// invalid rbp or we're at the end
|
// invalid rbp or we're at the end
|
||||||
@@ -25,6 +36,10 @@ void debug_stack_trace(unsigned int max_frames)
|
|||||||
|
|
||||||
rbp = next_rbp;
|
rbp = next_rbp;
|
||||||
}
|
}
|
||||||
|
if (init.terminal)
|
||||||
|
{
|
||||||
|
printf("*** end stack trace ***");
|
||||||
|
}
|
||||||
DEBUG("*** end stack trace ***");
|
DEBUG("*** end stack trace ***");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -151,12 +151,13 @@ vector_7_handler:
|
|||||||
align 16
|
align 16
|
||||||
vector_8_handler:
|
vector_8_handler:
|
||||||
; No error code, we only push vector number
|
; No error code, we only push vector number
|
||||||
push qword 1
|
push qword 8
|
||||||
jmp interrupt_stub
|
jmp interrupt_stub
|
||||||
|
|
||||||
; Coprocessor Segment Overrun
|
; Coprocessor Segment Overrun
|
||||||
align 16
|
align 16
|
||||||
vector_9_handler:
|
vector_9_handler:
|
||||||
|
push qword 0
|
||||||
push qword 9
|
push qword 9
|
||||||
jmp interrupt_stub
|
jmp interrupt_stub
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -22,7 +22,7 @@ struct idtr idt_reg;
|
|||||||
extern char vector_0_handler[];
|
extern char vector_0_handler[];
|
||||||
|
|
||||||
// Timer ticks
|
// Timer ticks
|
||||||
extern uint64_t ticks;
|
extern volatile uint64_t ticks;
|
||||||
|
|
||||||
void idt_set_entry(uint8_t vector, void* handler, uint8_t dpl)
|
void idt_set_entry(uint8_t vector, void* handler, uint8_t dpl)
|
||||||
{
|
{
|
||||||
@@ -52,9 +52,8 @@ void idt_load(void* idt_addr)
|
|||||||
|
|
||||||
void idt_init()
|
void idt_init()
|
||||||
{
|
{
|
||||||
// We set 256 entries, but we have only the first few stubs.
|
// Hardcoded...
|
||||||
// Undefined behavior?
|
for (size_t i=0; i<=33; i++)
|
||||||
for (size_t i=0; i<256; i++)
|
|
||||||
{
|
{
|
||||||
// Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler
|
// Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler
|
||||||
idt_set_entry(i, vector_0_handler + (i*16), 0);
|
idt_set_entry(i, vector_0_handler + (i*16), 0);
|
||||||
@@ -210,6 +209,7 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
|||||||
case 33:
|
case 33:
|
||||||
DEBUG("Keyboard Interrupt");
|
DEBUG("Keyboard Interrupt");
|
||||||
keyboard_handler();
|
keyboard_handler();
|
||||||
|
outb(0x20, 0x20);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
+24
-13
@@ -17,6 +17,8 @@ uint8_t key_status = 0b00000000;
|
|||||||
unsigned char* keymap;
|
unsigned char* keymap;
|
||||||
unsigned char* keymap_shifted;
|
unsigned char* keymap_shifted;
|
||||||
|
|
||||||
|
extern struct init_status init;
|
||||||
|
|
||||||
unsigned char kbdus[128] =
|
unsigned char kbdus[128] =
|
||||||
{
|
{
|
||||||
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
|
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
|
||||||
@@ -176,9 +178,6 @@ void keyboard_handler()
|
|||||||
key_status &= ~ALT_PRESSED_BIT;
|
key_status &= ~ALT_PRESSED_BIT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send EOI
|
|
||||||
outb(0x20, 0x20);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -200,20 +199,25 @@ void keyboard_handler()
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Should we get a SHIFTED char or a regular one?
|
// Avoiding buffer overflow from extended keys lol
|
||||||
unsigned char c = (key_status & SHIFT_PRESSED_BIT) ? keymap_shifted[scancode] : keymap[scancode];
|
if (scancode < 128)
|
||||||
|
|
||||||
if (c)
|
|
||||||
{
|
{
|
||||||
// Should probably have a keyboard buffer here... instead of this
|
// Should we get a SHIFTED char or a regular one?
|
||||||
_putchar(c);
|
unsigned char c = (key_status & SHIFT_PRESSED_BIT) ? keymap_shifted[scancode] : keymap[scancode];
|
||||||
|
|
||||||
|
if (c)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
_putchar('\r');
|
||||||
|
}
|
||||||
|
// Should probably have a keyboard buffer here... instead of this
|
||||||
|
_putchar(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// End of Interrupt (to master PIC)
|
|
||||||
outb(0x20, 0x20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_init(unsigned char layout)
|
void keyboard_init(unsigned char layout)
|
||||||
@@ -233,14 +237,21 @@ void keyboard_init(unsigned char layout)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
skputs("Unsupported layout.");
|
panic(NULL, "Unsupported keyboard layout");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flush keyboard buffer
|
||||||
|
while (inb(0x64) & 1)
|
||||||
|
{
|
||||||
|
inb(0x60);
|
||||||
|
}
|
||||||
|
|
||||||
// Unmask IRQ1
|
// Unmask IRQ1
|
||||||
uint8_t mask = inb(0x21);
|
uint8_t mask = inb(0x21);
|
||||||
mask &= ~(1 << 1);
|
mask &= ~(1 << 1);
|
||||||
outb(0x21, mask);
|
outb(0x21, mask);
|
||||||
|
|
||||||
DEBUG("PS/2 Keyboard initialized");
|
DEBUG("PS/2 Keyboard initialized");
|
||||||
|
init.keyboard = true;
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
|
extern struct init_status init;
|
||||||
|
|
||||||
void outb(int port, unsigned char data)
|
void outb(int port, unsigned char data)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__("outb %%al, %%dx" :: "a" (data),"d" (port));
|
__asm__ __volatile__("outb %%al, %%dx" :: "a" (data),"d" (port));
|
||||||
@@ -43,6 +45,7 @@ int serial_init()
|
|||||||
outb(PORT + 4, 0x0F);
|
outb(PORT + 4, 0x0F);
|
||||||
|
|
||||||
DEBUG("*** Welcome to PepperOS! ***");
|
DEBUG("*** Welcome to PepperOS! ***");
|
||||||
|
init.serial = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +57,7 @@ static int is_transmit_empty()
|
|||||||
// Serial kernel putchar
|
// Serial kernel putchar
|
||||||
void skputc(char c)
|
void skputc(char c)
|
||||||
{
|
{
|
||||||
|
// TODO: Spinlock here (serial access)
|
||||||
while (!is_transmit_empty()); // wait for free spot
|
while (!is_transmit_empty()); // wait for free spot
|
||||||
outb(PORT, c);
|
outb(PORT, c);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,17 @@ because this shitty implementation will be replaced one day by Flanterm
|
|||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "flanterm.h"
|
#include "flanterm.h"
|
||||||
|
#include "flanterm_backends/fb.h"
|
||||||
|
#include "mem/heap/kheap.h"
|
||||||
|
#include "limine.h"
|
||||||
|
|
||||||
extern struct flanterm_context* ft_ctx;
|
extern struct flanterm_context* ft_ctx;
|
||||||
|
extern struct init_status init;
|
||||||
|
|
||||||
// Overhead that could be avoided, right? (for printf)
|
// Overhead that could be avoided, right? (for printf)
|
||||||
void _putchar(char character)
|
void _putchar(char character)
|
||||||
{
|
{
|
||||||
|
// TODO: Spinlock here (terminal access)
|
||||||
flanterm_write(ft_ctx, &character, 1);
|
flanterm_write(ft_ctx, &character, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,4 +40,35 @@ void kputs(const char* str)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
_putchar('\r');
|
_putchar('\r');
|
||||||
|
}
|
||||||
|
|
||||||
|
extern struct flanterm_context* ft_ctx;
|
||||||
|
extern struct boot_context boot_ctx;
|
||||||
|
|
||||||
|
void flanterm_free_wrapper(void* ptr, size_t size)
|
||||||
|
{
|
||||||
|
(void)size;
|
||||||
|
kfree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void term_init()
|
||||||
|
{
|
||||||
|
uint32_t bgColor = 0x252525;
|
||||||
|
ft_ctx = flanterm_fb_init(
|
||||||
|
kmalloc,
|
||||||
|
flanterm_free_wrapper,
|
||||||
|
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->green_mask_size, boot_ctx.fb->green_mask_shift,
|
||||||
|
boot_ctx.fb->blue_mask_size, boot_ctx.fb->blue_mask_shift,
|
||||||
|
NULL,
|
||||||
|
NULL, NULL,
|
||||||
|
&bgColor, NULL,
|
||||||
|
NULL, NULL,
|
||||||
|
NULL, 0, 0, 1,
|
||||||
|
0, 0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
init.terminal = true;
|
||||||
}
|
}
|
||||||
@@ -9,5 +9,6 @@
|
|||||||
|
|
||||||
void kputs(const char* str);
|
void kputs(const char* str);
|
||||||
void _putchar(char character);
|
void _putchar(char character);
|
||||||
|
void term_init();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+13
-1
@@ -19,9 +19,11 @@ enum ErrorCodes
|
|||||||
#include "io/serial/serial.h"
|
#include "io/serial/serial.h"
|
||||||
#include "io/term/printf.h"
|
#include "io/term/printf.h"
|
||||||
#include "idt/idt.h"
|
#include "idt/idt.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__)
|
extern volatile uint64_t ticks;
|
||||||
|
|
||||||
|
#define DEBUG(log, ...) fctprintf((void*)&skputc, 0, "[%8u] debug: <%s>: " log "\r\n", ticks, __func__, ##__VA_ARGS__)
|
||||||
|
|
||||||
/* #define DEBUG(log, ...) \
|
/* #define DEBUG(log, ...) \
|
||||||
printf("debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__); \
|
printf("debug: [%s]: " log "\r\n", __FILE__, ##__VA_ARGS__); \
|
||||||
@@ -38,6 +40,7 @@ void panic(struct cpu_status_t* ctx, const char* str);
|
|||||||
void hcf();
|
void hcf();
|
||||||
void idle();
|
void idle();
|
||||||
|
|
||||||
|
/* debug */
|
||||||
void debug_stack_trace(unsigned int max_frames);
|
void debug_stack_trace(unsigned int max_frames);
|
||||||
const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset);
|
const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset);
|
||||||
void boot_mem_display();
|
void boot_mem_display();
|
||||||
@@ -52,4 +55,13 @@ struct boot_context
|
|||||||
struct limine_kernel_address_response* kaddr;
|
struct limine_kernel_address_response* kaddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Are these modules initialized yet?
|
||||||
|
struct init_status
|
||||||
|
{
|
||||||
|
bool terminal;
|
||||||
|
bool serial;
|
||||||
|
bool keyboard;
|
||||||
|
bool timer;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+15
-35
@@ -30,8 +30,6 @@
|
|||||||
__attribute__((used, section(".limine_requests")))
|
__attribute__((used, section(".limine_requests")))
|
||||||
volatile LIMINE_BASE_REVISION(3);
|
volatile LIMINE_BASE_REVISION(3);
|
||||||
|
|
||||||
struct flanterm_context *ft_ctx;
|
|
||||||
|
|
||||||
// Halt and catch fire (makes machine stall)
|
// Halt and catch fire (makes machine stall)
|
||||||
void hcf()
|
void hcf()
|
||||||
{
|
{
|
||||||
@@ -41,9 +39,9 @@ void hcf()
|
|||||||
// Doing nothing (can be interrupted)
|
// Doing nothing (can be interrupted)
|
||||||
void idle() {SET_INTERRUPTS; for(;;)asm("hlt");}
|
void idle() {SET_INTERRUPTS; for(;;)asm("hlt");}
|
||||||
|
|
||||||
// uint8_t kernel_stack[KERNEL_STACK_SIZE] __attribute__((aligned(16)));
|
struct flanterm_context *ft_ctx;
|
||||||
|
|
||||||
struct boot_context boot_ctx;
|
struct boot_context boot_ctx;
|
||||||
|
struct init_status init = {0};
|
||||||
|
|
||||||
extern volatile struct limine_framebuffer_request framebuffer_request;
|
extern volatile struct limine_framebuffer_request framebuffer_request;
|
||||||
extern volatile struct limine_memmap_request memmap_request;
|
extern volatile struct limine_memmap_request memmap_request;
|
||||||
@@ -52,22 +50,25 @@ extern volatile struct limine_kernel_address_request kerneladdr_request;
|
|||||||
|
|
||||||
extern struct process_t* processes_list;
|
extern struct process_t* processes_list;
|
||||||
extern struct process_t* current_process;
|
extern struct process_t* current_process;
|
||||||
|
struct process_t* idle_proc;
|
||||||
|
|
||||||
|
bool iran = false;
|
||||||
|
|
||||||
|
// Never gets executed although pedicel is scheduled?
|
||||||
void pedicel_main(void* arg)
|
void pedicel_main(void* arg)
|
||||||
{
|
{
|
||||||
|
//panic(NULL, "test");
|
||||||
|
bool iran = true;
|
||||||
// FROM THE NEXT LINE ONWARDS, CANNOT WRITE TO FRAMEBUFFER WITHOUT PAGE FAULT!
|
// FROM THE NEXT LINE ONWARDS, CANNOT WRITE TO FRAMEBUFFER WITHOUT PAGE FAULT!
|
||||||
//printf("\n\nWelcome to PepperOS! Pedicel speaking.\nNothing left to do, halting the system!");
|
//printf("\n\nWelcome to PepperOS! Pedicel speaking.\nNothing left to do, halting the system!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void idle_main(void* arg)
|
void idle_main(void* arg)
|
||||||
{
|
{
|
||||||
for(;;)asm("hlt");
|
for (;;)
|
||||||
}
|
{
|
||||||
|
asm("hlt");
|
||||||
void flanterm_free_wrapper(void* ptr, size_t size)
|
}
|
||||||
{
|
|
||||||
(void)size;
|
|
||||||
kfree(ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uintptr_t kheap_start;
|
extern uintptr_t kheap_start;
|
||||||
@@ -79,6 +80,7 @@ void kmain()
|
|||||||
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
|
if (!LIMINE_BASE_REVISION_SUPPORTED) hcf();
|
||||||
|
|
||||||
serial_init();
|
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;
|
||||||
@@ -95,41 +97,19 @@ void kmain()
|
|||||||
|
|
||||||
keyboard_init(FR);
|
keyboard_init(FR);
|
||||||
|
|
||||||
uint32_t bgColor = 0x252525;
|
term_init();
|
||||||
ft_ctx = flanterm_fb_init(
|
|
||||||
kmalloc,
|
|
||||||
flanterm_free_wrapper,
|
|
||||||
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->green_mask_size, boot_ctx.fb->green_mask_shift,
|
|
||||||
boot_ctx.fb->blue_mask_size, boot_ctx.fb->blue_mask_shift,
|
|
||||||
NULL,
|
|
||||||
NULL, NULL,
|
|
||||||
&bgColor, NULL, // &bgColor
|
|
||||||
NULL, NULL,
|
|
||||||
NULL, 0, 0, 1,
|
|
||||||
0, 0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
idt_init();
|
idt_init();
|
||||||
|
|
||||||
timer_init();
|
|
||||||
vmm_init();
|
|
||||||
|
|
||||||
process_init();
|
process_init();
|
||||||
struct process_t* 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);
|
struct process_t* pedicel = process_create("pedicel", (void*)pedicel_main, 0);
|
||||||
|
|
||||||
process_display_list(processes_list);
|
process_display_list(processes_list);
|
||||||
|
|
||||||
scheduler_init();
|
scheduler_init();
|
||||||
|
|
||||||
current_process = idle_proc;
|
|
||||||
current_process->status = RUNNING;
|
|
||||||
|
|
||||||
kputs(PEPPEROS_SPLASH);
|
kputs(PEPPEROS_SPLASH);
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -45,7 +45,7 @@ void process_display_list(struct process_t* processes_list)
|
|||||||
|
|
||||||
struct process_t* process_create(char* name, void(*function)(void*), void* arg)
|
struct process_t* process_create(char* name, void(*function)(void*), void* arg)
|
||||||
{
|
{
|
||||||
/* CLEAR_INTERRUPTS; */
|
CLEAR_INTERRUPTS;
|
||||||
struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t));
|
struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t));
|
||||||
|
|
||||||
struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t));
|
struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t));
|
||||||
@@ -79,7 +79,7 @@ struct process_t* process_create(char* name, void(*function)(void*), void* arg)
|
|||||||
|
|
||||||
process_add(&processes_list, proc);
|
process_add(&processes_list, proc);
|
||||||
|
|
||||||
/* SET_INTERRUPTS; */
|
SET_INTERRUPTS;
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
extern struct process_t* processes_list;
|
extern struct process_t* processes_list;
|
||||||
extern struct process_t* current_process;
|
extern struct process_t* current_process;
|
||||||
|
extern struct process_t* idle_proc;
|
||||||
|
|
||||||
void scheduler_init()
|
void scheduler_init()
|
||||||
{
|
{
|
||||||
@@ -28,9 +29,8 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
|
|||||||
|
|
||||||
if (current_process == NULL)
|
if (current_process == NULL)
|
||||||
{
|
{
|
||||||
// Wtf happened
|
// If no more processes, then set IDLE as the current process, that's it.
|
||||||
current_process = processes_list;
|
current_process = idle_proc;
|
||||||
//panic(NULL, "Scheduler called without current process");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current_process->context = context;
|
current_process->context = context;
|
||||||
@@ -49,15 +49,15 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
|
|||||||
if (current_process != NULL && current_process->status == DEAD)
|
if (current_process != NULL && current_process->status == DEAD)
|
||||||
{
|
{
|
||||||
process_delete(&prev_process, current_process);
|
process_delete(&prev_process, current_process);
|
||||||
|
current_process = NULL;
|
||||||
|
return idle_proc->context;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
current_process->status = RUNNING;
|
current_process->status = RUNNING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Current_process gets wrong context?? (iret_rip points to other stuff than process function; like putpixel() for example)
|
|
||||||
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));
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ interested in multi-core functionnality like SMP)
|
|||||||
|
|
||||||
volatile uint64_t ticks = 0;
|
volatile uint64_t ticks = 0;
|
||||||
|
|
||||||
|
extern struct init_status init;
|
||||||
|
|
||||||
void pic_remap()
|
void pic_remap()
|
||||||
{
|
{
|
||||||
uint8_t master_mask = inb(0x21);
|
uint8_t master_mask = inb(0x21);
|
||||||
@@ -91,4 +93,5 @@ void timer_init()
|
|||||||
pic_enable();
|
pic_enable();
|
||||||
pit_init();
|
pit_init();
|
||||||
DEBUG("PIT initialized");
|
DEBUG("PIT initialized");
|
||||||
|
init.timer = true;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user