Prints initial memory map. Improvements to printk. Changed Makefile so that lgcc is linked after everything else.
This commit is contained in:
parent
f23f3a8a8d
commit
9994b80c0d
4
Makefile
4
Makefile
@ -13,14 +13,14 @@ OBJS += $(patsubst %.c,%.o,$(SOURCES_C))
|
||||
|
||||
# Build flags
|
||||
CFLAGS = -std=gnu99 -ffreestanding -Iinclude/ -O2 -Wall -Wextra
|
||||
LDFLAGS = -ffreestanding -O2 -nostdlib -lgcc
|
||||
LDFLAGS = -ffreestanding -O2 -nostdlib
|
||||
|
||||
# Build rules
|
||||
all: brados.bin
|
||||
.PHONY: all clean
|
||||
|
||||
brados.bin: $(OBJS) arch/$(ARCH)/linker.ld
|
||||
$(GNU)-gcc -T arch/$(ARCH)/linker.ld -o $@ $(LDFLAGS) $(OBJS)
|
||||
$(GNU)-gcc -T arch/$(ARCH)/linker.ld -o $@ $(LDFLAGS) $(OBJS) -lgcc
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) brados.bin
|
||||
|
@ -19,24 +19,41 @@ void brados_main(uint32_t multiMagic, uint32_t multiAddr)
|
||||
term_init(&term);
|
||||
|
||||
// Welcome message
|
||||
term_writeStr(&term, "Welcome to BRaDOS!\n");
|
||||
term_writeStr(&term, "written by L. Bradley LaBoon\n\n");
|
||||
|
||||
// VGA tests
|
||||
//term_test(&term);
|
||||
printk(&term, "Welcome to BRaDOS!\n");
|
||||
printk(&term, "written by L. Bradley LaBoon\n\n");
|
||||
|
||||
// Get multiboot info
|
||||
printk(&term, "Multiboot value: %x\n", multiMagic);
|
||||
if (multiMagic != 0x2BADB002) {
|
||||
term_writeStr(&term, "Error! Multiboot header not present. Quitting.\n");
|
||||
printk(&term, "Error! Multiboot header not present. Quitting.\n");
|
||||
return;
|
||||
}
|
||||
printk(&term, "Multiboot address: %x\n", multiAddr);
|
||||
struct multiboot_header *multiHead = (struct multiboot_header *) multiAddr;
|
||||
printk(&term, "Flags: %x\nMem Lower: %x\nMem Upper: %x\n", multiHead->flags, multiHead->mem_lower, multiHead->mem_upper);
|
||||
char *bootName = (char *) multiHead->boot_loader_name;
|
||||
printk(&term, "Boot loader: %s\n\n", bootName);
|
||||
if ((multiHead->flags >> 6) % 2 != 1) {
|
||||
printk(&term, "Error! Memory map not available from bootloader. Quitting.\n");
|
||||
return;
|
||||
}
|
||||
struct multiboot_mmap *memmap = (struct multiboot_mmap *) multiHead->mmap_addr;
|
||||
|
||||
// Print memory map
|
||||
printk(&term, "Memory map:\n");
|
||||
int numEntries = multiHead->mmap_length / sizeof(struct multiboot_mmap);
|
||||
uint64_t lastAddr = 0;
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
if (memmap[i].base_addr != lastAddr) {
|
||||
printk(&term, "%llx - %llx: Unknown\n", lastAddr, memmap[i].base_addr - 1);
|
||||
lastAddr = memmap[i].base_addr;
|
||||
}
|
||||
|
||||
printk(&term, "%llx - %llx: ", memmap[i].base_addr, memmap[i].base_addr + memmap[i].length - 1);
|
||||
if (memmap[i].type == 1)
|
||||
printk(&term, "Available\n");
|
||||
else
|
||||
printk(&term, "Reserved\n");
|
||||
|
||||
lastAddr = memmap[i].base_addr + memmap[i].length;
|
||||
}
|
||||
|
||||
|
||||
// Done
|
||||
term_writeStr(&term, "Done.");
|
||||
term_writeStr(&term, "\nDone.");
|
||||
}
|
||||
|
229
kernel/printk.c
229
kernel/printk.c
@ -6,68 +6,213 @@
|
||||
#include <video/vga.h>
|
||||
|
||||
const char *BASE16 = "0123456789ABCDEF";
|
||||
const char *BASE16L = "0123456789abcdef";
|
||||
|
||||
static int printNum(struct vgastate *term, unsigned int num, unsigned int base)
|
||||
// Print an unsigned number as a string; return the number of characters printed
|
||||
static int printNum(struct vgastate *term, unsigned long long num, unsigned int base, const char *digits)
|
||||
{
|
||||
if (base > strlen(digits))
|
||||
return 0;
|
||||
|
||||
int numPrinted = 0;
|
||||
int digit = num % base;
|
||||
if (num >= base)
|
||||
numPrinted += printNum(term, num / base, base);
|
||||
term_putChar(term, BASE16[digit]);
|
||||
numPrinted += printNum(term, num / base, base, digits);
|
||||
term_putChar(term, digits[digit]);
|
||||
numPrinted++;
|
||||
return numPrinted;
|
||||
}
|
||||
|
||||
// Print a formatted string to the given terminal
|
||||
int printk(struct vgastate *term, const char *fmt, ...)
|
||||
{
|
||||
int numPrinted = 0;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
for (size_t i = 0; i < strlen(fmt); i++) {
|
||||
size_t i = 0;
|
||||
while (i < strlen(fmt)) {
|
||||
if (fmt[i] == '%') {
|
||||
int d;
|
||||
unsigned int x;
|
||||
char *s;
|
||||
switch (fmt[i+1]) {
|
||||
case '%':
|
||||
term_putChar(term, '%');
|
||||
numPrinted++;
|
||||
break;
|
||||
case 'c':
|
||||
term_putChar(term, (char) va_arg(args, int));
|
||||
numPrinted++;
|
||||
break;
|
||||
case 'i':
|
||||
d = va_arg(args, int);
|
||||
if (d < 0) {
|
||||
term_putChar(term, '-');
|
||||
numPrinted++;
|
||||
d *= -1;
|
||||
}
|
||||
numPrinted += printNum(term, (unsigned int) d, 10);
|
||||
break;
|
||||
case 's':
|
||||
s = va_arg(args, char *);
|
||||
term_writeStr(term, s);
|
||||
numPrinted += strlen(s);
|
||||
break;
|
||||
case 'x':
|
||||
x = va_arg(args, unsigned int);
|
||||
term_writeStr(term, "0x");
|
||||
numPrinted += 2;
|
||||
numPrinted += printNum(term, x, 16);
|
||||
break;
|
||||
default:
|
||||
term_putChar(term, fmt[i+1]);
|
||||
numPrinted++;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
int end = 0, lng = 0;
|
||||
|
||||
while (end == 0) {
|
||||
switch (fmt[i]) {
|
||||
// Print a percent sign
|
||||
case '%':
|
||||
term_putChar(term, '%');
|
||||
numPrinted++;
|
||||
end = 1;
|
||||
break;
|
||||
// Print a single character
|
||||
case 'c':
|
||||
term_putChar(term, (char) va_arg(args, int));
|
||||
numPrinted++;
|
||||
end = 1;
|
||||
break;
|
||||
// Print an integer number
|
||||
case 'd':
|
||||
case 'i':
|
||||
switch (lng) {
|
||||
case 0: {
|
||||
int d;
|
||||
d = va_arg(args, int);
|
||||
if (d < 0) {
|
||||
term_putChar(term, '-');
|
||||
numPrinted++;
|
||||
d *= -1;
|
||||
}
|
||||
numPrinted += printNum(term, (unsigned int) d, 10, BASE16);
|
||||
break;
|
||||
} case 1: {
|
||||
long ld;
|
||||
ld = va_arg(args, long);
|
||||
if (ld < 0) {
|
||||
term_putChar(term, '-');
|
||||
numPrinted++;
|
||||
ld *= -1;
|
||||
}
|
||||
numPrinted += printNum(term, (unsigned long) ld, 10, BASE16);
|
||||
break;
|
||||
} default: {
|
||||
long long lld;
|
||||
lld = va_arg(args, long long);
|
||||
if (lld < 0) {
|
||||
term_putChar(term, '-');
|
||||
numPrinted++;
|
||||
lld *= -1;
|
||||
}
|
||||
numPrinted += printNum(term, (unsigned long long) lld, 10, BASE16);
|
||||
break;
|
||||
}}
|
||||
end = 1;
|
||||
break;
|
||||
// Expect a long (long) value
|
||||
case 'l':
|
||||
lng++;
|
||||
break;
|
||||
// Store the number of printed characters
|
||||
case 'n': {
|
||||
int *n;
|
||||
n = va_arg(args, int *);
|
||||
*n = numPrinted;
|
||||
end = 1;
|
||||
break;
|
||||
// Print an unsigned integer in octal form
|
||||
} case 'o':
|
||||
term_putChar(term, '0');
|
||||
numPrinted++;
|
||||
switch (lng) {
|
||||
case 0: {
|
||||
unsigned int o;
|
||||
o = va_arg(args, unsigned int);
|
||||
numPrinted += printNum(term, o, 8, BASE16);
|
||||
break;
|
||||
} case 1: {
|
||||
unsigned long lo;
|
||||
lo = va_arg(args, unsigned long);
|
||||
numPrinted += printNum(term, lo, 8, BASE16);
|
||||
break;
|
||||
} default: {
|
||||
unsigned long long llo;
|
||||
llo = va_arg(args, unsigned long long);
|
||||
numPrinted += printNum(term, llo, 8, BASE16);
|
||||
break;
|
||||
}}
|
||||
end = 1;
|
||||
break;
|
||||
// Print a null-terminated string
|
||||
case 's': {
|
||||
char *s;
|
||||
s = va_arg(args, char *);
|
||||
term_writeStr(term, s);
|
||||
numPrinted += strlen(s);
|
||||
end = 1;
|
||||
break;
|
||||
// Print an unsigned integer value
|
||||
} case 'u':
|
||||
switch (lng) {
|
||||
case 0: {
|
||||
unsigned int u;
|
||||
u = va_arg(args, unsigned int);
|
||||
numPrinted += printNum(term, u, 10, BASE16);
|
||||
break;
|
||||
} case 1: {
|
||||
unsigned long lu;
|
||||
lu = va_arg(args, unsigned long);
|
||||
numPrinted += printNum(term, lu, 10, BASE16);
|
||||
break;
|
||||
} default: {
|
||||
unsigned long long llu;
|
||||
llu = va_arg(args, unsigned long long);
|
||||
numPrinted += printNum(term, llu, 10, BASE16);
|
||||
break;
|
||||
}}
|
||||
end = 1;
|
||||
break;
|
||||
// Print an unsigned integer in lower hex form
|
||||
case 'x':
|
||||
term_writeStr(term, "0x");
|
||||
numPrinted += 2;
|
||||
switch (lng) {
|
||||
case 0: {
|
||||
unsigned int x;
|
||||
x = va_arg(args, unsigned int);
|
||||
numPrinted += printNum(term, x, 16, BASE16L);
|
||||
break;
|
||||
} case 1: {
|
||||
unsigned long lx;
|
||||
lx = va_arg(args, unsigned long);
|
||||
numPrinted += printNum(term, lx, 16, BASE16L);
|
||||
break;
|
||||
} default: {
|
||||
unsigned long long llx;
|
||||
llx = va_arg(args, unsigned long long);
|
||||
numPrinted += printNum(term, llx, 16, BASE16L);
|
||||
break;
|
||||
}}
|
||||
end = 1;
|
||||
break;
|
||||
// Print an unsigned integer in upper hex form
|
||||
case 'X':
|
||||
term_writeStr(term, "0X");
|
||||
numPrinted += 2;
|
||||
switch (lng) {
|
||||
case 0: {
|
||||
unsigned int x;
|
||||
x = va_arg(args, unsigned int);
|
||||
numPrinted += printNum(term, x, 16, BASE16);
|
||||
break;
|
||||
} case 1: {
|
||||
unsigned long lx;
|
||||
lx = va_arg(args, unsigned long);
|
||||
numPrinted += printNum(term, lx, 16, BASE16);
|
||||
break;
|
||||
} default: {
|
||||
unsigned long long llx;
|
||||
llx = va_arg(args, unsigned long long);
|
||||
numPrinted += printNum(term, llx, 16, BASE16);
|
||||
break;
|
||||
}}
|
||||
end = 1;
|
||||
break;
|
||||
// Exit if we reach the end of the string
|
||||
case '\0':
|
||||
end = 1;
|
||||
break;
|
||||
// Unknown character; just print the character
|
||||
default:
|
||||
term_putChar(term, fmt[i+end]);
|
||||
numPrinted++;
|
||||
end = 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
term_putChar(term, fmt[i]);
|
||||
numPrinted++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user