mirror of
https://github.com/CIS-osdev/kernel
synced 2025-03-13 02:03:47 +03:00
Add some stuff (printf)
This commit is contained in:
parent
b00d5ed2a5
commit
4f714b0bc3
@ -10,6 +10,7 @@ extern uint64_t paging_main[3][512] __attribute__((aligned(4096)));
|
||||
|
||||
void serial_write_byte(uint8_t byte);
|
||||
int serial_init( );
|
||||
void serial_printf(const char *fmt, ...) ;
|
||||
|
||||
#else
|
||||
#error "Only AMD64 is supported"
|
||||
|
@ -11,4 +11,6 @@ typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef uint64_t uintptr_t;
|
||||
|
||||
#endif
|
@ -5,23 +5,15 @@ int multiboot2_init(uint64_t *addr, uint32_t magic);
|
||||
|
||||
void kernel_main64(uint64_t *multiboot2, uint32_t magic, void *esp, uint64_t base) {
|
||||
serial_init( );
|
||||
serial_write_byte(':');
|
||||
serial_write_byte('D');
|
||||
serial_write_byte('\n');
|
||||
serial_printf(":D\n");
|
||||
|
||||
int status = multiboot2_init(multiboot2, magic);
|
||||
serial_write_byte('\n');
|
||||
|
||||
if (status) {
|
||||
serial_write_byte('[');
|
||||
serial_write_byte('O');
|
||||
serial_write_byte('K');
|
||||
serial_write_byte(']');
|
||||
serial_printf("[OK]\n");
|
||||
} else {
|
||||
serial_write_byte('[');
|
||||
serial_write_byte('E');
|
||||
serial_write_byte('R');
|
||||
serial_write_byte('R');
|
||||
serial_write_byte(']');
|
||||
serial_printf("[ERR]\n");
|
||||
}
|
||||
|
||||
for (;;) {}
|
||||
}
|
80
kernel/klibc/printf.c
Normal file
80
kernel/klibc/printf.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include <stdarg.h>
|
||||
#include <kstdint.h>
|
||||
#include <khal.h>
|
||||
|
||||
static char *itoa(uint64_t value, char *buf, uint8_t base) {
|
||||
char *ptr = buf;
|
||||
uint64_t temp = value;
|
||||
do {
|
||||
uint64_t digit = temp % base;
|
||||
if (digit < 10)
|
||||
*ptr = '0' + digit;
|
||||
else
|
||||
*ptr = 'A' + (digit - 10);
|
||||
ptr++;
|
||||
temp /= base;
|
||||
} while (temp);
|
||||
*ptr = '\0';
|
||||
// Reverse the string
|
||||
char *start = buf;
|
||||
char *end = ptr - 1;
|
||||
while (start < end) {
|
||||
char tmp = *start;
|
||||
*start = *end;
|
||||
*end = tmp;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
void serial_printf(const char *fmt, ...) {
|
||||
char buf[32];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
while (*fmt) {
|
||||
if (*fmt == '%') {
|
||||
fmt++;
|
||||
switch (*fmt) {
|
||||
case 's':
|
||||
{
|
||||
char *str = va_arg(args, char *);
|
||||
while (*str)
|
||||
serial_write_byte(*str++);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
{
|
||||
int64_t num = va_arg(args, int64_t);
|
||||
itoa(num, buf, 10);
|
||||
serial_printf("%s", buf);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
{
|
||||
uint64_t num = va_arg(args, uint64_t);
|
||||
itoa(num, buf, 10);
|
||||
serial_printf("%s", buf);
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
uint64_t num = va_arg(args, uint64_t);
|
||||
itoa(num, buf, 16);
|
||||
serial_printf("%s", buf);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
serial_write_byte(va_arg(args, int));
|
||||
break;
|
||||
default:
|
||||
serial_write_byte(*fmt);
|
||||
break;
|
||||
}
|
||||
fmt++;
|
||||
} else {
|
||||
serial_write_byte(*fmt++);
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
}
|
@ -4,28 +4,98 @@
|
||||
#include <kstdlib.h>
|
||||
|
||||
#define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit)))
|
||||
#define printf(...)
|
||||
|
||||
void handle_cmdline_tag(struct multiboot_tag *tag);
|
||||
void handle_module_tag(struct multiboot_tag *tag);
|
||||
void handle_basic_load_base_addr(struct multiboot_tag *tag);
|
||||
void handle_basic_meminfo_tag(struct multiboot_tag *tag);
|
||||
void handle_mmap_tag(struct multiboot_tag *tag);
|
||||
|
||||
int multiboot2_init(uint64_t *addr, uint32_t magic) {
|
||||
serial_write_byte('1' + __COUNTER__);
|
||||
struct multiboot_tag *tag;
|
||||
|
||||
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
|
||||
printf("Invalid magic number: 0x%x\n", (unsigned)magic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((uint64_t)addr & 7) {
|
||||
printf ("Unaligned mbi: 0x%x\n", addr);
|
||||
return -2;
|
||||
struct multiboot_tag *tag;
|
||||
uint64_t mbi_addr = (uint64_t)addr;
|
||||
|
||||
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
|
||||
serial_printf("Invalid magic number: 0x%x\n", (unsigned)magic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t size = *addr;
|
||||
IGNORE_UNUSED(size);
|
||||
IGNORE_UNUSED(tag);
|
||||
if (mbi_addr & 7) {
|
||||
serial_printf("Unaligned mbi: 0x%x\n", mbi_addr);
|
||||
return -2;
|
||||
}
|
||||
|
||||
printf ("Announced mbi size 0x%x\n", size);
|
||||
uint64_t size = *addr;
|
||||
serial_printf("Announced mbi size 0x%x\n", size);
|
||||
|
||||
serial_write_byte('1' + __COUNTER__);
|
||||
return 1;
|
||||
tag = (struct multiboot_tag *)(mbi_addr + sizeof(uint64_t));
|
||||
|
||||
while (tag->type != MULTIBOOT_TAG_TYPE_END) {
|
||||
if ((uintptr_t)tag % MULTIBOOT_TAG_ALIGN != 0) {
|
||||
serial_printf("Tag at 0x%x is not aligned correctly\n", (uintptr_t)tag);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tag->type) {
|
||||
case MULTIBOOT_TAG_TYPE_CMDLINE:
|
||||
handle_cmdline_tag(tag);
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_MODULE:
|
||||
handle_module_tag(tag);
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
|
||||
handle_basic_meminfo_tag(tag);
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_MMAP:
|
||||
handle_mmap_tag(tag);
|
||||
break;
|
||||
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
|
||||
handle_basic_load_base_addr(tag);
|
||||
break;
|
||||
default:
|
||||
serial_printf("Tag at 0x%x | %d\n", (uintptr_t)tag, tag->type);
|
||||
break;
|
||||
}
|
||||
|
||||
// Move to the next tag
|
||||
tag = (struct multiboot_tag *)((uintptr_t)tag) + ((tag->size + 7) & ~7);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void handle_cmdline_tag(struct multiboot_tag *tag) {
|
||||
struct multiboot_tag_string *cmdline = (struct multiboot_tag_string *)tag;
|
||||
serial_printf("Command line: %s\n", cmdline->string);
|
||||
}
|
||||
|
||||
void handle_module_tag(struct multiboot_tag *tag) {
|
||||
struct multiboot_tag_module *module = (struct multiboot_tag_module *)tag;
|
||||
serial_printf("Module at 0x%x - 0x%x\n", module->mod_start, module->mod_end);
|
||||
serial_printf("Module cmdline: %s\n", module->cmdline);
|
||||
}
|
||||
|
||||
void handle_basic_meminfo_tag(struct multiboot_tag *tag) {
|
||||
struct multiboot_tag_basic_meminfo *meminfo = (struct multiboot_tag_basic_meminfo *)tag;
|
||||
serial_printf("Memory lower: %u KB\n", meminfo->mem_lower);
|
||||
serial_printf("Memory upper: %u KB\n", meminfo->mem_upper);
|
||||
}
|
||||
|
||||
void handle_basic_load_base_addr(struct multiboot_tag *tag) {
|
||||
struct multiboot_tag_load_base_addr *base_addr = (struct multiboot_tag_load_base_addr *)tag;
|
||||
serial_printf("load_base_size: %u\n", base_addr->size);
|
||||
serial_printf("load_base_addr: 0x%x\n", base_addr->load_base_addr);
|
||||
}
|
||||
|
||||
void handle_mmap_tag(struct multiboot_tag *tag) {
|
||||
struct multiboot_tag_mmap *mmap = (struct multiboot_tag_mmap *)tag;
|
||||
struct multiboot_mmap_entry *entry;
|
||||
uint64_t entry_size = mmap->entry_size;
|
||||
uint64_t entry_count = (mmap->size - sizeof(struct multiboot_tag_mmap)) / entry_size;
|
||||
|
||||
serial_printf("Memory map:\n");
|
||||
for (uint64_t i = 0; i < entry_count; i++) {
|
||||
entry = (struct multiboot_mmap_entry *)((uintptr_t)mmap + sizeof(struct multiboot_tag_mmap) + i * entry_size);
|
||||
serial_printf(" 0x%x - 0x%x: type %u\n", entry->addr, entry->addr + entry->len, entry->type);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user