mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
Began work on proper terminal I/O
- Chenged Puts() syscall to Write() - Improved syscalls.h - added a new header in terminal/terminal.h - moved gfxMode into screen/gfxmode.h
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
--- Terminal Escape Sequences ---
|
||||
|
||||
Escape character:
|
||||
char: '\e'
|
||||
hex: 0x1b
|
||||
oct: 0o33
|
||||
dec: 27
|
||||
|
||||
Note: the escape character will be denoted by ESC here
|
||||
|
||||
Syntax:
|
||||
All escape sequenced start with the escape character followed by an opening square bracket '['
|
||||
The sequence can take any number of arguments in a semicolon separated list
|
||||
If a argument is skipped, it will be implicitly set to 0
|
||||
The escape sequence must end with a uppercase or lowercase letter
|
||||
|
||||
Available escape sequences:
|
||||
- Cursor Controls -
|
||||
`ESC[#A` - Moves cursor # rows up
|
||||
`ESC[#B` - Moves cursor # rows down
|
||||
`ESC[#C` - Moves cursor # columns left
|
||||
`ESC[#D` - Moves cursor # columns right
|
||||
`ESC[#E` - Moves cursor to #th row
|
||||
`ESC[#F` - Moves cursor to #th column
|
||||
`ESC[#G` - Show (# = 1) or hide (# = 0) cursor
|
||||
`ESC[{row};{col}H` - Moves cursor to specified position (if not arguments given, moves to [0,0])a
|
||||
- Erase functions -
|
||||
`ESC[I` - Reserved
|
||||
`ESC[J` - Erase screen
|
||||
`ESC[K` - Erase line (not implemented)
|
||||
`ESC[L` - Erase column (not implemented)
|
||||
- Text Style -
|
||||
`ESC[#M` - Sets foreground color to #
|
||||
`ESC[#N` - Sets backgorund color to #
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
--- Memory Map ---
|
||||
0x1000 - Kernel
|
||||
0x6000 - Font
|
||||
0x7000 - Filetable (0x7c00 - Bootloader)
|
||||
0x8500 - ACPI Memory map
|
||||
0x9000 - VBE Mode Info Block
|
||||
0x30000 - Memory manager memmap
|
||||
|
||||
+17
-2
@@ -2,10 +2,25 @@
|
||||
|
||||
Syscall handlers are prefixed by 'sys_'
|
||||
Syscalls can be called using interrupt 0x80
|
||||
The EAX register should countain a syscall number
|
||||
The EAX register should countain a syscall number on calling and it will contain a return value (if applicable) after calling
|
||||
|
||||
Here's a list of syscalls: (and their numbers)
|
||||
|
||||
syscall(0) : Sleep()
|
||||
Syscall(0) : Sleep()
|
||||
Args: EBX - Number of miliseconds to sleep for
|
||||
|
||||
Syscall(1) : Write()
|
||||
Args: EBX - File descriptor
|
||||
ECX - Buffer to write
|
||||
EDX - Length
|
||||
Returns: Status
|
||||
|
||||
Syscall(2) : Read() #TBD
|
||||
|
||||
Syscall(3) : Malloc()
|
||||
Args: EBX - Amount of bytes to malloc
|
||||
Returns: Address of allocated memory
|
||||
|
||||
Syscall(4) : Free()
|
||||
Args: EBX - Pointer to free
|
||||
|
||||
|
||||
+10
-4
@@ -1,12 +1,18 @@
|
||||
#ifndef STDIO_H
|
||||
#define STDIO_H
|
||||
|
||||
void print(const char* s) { // Use Syscall(1) - Puts()
|
||||
__asm__ volatile ("int $0x80" : : "a"(1), "b"(s));
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
|
||||
// TODO: Make a proper file descriptor table
|
||||
#define STDOUT 1
|
||||
|
||||
void print(const char* s) {
|
||||
write(STDOUT, s, strlen(s));
|
||||
}
|
||||
|
||||
void read(char* s) { // Use Syscall(2) - Gets()
|
||||
__asm__ volatile ("int $0x80" : : "a"(2), "b"(s));
|
||||
void read(char* s) {
|
||||
print("\x1b[1M[ ERROR: Read() Syscall not found! ]\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef SYSCALLNUMS_H
|
||||
#define SYSCALLNUMS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_SYSCALLS 5
|
||||
|
||||
typedef enum {
|
||||
SYS_SLEEP,
|
||||
SYS_WRITE,
|
||||
SYS_GETS,
|
||||
SYS_MALLOC,
|
||||
SYS_FREE,
|
||||
} SYSCALL_NUMBERS;
|
||||
|
||||
// TODO: Add malloc() and free() syscall wrappers??
|
||||
int32_t write(int32_t fd, const void* buf, uint32_t len) {
|
||||
int32_t result = -1;
|
||||
__asm__ volatile ("int $0x80" : "=a"(result) : "a"(SYS_WRITE), "b"(fd), "c"(buf), "d"(len));
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
#include <interrupt/idt.h>
|
||||
#include <interrupt/pit.h>
|
||||
#include <screen/text.h>
|
||||
#include <terminal/terminal.h>
|
||||
#include <keyboard/keyboard.h>
|
||||
#include <memory/malloc.h>
|
||||
#include <syscall.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// System call count
|
||||
#define MAX_SYSCALLS 5
|
||||
|
||||
// Syscall(0) - Sleep()
|
||||
// Args: ebx - number of miliseconds
|
||||
void sys_sleep() {
|
||||
uint32_t ms;
|
||||
@@ -21,12 +21,24 @@ void sys_sleep() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use a Write() syscall and write to stdout
|
||||
// Args: ebx - char* string
|
||||
void sys_puts() {
|
||||
char* s;
|
||||
__asm__ volatile ("movl %%ebx, %0" : "=r"(s));
|
||||
print(s);
|
||||
// Syscall(1) - Write()
|
||||
// Args: ebx - int fd
|
||||
// ecx - void* buf
|
||||
// edx - uint32_t len
|
||||
void sys_write() {
|
||||
int32_t fd = 0;
|
||||
void* buf = NULL;
|
||||
uint32_t len = 0;
|
||||
|
||||
__asm__ volatile ("nop" : "=b"(fd), "=c"(buf), "=d"(len));
|
||||
|
||||
// TODO: Open fd table?
|
||||
if (fd == 1) { // "stdout"
|
||||
int32_t result = terminalWrite(buf, len); // Call a terminal print function
|
||||
__asm__ volatile ("movl %0, %%eax" : : "r"(result));
|
||||
} else { // Not implemented
|
||||
__asm__ volatile ("movl $1, %eax");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use a Read() sycall and read from stdin
|
||||
@@ -37,7 +49,9 @@ void sys_gets() {
|
||||
read(s);
|
||||
}
|
||||
|
||||
// Syscall(3) - Malloc()
|
||||
// Args: ebx - amount of bytes to malloc
|
||||
// Returns: eax - Pointer to allocated memory
|
||||
void sys_malloc() {
|
||||
uint32_t size = 0;
|
||||
__asm__ volatile ("movl %%ebx, %0" : "=b"(size));
|
||||
@@ -54,6 +68,7 @@ void sys_malloc() {
|
||||
__asm__ volatile ("movl %0, %%eax" : : "r"(ptr));
|
||||
}
|
||||
|
||||
// Syscall(4) - Free()
|
||||
// Args: ebx - allocated pointer
|
||||
void sys_free() {
|
||||
void* ptr = NULL;
|
||||
@@ -62,12 +77,12 @@ void sys_free() {
|
||||
}
|
||||
|
||||
// System call table
|
||||
void* syscalls[MAX_SYSCALLS] = {
|
||||
sys_sleep, // Syscall(0)
|
||||
sys_puts, // Syscall(1)
|
||||
sys_gets, // Syscall(2)
|
||||
sys_malloc, // Syscall(3)
|
||||
sys_free, // Syscall(4)
|
||||
void (*syscalls[MAX_SYSCALLS])(void) = {
|
||||
[SYS_SLEEP] = sys_sleep,
|
||||
[SYS_WRITE] = sys_write,
|
||||
[SYS_GETS] = sys_gets,
|
||||
[SYS_MALLOC] = sys_malloc,
|
||||
[SYS_FREE] = sys_free,
|
||||
};
|
||||
|
||||
// int 0x80 - Syscall interrupt, handled by this function
|
||||
@@ -1,9 +1,18 @@
|
||||
#ifndef ADDRESSES_H
|
||||
#define ADDRESSES_H
|
||||
|
||||
// TODO: Don't let these be just random numbers?
|
||||
|
||||
// Locations
|
||||
#define KERNEL_LOC 0x100000
|
||||
#define FILETABLE_LOC 0x7000
|
||||
#define TERMINAL_INFO_LOC 0x2000
|
||||
#define MODE_INFO_BLOCK_LOC 0x9000
|
||||
|
||||
// Font
|
||||
#define FONT_LOC 0x6000
|
||||
#define FONT_WIDTH (FONT_LOC)
|
||||
#define FONT_HEIGHT (FONT_LOC + 1)
|
||||
|
||||
// Physical memory manager
|
||||
#define MEMMAP_AREA 0x30000
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#ifndef GFXMODE_H
|
||||
#define GFXMODE_H
|
||||
|
||||
#include <memory/addresses.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define BLACK 0x00000000 // 0
|
||||
#define RED 0x00ff0000 // 1
|
||||
#define GREEN 0x0000ff00 // 2
|
||||
#define YELLOW 0x00ffff00 // 3
|
||||
#define BLUE 0x000000ff // 4
|
||||
#define MAGENTA 0x00ff00ff // 5
|
||||
#define CYAN 0x0000ffff // 6
|
||||
#define WHITE 0x00ffffff // 7
|
||||
|
||||
#define BG_COLOR 0x00010b17
|
||||
#define FG_COLOR 0x00ebddf4
|
||||
|
||||
typedef struct modeInfoBlock_s {
|
||||
// Required by all VBE revisions
|
||||
uint16_t modeAttr;
|
||||
uint8_t windowAAtrr;
|
||||
uint8_t windowBAttr;
|
||||
uint16_t windowGranularity;
|
||||
uint16_t windowSize;
|
||||
uint16_t windowASegment;
|
||||
uint16_t windowBSegment;
|
||||
uint32_t windowFunctionPtr;
|
||||
uint16_t bytesPerScanline;
|
||||
|
||||
// Required by VBE 1.2+
|
||||
uint16_t xRes;
|
||||
uint16_t yRes;
|
||||
uint8_t xCharSize;
|
||||
uint8_t yCharSize;
|
||||
uint8_t planeCount;
|
||||
uint8_t bpp;
|
||||
uint8_t bankCount;
|
||||
uint8_t memoryModel;
|
||||
uint8_t bankSize;
|
||||
uint8_t imagePageCount;
|
||||
uint8_t reserved1;
|
||||
|
||||
// Direct color fields
|
||||
uint8_t redMaskSize;
|
||||
uint8_t redFieldPos;
|
||||
uint8_t greenMaskSize;
|
||||
uint8_t greenFieldPos;
|
||||
uint8_t blueMaskSize;
|
||||
uint8_t blueFieldPos;
|
||||
uint8_t reservedMaskSize;
|
||||
uint8_t reservedFieldPos;
|
||||
uint8_t directColorModeInfo;
|
||||
|
||||
// Required by VBE 2.0+
|
||||
uint32_t physicalBasePtr;
|
||||
uint32_t reserved2;
|
||||
uint16_t reserved3;
|
||||
|
||||
// Required by VBE 3.0+
|
||||
uint16_t linearBytesPerScanline;
|
||||
uint8_t bankImagePageCount;
|
||||
uint8_t linearImagePageCount;
|
||||
uint8_t linearRedMaskSize;
|
||||
uint8_t linearRedFieldPos;
|
||||
uint8_t linearGreenMaskSize;
|
||||
uint8_t linearGreenFieldPos;
|
||||
uint8_t linearBlueMaskSize;
|
||||
uint8_t linearBlueFieldPos;
|
||||
uint8_t linearReservedMaskSize;
|
||||
uint8_t linearReservedFieldPos;
|
||||
uint32_t maxPixelClock;
|
||||
|
||||
uint8_t reserved4[190];
|
||||
} __attribute__ ((packed)) modeInfoBlock_t;
|
||||
|
||||
static modeInfoBlock_t* gfxMode = (modeInfoBlock_t*)MODE_INFO_BLOCK_LOC;
|
||||
|
||||
#endif
|
||||
+12
-78
@@ -1,89 +1,18 @@
|
||||
#ifndef SCREEN_H
|
||||
#define SCREEN_H
|
||||
|
||||
#include <memory/addresses.h>
|
||||
#include <screen/gfxmode.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
// Basic full saturation colors
|
||||
#define BLACK 0x00000000 // 0
|
||||
#define RED 0x00ff0000 // 1
|
||||
#define GREEN 0x0000ff00 // 2
|
||||
#define YELLOW 0x00ffff00 // 3
|
||||
#define BLUE 0x000000ff // 4
|
||||
#define MAGENTA 0x00ff00ff // 5
|
||||
#define CYAN 0x0000ffff // 6
|
||||
#define WHITE 0x00ffffff // 7
|
||||
|
||||
#define MODE_INFO_BLOCK 0x9000
|
||||
#define BG_COLOR 0x00010b17
|
||||
#define FG_COLOR 0x00ebddf4
|
||||
|
||||
typedef struct modeInfoBlock_s {
|
||||
// Required by all VBE revisions
|
||||
uint16_t modeAttr;
|
||||
uint8_t windowAAtrr;
|
||||
uint8_t windowBAttr;
|
||||
uint16_t windowGranularity;
|
||||
uint16_t windowSize;
|
||||
uint16_t windowASegment;
|
||||
uint16_t windowBSegment;
|
||||
uint32_t windowFunctionPtr;
|
||||
uint16_t bytesPerScanline;
|
||||
|
||||
// Required by VBE 1.2+
|
||||
uint16_t xRes;
|
||||
uint16_t yRes;
|
||||
uint8_t xCharSize;
|
||||
uint8_t yCharSize;
|
||||
uint8_t planeCount;
|
||||
uint8_t bpp;
|
||||
uint8_t bankCount;
|
||||
uint8_t memoryModel;
|
||||
uint8_t bankSize;
|
||||
uint8_t imagePageCount;
|
||||
uint8_t reserved1;
|
||||
|
||||
// Direct color fields
|
||||
uint8_t redMaskSize;
|
||||
uint8_t redFieldPos;
|
||||
uint8_t greenMaskSize;
|
||||
uint8_t greenFieldPos;
|
||||
uint8_t blueMaskSize;
|
||||
uint8_t blueFieldPos;
|
||||
uint8_t reservedMaskSize;
|
||||
uint8_t reservedFieldPos;
|
||||
uint8_t directColorModeInfo;
|
||||
|
||||
// Required by VBE 2.0+
|
||||
uint32_t physicalBasePtr;
|
||||
uint32_t reserved2;
|
||||
uint16_t reserved3;
|
||||
|
||||
// Required by VBE 3.0+
|
||||
uint16_t linearBytesPerScanline;
|
||||
uint8_t bankImagePageCount;
|
||||
uint8_t linearImagePageCount;
|
||||
uint8_t linearRedMaskSize;
|
||||
uint8_t linearRedFieldPos;
|
||||
uint8_t linearGreenMaskSize;
|
||||
uint8_t linearGreenFieldPos;
|
||||
uint8_t linearBlueMaskSize;
|
||||
uint8_t linearBlueFieldPos;
|
||||
uint8_t linearReservedMaskSize;
|
||||
uint8_t linearReservedFieldPos;
|
||||
uint32_t maxPixelClock;
|
||||
|
||||
uint8_t reserved4[190];
|
||||
} __attribute__ ((packed)) modeInfoBlock_t;
|
||||
|
||||
struct cursor_s {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
};
|
||||
|
||||
static char* font = (char*)0x6000;
|
||||
static char* font = (char*)FONT_LOC;
|
||||
static struct cursor_s cursor = { 0, 0 };
|
||||
static modeInfoBlock_t* gfxMode = (modeInfoBlock_t*)MODE_INFO_BLOCK;
|
||||
|
||||
uint32_t bgColor = BG_COLOR;
|
||||
uint32_t fgColor = FG_COLOR;
|
||||
@@ -105,8 +34,8 @@ uint32_t convertColor(uint32_t color) {
|
||||
// TODO: Reimplement larger text
|
||||
void putcAt(unsigned char c, uint32_t x, uint32_t y) {
|
||||
// Font info
|
||||
uint8_t charWidth = *(font);
|
||||
uint8_t charHeight = *(font + 1);
|
||||
uint8_t charWidth = *(uint8_t*)FONT_WIDTH;
|
||||
uint8_t charHeight = *(uint8_t*)FONT_HEIGHT;
|
||||
// uint8_t bitmapRowLen = (charWidth - 1) / 8 + 1; // TODO: Larger font support
|
||||
|
||||
// Video stuff
|
||||
@@ -133,6 +62,7 @@ void putcAt(unsigned char c, uint32_t x, uint32_t y) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Probably get rid of this, idk (use terminal control codes)
|
||||
void printAt(const char* str, uint32_t x, uint32_t y) {
|
||||
while (*str != '\0') {
|
||||
putcAt(*str++, x, y);
|
||||
@@ -140,8 +70,9 @@ void printAt(const char* str, uint32_t x, uint32_t y) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Use terminal.x/y instead of cursor.x/y
|
||||
void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() helped alot)
|
||||
uint8_t charHeight = *(font + 1);
|
||||
uint8_t charHeight = *(uint8_t*)FONT_HEIGHT;
|
||||
if ((cursor.y+1) * charHeight < gfxMode->yRes) { return; } // Check if we should scroll
|
||||
|
||||
uint32_t bytesPerLine = charHeight * gfxMode->bytesPerScanline;
|
||||
@@ -167,8 +98,9 @@ void scroll() { // TODO: Make this faster (still kinda slow, but memcpy32() help
|
||||
cursor.y--;
|
||||
}
|
||||
|
||||
// DEPRICATED - TODO: Remove this from everywhere so i can delete it
|
||||
void putc(char c) {
|
||||
uint8_t charWidth = *(font);
|
||||
uint8_t charWidth = *(uint8_t*)FONT_WIDTH;
|
||||
|
||||
if (c == '\n') {
|
||||
putcAt(' ', cursor.x, cursor.y); // Make sure we don't leave an extra cursor
|
||||
@@ -198,12 +130,14 @@ void putc(char c) {
|
||||
scroll();
|
||||
}
|
||||
|
||||
// DEPRICATED - TODO: Remove this everywhere it's used and delete it's definition here
|
||||
void print(const char* str) {
|
||||
while (*str != '\0') {
|
||||
putc(*str++);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make this comply with the new terminal.h thing!
|
||||
void clear() {
|
||||
uint8_t* vidmem = (uint8_t*)gfxMode->physicalBasePtr;
|
||||
uint8_t bytesPerPx = (gfxMode->bpp+1) / 8;
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef TERMINAL_H
|
||||
#define TERMINAL_H
|
||||
|
||||
#include <screen/text.h>
|
||||
#include <screen/gfxmode.h>
|
||||
#include <memory/addresses.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t x; // X Position of cursor in characters
|
||||
uint32_t y; // Y Position of cursor in characters
|
||||
uint32_t bg; // Printed character background
|
||||
uint32_t fg; // Printed character foreground
|
||||
uint32_t width; // Width in characters
|
||||
uint32_t height; // Height in characters
|
||||
bool showCursor; // Should we display the cursor
|
||||
} terminal_t;
|
||||
|
||||
terminal_t* terminal = (terminal_t*)TERMINAL_INFO_LOC;
|
||||
|
||||
int32_t terminalWrite(const void* buf, uint32_t len) {
|
||||
terminal->width = gfxMode->xRes / *(uint8_t*)FONT_WIDTH;
|
||||
terminal->height = gfxMode->yRes / *(uint8_t*)FONT_HEIGHT;
|
||||
|
||||
char* str = (char*)buf;
|
||||
uint32_t i;
|
||||
|
||||
// Do we need to check for NULL? Can we just skip it/ignore it?
|
||||
for (i = 0; i < len && str[i] != '\0'; i++) {
|
||||
if (str[i] == '\n') {
|
||||
putcAt(' ', terminal->x, terminal->y); // Remove extra cursor
|
||||
terminal->y++;
|
||||
terminal->x = 0;
|
||||
} else if (str[i] == '\b') {
|
||||
putcAt(' ', terminal->x, terminal->y); // Remove extra cursor
|
||||
if (terminal->x == 0) {
|
||||
terminal->x = terminal->width - 1;
|
||||
terminal->y--; // Y could be 0?
|
||||
} else {
|
||||
terminal->x--;
|
||||
}
|
||||
putcAt(' ', terminal->x, terminal->y);
|
||||
} else if (str[i] == '\x1b') { // Escape sequence
|
||||
if (str[++i] != '[') { // TODO: Suppord more types of escape sequences
|
||||
continue;
|
||||
}
|
||||
|
||||
putcAt(str[++i], terminal->x++, terminal->y);
|
||||
} else {
|
||||
putcAt(str[i], terminal->x, terminal->y);
|
||||
terminal->x++;
|
||||
|
||||
if (terminal->x >= terminal->width) { // Go to next line
|
||||
terminal->y++;
|
||||
terminal->x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
scroll();
|
||||
|
||||
return i; // Number of characters that were printed
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -75,7 +75,8 @@ Legend:
|
||||
- [x] PI
|
||||
- [ ] Floating point macros/functions
|
||||
- [ ] Filesystem
|
||||
- [ ] Utility for filesystem building (not just an assembly file)
|
||||
- [!] Utility for filesystem building (not just an assembly file)
|
||||
- [x] Better header for file i/o (disk/filesys.h)
|
||||
- [x] Filetable
|
||||
- [ ] Files
|
||||
- [x] Larger than one sector (512B)
|
||||
@@ -89,7 +90,7 @@ Legend:
|
||||
- [ ] Hard
|
||||
- [ ] System Calls
|
||||
- [x] Sleep()
|
||||
- [ ] Write() (temporarly puts())
|
||||
- [x] Write()
|
||||
- [ ] Read() (temporarly gets())
|
||||
- [ ] Open()
|
||||
- [ ] Close()
|
||||
@@ -131,7 +132,7 @@ Legend:
|
||||
- [ ] Standalone shell program
|
||||
- [ ] Userspace programs
|
||||
- [ ] Calculator
|
||||
- [ ] Caledar
|
||||
- [ ] Calendar
|
||||
- [ ] Code Editor
|
||||
- [ ] Text editor
|
||||
- [ ] Syntax highlighting
|
||||
|
||||
Reference in New Issue
Block a user