Start at framebuffer drawing
This commit is contained in:
parent
60bb1bd039
commit
7843bf11d0
@ -20,18 +20,16 @@ registers *divbyzero(registers *r) {
|
|||||||
|
|
||||||
void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||||
{
|
{
|
||||||
vga_init();
|
|
||||||
|
|
||||||
debug("Started kernel\n");
|
|
||||||
|
|
||||||
cpu_init();
|
|
||||||
|
|
||||||
multiboot_init(multiboot_magic, P2V(multiboot_data));
|
multiboot_init(multiboot_magic, P2V(multiboot_data));
|
||||||
|
|
||||||
debug_info("Kernel loaded with command line: \"%s\" by <%s>\n", kernel_boot_data.commandline, kernel_boot_data.bootloader);
|
cpu_init();
|
||||||
|
|
||||||
memory_init();
|
memory_init();
|
||||||
|
|
||||||
|
vga_init();
|
||||||
|
|
||||||
|
debug("Started kernel\n");
|
||||||
|
debug_info("Kernel loaded with command line: \"%s\" by <%s>\n", kernel_boot_data.commandline, kernel_boot_data.bootloader);
|
||||||
|
|
||||||
bind_interrupt(0, divbyzero);
|
bind_interrupt(0, divbyzero);
|
||||||
|
|
||||||
// Force a divide by zero error
|
// Force a divide by zero error
|
||||||
|
@ -29,17 +29,6 @@ struct mmap {
|
|||||||
struct mmap_entry entries[];
|
struct mmap_entry entries[];
|
||||||
}__attribute__((packed));
|
}__attribute__((packed));
|
||||||
|
|
||||||
struct fbinfo {
|
|
||||||
uint64_t framebuffer_addr;
|
|
||||||
uint32_t framebuffer_pitch;
|
|
||||||
uint32_t framebuffer_width;
|
|
||||||
uint32_t framebuffer_height;
|
|
||||||
uint8_t framebuffer_bpp;
|
|
||||||
uint8_t framebuffer_type;
|
|
||||||
uint8_t reserved;
|
|
||||||
uint8_t data[];
|
|
||||||
}__attribute__((packed));
|
|
||||||
|
|
||||||
static int parse_multiboot2(struct taglist *tags)
|
static int parse_multiboot2(struct taglist *tags)
|
||||||
{
|
{
|
||||||
struct mmap *mmap;
|
struct mmap *mmap;
|
||||||
@ -60,7 +49,8 @@ static int parse_multiboot2(struct taglist *tags)
|
|||||||
kernel_boot_data.mmap_len = (tag->size - 8)/mmap->entry_size;
|
kernel_boot_data.mmap_len = (tag->size - 8)/mmap->entry_size;
|
||||||
kernel_boot_data.mmap_size = (tag->size - 8);
|
kernel_boot_data.mmap_size = (tag->size - 8);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case MBOOT2_TAG_FBINFO:
|
||||||
|
kernel_boot_data.fbinfo = (void *)tag->data;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,10 +91,18 @@ int multiboot_get_memory_area(size_t index, uintptr_t *start, uintptr_t *end, ui
|
|||||||
int multiboot_page_used(uintptr_t page)
|
int multiboot_page_used(uintptr_t page)
|
||||||
{
|
{
|
||||||
#define within_page(st, l) (((uintptr_t)st + l) > page && (uintptr_t)st < (page + PAGE_SIZE))
|
#define within_page(st, l) (((uintptr_t)st + l) > page && (uintptr_t)st < (page + PAGE_SIZE))
|
||||||
|
|
||||||
|
size_t fb_size = 0;
|
||||||
|
uintptr_t fb_start = 0;
|
||||||
|
if(kernel_boot_data.fbinfo) {
|
||||||
|
fb_start = kernel_boot_data.fbinfo->framebuffer_addr;
|
||||||
|
fb_size = kernel_boot_data.fbinfo->framebuffer_pitch*(kernel_boot_data.fbinfo->framebuffer_height + 1);
|
||||||
|
}
|
||||||
if(
|
if(
|
||||||
within_page(kernel_boot_data.bootloader, strlen(kernel_boot_data.bootloader)) ||
|
within_page(kernel_boot_data.bootloader, strlen(kernel_boot_data.bootloader)) ||
|
||||||
within_page(kernel_boot_data.commandline, strlen(kernel_boot_data.commandline)) ||
|
within_page(kernel_boot_data.commandline, strlen(kernel_boot_data.commandline)) ||
|
||||||
within_page(kernel_boot_data.mmap, kernel_boot_data.mmap_size) ||
|
within_page(kernel_boot_data.mmap, kernel_boot_data.mmap_size) ||
|
||||||
|
within_page(fb_start, fb_size) ||
|
||||||
0) {
|
0) {
|
||||||
debug("Page %x used\n", page);
|
debug("Page %x used\n", page);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -10,6 +10,15 @@ Multiboot2Header:
|
|||||||
|
|
||||||
//; Multiboot tag list
|
//; Multiboot tag list
|
||||||
|
|
||||||
|
.short 5 //; Request graphics mode
|
||||||
|
.short 0
|
||||||
|
.long 20
|
||||||
|
.long 0
|
||||||
|
.long 0
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
.long 0 //; Pad to multiple of 8 bytes
|
||||||
|
|
||||||
.short 0 //; End tag
|
.short 0 //; End tag
|
||||||
.short 0
|
.short 0
|
||||||
.long 8
|
.long 8
|
||||||
|
31
src/kernel/drivers/framebuffer.c
Normal file
31
src/kernel/drivers/framebuffer.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <multiboot.h>
|
||||||
|
|
||||||
|
void framebuffer_init(struct fbinfo *fbinfo)
|
||||||
|
{
|
||||||
|
size_t fb_size = fbinfo->framebuffer_pitch * (fbinfo->framebuffer_height+1);
|
||||||
|
uintptr_t fb_end = fbinfo->framebuffer_addr + fb_size;
|
||||||
|
|
||||||
|
for(uintptr_t p = fbinfo->framebuffer_addr; p < fb_end; p += PAGE_SIZE)
|
||||||
|
{
|
||||||
|
vmm_set_page(kernel_P4, (uint64_t)P2V(p), p, PAGE_WRITE | PAGE_PRESENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *fb = P2V(fbinfo->framebuffer_addr);
|
||||||
|
|
||||||
|
for(uint32_t y = 0; y < 1; y++)
|
||||||
|
{
|
||||||
|
for(uint32_t x = 0; x < fbinfo->framebuffer_width; x++)
|
||||||
|
{
|
||||||
|
unsigned int bpp = fbinfo->framebuffer_bpp/8;
|
||||||
|
unsigned int loc = \
|
||||||
|
y*fbinfo->framebuffer_pitch + \
|
||||||
|
x*(bpp);
|
||||||
|
fb[loc++] = 0xFF;
|
||||||
|
fb[loc++] = 0;
|
||||||
|
fb[loc] = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
#include <vga.h>
|
#include <vga.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <ports.h>
|
#include <ports.h>
|
||||||
|
#include <multiboot.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#define VGA_COLS 80
|
#define VGA_COLS 80
|
||||||
#define VGA_ROWS 24
|
#define VGA_ROWS 24
|
||||||
@ -26,15 +29,29 @@ struct vga_cell buffer[VGA_SIZE];
|
|||||||
uint64_t cursor;
|
uint64_t cursor;
|
||||||
uint8_t format;
|
uint8_t format;
|
||||||
|
|
||||||
|
static int vga_setup = 0;
|
||||||
|
static int vga_type;
|
||||||
|
|
||||||
void vga_init()
|
void vga_init()
|
||||||
{
|
{
|
||||||
vidmem = VGA_MEMORY;
|
struct fbinfo *fbinfo = kernel_boot_data.fbinfo;
|
||||||
memset(vidmem, 0, VGA_SIZE*sizeof(struct vga_cell));
|
vga_type = fbinfo->framebuffer_type;
|
||||||
|
switch(vga_type)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
framebuffer_init(fbinfo);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
vidmem = VGA_MEMORY;
|
||||||
|
memset(vidmem, 0, VGA_SIZE*sizeof(struct vga_cell));
|
||||||
|
format = 0x07;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
format = 0x07;
|
vga_setup = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void movecursor()
|
static void movecursor()
|
||||||
{
|
{
|
||||||
outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_LOW);
|
outb(VGA_ADDRESS_PORT, VGA_REGISTER_CURSOR_POS_LOW);
|
||||||
outb(VGA_DATA_PORT, (uint8_t)(cursor & 0xFF));
|
outb(VGA_DATA_PORT, (uint8_t)(cursor & 0xFF));
|
||||||
@ -42,12 +59,13 @@ void movecursor()
|
|||||||
outb(VGA_DATA_PORT, (uint8_t)((cursor >> 8) & 0xFF));
|
outb(VGA_DATA_PORT, (uint8_t)((cursor >> 8) & 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush()
|
static void flush()
|
||||||
{
|
{
|
||||||
memcpy(vidmem, buffer, sizeof(buffer));
|
if(vga_setup)
|
||||||
|
memcpy(vidmem, buffer, sizeof(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void scroll()
|
static void scroll()
|
||||||
{
|
{
|
||||||
while(cursor >= VGA_SIZE)
|
while(cursor >= VGA_SIZE)
|
||||||
{
|
{
|
||||||
@ -59,15 +77,20 @@ void scroll()
|
|||||||
|
|
||||||
void vga_write(char c)
|
void vga_write(char c)
|
||||||
{
|
{
|
||||||
switch(c)
|
switch(vga_type)
|
||||||
{
|
{
|
||||||
case '\n':
|
case 2:
|
||||||
cursor += VGA_COLS - VGA_COL(cursor);
|
switch(c)
|
||||||
|
{
|
||||||
|
case '\n':
|
||||||
|
cursor += VGA_COLS - VGA_COL(cursor);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buffer[cursor++] = (struct vga_cell){.c = c, .f = format};
|
||||||
|
}
|
||||||
|
scroll();
|
||||||
|
flush();
|
||||||
|
movecursor();
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
buffer[cursor++] = (struct vga_cell){.c = c, .f = format};
|
|
||||||
}
|
}
|
||||||
scroll();
|
|
||||||
flush();
|
|
||||||
movecursor();
|
|
||||||
}
|
}
|
@ -13,6 +13,18 @@
|
|||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct fbinfo {
|
||||||
|
uint64_t framebuffer_addr;
|
||||||
|
uint32_t framebuffer_pitch;
|
||||||
|
uint32_t framebuffer_width;
|
||||||
|
uint32_t framebuffer_height;
|
||||||
|
uint8_t framebuffer_bpp;
|
||||||
|
uint8_t framebuffer_type;
|
||||||
|
uint8_t reserved;
|
||||||
|
uint8_t color_info[];
|
||||||
|
}__attribute__((packed));
|
||||||
|
|
||||||
struct kernel_boot_data_st{
|
struct kernel_boot_data_st{
|
||||||
int multiboot_version;
|
int multiboot_version;
|
||||||
char *bootloader;
|
char *bootloader;
|
||||||
@ -20,6 +32,7 @@ struct kernel_boot_data_st{
|
|||||||
size_t mmap_size;
|
size_t mmap_size;
|
||||||
unsigned int mmap_len;
|
unsigned int mmap_len;
|
||||||
void *mmap;
|
void *mmap;
|
||||||
|
struct fbinfo *fbinfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MMAP_FREE 1
|
#define MMAP_FREE 1
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include <multiboot.h>
|
||||||
|
|
||||||
#define VGA_MEMORY P2V(0xB8000)
|
#define VGA_MEMORY P2V(0xB8000)
|
||||||
|
|
||||||
// drivers/vga.c
|
// drivers/vga.c
|
||||||
void vga_init();
|
void vga_init();
|
||||||
void vga_write(char c);
|
void vga_write(char c);
|
||||||
|
|
||||||
|
// drivers/framebuffer.c
|
||||||
|
void framebuffer_init(struct fbinfo *fbinfo);
|
Loading…
x
Reference in New Issue
Block a user