mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
Write vsnprintf() implementation
This commit is contained in:
+10
-4
@@ -2,15 +2,16 @@
|
|||||||
#define _KERNEL_H
|
#define _KERNEL_H
|
||||||
|
|
||||||
// Null definition
|
// Null definition
|
||||||
#define NULL ((void*)0)
|
#define NULL ((void*)0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variable arguments
|
* Variable arguments
|
||||||
*/
|
*/
|
||||||
typedef void* va_list;
|
typedef void* va_list;
|
||||||
#define va_start(ap, param) (void)((ap) = (char*)(&(param) + 1))
|
#define __va_align(size) ((size + sizeof(int) - 1) & ~(sizeof(int) - 1))
|
||||||
#define va_end(ap) (void)((ap) = 0)
|
#define va_start(ap, param) (void)((ap) = (char*)(&(param) + 1))
|
||||||
#define va_arg(ap, type) (((type*)((ap) = ((ap) + sizeof(type))))[-1])
|
#define va_end(ap) (void)((ap) = 0)
|
||||||
|
#define va_arg(ap, type) (*(type*)(((ap) += __va_align(sizeof(type))) - sizeof(type)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility macros
|
* Utility macros
|
||||||
@@ -67,6 +68,11 @@ typedef int32_t intptr_t;
|
|||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linker defined values
|
||||||
|
*/
|
||||||
|
extern uint32_t __kernel_start, __kernel_end;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Logging and errors
|
* Logging and errors
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _VSNPRINTF_H
|
||||||
|
#define _VSNPRINTF_H
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
|
int vsnprintf(char* buf, size_t len, char* fmt, va_list args);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -31,6 +31,7 @@ global _start
|
|||||||
extern kmain
|
extern kmain
|
||||||
_start:
|
_start:
|
||||||
mov esp, stack_top ; Setup stack
|
mov esp, stack_top ; Setup stack
|
||||||
|
push eax
|
||||||
push ebx
|
push ebx
|
||||||
call kmain ; Call kernel main
|
call kmain ; Call kernel main
|
||||||
|
|
||||||
|
|||||||
+9
-22
@@ -1,4 +1,4 @@
|
|||||||
#include <multiboot.h>
|
#include <bootloader.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
#include <pmm.h>
|
#include <pmm.h>
|
||||||
@@ -6,43 +6,30 @@
|
|||||||
|
|
||||||
#define _hlt() while (1) __asm__ volatile ("cli; hlt");
|
#define _hlt() while (1) __asm__ volatile ("cli; hlt");
|
||||||
|
|
||||||
char* itoa(uint8_t n) {
|
|
||||||
static char str[32];
|
|
||||||
int i = sizeof(str) - 2;
|
|
||||||
while (n) {
|
|
||||||
str[i--] = (n % 10) + '0';
|
|
||||||
n /= 10;
|
|
||||||
}
|
|
||||||
str[sizeof(str) - 1] = '\0';
|
|
||||||
return &str[i+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
__noreturn
|
__noreturn
|
||||||
void kmain(void* ptr) {
|
void kmain(void* ptr, uint32_t magic) {
|
||||||
multiboot_info_t* mbi = ptr;
|
// Init with MultiBoot 1, this populates the global bootloader struct
|
||||||
|
//if (boot_init(BOOT_MB1, ptr, magic) != 0) panic("Unsupporred bootloader.");
|
||||||
|
|
||||||
// Serial console for debugging
|
// Serial console for debugging
|
||||||
serial_init(COM1);
|
serial_init(COM1);
|
||||||
serial_puts(COM1, "\x1b[0H\x1b[Jkern.\n");
|
serial_puts(COM1, "\x1b[0H\x1b[Jkern.\n");
|
||||||
|
|
||||||
// Check if we have a valid memmap
|
|
||||||
if (!(mbi->flags >> 6 & 1)) {
|
|
||||||
panic("Invalid memory map.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// VGA tty thingy
|
// VGA tty thingy
|
||||||
tty_init();
|
tty_init();
|
||||||
tty_puts("kern.");
|
tty_puts("kern.\n\n");
|
||||||
|
|
||||||
// Memory manager init
|
// Memory manager init
|
||||||
// pmm_init();
|
// pmm_init();
|
||||||
// vmm_init();
|
// vmm_init();
|
||||||
|
|
||||||
// x86 shit
|
|
||||||
// gdt_init();
|
// gdt_init();
|
||||||
// isr_init();
|
// isr_init();
|
||||||
|
// pag_init();
|
||||||
|
|
||||||
/* TODO: Commeted out stuff */
|
debugf("Basic initialization complete!\n");
|
||||||
|
|
||||||
|
/* TODO: Commented out stuff */
|
||||||
|
|
||||||
panic("kmain() reached end.");
|
panic("kmain() reached end.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <vsnprintf.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <system.h>
|
#include <system.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
@@ -51,3 +52,18 @@ void serial_puts(int dev, char* s) {
|
|||||||
serial_write(dev, s, len);
|
serial_write(dev, s, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int debugf(char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
int ret = vdebugf(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vdebugf(char* fmt, va_list args) {
|
||||||
|
static char buf[DF_BUF_LEN];
|
||||||
|
int ret = vsnprintf(buf, DF_BUF_LEN, fmt, args);
|
||||||
|
serial_puts(COM1, buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -89,7 +89,7 @@ scroll_check:
|
|||||||
|
|
||||||
void tty_write(char* buf, size_t len) {
|
void tty_write(char* buf, size_t len) {
|
||||||
ctx.updateWait = len - 1;
|
ctx.updateWait = len - 1;
|
||||||
for (int i = 0; i < len; i++) tty_putc(buf[i]);
|
for (size_t i = 0; i < len; i++) tty_putc(buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tty_puts(char* s) {
|
void tty_puts(char* s) {
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
#include <kernel.h>
|
||||||
|
#include <vsnprintf.h>
|
||||||
|
|
||||||
|
int pf_isdigit(char c) {
|
||||||
|
if (c >= '0' && c <= '9') return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* pf_itoa(uint32_t num, uint8_t base) {
|
||||||
|
static char buf[32];
|
||||||
|
|
||||||
|
if (base == 0 || base > 16) return NULL;
|
||||||
|
|
||||||
|
if (num == 0) {
|
||||||
|
buf[0] = '0';
|
||||||
|
buf[1] = '\0';
|
||||||
|
return &buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 30; num && i; i--, num /= base) {
|
||||||
|
buf[i] = "0123456789abcdef"[num % base];
|
||||||
|
}
|
||||||
|
|
||||||
|
return &buf[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
char* pf_ftoa(float f) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsnprintf(char* buf, size_t len, char* fmt, va_list args) {
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while (*fmt != '\0' && i < len) {
|
||||||
|
if (*fmt != '%') {
|
||||||
|
if (i < len) buf[i++] = *fmt++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt++; // Consume the '%'
|
||||||
|
if (*fmt == '\0') {
|
||||||
|
if (i < len) buf[i++] = '%';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the format specifier
|
||||||
|
int width = 0;
|
||||||
|
char pad = ' ';
|
||||||
|
|
||||||
|
if (pf_isdigit(*fmt)) {
|
||||||
|
if (*fmt == '0') { pad = '0'; fmt++; }
|
||||||
|
|
||||||
|
while (pf_isdigit(*fmt)) {
|
||||||
|
width *= 10;
|
||||||
|
width += *fmt++ - '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* s;
|
||||||
|
switch (*fmt) {
|
||||||
|
case 'c': // Char
|
||||||
|
if (i < len) buf[i++] = (char)va_arg(args, int);
|
||||||
|
break;
|
||||||
|
case 'd': // Int (TODO: %d for signed, %u for unsigned
|
||||||
|
s = pf_itoa(va_arg(args, unsigned int), 10);
|
||||||
|
goto string;
|
||||||
|
case 'x': // Unsigned hex int
|
||||||
|
s = pf_itoa(va_arg(args, unsigned int), 16);
|
||||||
|
goto string;
|
||||||
|
case 'f': // Float
|
||||||
|
s = pf_ftoa(va_arg(args, double));
|
||||||
|
goto string;
|
||||||
|
case 's': // String
|
||||||
|
s = va_arg(args, char*);
|
||||||
|
string: // Prints the string in s
|
||||||
|
if (s == NULL) s = "(null)";
|
||||||
|
while (*s != '\0' && i < len) buf[i++] = *s++;
|
||||||
|
break;
|
||||||
|
default: // Something else
|
||||||
|
if (i < len) buf[i++] = '%';
|
||||||
|
if (i < len) buf[i++] = *fmt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < len) buf[i++] = '\0';
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user