|
|
|
@ -1,11 +1,12 @@
|
|
|
|
|
/* See the end of this file for copyright and license terms. */
|
|
|
|
|
|
|
|
|
|
#include <multiboot.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include <arch/multiboot.h>
|
|
|
|
|
|
|
|
|
|
#include <gay/cdefs.h>
|
|
|
|
|
#include <gay/kprintf.h>
|
|
|
|
|
#include <gay/types.h>
|
|
|
|
|
#include <gay/util.h>
|
|
|
|
|
|
|
|
|
|
enum vga_color {
|
|
|
|
|
VGA_COLOR_BLACK = 0,
|
|
|
|
@ -47,11 +48,81 @@ enum vga_color fb_background;
|
|
|
|
|
/** @brief current foreground color */
|
|
|
|
|
enum vga_color fb_foreground;
|
|
|
|
|
|
|
|
|
|
static inline volatile struct fb_cell *cell_at(unsigned int line, unsigned int col)
|
|
|
|
|
static volatile struct fb_cell *cell_at(unsigned int line, unsigned int col);
|
|
|
|
|
#define current_cell (cell_at(fb_line, fb_col))
|
|
|
|
|
|
|
|
|
|
static ssize_t fb_write(struct kprintf_renderer *renderer, const void *buf, size_t size);
|
|
|
|
|
static ssize_t fb_flush(struct kprintf_renderer *renderer);
|
|
|
|
|
static struct kprintf_renderer fb_kprintf_renderer = {
|
|
|
|
|
.write = fb_write,
|
|
|
|
|
.flush = fb_flush,
|
|
|
|
|
};
|
|
|
|
|
static void fb_newline(void);
|
|
|
|
|
static void fb_clear(void);
|
|
|
|
|
static void fb_init(enum vga_color fg, enum vga_color bg);
|
|
|
|
|
|
|
|
|
|
static void print_gay_propaganda(void);
|
|
|
|
|
|
|
|
|
|
static struct mb2_tag *next_tag(struct mb2_tag *tag);
|
|
|
|
|
static void handle_tag(struct mb2_tag *tag);
|
|
|
|
|
static void handle_mmap_tag(struct mb2_tag_mmap *tag);
|
|
|
|
|
|
|
|
|
|
void _boot(u32 magic, void *address)
|
|
|
|
|
{
|
|
|
|
|
return (volatile struct fb_cell *)&framebuffer[line * FB_COLS + col];
|
|
|
|
|
kprintf_set_renderer(&fb_kprintf_renderer);
|
|
|
|
|
fb_init(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
|
|
|
|
|
|
|
|
|
|
if (magic != MB2_BOOTLOADER_MAGIC) {
|
|
|
|
|
kprintf("Error: invalid bootloader magic, aborting\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print_gay_propaganda();
|
|
|
|
|
|
|
|
|
|
for (struct mb2_tag *tag = address + 8; tag != NULL; tag = next_tag(tag))
|
|
|
|
|
handle_tag(tag);
|
|
|
|
|
|
|
|
|
|
while (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void handle_tag(struct mb2_tag *tag)
|
|
|
|
|
{
|
|
|
|
|
switch (tag->type) {
|
|
|
|
|
case MB2_TAG_TYPE_END:
|
|
|
|
|
break;
|
|
|
|
|
case MB2_TAG_TYPE_MMAP:
|
|
|
|
|
handle_mmap_tag((struct mb2_tag_mmap *)tag);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
//kprintf("Unknown tag %u\n", tag->type);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void handle_mmap_tag(struct mb2_tag_mmap *tag)
|
|
|
|
|
{
|
|
|
|
|
kprintf("Memory map:\n");
|
|
|
|
|
|
|
|
|
|
struct mb2_mmap_entry *entry = tag->entries;
|
|
|
|
|
while ((void *)entry < (void *)tag + tag->tag.size) {
|
|
|
|
|
unsigned int type = entry->type;
|
|
|
|
|
// kprintf("start = %p, ", (void *)entry->addr);
|
|
|
|
|
// kprintf("len = %p, ", (void *)entry->len);
|
|
|
|
|
// kprintf("type = %u\n", type);
|
|
|
|
|
kprintf("start = %p, len = %p, type = %u\n",
|
|
|
|
|
(void *)entry->addr, (void *)entry->len, type);
|
|
|
|
|
|
|
|
|
|
entry = (void *)entry + tag->entry_size;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct mb2_tag *next_tag(struct mb2_tag *tag)
|
|
|
|
|
{
|
|
|
|
|
if (tag->type == MB2_TAG_TYPE_END)
|
|
|
|
|
return NULL;
|
|
|
|
|
else
|
|
|
|
|
return (void *)tag + ( (tag->size + 7) & ~7 );
|
|
|
|
|
}
|
|
|
|
|
#define current_cell (cell_at(fb_line, fb_col))
|
|
|
|
|
|
|
|
|
|
static void fb_newline(void)
|
|
|
|
|
{
|
|
|
|
@ -59,7 +130,7 @@ static void fb_newline(void)
|
|
|
|
|
|
|
|
|
|
if (fb_line == FB_LINES - 1) {
|
|
|
|
|
u8 *first_row = (u8 *)cell_at(0, 0);
|
|
|
|
|
u8 *second_row = (u8 *)cell_at(0, 1);
|
|
|
|
|
u8 *second_row = (u8 *)cell_at(1, 0);
|
|
|
|
|
u8 *last_row_end = (u8 *)cell_at(FB_LINES, FB_COLS);
|
|
|
|
|
memmove(first_row, second_row, last_row_end - second_row);
|
|
|
|
|
} else {
|
|
|
|
@ -99,12 +170,7 @@ static ssize_t fb_flush(struct kprintf_renderer *renderer)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct kprintf_renderer fb_kprintf_renderer = {
|
|
|
|
|
.write = fb_write,
|
|
|
|
|
.flush = fb_flush,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void cls(void)
|
|
|
|
|
static void fb_clear(void)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned int l = 0; l < FB_LINES; l++) {
|
|
|
|
|
for (unsigned int c = 0; c < FB_COLS; c++) {
|
|
|
|
@ -115,14 +181,14 @@ static void cls(void)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void vga_init(enum vga_color fg, enum vga_color bg)
|
|
|
|
|
static void fb_init(enum vga_color fg, enum vga_color bg)
|
|
|
|
|
{
|
|
|
|
|
fb_line = 0;
|
|
|
|
|
fb_col = 0;
|
|
|
|
|
fb_foreground = VGA_COLOR_LIGHT_GREY;
|
|
|
|
|
fb_background = VGA_COLOR_BLACK;
|
|
|
|
|
|
|
|
|
|
cls();
|
|
|
|
|
fb_clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void print_gay_propaganda(void)
|
|
|
|
@ -131,9 +197,9 @@ static void print_gay_propaganda(void)
|
|
|
|
|
VGA_COLOR_RED,
|
|
|
|
|
VGA_COLOR_LIGHT_RED,
|
|
|
|
|
VGA_COLOR_LIGHT_BROWN,
|
|
|
|
|
VGA_COLOR_LIGHT_GREEN,
|
|
|
|
|
VGA_COLOR_LIGHT_CYAN,
|
|
|
|
|
VGA_COLOR_GREEN,
|
|
|
|
|
VGA_COLOR_BLUE,
|
|
|
|
|
VGA_COLOR_MAGENTA,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum vga_color bg_before = fb_background;
|
|
|
|
@ -152,17 +218,12 @@ static void print_gay_propaganda(void)
|
|
|
|
|
kprintf("%c", *tmp);
|
|
|
|
|
}
|
|
|
|
|
fb_foreground = fg_before;
|
|
|
|
|
kprintf(", be gay do crime!");
|
|
|
|
|
kprintf(", be gay do crime!\n\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _boot(u32 magic, void *address)
|
|
|
|
|
static inline volatile struct fb_cell *cell_at(unsigned int line, unsigned int col)
|
|
|
|
|
{
|
|
|
|
|
kprintf_set_renderer(&fb_kprintf_renderer);
|
|
|
|
|
vga_init(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
|
|
|
|
|
|
|
|
|
|
print_gay_propaganda();
|
|
|
|
|
|
|
|
|
|
while (1);
|
|
|
|
|
return (volatile struct fb_cell *)&framebuffer[line * FB_COLS + col];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|