[bochs] Framebuffer terminal. PAGING HAS BEEN DISABLED

This commit is contained in:
Kevin Lange 2011-03-28 19:34:44 -05:00
parent b01c79a95c
commit 9b1ab6e97f
8 changed files with 250 additions and 51 deletions

View File

@ -27,9 +27,9 @@ parse_args(char * arg) {
/* QEMU Video Mode, we are free to set things for 1024x768 */
graphics_install_bochs();
bochs_draw_logo("/bs.bmp");
char * welcome = "Welcome to \200\201\202OS!";
char * welcome = "Welcome to \200\201\202OS!\n";
for (uint16_t i = 0; i < strlen(welcome); ++i) {
bochs_write_char(welcome[i], i * 8, 0, 0x00FFFFFF, 0x0);
bochs_write(welcome[i]);
}
}
}

View File

@ -196,6 +196,9 @@ paging_install(uint32_t memsize) {
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
i += 0x1000;
}
for (i = 0; i < 0xFFFFFF; i += 0x1000) {
alloc_frame(get_page(0xE0000000 + i, 1, kernel_directory), 0, 0);
}
isrs_install_handler(14, page_fault);
kernel_directory->physical_address = (uintptr_t)kernel_directory->physical_tables;
@ -209,6 +212,7 @@ switch_page_directory(
page_directory_t * dir
) {
current_directory = dir;
return;
__asm__ __volatile__ ("mov %0, %%cr3":: "r"(dir->physical_address));
uint32_t cr0;
__asm__ __volatile__ ("mov %%cr0, %0": "=r"(cr0));

View File

@ -1,3 +1,7 @@
/*
* vim:tabstop=4
* vim:noexpandtab
*/
#include <system.h>
/*
@ -20,6 +24,27 @@ memcpy(
return dest;
}
void *
memmove(
void * restrict dest,
const void * restrict src,
size_t count
) {
size_t i;
unsigned char *a = dest;
const unsigned char *b = src;
if (src < dest) {
for ( i = count; i > 0; --i) {
a[i-1] = b[i-1];
}
} else {
for ( i = 0; i < count; ++i) {
a[i] = b[i];
}
}
return dest;
}
int
strcmp(
const char * a,
@ -140,6 +165,23 @@ outports(
__asm__ __volatile__ ("outw %1, %0" : : "dN" (_port), "a" (_data));
}
unsigned int
inportl(
unsigned short _port
) {
unsigned short rv;
__asm__ __volatile__ ("inl %%dx, %%eax" : "=a" (rv) : "dN" (_port));
return rv;
}
void
outportl(
unsigned short _port,
unsigned int _data
) {
__asm__ __volatile__ ("outl %%eax, %%dx" : : "dN" (_port), "a" (_data));
}
/*
* inportb

View File

@ -105,6 +105,9 @@ cls() {
csr_x = 0;
csr_y = 0;
move_csr();
if (bochs_resolution_x) {
bochs_term_clear();
}
}
/*
@ -157,6 +160,10 @@ writech(
if (use_serial) {
serial_send(c);
}
if (bochs_resolution_x) {
bochs_write(c);
return;
}
if (c == 0x08) {
/* Backspace */
if (csr_x != 0) csr_x--;
@ -209,6 +216,14 @@ settextcolor(
unsigned char backcolor
) {
attrib = (backcolor << 4) | (forecolor & 0x0F);
if (use_serial) {
serial_send('\033');
serial_send('[');
serial_send('3');
serial_send(forecolor % 8 + '0');
serial_send('m');
}
bochs_set_colors(forecolor, backcolor);
}
/*
@ -218,6 +233,13 @@ settextcolor(
void
resettextcolor() {
settextcolor(7,0);
if (use_serial) {
serial_send('\033');
serial_send('[');
serial_send('0');
serial_send('m');
}
bochs_reset_colors();
}
void

View File

@ -1046,9 +1046,9 @@ uint8_t number_font[][12] = {
0b00000000,
0b00000000,
0b00000000, /* 4 */
0b00000000,
0b11011100,
0b01100110,
0b01100110,
0b01100110, /* 8 */
0b01100110,
0b01111100,
@ -1059,9 +1059,9 @@ uint8_t number_font[][12] = {
0b00000000,
0b00000000,
0b00000000, /* 4 */
0b00000000,
0b01110110,
0b11001100,
0b11001100,
0b11001100, /* 8 */
0b11001100,
0b01111100,
@ -1096,11 +1096,11 @@ uint8_t number_font[][12] = {
},
{ 0b00000000,
0b00000000,
0b00000000,
0b00100000, /* 4 */
0b01100000,
0b00100000,
0b01100000, /* 4 */
0b11111100,
0b01100000,
0b01100000,
0b01100000, /* 8 */
0b01101100,
0b00111000,

View File

@ -15,11 +15,17 @@
uint16_t bochs_resolution_x = 0;
uint16_t bochs_resolution_y = 0;
uint16_t bochs_resolution_b = 0;
uint16_t bochs_current_bank = 0;
#define BOCHS_BANK_SIZE 16384
#define BOCHS_VID_MEMORY ((uint32_t *)0xA0000)
#define BOCHS_BANKS (bochs_resolution_x * bochs_resolution_y * bochs_resolution_b / (BOCHS_BANK_SIZE * 32))
#define BOCHS_VID_MEMORY ((uint32_t *)0xE0000000) //((uint32_t *)0xA0000)
#define TERM_WIDTH 128
#define TERM_HEIGHT 64
static short csr_x = 0;
static short csr_y = 0;
static uint8_t * term_buffer;
static uint8_t current_fg = 7;
static uint8_t current_bg = 0;
void
graphics_install_bochs() {
@ -41,31 +47,31 @@ graphics_install_bochs() {
/* Set X resolution to 1024 */
outports(0x1CE, 0x01);
outports(0x1CF, PREFERRED_X);
bochs_resolution_x = PREFERRED_X;
/* Set Y resolution to 768 */
outports(0x1CE, 0x02);
outports(0x1CF, PREFERRED_Y);
bochs_resolution_y = PREFERRED_Y;
/* Set bpp to 32 */
outports(0x1CE, 0x03);
outports(0x1CF, PREFERRED_B);
bochs_resolution_b = PREFERRED_B;
/* Re-enable VBE */
outports(0x1CE, 0x04);
outports(0x1CF, 0x01);
}
outports(0x1CF, 0x41);
/* Herp derp */
void
bochs_set_bank(
uint16_t bank
) {
if (bank == bochs_current_bank) {
/* We are already in this bank, stop wasting cycles */
return;
for (uint16_t x = 0; x < 1024; ++x) {
for (uint16_t y = 0; y < 768; ++y) {
BOCHS_VID_MEMORY[y * 1024 + x] = 0xFFFFFF;
}
}
outports(0x1CE, 0x05); /* Bank */
outports(0x1CF, bank);
bochs_current_bank = bank;
//HALT_AND_CATCH_FIRE("Herp");
bochs_resolution_x = PREFERRED_X;
bochs_resolution_y = PREFERRED_Y;
bochs_resolution_b = PREFERRED_B;
/* Buffer contains characters, fg (of 256), bg (same), flags (one byte) */
term_buffer = (uint8_t *)malloc(sizeof(uint8_t) * 4 * TERM_WIDTH * TERM_HEIGHT);
}
static void
@ -74,32 +80,14 @@ bochs_set_point(
uint16_t y,
uint32_t color
) {
BOCHS_VID_MEMORY[(y * bochs_resolution_x + x) % BOCHS_BANK_SIZE] = color;
}
void
bochs_set_coord(
uint16_t x,
uint16_t y,
uint32_t color
) {
uint32_t location = y * bochs_resolution_x + x;
bochs_set_bank(location / BOCHS_BANK_SIZE);
uint32_t offset = location % BOCHS_BANK_SIZE;
BOCHS_VID_MEMORY[offset] = color;
BOCHS_VID_MEMORY[(y * bochs_resolution_x + x)] = color;
}
void
bochs_scroll() {
__asm__ __volatile__ ("cli");
uint32_t * bank_store = malloc(sizeof(uint32_t) * BOCHS_BANK_SIZE);
for (int i = 1; i < BOCHS_BANKS; ++i) {
bochs_set_bank(i);
memcpy(bank_store, BOCHS_VID_MEMORY, sizeof(uint32_t) * BOCHS_BANK_SIZE);
bochs_set_bank(i - 1);
memcpy(BOCHS_VID_MEMORY, bank_store, sizeof(uint32_t) * BOCHS_BANK_SIZE);
}
free(bank_store);
uint32_t size = sizeof(uint32_t) * bochs_resolution_x * (bochs_resolution_y - 12);
memmove((void *)BOCHS_VID_MEMORY, (void *)((uintptr_t)BOCHS_VID_MEMORY + bochs_resolution_x * 12 * sizeof(uint32_t)), size);
__asm__ __volatile__ ("sti");
}
@ -129,10 +117,11 @@ bochs_draw_logo(char * filename) {
bufferb[i+1 + 3 * x] * 0x100 +
bufferb[i+2 + 3 * x] * 0x10000;
/* Set our point */
bochs_set_coord((bochs_resolution_x - width) / 2 + x, (bochs_resolution_y - height) / 2 + (height - y), color);
bochs_set_point((bochs_resolution_x - width) / 2 + x, (bochs_resolution_y - height) / 2 + (height - y), color);
}
i += row_width;
}
free(bufferb);
}
void
@ -144,7 +133,6 @@ bochs_fill_rect(
uint32_t color
) {
for (uint16_t i = y; i < h + y; ++i) {
bochs_set_bank(y * bochs_resolution_x / BOCHS_BANK_SIZE);
for (uint16_t j = x; j < w + x; ++j) {
bochs_set_point(j,i,color);
}
@ -160,8 +148,8 @@ bochs_write_char(
uint32_t bg
) {
uint8_t * c = number_font[val - 0x20];
__asm__ __volatile__ ("cli");
for (uint8_t i = 0; i < 12; ++i) {
bochs_set_bank((y+i) * bochs_resolution_x / BOCHS_BANK_SIZE);
if (c[i] & 0x80) { bochs_set_point(x,y+i,fg); } else { bochs_set_point(x,y+i,bg); }
if (c[i] & 0x40) { bochs_set_point(x+1,y+i,fg); } else { bochs_set_point(x+1,y+i,bg); }
if (c[i] & 0x20) { bochs_set_point(x+2,y+i,fg); } else { bochs_set_point(x+2,y+i,bg); }
@ -171,4 +159,136 @@ bochs_write_char(
if (c[i] & 0x02) { bochs_set_point(x+6,y+i,fg); } else { bochs_set_point(x+6,y+i,bg); }
if (c[i] & 0x01) { bochs_set_point(x+7,y+i,fg); } else { bochs_set_point(x+7,y+i,bg); }
}
__asm__ __volatile__ ("sti");
}
uint32_t bochs_colors[16] = {
/* black */ 0x000000,
/* red */ 0xcc0000,
/* green */ 0x3e9a06,
/* brown */ 0xc4a000,
/* navy */ 0x3465a4,
/* purple */ 0x75507b,
/* d cyan */ 0x06989a,
/* gray */ 0xeeeeec,
/* d gray */ 0x555753,
/* red */ 0xef2929,
/* green */ 0x8ae234,
/* yellow */ 0xfce94f,
/* blue */ 0x729fcf,
/* magenta*/ 0xad7fa8,
/* cyan */ 0x34e2e2,
/* white */ 0xFFFFFF
};
static void cell_set(uint16_t x, uint16_t y, uint8_t c, uint8_t fg, uint8_t bg) {
uint8_t * cell = (uint8_t *)((uintptr_t)term_buffer + (y * TERM_WIDTH + x) * 4);
cell[0] = c;
cell[1] = fg;
cell[2] = bg;
}
static uint16_t cell_ch(uint16_t x, uint16_t y) {
uint8_t * cell = (uint8_t *)((uintptr_t)term_buffer + (y * TERM_WIDTH + x) * 4);
return cell[0];
}
static uint16_t cell_fg(uint16_t x, uint16_t y) {
uint8_t * cell = (uint8_t *)((uintptr_t)term_buffer + (y * TERM_WIDTH + x) * 4);
return cell[1];
}
static uint16_t cell_bg(uint16_t x, uint16_t y) {
uint8_t * cell = (uint8_t *)((uintptr_t)term_buffer + (y * TERM_WIDTH + x) * 4);
return cell[2];
}
static void cell_redraw(uint16_t x, uint16_t y) {
uint8_t * cell = (uint8_t *)((uintptr_t)term_buffer + (y * TERM_WIDTH + x) * 4);
bochs_write_char(cell[0], x * 8, y * 12, bochs_colors[cell[1]], bochs_colors[cell[2]]);
}
void bochs_redraw() {
for (uint16_t y = 0; y < TERM_HEIGHT; ++y) {
for (uint16_t x = 0; x < TERM_WIDTH; ++x) {
cell_redraw(x,y);
}
}
}
void bochs_term_scroll() {
/* Oh dear */
bochs_scroll();
for (uint16_t y = 0; y < TERM_HEIGHT - 1; ++y) {
for (uint16_t x = 0; x < TERM_WIDTH; ++x) {
cell_set(x,y,cell_ch(x,y+1),cell_fg(x,y+1),cell_bg(x,y+1));
}
}
for (uint16_t x = 0; x < TERM_WIDTH; ++x) {
cell_set(x, TERM_HEIGHT-1,' ',current_fg, current_bg);
cell_redraw(csr_x, csr_y);
}
//bochs_redraw();
}
void bochs_term_clear() {
/* Oh dear */
for (uint16_t y = 0; y < TERM_HEIGHT; ++y) {
for (uint16_t x = 0; x < TERM_WIDTH; ++x) {
cell_set(x,y,' ',current_fg, current_bg);
}
}
bochs_redraw();
csr_x = 0;
csr_y = 0;
}
void bochs_set_colors(uint8_t fg, uint8_t bg) {
current_fg = fg;
current_bg = bg;
}
void bochs_reset_colors() {
current_fg = 7;
current_bg = 0;
}
void draw_cursor() {
for (uint32_t x = 0; x < 8; ++x) {
bochs_set_point(csr_x * 8 + x, csr_y * 12 + 11, bochs_colors[current_fg]);
}
}
void bochs_write(char c) {
__asm__ __volatile__ ("cli");
cell_redraw(csr_x, csr_y);
if (c == '\n') {
for (uint16_t i = csr_x; i < TERM_WIDTH; ++i) {
/* I like this behaviour */
cell_set(i, csr_y, ' ',current_fg, current_bg);
cell_redraw(i, csr_y);
}
csr_x = 0;
++csr_y;
} else if (c == '\b') {
--csr_x;
cell_set(csr_x, csr_y, ' ',current_fg, current_bg);
cell_redraw(csr_x, csr_y);
} else {
cell_set(csr_x,csr_y, c, current_fg, current_bg);
cell_redraw(csr_x,csr_y);
csr_x++;
}
if (csr_x == TERM_WIDTH) {
csr_x = 0;
++csr_y;
}
if (csr_y == TERM_HEIGHT) {
bochs_term_scroll();
csr_y = TERM_HEIGHT - 1;
}
draw_cursor();
__asm__ __volatile__ ("sti");
}

View File

@ -12,6 +12,7 @@ extern void *sbrk(uintptr_t increment);
/* Kernel Main */
extern void *memcpy(void *restrict dest, const void *restrict src, size_t count);
extern void *memmove(void *restrict dest, const void *restrict src, size_t count);
extern void *memset(void *dest, int val, size_t count);
extern unsigned short *memsetw(unsigned short *dest, unsigned short val, int count);
extern int strlen(const char *str);
@ -20,6 +21,8 @@ extern unsigned char inportb(unsigned short _port);
extern void outportb(unsigned short _port, unsigned char _data);
extern unsigned short inports(unsigned short _port);
extern void outports(unsigned short _port, unsigned short _data);
extern unsigned int inportl(unsigned short _port);
extern void outportl(unsigned short _port, unsigned int _data);
extern int strcmp(const char *a, const char *b);
extern char * strtok_r(char * str, const char * delim, char ** saveptr);
extern size_t lfind(const char * str, const char accept);
@ -198,6 +201,12 @@ extern void bochs_write_char(uint8_t val, uint16_t x, uint16_t y, uint32_t fg, u
extern uint16_t bochs_resolution_x;
extern uint16_t bochs_resolution_y;
extern uint16_t bochs_resolution_b;
extern uint32_t bochs_colors[];
/* Terminal functions */
extern void bochs_term_clear();
extern void bochs_write(char c);
extern void bochs_reset_colors();
extern void bochs_set_colors(uint8_t, uint8_t);
extern uint8_t number_font[][12];

View File

@ -146,7 +146,7 @@ int main(struct multiboot *mboot_ptr, uint32_t mboot_mag, uintptr_t esp)
fork();
if (getpid() == 0) {
while (1) {
while (0) {
uint16_t hours, minutes, seconds;
get_time(&hours, &minutes, &seconds);
@ -180,6 +180,8 @@ int main(struct multiboot *mboot_ptr, uint32_t mboot_mag, uintptr_t esp)
restore_csr();
}
__asm__ __volatile__ ("sti");
}
while (1) {
__asm__ __volatile__ ("hlt");
}
} else {