Browse Source

finished terminal !

master
Mathieu Serandour 1 year ago
parent
commit
709a33d95a
  1. 2
      kernel/Makefile
  2. 8
      kernel/entry.c
  3. 11
      kernel/extern_files.s
  4. 7
      kernel/klib/sprintf.c
  5. 2
      kernel/klib/sprintf.h
  6. 149
      kernel/video/terminal.c
  7. 50
      kernel/video/video.c
  8. 10
      kernel/video/video.h
  9. 25
      resources/ascii/boot_message.txt
  10. BIN
      resources/bmp/charmap.bmp

2
kernel/Makefile

@ -43,6 +43,8 @@ $(KERNEL): $(OBJ)
%.bmp.o: ../resources/bmp/%.bmp
$(LD) -r -b binary -o $@ $<
%.txt.o: ../resources/ascii/%.txt
$(LD) -r -b binary -o $@ $<
%.c.o: %.c
$(CC) $(CFLAGS) $(INTERNALCFLAGS) -c $< -o $@

8
kernel/entry.c

@ -103,6 +103,9 @@ void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) {
extern uint64_t test(void);
extern int64_t test_size;
// const char but represents a big string
extern const char _binary_bootmessage_txt;
// Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling functio
// The following will be our kernel's entry point.
void _start(struct stivale2_struct *stivale2_struct) {
@ -161,8 +164,11 @@ void _start(struct stivale2_struct *stivale2_struct) {
_ds(), _ss(), _cs(),_es(),_fs(),_gs());
kprintf("print=0x%lx\n\n", kprintf);//0x00ea60
//0x100a60
setup_terminal();
init_gdt_table();
kputs(&_binary_bootmessage_txt);
//*ptr = 0xfffa24821;
asm("hlt");

11
kernel/extern_files.s

@ -0,0 +1,11 @@
section .rodata
global _binary_charmap_bmp
global _binary_bootmessage_txt
_binary_charmap_bmp:
incbin "../resources/bmp/charmap.bmp"
_binary_bootmessage_txt:
incbin "../resources/ascii/boot_message.txt"
db 0

7
kernel/klib/sprintf.c

@ -175,6 +175,13 @@ int sprintf(char* str, const char* format, ...) {
//
//}
void kputs(const char* s) {
terminal_handler_t print_fun = get_terminal_handler();
if(print_fun)
print_fun(s, strlen(s));
}
int kprintf(const char* format, ...) {
va_list ap;
int ret;

2
kernel/klib/sprintf.h

@ -14,4 +14,6 @@ int vsnprintf(char *str, size_t size, const char *format, va_list ap);
int kprintf(const char* format, ...);
void kputs(const char* s);
#endif

149
kernel/video/terminal.c

@ -1,4 +1,5 @@
#include <stddef.h>
#include <stdbool.h>
#include "terminal.h"
#include "../debug/assert.h"
#include "video.h"
@ -7,10 +8,15 @@
#define TAB_SPACE 6
static void write_string(const char *string, size_t length);
static struct Char make_Char(char c);
terminal_handler_t terminal_handler = NULL;
uint32_t terminal_foreground = 0xa0a0a0;
uint32_t terminal_background = 0x00;
static terminal_handler_t terminal_handler = NULL;
static uint32_t terminal_foreground = 0xa0a0a0;
static uint32_t terminal_background = 0x00;
// need to redraw the entire terminal
static bool need_refresh = false;
struct Char {
uint32_t fg_color: 24;
@ -18,48 +24,74 @@ struct Char {
uint32_t bg_color;
};
#define CHARSIZE 16
#define CHARMAP_W 192
#define CHARMAP_H 256
#define FONTWIDTH (CHARMAP_W / 16)
#define FONTHEIGHT (CHARMAP_H / 16)
#define INTERLINE 4
#define LINE_HEIGHT (FONTHEIGHT + INTERLINE)
Image* charmap = NULL;
struct Char* buffer = NULL;
static Image* charmap = NULL;
static struct Char* buffer = NULL;
int ncols, nlines;
int cur_col, cur_line;
static uint16_t ncols, nlines;
static uint16_t cur_col, cur_line;
static uint32_t current_fgcolor = 0xffffff;
static uint32_t current_bgcolor = 0;
// "int" but designates a binary file
extern int _binary____resources_bmp_charmap_bmp_start;
extern int _binary_charmap_bmp;
void setup_terminal(void) {
assert(charmap != NULL);
assert(charmap == NULL);
charmap = loadBMP(&_binary____resources_bmp_charmap_bmp_start);
charmap = loadBMP(&_binary_charmap_bmp);
assert(charmap != NULL);
assert(charmap != NULL);
assert(charmap->bpp == 32);
assert(charmap->w == 256);
assert(charmap->h == 256);
assert(charmap->w == CHARMAP_W);
assert(charmap->h == CHARMAP_H);
const Image* screenImage = getScreenImage();
ncols = screenImage->w / CHARSIZE;
nlines = screenImage->h / CHARSIZE;
// dynamicly create the terminal
// with right size
ncols = screenImage->w / FONTWIDTH;
nlines = screenImage->h / LINE_HEIGHT;
size_t buffer_len = screenImage->w * screenImage->h;
buffer = kmalloc(buffer_len * sizeof(struct Char));
size_t buffer_size = screenImage->w * screenImage->h *
sizeof(struct Char);
buffer = kmalloc(buffer_size);
struct Char* ptr = buffer;
for(;buffer_len > 0; --buffer_len)
*(ptr++) = make_Char(0);
memset(buffer, 0, buffer_size);
cur_col = 0;
cur_line= 0;
set_terminal_handler(write_string);
}
static void scroll(int lines) {
/*
// return a ptr to the actual char at pos
static struct Char* get_Char_at(int l, int c) {
return & buffer [ c + l * ncols ];
}
*/
static void scroll(int lines) {
need_refresh = true;
}
static void next_line(void) {
@ -72,9 +104,21 @@ static void next_line(void) {
}
}
// create the char struct
static struct Char make_Char(char c) {
return (struct Char) {
current_fgcolor,
c,
current_bgcolor
};
}
static void advance_cursor(char c) {
switch(c) {
// any character
default:
buffer[ncols * cur_line + cur_col] = make_Char(c);
cur_col += 1;
if(cur_col >= ncols)
@ -98,12 +142,71 @@ static void advance_cursor(char c) {
}
}
void printchar(char c) {
// emplace the char in the buffer, dosn't draw anything
static void emplace_char(char c) {
advance_cursor(c);
}
static void print_char(const struct Char* c, int line, int col) {
uint16_t c_x = c->c % 16,
c_y = c->c / 16;
Pos srcpos = {
FONTWIDTH * c_x ,
FONTHEIGHT * c_y,
};
Rect dstrect = {
.x = col * FONTWIDTH,
.y = line * LINE_HEIGHT,
.w = FONTWIDTH,
.h = FONTHEIGHT,
};
imageDraw(charmap, &srcpos, &dstrect);
Rect interlineRect = {
.x = dstrect.x,
.y = dstrect.y + FONTHEIGHT,
.w = FONTWIDTH,
.h = INTERLINE,
};
imageFillRect(c->bg_color, &interlineRect);
}
static void flush_screen(void) {
// if(need_refresh)
// imageDraw(charmap, NULL, NULL);
const struct Char* curr = buffer;
for(size_t l = 0; l < nlines; l++) {
for(size_t c = 0; c < ncols; c++) {
print_char(curr++, l, c);
}
}
}
static void write_string(const char *string, size_t length) {
for(;length>0;--length) {
char c = *string++;
if(!c)
break;
emplace_char(c);
}
flush_screen();
//imageDraw(charmap, NULL, NULL);
}

50
kernel/video/video.c

@ -39,8 +39,8 @@ inline void lower_blit(const Image* src, const Image* dst,
size_t copy_size = width * BPP;
kprintf("copy_size: %lu\n"
"dst_skip: %lu", copy_size, dst_skip);
//kprintf("copy_size: %lu\n"
// "dst_skip: %lu", copy_size, dst_skip);
for(size_t i = height+1; i > 0 ; i--) {
@ -54,14 +54,41 @@ inline void lower_blit(const Image* src, const Image* dst,
src_line_start += src_skip;
dst_line_start += dst_skip;
}
}
void imageFillRect(uint32_t color, const Rect* rect) {
uint32_t beginx, beginy, endx, endy;
if(rect != NULL) {
beginx = rect->x;
beginy = rect->y;
endx = rect->x + rect->w;
endy = rect->y + rect->h;
}
else {
beginx = 0;
beginy = 0;
endx = screen.w;
endy = screen.h;
}
for(size_t y = beginy; y < endy; y++) {
uint32_t* px = (uint32_t *) (
screen.pix
+ y * screen.pitch
+ beginx * 4);
for(size_t x = 0; x <= endx - beginx ; x++)
*(px++) = color;
}
}
void draw(const Image* img, const Pos* srcpos, const Rect* dstrect) {
blit(img, &screen, srcpos, dstrect);
void imageDraw(const Image* img, const Pos* srcpos, const Rect* dstrect) {
imageBlit(img, &screen, srcpos, dstrect);
}
void blit(const Image* restrict src, Image* restrict dst,
void imageBlit(const Image* restrict src, Image* restrict dst,
const Pos* srcpos, const Rect* dstrect) {
uint32_t sxbegin,
sybegin,
@ -128,12 +155,14 @@ void blit(const Image* restrict src, Image* restrict dst,
}
Image* alloc_image(uint32_t width, uint32_t height, uint32_t bpp) {
Image* ret = kmalloc(sizeof(Image));
ret->w = width;
ret->h = height;
ret->pitch = (uint32_t)allign16(width * (bpp/8));
ret->bpp = bpp;
ret->pix = kmalloc(ret->pitch * height);
@ -209,20 +238,13 @@ Image* loadBMP(const void* rawFile) {
for(size_t x = 0; x < w; x++) {
const uint32_t* src_ptr = (const uint32_t *)(srcpix24
+ x * 3
+ (h+1 - y) * 3 * w);
+ (h-1 - y) * 3 * w);
/// the image is reversed along
/// the y axis
pix32[x + y * bpitch] = (*(const uint32_t *)src_ptr) & 0x00ffffff;
pix32[x + y * bpitch] = (*(const uint32_t *)src_ptr) & 0x00ffffff;
}
}
PRINT_VAL(ret->w);
PRINT_VAL(ret->h);
PRINT_VAL(ret->pix);
PRINT_VAL(ret->pitch);
return ret;
}

10
kernel/video/video.h

@ -26,10 +26,12 @@ typedef struct {
const Image* getScreenImage(void);
void initVideo(const Image* srceen);
void draw(const Image* img, const Pos* srcpos, const Rect* dstrect);
void blit(const Image* __restrict__ src,
Image* __restrict__ dst,
const Pos* srcpos, const Rect* dstrect);
void imageDraw(const Image* img, const Pos* srcpos, const Rect* dstrect);
void imageBlit(const Image* __restrict__ src,
Image* __restrict__ dst,
const Pos* srcpos, const Rect* dstrect);
void imageFillRect(uint32_t color, const Rect* rect);
Image* loadBMP(const void* rawFile);

25
resources/ascii/boot_message.txt

@ -0,0 +1,25 @@
__________ .__ _________
\______ \|__| ____ \_ ___ \ ____ __ _ __ ______
| | _/| | / \ / \ \/ / _ \ \ \/ \/ / / ___/
| | \| || | \\ \____( <_> ) \ / \___ \
|______ /|__||___| / \______ / \____/ \/\_/ /____ >
\/ \/ \/ \/
.= , =.
_ _ /'/ )\,/,/(_ \ \
`//-.| ( ,\\)\//\)\/_ ) |
//___\ `\\\/\\/\/\\///' /
,-"~`-._ `"--'_ `"""` _ \`'"~-,_
\ `-. '_`. .'_` \ ,-"~`/
`.__.-'`/ (-\ /-) |-.__,'
|| | \O) /^\ (O/ |
`\\ | / `\ /
\\ \ / `\ /
`\\ `-. /' .---.--.\
`\\/`~(, '() ('
/(O) \\ _,.-.,_)
// \\ `\'` /
/ | || `""""~"`
/' |__||
`o
"
;

BIN
resources/bmp/charmap.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Loading…
Cancel
Save