Reimplemented PIT Timer. Sleep is now a syscall. Also made docs/ that contains some info so i don't forget.

This commit is contained in:
2024-05-07 20:25:48 +02:00
parent e617f4fe69
commit 41e0b93f52
10 changed files with 137 additions and 62 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ CC = i386-elf-gcc
LD = i386-elf-ld LD = i386-elf-ld
AS = nasm AS = nasm
CFLAGS = -ffreestanding -fno-builtin -fno-stack-protector -nostdinc -mgeneral-regs-only -m32 -march=i386 -Iinclude -Wall CFLAGS = -ffreestanding -fno-builtin -fno-stack-protector -nostdinc -mgeneral-regs-only -m32 -march=i386 -Iinclude -Wall
SRC = ./src SRC = ./src
BUILD = ./build BUILD = ./build
View File
+11
View File
@@ -0,0 +1,11 @@
=== System Calls ===
Syscall handlers are prefixed by 'sys_'
Syscalls can be called using interrupt 0x80
The EAX register should countain a syscall number
Here's a list of syscalls: (and their numbers)
syscall(0) : Sleep()
Args: EBX - Number of miliseconds to sleep for
+47
View File
@@ -0,0 +1,47 @@
#ifndef TIMER_H
#define TIMER_H
#include <stdint.h>
#include <idt.h>
#include <pic.h>
#include <screen.h>
#define CHANNEL_0 0x40 // Offset it by 1 or 2 for ch1 and ch2
#define COMMAND 0x43
#define INPUT_CLK 1193182
static uint32_t* timerTicks = (uint32_t*)0x1000;
__attribute__ ((interrupt))
void timerHandler(intFrame_t* iframe) {
*timerTicks += 1;
// TODO: Improve the cursor rendering
if (*timerTicks % 500 == 0) putcAt(' ', cursor.x, cursor.y);
else if (*timerTicks % 250 == 0) putcAt(127, cursor.x, cursor.y);
sendPicEOI(0);
}
void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz) {
if (channel > 2 || opMode > 7) { return; }
__asm__ volatile ("cli");
// Send command - bits 7-6 channel, 5-4 Access mode, 3-1 operating mode, 0 - Should be zero in x86
outb(COMMAND, ((channel << 6) | (3 << 4) | (opMode << 1)));
// Send frequency
uint16_t freq = INPUT_CLK / hz; // I solved an equation to figure this out
outb(CHANNEL_0 + channel, (uint8_t)freq);
outb(CHANNEL_0 + channel, (uint8_t)(freq >> 8));
__asm__ volatile ("sti");
}
void setupTimer() { // Sets up IRQ 0 - PIT
idtSetGate(0x20, timerHandler, INT_GATE_FLAGS);
unsetIrqMask(0);
setPitPhase(0, 2, 1000); // Default setup: 1000Hz - 1 tick per 1ms
}
#endif
+10 -12
View File
@@ -1,27 +1,25 @@
#ifndef SYSCALL_H #ifndef SYSCALL_H
#define SYSCALL_H #define SYSCALL_H
#include <screen.h> #include <pit.h>
// System call count // System call count
#define MAX_SYSCALLS 2 #define MAX_SYSCALLS 2
void sys_test0() { // Args: ebx - number of miliseconds
fgColor = YELLOW; void sys_sleep() {
print("Syscall 0 - Test\n"); uint32_t ms;
fgColor = FG_COLOR; __asm__ volatile ("movl %%ebx, %0" : "=r"(ms));
}
void sys_test1() { uint32_t requiredTicks = *timerTicks + ms;
fgColor = CYAN; while (*timerTicks != requiredTicks) { // Wait...
print("Syscall 1 - Test\n"); __asm__ volatile ("sti;hlt;cli;");
fgColor = FG_COLOR; }
} }
// System call table // System call table
void* syscalls[MAX_SYSCALLS] = { void* syscalls[MAX_SYSCALLS] = {
sys_test0, sys_sleep,
sys_test1,
}; };
// int 0x80 - Syscall interrupt, handled by this function // int 0x80 - Syscall interrupt, handled by this function
+8
View File
@@ -0,0 +1,8 @@
#ifndef TIME_H
#define TIME_H
void sleep(uint32_t ms) {
__asm__ volatile ("int $0x80" : : "a"(0), "b"(ms));
}
#endif
+22 -21
View File
@@ -4,43 +4,44 @@
#include <stdint.h> #include <stdint.h>
#include <idt.h> #include <idt.h>
#include <pic.h> #include <pic.h>
#include <system.h>
#include <screen.h> #include <screen.h>
#define INPUT_CLK 1193180 #define CHANNEL_0 0x40 // Offset it by 1 or 2 for ch1 and ch2
#define COMMAND 0x43
#define INPUT_CLK 1193182
uint32_t timerTicks = 0; static uint32_t* timerTicks = (uint32_t*)0x1000;
__attribute__ ((interrupt)) __attribute__ ((interrupt))
void timerHandler(intFrame_t* iframe) { void timerHandler(intFrame_t* iframe) {
timerTicks++; *timerTicks += 1;
// TODO: Improve the cursor rendering // TODO: Improve the cursor rendering
if (timerTicks % 500 == 0) putcAt(127, cursor.x, cursor.y); if (*timerTicks % 500 == 0) putcAt(' ', cursor.x, cursor.y);
else if (timerTicks % 250 == 0) putcAt(' ', cursor.x, cursor.y); else if (*timerTicks % 250 == 0) putcAt(127, cursor.x, cursor.y);
sendPicEOI(0); sendPicEOI(0);
} }
void setupTimer() { void setPitPhase(uint8_t channel, uint8_t opMode, uint16_t hz) {
idtSetGate(32, timerHandler, INT_GATE_FLAGS); if (channel > 2 || opMode > 7) { return; }
unsetIrqMask(0); __asm__ volatile ("cli");
}
// Source: https://en.wikibooks.org/wiki/X86_Assembly/Programmable_Interval_Timer // Send command - bits 7-6 channel, 5-4 Access mode, 3-1 operating mode, 0 - Should be zero in x86
void timerPhase(uint32_t hz) { outb(COMMAND, ((channel << 6) | (3 << 4) | (opMode << 1)));
uint16_t div = INPUT_CLK / hz;
outb(0x43, 0x36); // Tell PIT that we're setting channel 0 // Send frequency
outb(0x40, div & 0xff); // Low byte uint16_t freq = INPUT_CLK / hz; // I solved an equation to figure this out
outb(0x40, div >> 8); // High byte outb(CHANNEL_0 + channel, (uint8_t)freq);
} outb(CHANNEL_0 + channel, (uint8_t)(freq >> 8));
void sleep(uint32_t ticks) {
uint32_t eticks = ticks + timerTicks;
while (timerTicks != eticks); // Should ignore overflows unlike '<' __asm__ volatile ("sti");
} }
void setupTimer() { // Sets up IRQ 0 - PIT
idtSetGate(0x20, timerHandler, INT_GATE_FLAGS);
unsetIrqMask(0);
setPitPhase(0, 2, 1000); // Default setup: 1000Hz - 1 tick per 1ms
}
#endif #endif
+16 -16
View File
@@ -1526,22 +1526,22 @@ db 00h,\
00h,\ 00h,\
00h,\ 00h,\
00h 00h
db 00h,\ db 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
00h,\ 0xFF,\
0FEh 0xFF
;; End of visible ascii characters ;; End of visible ascii characters
times 2048-($-$$) db 0 times 2048-($-$$) db 0
+11 -6
View File
@@ -9,7 +9,8 @@
#include <string.h> #include <string.h>
#include <graphics.h> #include <graphics.h>
#include <keyboard.h> #include <keyboard.h>
#include <timer.h> #include <pit.h>
#include <time.h>
#define PROMPT "#> " #define PROMPT "#> "
@@ -54,7 +55,6 @@ void main() {
__asm__ volatile ("sti"); __asm__ volatile ("sti");
setupTimer(); setupTimer();
timerPhase(1000); // 1 kHz
setupKeyboard(); setupKeyboard();
// Run Interactive Shell Program // Run Interactive Shell Program
@@ -166,7 +166,7 @@ void main() {
drawCircle(1500, 600, 300, WHITE); drawCircle(1500, 600, 300, WHITE);
fillCircle(950, 750, 75, rgb(0xa2, 0xd6, 0xf9)); fillCircle(950, 750, 75, rgb(0xa2, 0xd6, 0xf9));
//read('q'); // Wait until we get a 'q' read('q'); // Wait until we get a 'q'
clear(); clear();
} else if (strcmp(input, "help") == 0) { } else if (strcmp(input, "help") == 0) {
print("Available Commands:\n"); print("Available Commands:\n");
@@ -179,6 +179,7 @@ void main() {
print(" ls | Lists all available files\n"); print(" ls | Lists all available files\n");
print(" memmap | Prints the memory map and info\n"); print(" memmap | Prints the memory map and info\n");
print(" reboot | Reboots the system\n"); print(" reboot | Reboots the system\n");
print(" sleep | Sleeps for input number of seconds\n");
print(" test | Performs tests\n"); print(" test | Performs tests\n");
} else if (strcmp(input, "ls") == 0) { } else if (strcmp(input, "ls") == 0) {
printFiletable(filetable); printFiletable(filetable);
@@ -186,6 +187,13 @@ void main() {
printPhysicalMemmap(); printPhysicalMemmap();
} else if (strcmp(input, "reboot") == 0) { } else if (strcmp(input, "reboot") == 0) {
outb(0x64, 0xFE); outb(0x64, 0xFE);
} else if (strcmp(input, "sleep") == 0) {
if (*args == '\0') continue;
uint32_t ms = atoi(args) * 1000; // Convert seconds to miliseconds
if (ms == 0) continue;
sleep(ms);
} else if (strcmp(input, "test") == 0) { } else if (strcmp(input, "test") == 0) {
print("Running Tests...\n"); print("Running Tests...\n");
uint8_t buf[512]; uint8_t buf[512];
@@ -206,9 +214,6 @@ void main() {
} else { } else {
print("[ FAIL ]\n"); print("[ FAIL ]\n");
} }
print("Syscall Test:\n");
__asm__ volatile ("movl $0, %eax; int $0x80"); // Syscall(0);
__asm__ volatile ("movl $1, %eax; int $0x80"); // Syscall(1);
print("\nTests Finished!\n"); print("\nTests Finished!\n");
} else { } else {
+11 -6
View File
@@ -9,10 +9,11 @@ Legend:
- [x] Multistage Bootloader - [x] Multistage Bootloader
- [ ] Bootloader reads filetable to find files - [ ] Bootloader reads filetable to find files
- [ ] The almighty 'printf()'
- [!] Makefile refactorin' - [!] Makefile refactorin'
- [x] Write down where stuff is in memory (in notes.txt) - [x] Write down where stuff is in memory (in notes.txt)
- [ ] "Text" mode (not actually) - [ ] "Text" mode (not actually)
- [ ] Scrolling - [x] Scrolling
- [ ] Scroll-back - [ ] Scroll-back
- [ ] Color codes (and just multicolor text in general) - [ ] Color codes (and just multicolor text in general)
- [x] VESA BIOS Extensions - [x] VESA BIOS Extensions
@@ -34,12 +35,15 @@ Legend:
- [x] Triangles (3D?!!???) - [x] Triangles (3D?!!???)
- [x] Rectange :) - [x] Rectange :)
- [x] Circle! - [x] Circle!
- [_] Filled verisons - [x] Filled verisons
- [ ] Interrupts - [ ] Interrupts
- [x] IDT Setup (idt.h) - [x] IDT Setup (idt.h)
- [x] Exception handling - [x] Exception handling
- [ ] Hardware/software interrupts - [x] Hardware/software interrupts
- [ ] Syscalls! (int 0x80) - [x] Syscalls! (int 0x80)
- [ ] IRQ 0 - PIT
- [ ] IRQ 1 - Keyboard
- [ ] IRQ 8 - CMOS Real time clock
- [ ] Math - [ ] Math
- [ ] Trigonometry - [ ] Trigonometry
- [ ] Sine - [ ] Sine
@@ -63,6 +67,7 @@ Legend:
- [ ] NAN - [ ] NAN
- [x] E (eulers number) - [x] E (eulers number)
- [x] PI - [x] PI
- [ ] Floating point macros/functions
- [ ] Filesystem - [ ] Filesystem
- [ ] Utility for filesystem building (not just an assembly file) - [ ] Utility for filesystem building (not just an assembly file)
- [x] Filetable - [x] Filetable
@@ -77,6 +82,7 @@ Legend:
- [ ] Symbolic - [ ] Symbolic
- [ ] Hard - [ ] Hard
- [ ] System Calls - [ ] System Calls
- [ ] Sleep()
- [ ] Write() - [ ] Write()
- [ ] Read() - [ ] Read()
- [ ] Open() - [ ] Open()
@@ -103,7 +109,6 @@ Legend:
- [ ] stdin - [ ] stdin
- [ ] stdout - [ ] stdout
- [ ] stderr - [ ] stderr
- [ ] printf
- [ ] Memory manager - [ ] Memory manager
- [x] Memory map - [x] Memory map
- [x] Print mem map - [x] Print mem map