mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
IMPLEMENTED printf()!!!!!!!
It's kinda bad :/
This commit is contained in:
+53
-4
@@ -7,6 +7,14 @@
|
|||||||
// TODO: Make a proper file descriptor table
|
// TODO: Make a proper file descriptor table
|
||||||
#define STDOUT 1
|
#define STDOUT 1
|
||||||
|
|
||||||
|
/* --- Output --- */
|
||||||
|
void putc(char c) {
|
||||||
|
// write(STDOUT, &c, 1); TODO: This doesn't work and we need to use a static variable
|
||||||
|
static char _c;
|
||||||
|
_c = c;
|
||||||
|
write(STDOUT, &_c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void print(const char* s) {
|
void print(const char* s) {
|
||||||
write(STDOUT, s, strlen(s));
|
write(STDOUT, s, strlen(s));
|
||||||
}
|
}
|
||||||
@@ -15,12 +23,53 @@ void clear() {
|
|||||||
print("\x1b[J");
|
print("\x1b[J");
|
||||||
}
|
}
|
||||||
|
|
||||||
void putc(char c) {
|
// TODO: Dynamically allocate memory and print once instead of calling putc for every character :/
|
||||||
static char _c; // We need to pass in a static address. Idk why
|
// TODO: Support negative numbers
|
||||||
_c = c;
|
// TODO: Printing individual characters doesn't let escape sequences work :(
|
||||||
write(STDOUT, &_c, 1);
|
int printf(const char* fmt, ...) {
|
||||||
|
char* argPtr = (char*)&fmt + sizeof(char*); // First arg after fmt
|
||||||
|
uint8_t state = 0;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; fmt[i] != '\0'; i++) {
|
||||||
|
char c = fmt[i];
|
||||||
|
|
||||||
|
if (state == 0) {
|
||||||
|
if (c == '%') state = '%';
|
||||||
|
else putc(c);
|
||||||
|
} else if (state == '%') {
|
||||||
|
switch (c) {
|
||||||
|
case 'd': // Decimal number
|
||||||
|
print(itoa(*(uint32_t*)argPtr, 10));
|
||||||
|
argPtr += sizeof(unsigned int);
|
||||||
|
break;
|
||||||
|
case 'x': // Hex number
|
||||||
|
print(itoa(*(uint32_t*)argPtr, 16));
|
||||||
|
argPtr += sizeof(unsigned int);
|
||||||
|
break;
|
||||||
|
case 's': // String
|
||||||
|
print(*(char**)argPtr);
|
||||||
|
argPtr += sizeof(char*);
|
||||||
|
break;
|
||||||
|
case 'c': // Char
|
||||||
|
putc(*(char*)argPtr);
|
||||||
|
argPtr += sizeof(char);
|
||||||
|
break;
|
||||||
|
case '%': // Just print '%'
|
||||||
|
putc('%');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
putc('%');
|
||||||
|
putc(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Input --- */
|
||||||
char getc() {
|
char getc() {
|
||||||
char* character = (char*)0x2100;
|
char* character = (char*)0x2100;
|
||||||
*character = '\0';
|
*character = '\0';
|
||||||
|
|||||||
+4
-7
@@ -6,19 +6,16 @@
|
|||||||
// Source: http://www.strudel.org.uk/itoa/
|
// Source: http://www.strudel.org.uk/itoa/
|
||||||
char* itoa(uint32_t val, uint8_t base) {
|
char* itoa(uint32_t val, uint8_t base) {
|
||||||
static char buf[32] = { 0 };
|
static char buf[32] = { 0 };
|
||||||
|
|
||||||
if (base == 0 || base > 16) {
|
if (base == 0 || base > 16) { return NULL; }
|
||||||
// TODO: Add errors!!
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val == 0) {
|
if (val == 0) {
|
||||||
buf[0] = '0';
|
buf[0] = '0';
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 30;
|
int i;
|
||||||
for (; val && i; i--, val /= base) {
|
for (i = 30; val && i; i--, val /= base) {
|
||||||
buf[i] = "0123456789abcdef"[val % base];
|
buf[i] = "0123456789abcdef"[val % base];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
// Exception handlers
|
// Exception handlers
|
||||||
__attribute__ ((interrupt))
|
__attribute__ ((interrupt))
|
||||||
void excp_divideErr(intFrame_t* iframe) { // ISR 0
|
void excp_divideErr(intFrame_t* iframe) { // ISR 0
|
||||||
print("\x1b[1M[ Division Error ]\n\x1b[8M");
|
printf("\x1b[1M[ Division Error ]\n\x1b[8M");
|
||||||
iframe->eip++;
|
iframe->eip++;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((interrupt))
|
__attribute__ ((interrupt))
|
||||||
void excp_doubleFault(intFrame_t* iframe, uint32_t errCode) { // ISR 8
|
void excp_doubleFault(intFrame_t* iframe, uint32_t errCode) { // ISR 8
|
||||||
print("\x1b[1M[ Double Fault ]\n\x1b[8M"); // Error code should be 0 (TODO: Maybe check if it's != 0?)
|
printf("\x1b[1M[ Double Fault ]\n\x1b[8M"); // Error code should be 0 (TODO: Maybe check if it's != 0?)
|
||||||
__asm__ volatile ("cli; hlt");
|
__asm__ volatile ("cli; hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,11 +24,7 @@ void excp_pageFault(intFrame_t* iframe, uint32_t errCode) { // ISR 14
|
|||||||
// cr2 should contain invalid address
|
// cr2 should contain invalid address
|
||||||
__asm__ volatile("movl %%cr2, %0" : "=r"(badAddress));
|
__asm__ volatile("movl %%cr2, %0" : "=r"(badAddress));
|
||||||
|
|
||||||
print("\x1b[1M[ Page Fault : 0x");
|
printf("\x1b[1M[ Page Fault : 0x%x ] - Tried to access 0x%x.\n\x1b[8M", errCode, badAddress);
|
||||||
print(itoa(errCode, 16));
|
|
||||||
print(" ] - Tried to access 0x");
|
|
||||||
print(itoa(badAddress, 16));
|
|
||||||
print(".\n\x1b[8M");
|
|
||||||
__asm__ volatile ("cli; hlt");
|
__asm__ volatile ("cli; hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ void sys_write() {
|
|||||||
int32_t result = terminalWrite(buf, len); // Call a terminal print function
|
int32_t result = terminalWrite(buf, len); // Call a terminal print function
|
||||||
__asm__ volatile ("movl %0, %%eax" : : "r"(result));
|
__asm__ volatile ("movl %0, %%eax" : : "r"(result));
|
||||||
} else { // Not implemented
|
} else { // Not implemented
|
||||||
__asm__ volatile ("movl $1, %eax");
|
__asm__ volatile ("movl $-1, %eax");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-70
@@ -56,7 +56,7 @@ void main() {
|
|||||||
terminal->fg = FG_COLOR;
|
terminal->fg = FG_COLOR;
|
||||||
terminal->bg = BG_COLOR;
|
terminal->bg = BG_COLOR;
|
||||||
clear();
|
clear();
|
||||||
print("kern.\n\n");
|
printf("\x1b[2Mkern.\n\n\x1b[8M");
|
||||||
|
|
||||||
// Run Interactive Shell Program
|
// Run Interactive Shell Program
|
||||||
// TODO: Make it in another file
|
// TODO: Make it in another file
|
||||||
@@ -97,7 +97,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*str = '\0';
|
*str = '\0';
|
||||||
print(printStr);
|
printf("%s", printStr);
|
||||||
} else if (strcmp(input, "exit") == 0) {
|
} else if (strcmp(input, "exit") == 0) {
|
||||||
break;
|
break;
|
||||||
} else if (strcmp(input, "gfx") == 0) {
|
} else if (strcmp(input, "gfx") == 0) {
|
||||||
@@ -160,7 +160,7 @@ void main() {
|
|||||||
|
|
||||||
sleep(ms);
|
sleep(ms);
|
||||||
} else if (strcmp(input, "soundtest") == 0) {
|
} else if (strcmp(input, "soundtest") == 0) {
|
||||||
print("Playing...\n");
|
printf("Playing...\n");
|
||||||
enableSpeaker();
|
enableSpeaker();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -185,38 +185,12 @@ void main() {
|
|||||||
|
|
||||||
disableSpeaker();
|
disableSpeaker();
|
||||||
} else if (strcmp(input, "test") == 0) {
|
} else if (strcmp(input, "test") == 0) {
|
||||||
print("Running Tests...\n");
|
printf("\x1b[1MError: 'test' is not available.\x1b[8M");
|
||||||
uint8_t buf[512];
|
|
||||||
|
|
||||||
print("Read Test .......... ");
|
|
||||||
diskRead(0, 1, (char*)buf);
|
|
||||||
if (buf[510] == 0x55 && buf[511] == 0xaa) {
|
|
||||||
print("[ DONE ]\n");
|
|
||||||
} else {
|
|
||||||
print("[ FAIL ]\n");
|
|
||||||
}
|
|
||||||
print("Write Test ......... ");
|
|
||||||
buf[510] = 0x55; buf[511] = 0xaa;
|
|
||||||
diskWrite(0, 1, (char*)buf);
|
|
||||||
diskRead(0, 1, (char*)buf); // Idk how else to test if the right data was written (also could break the bootloader if it fails)
|
|
||||||
if (buf[510] == 0x55 && buf[511] == 0xaa) {
|
|
||||||
print("[ DONE ]\n");
|
|
||||||
} else {
|
|
||||||
print("[ FAIL ]\n");
|
|
||||||
}
|
|
||||||
print("Malloc Test ........ ");
|
|
||||||
void* buffer = malloc(100);
|
|
||||||
free(buffer);
|
|
||||||
print("[ DONE ]\n");
|
|
||||||
|
|
||||||
print("\nTests Finished!\n");
|
|
||||||
} else {
|
} else {
|
||||||
fileEntry_t* file = findFile(input);
|
fileEntry_t* file = findFile(input);
|
||||||
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
print("Command not found: ");
|
printf("Command not found: %s\n", input);
|
||||||
print(input);
|
|
||||||
putc('\n');
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +203,7 @@ void main() {
|
|||||||
uint32_t physicalAddress = (uint32_t)allocPage(&page);
|
uint32_t physicalAddress = (uint32_t)allocPage(&page);
|
||||||
|
|
||||||
if (mapPage((void*)physicalAddress, (void*)(entryPoint + i * PAGE_SIZE)) != 0) {
|
if (mapPage((void*)physicalAddress, (void*)(entryPoint + i * PAGE_SIZE)) != 0) {
|
||||||
print("\n\x1b[1MNot enough memory to allocate!\n");
|
printf("\n\x1b[1MNot enough memory to allocate!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,11 +236,9 @@ void main() {
|
|||||||
} else if (strcmp(file->filetype, "tab") == 0) {
|
} else if (strcmp(file->filetype, "tab") == 0) {
|
||||||
printFiletable(entryPoint);
|
printFiletable(entryPoint);
|
||||||
} else if (strcmp(file->filetype, "fnt") == 0) {
|
} else if (strcmp(file->filetype, "fnt") == 0) {
|
||||||
print("Loading ");
|
printf("Loading %s...\n", file->filename);
|
||||||
print(file->filename);
|
|
||||||
print("...\n");
|
|
||||||
memcpy(entryPoint, (char*)FONT_LOC, file->length * 512);
|
memcpy(entryPoint, (char*)FONT_LOC, file->length * 512);
|
||||||
print("Font loaded\n");
|
printf("Font loaded\n");
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < file->length * 512; i++) {
|
for (size_t i = 0; i < file->length * 512; i++) {
|
||||||
if (entryPoint[i] != '\0') {
|
if (entryPoint[i] != '\0') {
|
||||||
@@ -308,24 +280,21 @@ void printFiletable(char* ft) {
|
|||||||
uint8_t sector = *ft++;
|
uint8_t sector = *ft++;
|
||||||
uint8_t size = *ft++;
|
uint8_t size = *ft++;
|
||||||
|
|
||||||
|
// TODO: Use printf() here for padding
|
||||||
if (sector < 10) putc('0');
|
if (sector < 10) putc('0');
|
||||||
if (sector == 0) putc('0');
|
if (sector == 0) putc('0');
|
||||||
else print(itoa(sector, 10));
|
else printf("%d", sector);
|
||||||
print(": ");
|
printf(": %s", filename);
|
||||||
print(filename);
|
|
||||||
|
|
||||||
for (uint8_t i = 14 - strlen(filename); i > 0; i--) {
|
for (uint8_t i = 14 - strlen(filename); i > 0; i--) {
|
||||||
putc(' ');
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
print(" | ");
|
printf(" | ");
|
||||||
if (size >> 1) {
|
if (size >> 1) {
|
||||||
print(itoa(size >> 1, 10));
|
printf("%d%skB\n", size >> 1, (size & 0x01) ? ".5" : "");
|
||||||
if (size & 0x01) { print(".5"); }
|
|
||||||
print("kB\n");
|
|
||||||
} else {
|
} else {
|
||||||
print(itoa(size*512, 10));
|
printf("%dB\n", size * 512);
|
||||||
print("B\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,39 +304,26 @@ void printPhysicalMemmap() {
|
|||||||
smapEntry_t* smapEntry = (smapEntry_t*)SMAP_ENTRIES;
|
smapEntry_t* smapEntry = (smapEntry_t*)SMAP_ENTRIES;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < entryCount; i++) {
|
for (uint32_t i = 0; i < entryCount; i++) {
|
||||||
print("Region ");
|
// Need to cast to uint32_t because they are uint64_t
|
||||||
print(itoa(i, 10));
|
printf("Region %d - base: 0x%x length: 0x%x type: %d ", i, (uint32_t)smapEntry->baseAddress, (uint32_t)smapEntry->length, smapEntry->type);
|
||||||
print(" - base: 0x");
|
|
||||||
print(itoa(smapEntry->baseAddress, 16));
|
|
||||||
print(" length: 0x");
|
|
||||||
print(itoa(smapEntry->length, 16));
|
|
||||||
print(" type: ");
|
|
||||||
print(itoa(smapEntry->type, 10));
|
|
||||||
|
|
||||||
switch (smapEntry->type) {
|
switch (smapEntry->type) {
|
||||||
case 1: print(" (Available)"); break;
|
case 1: printf("(Available)\n"); break;
|
||||||
case 2: print(" (Reserved)"); break;
|
case 2: printf("(Reserved)\n"); break;
|
||||||
case 3: print(" (ACPI Reclaim)"); break;
|
case 3: printf("(ACPI Reclaim)\n"); break;
|
||||||
case 4: print(" (ACPI NVS)"); break;
|
case 4: printf("(ACPI NVS)\n"); break;
|
||||||
default: print(" (Reserved)"); break;
|
default: printf("(Reserved)\n"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
putc('\n');
|
|
||||||
smapEntry++;
|
smapEntry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
smapEntry--; // We incremented it after the last entry
|
smapEntry--; // We incremented it after the last entry
|
||||||
|
|
||||||
print("\nTotal memory: 0x");
|
printf("\nTotal memory: 0x%x Bytes\n", smapEntry->baseAddress + smapEntry->length - 1);
|
||||||
print(itoa(smapEntry->baseAddress + smapEntry->length - 1, 16));
|
|
||||||
print(" Bytes\n");
|
|
||||||
|
|
||||||
print("Total 4kB Blocks: ");
|
printf("Total 4kB Blocks: %d\n", maxBlocks);
|
||||||
print(itoa(maxBlocks, 10));
|
printf("Used or reserved blocks: %d\n", usedBlocks);
|
||||||
print("\nUsed or reserved blocks: ");
|
printf("Free blocks: %d\n\n", maxBlocks - usedBlocks);
|
||||||
print(itoa(usedBlocks, 10));
|
|
||||||
print("\nFree blocks: ");
|
|
||||||
print(itoa(maxBlocks - usedBlocks, 10));
|
|
||||||
print("\n\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Legend:
|
|||||||
|
|
||||||
- [x] Multistage Bootloader
|
- [x] Multistage Bootloader
|
||||||
- [ ] Bootloader reads filetable to find files
|
- [ ] Bootloader reads filetable to find files
|
||||||
- [ ] The almighty 'printf()'
|
- [x] 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)
|
||||||
@@ -79,6 +79,7 @@ Legend:
|
|||||||
- [!] 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] Better header for file i/o (disk/filesys.h)
|
||||||
- [x] Filetable
|
- [x] Filetable
|
||||||
|
- [ ] A better filesystem using INodes etc.
|
||||||
- [ ] Files
|
- [ ] Files
|
||||||
- [x] Larger than one sector (512B)
|
- [x] Larger than one sector (512B)
|
||||||
- [ ] Any file size (Not multiples of 512B)
|
- [ ] Any file size (Not multiples of 512B)
|
||||||
|
|||||||
Reference in New Issue
Block a user