mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
201 lines
3.6 KiB
C
201 lines
3.6 KiB
C
#include "stdint.h"
|
|
#include "multiboot.h"
|
|
|
|
/* Constants */
|
|
#define COLS 80
|
|
#define ROWS 24
|
|
#define ATTR 0x0f
|
|
#define VID_MEM 0xb8000
|
|
|
|
/* Variables */
|
|
static int xpos;
|
|
static int ypos;
|
|
static uint8_t* video;
|
|
|
|
/* Forward Declarations */
|
|
void cls(void);
|
|
void itoa(char* buf, int base, int d);
|
|
void putc(int c);
|
|
void printf(const char* fmt, ...);
|
|
|
|
/* Entry Point */
|
|
void kmain(void) {
|
|
uint32_t magic, addr;
|
|
__asm__ volatile ("movl %%eax, %0; movl %%ebx, %1" : "=m"(magic), "=m"(addr));
|
|
struct multiboot_info* mbi;
|
|
video = (uint8_t*)VID_MEM;
|
|
|
|
// Clear Screen
|
|
cls();
|
|
|
|
// Didn't boot with Multiboot
|
|
if (magic != BOOT_MAGIC) {
|
|
printf("Invalid Magic Number: 0x%x\n", magic);
|
|
while (1);
|
|
}
|
|
|
|
mbi = (struct multiboot_info*)addr;
|
|
|
|
printf("flags: 0x%x\n", mbi->flags);
|
|
|
|
if (mbi->flags & MBI_MEMORY) {
|
|
printf("mem_lower: %ukB, mem_upper: %ukB\n",
|
|
mbi->mem_lower, mbi->mem_upper);
|
|
}
|
|
|
|
if (mbi->flags & MBI_BOOT_DEV) {
|
|
printf("boot_device: 0x%x\n", mbi->boot_device);
|
|
}
|
|
|
|
if (mbi->flags & MBI_CMDLINE) {
|
|
printf("cmdline: %s\n", mbi->cmdline);
|
|
}
|
|
|
|
if (mbi->flags & MBI_MODS) {
|
|
printf("mods_count: %d, mods_addr: 0x%x\n",
|
|
mbi->mods_count, mbi->mods_addr);
|
|
|
|
struct multiboot_module* mod =
|
|
(struct multiboot_module*)mbi->mods_addr;
|
|
|
|
for (size_t i = 0; i < mbi->mods_count; i++) {
|
|
printf(" start 0x%x, end: 0x%x, cmdline: %s\n",
|
|
mod->start, mod->end, mod->cmdline);
|
|
mod++;
|
|
}
|
|
}
|
|
|
|
if (mbi->flags & MBI_SYMBOLS &&
|
|
mbi->flags & MBI_ELF_HEAD) {
|
|
printf("Flag SYMBOLS and ELF HEADER are both set!\n");
|
|
while (1);
|
|
}
|
|
|
|
if (mbi->flags & MBI_MEMMAP) {
|
|
printf("mmap_addr: 0x%x, mmap_length: 0x%x\n",
|
|
mbi->mmap_addr, mbi->mmap_length);
|
|
|
|
struct multiboot_memmap* mmap =
|
|
(struct multiboot_memmap*)mbi->mmap_addr;
|
|
|
|
while ((uint32_t)mmap < mbi->mmap_addr + mbi->mmap_length) {
|
|
printf( " size: 0x%x, base: 0x%08x, "
|
|
"length: 0x%08x, type: 0x%x\n",
|
|
mmap->size, mmap->base, mmap->len, mmap->type);
|
|
|
|
mmap = (struct multiboot_memmap*)
|
|
((uint32_t)mmap + mmap->size + (sizeof(mmap->size)));
|
|
}
|
|
}
|
|
|
|
while (1);
|
|
}
|
|
|
|
void cls(void) {
|
|
for (int i = 0; i < COLS * ROWS * 2; i++) video[i] = 0;
|
|
xpos = 0;
|
|
ypos = 0;
|
|
}
|
|
|
|
void itoa(char* buf, int base, int d) {
|
|
char* p = buf;
|
|
char* p1;
|
|
char* p2;
|
|
uint32_t ud = d;
|
|
int divisor = 10;
|
|
|
|
if (base == 'd' && d < 0) {
|
|
*p++ = '-';
|
|
buf++;
|
|
ud = -d;
|
|
} else if (base == 'x') divisor = 16;
|
|
|
|
do {
|
|
int remainder = ud % divisor;
|
|
*p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
|
|
} while (ud /= divisor);
|
|
|
|
*p = 0;
|
|
|
|
p1 = buf;
|
|
p2 = p - 1;
|
|
while (p1 < p2) {
|
|
char tmp = *p1;
|
|
*p1 = *p2;
|
|
*p2 = tmp;
|
|
p1++;
|
|
p2--;
|
|
}
|
|
}
|
|
|
|
/* Put the character C on the screen. */
|
|
void putc(int c) {
|
|
if (c == '\n' || c == '\r') {
|
|
newline:
|
|
xpos = 0;
|
|
ypos++;
|
|
if (ypos >= ROWS)
|
|
ypos = 0;
|
|
return;
|
|
}
|
|
|
|
video[(xpos + ypos * COLS) * 2] = c & 0xFF;
|
|
video[(xpos + ypos * COLS) * 2 + 1] = ATTR;
|
|
|
|
xpos++;
|
|
if (xpos >= COLS)
|
|
goto newline;
|
|
}
|
|
|
|
void printf(const char *format, ...) {
|
|
char** arg = (char**)&format;
|
|
int c;
|
|
char buf[20];
|
|
|
|
arg++;
|
|
|
|
while ((c = *format++) != 0) {
|
|
if (c != '%') {
|
|
putc (c);
|
|
continue;
|
|
}
|
|
|
|
char *p, *p2;
|
|
int pad0 = 0, pad = 0;
|
|
|
|
c = *format++;
|
|
|
|
if (c == '0') {
|
|
pad0 = 1;
|
|
c = *format++;
|
|
}
|
|
|
|
if (c >= '0' && c <= '9') {
|
|
pad = c - '0';
|
|
c = *format++;
|
|
}
|
|
|
|
switch (c) {
|
|
case 'd':
|
|
case 'u':
|
|
case 'x':
|
|
itoa(buf, c, *((int *) arg++));
|
|
p = buf;
|
|
goto string;
|
|
break;
|
|
case 's':
|
|
p = *arg++;
|
|
if (! p) p = "(null)";
|
|
string:
|
|
for (p2 = p; *p2; p2++);
|
|
for (; p2 < p + pad; p2++) putc (pad0 ? '0' : ' ');
|
|
while (*p) putc (*p++);
|
|
break;
|
|
default:
|
|
putc(*((int *) arg++));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|