Prints initial memory map. Improvements to printk. Changed Makefile so that lgcc is linked after everything else.

This commit is contained in:
L. Bradley LaBoon 2014-02-11 11:57:26 -05:00
parent f23f3a8a8d
commit 9994b80c0d
3 changed files with 218 additions and 56 deletions

View File

@ -13,14 +13,14 @@ OBJS += $(patsubst %.c,%.o,$(SOURCES_C))
# Build flags # Build flags
CFLAGS = -std=gnu99 -ffreestanding -Iinclude/ -O2 -Wall -Wextra CFLAGS = -std=gnu99 -ffreestanding -Iinclude/ -O2 -Wall -Wextra
LDFLAGS = -ffreestanding -O2 -nostdlib -lgcc LDFLAGS = -ffreestanding -O2 -nostdlib
# Build rules # Build rules
all: brados.bin all: brados.bin
.PHONY: all clean .PHONY: all clean
brados.bin: $(OBJS) arch/$(ARCH)/linker.ld 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: clean:
rm -f $(OBJS) brados.bin rm -f $(OBJS) brados.bin

View File

@ -19,24 +19,41 @@ void brados_main(uint32_t multiMagic, uint32_t multiAddr)
term_init(&term); term_init(&term);
// Welcome message // Welcome message
term_writeStr(&term, "Welcome to BRaDOS!\n"); printk(&term, "Welcome to BRaDOS!\n");
term_writeStr(&term, "written by L. Bradley LaBoon\n\n"); printk(&term, "written by L. Bradley LaBoon\n\n");
// VGA tests
//term_test(&term);
// Get multiboot info // Get multiboot info
printk(&term, "Multiboot value: %x\n", multiMagic);
if (multiMagic != 0x2BADB002) { if (multiMagic != 0x2BADB002) {
term_writeStr(&term, "Error! Multiboot header not present. Quitting.\n"); printk(&term, "Error! Multiboot header not present. Quitting.\n");
return; return;
} }
printk(&term, "Multiboot address: %x\n", multiAddr);
struct multiboot_header *multiHead = (struct multiboot_header *) 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); if ((multiHead->flags >> 6) % 2 != 1) {
char *bootName = (char *) multiHead->boot_loader_name; printk(&term, "Error! Memory map not available from bootloader. Quitting.\n");
printk(&term, "Boot loader: %s\n\n", bootName); 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 // Done
term_writeStr(&term, "Done."); term_writeStr(&term, "\nDone.");
} }

View File

@ -6,68 +6,213 @@
#include <video/vga.h> #include <video/vga.h>
const char *BASE16 = "0123456789ABCDEF"; 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 numPrinted = 0;
int digit = num % base; int digit = num % base;
if (num >= base) if (num >= base)
numPrinted += printNum(term, num / base, base); numPrinted += printNum(term, num / base, base, digits);
term_putChar(term, BASE16[digit]); term_putChar(term, digits[digit]);
numPrinted++; numPrinted++;
return numPrinted; return numPrinted;
} }
// Print a formatted string to the given terminal
int printk(struct vgastate *term, const char *fmt, ...) int printk(struct vgastate *term, const char *fmt, ...)
{ {
int numPrinted = 0; int numPrinted = 0;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
for (size_t i = 0; i < strlen(fmt); i++) { size_t i = 0;
while (i < strlen(fmt)) {
if (fmt[i] == '%') { if (fmt[i] == '%') {
int d; i++;
unsigned int x; int end = 0, lng = 0;
char *s;
switch (fmt[i+1]) { while (end == 0) {
switch (fmt[i]) {
// Print a percent sign
case '%': case '%':
term_putChar(term, '%'); term_putChar(term, '%');
numPrinted++; numPrinted++;
end = 1;
break; break;
// Print a single character
case 'c': case 'c':
term_putChar(term, (char) va_arg(args, int)); term_putChar(term, (char) va_arg(args, int));
numPrinted++; numPrinted++;
end = 1;
break; break;
// Print an integer number
case 'd':
case 'i': case 'i':
switch (lng) {
case 0: {
int d;
d = va_arg(args, int); d = va_arg(args, int);
if (d < 0) { if (d < 0) {
term_putChar(term, '-'); term_putChar(term, '-');
numPrinted++; numPrinted++;
d *= -1; d *= -1;
} }
numPrinted += printNum(term, (unsigned int) d, 10); numPrinted += printNum(term, (unsigned int) d, 10, BASE16);
break; break;
case 's': } 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 *); s = va_arg(args, char *);
term_writeStr(term, s); term_writeStr(term, s);
numPrinted += strlen(s); numPrinted += strlen(s);
end = 1;
break; 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': case 'x':
x = va_arg(args, unsigned int);
term_writeStr(term, "0x"); term_writeStr(term, "0x");
numPrinted += 2; numPrinted += 2;
numPrinted += printNum(term, x, 16); switch (lng) {
case 0: {
unsigned int x;
x = va_arg(args, unsigned int);
numPrinted += printNum(term, x, 16, BASE16L);
break; 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: default:
term_putChar(term, fmt[i+1]); term_putChar(term, fmt[i+end]);
numPrinted++; numPrinted++;
end = 1;
break; break;
} }
i++; i++;
}
} else { } else {
term_putChar(term, fmt[i]); term_putChar(term, fmt[i]);
numPrinted++; numPrinted++;
i++;
} }
} }