From f90c07132aabfa6cc5a1632365a1c1739f8e4e1d Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Sat, 18 Dec 2021 13:52:13 +0100 Subject: [PATCH] vxBoot - 0.1.0 : First version @add <> builtin/loader : add "ld" builtin command <> loader/entry : add gintrace support to potentially trace an operating system <> loader/entry : add "image" dump generation in the SMEM @update <> builtin/hw : isolate hardware interaction <> fs/smemfs/pread : change long function name formalism <> loader/elf/entry : isolate hardware interaction <> terminal/read : if not cursor time is available, force-display the cursor <> terminal/util : change complex C semantic abuse @fix: <> loader/elf/image : check the available RAM size before load the image <> loader/elf/image : use non-cacheable area address to load the image <> loader/elf/image : use cacheable area address for the "entry" address generation <> loader/elf/entry : display appropriate error string if needed <> terminal/open : reduce buffer size <> terminal/open : enable cursor blink only if the device is not an emulator <> terminal/read : add "mutex" for the display <> terminal/read : sign comparison --- CMakeLists.txt | 7 +++- include/vxBoot/builtin.h | 1 + include/vxBoot/fs/smemfs.h | 8 +++- include/vxBoot/hardware.h | 6 ++- include/vxBoot/loader.h | 19 ++++++---- include/vxBoot/terminal.h | 2 +- src/builtin/hw.c | 43 +++++++-------------- src/builtin/loader.c | 62 ++++++++++++++++++++++++++++++ src/fs/smemfs/pread.c | 17 ++++++--- src/hardware/get_info.c | 37 ++++++++++++++++++ src/loader/elf/header.c | 2 +- src/loader/elf/image.c | 19 +++++++--- src/loader/entry.c | 77 ++++++++++++++++++++++++++++++++++---- src/main.c | 2 +- src/terminal/open.c | 21 ++++++----- src/terminal/read.c | 24 ++++++++++-- src/terminal/util.c | 17 ++++++--- 17 files changed, 282 insertions(+), 82 deletions(-) create mode 100644 src/builtin/loader.c create mode 100644 src/hardware/get_info.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 47c2718..b35c017 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,11 +19,13 @@ set(SOURCES src/builtin/ls.c src/builtin/help.c src/builtin/hw.c + src/builtin/loader.c src/loader/scan.c src/loader/elf/header.c src/loader/elf/image.c src/loader/error.c - src/loader/scan.c + src/loader/entry.c + src/hardware/get_info.c ) # Shared assets, fx-9860G-only assets and fx-CG-50-only assets set(ASSETS @@ -41,12 +43,13 @@ fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA) add_executable(vxBoot ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}}) target_compile_options(vxBoot PRIVATE -Wall -Wextra -Os) target_include_directories(vxBoot PRIVATE include/) -target_link_libraries(vxBoot Gint::Gint) if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G) + target_link_libraries(vxBoot -lgintrace-fx Gint::Gint) generate_g1a(TARGET vxBoot OUTPUT "vxBoot.g1a" NAME "vxBoot" ICON assets-fx/icon.png) elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50) + target_link_libraries(vxBoot -lgintrace-cg Gint::Gint) generate_g3a(TARGET vxBoot OUTPUT "vxBoot.g3a" NAME "vxBoot" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png) endif() diff --git a/include/vxBoot/builtin.h b/include/vxBoot/builtin.h index ba13c7e..34b9073 100644 --- a/include/vxBoot/builtin.h +++ b/include/vxBoot/builtin.h @@ -7,6 +7,7 @@ extern int ls_main(int argc, char **argv); extern int os_main(int argc, char **argv); extern int hw_main(int argc, char **argv); +extern int ld_main(int argc, char **argv); extern int help_main(int argc, char **argv); #endif /*__VXBOOT_BUILTIN_H__*/ diff --git a/include/vxBoot/fs/smemfs.h b/include/vxBoot/fs/smemfs.h index a71340e..0496713 100644 --- a/include/vxBoot/fs/smemfs.h +++ b/include/vxBoot/fs/smemfs.h @@ -44,8 +44,12 @@ extern struct smemfs_superblock smemfs_superblock; //--- extern struct smemfs_inode *smemfs_mount(void); -extern ssize_t smemfs_pread(struct smemfs_inode *inode, - void *buf, size_t count, off_t pos); +extern ssize_t smemfs_pread( + struct smemfs_inode const * restrict const inode, + void *buf, + size_t count, + off_t pos +); extern struct smemfs_inode *smemfs_alloc_inode(void); diff --git a/include/vxBoot/hardware.h b/include/vxBoot/hardware.h index 3aa3185..17b8285 100644 --- a/include/vxBoot/hardware.h +++ b/include/vxBoot/hardware.h @@ -1,6 +1,9 @@ #ifndef __VXBOOT_HARDWARE_H__ # define __VXBOOT_HARDWARE_H__ +#include +#include + /* define hardware information struct */ struct hwinfo { struct { @@ -9,6 +12,7 @@ struct hwinfo { uintptr_t user_addr; } physical; size_t size; + size_t available; } ram; }; @@ -17,7 +21,7 @@ struct hwinfo { //--- /* hardware_get_info() : get hardware information */ -extern void hardware_get_info(struct hwinfo * const hwinfo); +extern int hardware_get_info(struct hwinfo * const hwinfo); #endif /*__VXBOOT_HARDWARE_H__*/ diff --git a/include/vxBoot/loader.h b/include/vxBoot/loader.h index e5622c0..62e2f0d 100644 --- a/include/vxBoot/loader.h +++ b/include/vxBoot/loader.h @@ -4,6 +4,7 @@ #include #include #include "vxBoot/hardware.h" +#include "vxBoot/fs/smemfs.h" //--- // ELF struct definition @@ -114,7 +115,10 @@ struct ldimg { extern int loader_scan(void); /* loader() : try to load a ELF PIE file */ -extern int loader(struct smemfs_inode const * restrict const inode); +#define LOADER_DEFAULT 0 +#define LOADER_DUMP 1 +#define LOADER_TRACE 2 +extern int loader(struct smemfs_inode const * restrict const inode, int mode); //--- @@ -146,7 +150,7 @@ enum { }; /* loader_header_get() : get / check ELF header information */ extern int loader_header_get( - struct smemfs_inode * restrict const inode, + struct smemfs_inode const * restrict const inode, Elf32_Ehdr *hdr ); /* loader_header_check() : load and check the file header validity */ @@ -160,15 +164,16 @@ extern int loader_header_error(int errnum); // ELF image ldpers //--- enum { - ld_image_success = 0, - ld_image_size_error = -1, - ld_image_type_error = -2, - ld_image_mem_error = -3, + ld_image_success = 0, + ld_image_size_error = -1, + ld_image_type_error = -2, + ld_image_mem_error = -3, + ld_image_mem_not_available = -4, }; /* loader_image_load() : try to load the entier image data */ extern int loader_image_load( + struct smemfs_inode const * restrict const inode, struct kernel_info * restrict const info, - struct smemfs_inode * restrict const inode, Elf32_Ehdr *hdr ); extern int loader_image_error(int const errnum); diff --git a/include/vxBoot/terminal.h b/include/vxBoot/terminal.h index afb0e9e..49c6a1d 100644 --- a/include/vxBoot/terminal.h +++ b/include/vxBoot/terminal.h @@ -7,7 +7,7 @@ /* internal terminal hardcoded information */ #define TERM_PRIVATE_WATERMARK (0xdeadbeef) -#define TERM_RDBUFFER_NBLINE (32) +#define TERM_BUFFER_NB_FRAME (2) /* hardcoded font size (TODO: dynamic !) */ #ifdef FXCG50 diff --git a/src/builtin/hw.c b/src/builtin/hw.c index e80c925..5ead07f 100644 --- a/src/builtin/hw.c +++ b/src/builtin/hw.c @@ -1,42 +1,27 @@ #include "vxBoot/builtin.h" #include "vxBoot/terminal.h" +#include "vxBoot/hardware.h" -#include - -static ptrdiff_t __ram_get_size(uintptr_t start_ram) -{ - volatile uint32_t *ptr = (void*)start_ram; - volatile uint32_t *tst = (void*)start_ram; - uint32_t backup; - - - //TODO: use UTLB page size information - while (1) { - ptr = &ptr[4096]; - backup = ptr[0]; - ptr[0] = 0xdeadbeef; - if (ptr[0] == tst[0]) break; - ptr[0] = backup; - } - ptr[0] = backup; - return ((ptrdiff_t)((uintptr_t)ptr - (uintptr_t)tst)); -} /* hw_main() : hw builtin entry */ int hw_main(int argc, char **argv) { + struct hwinfo hwinfo; + //TODO handle args (void)argc; (void)argv; - uintptr_t uram = mmu_translate(0x08100000, NULL); - uintptr_t bram = uram & 0xff000000; - terminal_write("user RAM physical addr: %p\n", uram); - terminal_write("RAM physical addr: %p\n", bram); - terminal_write("RAM size: "); - uintptr_t size = __ram_get_size((uram & 0xff000000) | 0xa0000000); - terminal_write("%d bytes\n", size); - terminal_write("kernel RAM space: %d o\n", size - (uram & 0x00ffffff)); - + hardware_get_info(&hwinfo); + terminal_write( + "- user RAM physical addr: %p\n" + "- RAM physical addr: %p\n" + "- RAM size: %d\n" + "- Kernel RAM space: %d o\n", + hwinfo.ram.physical.user_addr, + hwinfo.ram.physical.origin_addr, + hwinfo.ram.size, + hwinfo.ram.available + ); return (0); } diff --git a/src/builtin/loader.c b/src/builtin/loader.c new file mode 100644 index 0000000..19b5ac9 --- /dev/null +++ b/src/builtin/loader.c @@ -0,0 +1,62 @@ +#include "vxBoot/builtin.h" +#include "vxBoot/terminal.h" +#include "vxBoot/loader.h" + +#include +#include + +int ld_main(int argc, char **argv) +{ + extern struct ldimg *kernel_img_list; + char const *path; + struct ldimg *img; + char *endptr; + int counter; + int mode; + int idx; + + if (argc >= 4) { + terminal_write( + "too much argument, ony the kernel ID is needed\n" + ); + return (84); + } + if (argc == 1) { + if (kernel_img_list == NULL) { + terminal_write( + "no kernel found in you storage memroy :(\n" + ); + return (0); + } + counter = 0; + img = kernel_img_list; + while (img != NULL) { + terminal_write("[%d] %s\n", counter, img->inode->name); + img = img->next; + counter += 1; + } + return (0); + } + path = argv[1]; + mode = LOADER_DEFAULT; + if (strcmp(argv[1], "dump") == 0) { + path = argv[2]; + mode = LOADER_DUMP; + } + if (strcmp(argv[1], "trace") == 0) { + path = argv[2]; + mode = LOADER_TRACE; + } + img = kernel_img_list; + idx = strtol(path, &endptr, 10) + 1; + if (endptr == NULL || endptr[0] != '\0') { + terminal_write("kernel ID is not valid\n"); + return (84); + } + while (img != NULL && --idx > 0) { img = img->next; } + if (img == NULL) { + terminal_write("kernel ID '%d' does not exist :(\n"); + return (84); + } + return (loader(img->inode, mode)); +} diff --git a/src/fs/smemfs/pread.c b/src/fs/smemfs/pread.c index a0de81a..9ecfb7f 100644 --- a/src/fs/smemfs/pread.c +++ b/src/fs/smemfs/pread.c @@ -17,9 +17,11 @@ struct __file_info { This function will generate the absolute path of a file because Casio's open primitive doesn't handle cannonical path */ -static void generate_absolute_path(uint16_t *pathname, - struct smemfs_inode *inode, int *pos) -{ +static void generate_absolute_path( + uint16_t *pathname, + struct smemfs_inode const * restrict const inode, + int *pos +) { if (inode == NULL) { memcpy(pathname, u"\\\\fls0", 12); *pos = 6; @@ -51,9 +53,12 @@ static void __smemfs_pread(struct __file_info *info, ssize_t *read) } /* smemfs_read(): Read primitive */ -ssize_t smemfs_pread(struct smemfs_inode *inode, - void *buf, size_t count, off_t pos) -{ +ssize_t smemfs_pread( + struct smemfs_inode const * restrict const inode, + void *buf, + size_t count, + off_t pos +) { struct __file_info file_info = { .buf = buf, .count = count, diff --git a/src/hardware/get_info.c b/src/hardware/get_info.c new file mode 100644 index 0000000..1707f07 --- /dev/null +++ b/src/hardware/get_info.c @@ -0,0 +1,37 @@ +#include "vxBoot/hardware.h" + +#include + + +/* __ram_get_size() : try to determine the RAM size */ +static ptrdiff_t __ram_get_size(uintptr_t start_ram) +{ + volatile uint32_t *ptr = (void*)start_ram; + volatile uint32_t *tst = (void*)start_ram; + uint32_t backup; + + + //TODO: use UTLB page size information to walk through each pages + while (1) { + ptr = &ptr[4096]; + backup = ptr[0]; + ptr[0] = 0xdeadbeef; + if (ptr[0] != 0xdeadbeef || ptr[0] == tst[0]) break; + ptr[0] = backup; + } + ptr[0] = backup; + return ((ptrdiff_t)((uintptr_t)ptr - (uintptr_t)tst)); +} + +/* hardware_get_info() : get hardware information */ +int hardware_get_info(struct hwinfo * const hwinfo) +{ + if (hwinfo == NULL) + return (-1); + uintptr_t uram = mmu_translate(0x08100000, NULL); + hwinfo->ram.physical.origin_addr = uram & 0xff000000; + hwinfo->ram.physical.user_addr = uram; + hwinfo->ram.size = __ram_get_size(uram | 0xa0000000); + hwinfo->ram.available = hwinfo->ram.size - (uram & 0x00ffffff); + return (0); +} diff --git a/src/loader/elf/header.c b/src/loader/elf/header.c index 9f18916..cb5ee68 100644 --- a/src/loader/elf/header.c +++ b/src/loader/elf/header.c @@ -23,7 +23,7 @@ int loader_header_error(int const errnum) /* loader_header_get(): Get ELF header and check validity */ int loader_header_get( - struct smemfs_inode * restrict const inode, + struct smemfs_inode const * restrict const inode, Elf32_Ehdr *header ) { /* try to read the ELF header */ diff --git a/src/loader/elf/image.c b/src/loader/elf/image.c index a784e96..6519579 100644 --- a/src/loader/elf/image.c +++ b/src/loader/elf/image.c @@ -10,6 +10,7 @@ const struct ld_error_db image_error_db[] = { {.id = ld_image_size_error, .strerror = "size error"}, {.id = ld_image_type_error, .strerror = "type error"}, {.id = ld_image_mem_error, .strerror = "out of memory error"}, + {.id = ld_image_mem_not_available, .strerror = "memory not available"}, {.id = 0xdeb0cad0, .strerror = NULL}, }; @@ -21,12 +22,13 @@ int loader_image_error(int const errnum) /* loader_load_image() - Load the program into Virtual Memory */ int loader_image_load( + struct smemfs_inode const * restrict const inode, struct kernel_info * restrict const kernel, - struct smemfs_inode * restrict const inode, Elf32_Ehdr *hdr ) { Elf32_Phdr program; uintptr_t paddress; + uintptr_t origin; uintptr_t vmin; uintptr_t vmax; off_t offset; @@ -54,10 +56,14 @@ int loader_image_load( kernel->memory.program.elf.vmin = vmin; kernel->memory.program.elf.vmax = vmax; - /* Allocate programe memory */ - kernel->memory.program.start = calloc(1, kernel->memory.program.size); - if (kernel->memory.program.start == NULL) - return (ld_image_mem_error); + /* check available space in RAM to load the image */ + if (kernel->memory.program.size >= kernel->hardware.ram.available) + return (ld_image_mem_not_available); + + /* set the kernel's origin address */ + origin = kernel->hardware.ram.physical.user_addr; + origin |= 0xa0000000; + kernel->memory.program.start = (void*)origin; /* Now, load all program section into physical memory. To do this, we read each program hdr, generate the "real" physical address of @@ -84,6 +90,7 @@ int loader_image_load( /* Generate program entry address */ kernel->entry = (uintptr_t)hdr->e_entry - vmin; - kernel->entry += (uintptr_t)kernel->memory.program.start; + kernel->entry += (uintptr_t)kernel->hardware.ram.physical.user_addr; + kernel->entry |= (uintptr_t)0x80000000; return (ld_image_success); } diff --git a/src/loader/entry.c b/src/loader/entry.c index 7109ba5..16dc4e0 100644 --- a/src/loader/entry.c +++ b/src/loader/entry.c @@ -3,10 +3,34 @@ #include "vxBoot/hardware.h" #include "vxBoot/loader.h" -/* loader_inode: Load a ELF programm (PIE) */ -int loader_inode(struct smemfs_inode const * restrict const inode) +#include +#include + +//#include + +#include + +static int dump_reloc(struct kernel_info *kernel) { - struct hwinfo hwinfo; + int handle; + int size; + + size = kernel->memory.program.size + 1; + BFile_Remove(u"\\\\fls0\\reloc_dump.s"); + BFile_Create(u"\\\\fls0\\reloc_dump.s", BFile_File, &size); + handle = BFile_Open(u"\\\\fls0\\reloc_dump.s", BFile_WriteOnly); + BFile_Write( + handle, + (void*)kernel->memory.program.start, + kernel->memory.program.size + ); + return (0); +} + +/* loader_inode: Load a ELF programm (PIE) */ +int loader(struct smemfs_inode const * restrict const inode, int mode) +{ + struct kernel_info kernel; Elf32_Ehdr header; int err; @@ -17,16 +41,53 @@ int loader_inode(struct smemfs_inode const * restrict const inode) terminal_write("- check header information...\n"); err = loader_header_get(inode, &header); - if (err != 0) + if (err != 0) { + loader_header_error(err); return (-2); + } - terminal_write("- fetch hardware information...\n"); - hardware_get_info(&hwinfo); + terminal_write("- generate kernel geometry...\n"); + memset(&kernel, 0x00, sizeof(struct kernel_info)); + hardware_get_info(&kernel.hardware); terminal_write("- load image...\n"); - err = loader_image_load(&hwinfo, inode, &header); - if (err != 0) + err = loader_image_load(inode, &kernel, &header); + if (err != 0) { + loader_image_error(err); return (-3); + } terminal_write("image successfully loaded !\n"); + if (mode == LOADER_DUMP) { + terminal_write( + "kernel information:\n" + "|-- kernel entry: %p\n" + "`-- memory:\n" + " `-- program:\n" + " |-- start: %p\n" + " |-- size: %do\n" + " `-- elf:\n" + " |-- vmin: %p\n" + " `-- vmax: %p\n", + kernel.entry, + kernel.memory.program.start, + kernel.memory.program.size, + kernel.memory.program.elf.vmin, + kernel.memory.program.elf.vmax + ); + gint_world_switch(GINT_CALL((void*)&dump_reloc, (void*)&kernel)); + return (0); + } +#if 0 + if (mode == LOADER_TRACE) { + struct tsession *session; + + session = tracer_create_session( + (void*)kernel.entry, + TRACER_DISASM | TRACER_CONTEXT | TRACER_HEXDUMP + ); + tracer_set_session(session); + } +#endif + gint_world_switch(GINT_CALL((void*)kernel.entry)); return (0); } diff --git a/src/main.c b/src/main.c index 9d108f6..25c6c66 100644 --- a/src/main.c +++ b/src/main.c @@ -17,7 +17,7 @@ struct { int (*f)(int argc, char **argv); } cmd_list[] = { {.name = "ls", &ls_main}, - {.name = "os", NULL}, + {.name = "ld", &ld_main}, {.name = "hw", &hw_main}, {.name = "help", &help_main}, {.name = NULL, NULL} diff --git a/src/terminal/open.c b/src/terminal/open.c index 0c7b7b3..a8c886e 100644 --- a/src/terminal/open.c +++ b/src/terminal/open.c @@ -24,21 +24,24 @@ int terminal_open(void) terminal.winsize.ws_row = DHEIGHT / terminal.winsize.ft_ypixel; terminal.buffer.size = terminal.winsize.ws_row * terminal.winsize.ws_col - * TERM_RDBUFFER_NBLINE + * TERM_BUFFER_NB_FRAME * sizeof(uint8_t); terminal.buffer.data = calloc(1, terminal.buffer.size); if (terminal.buffer.data == NULL) { terminal_close(); return (-1); } - terminal.private.timer.id = timer_configure( - TIMER_ANY, - 250000, - GINT_CALL(terminal_cursor_handler) - ); - if (terminal.private.timer.id < 0) { - terminal_close(); - return (-1); + /* workaround to disable cursor blink only in FXCG-Manager (emulator) */ + if (*(volatile uint32_t *)0xff000044 != 0x00000000) { + terminal.private.timer.id = timer_configure( + TIMER_ANY, + 250000, + GINT_CALL(terminal_cursor_handler) + ); + if (terminal.private.timer.id < 0) { + terminal_close(); + return (-1); + } } terminal.private.color.bg = C_BLACK; terminal.private.color.fg = C_WHITE; diff --git a/src/terminal/read.c b/src/terminal/read.c index 6a312f2..0738a4a 100644 --- a/src/terminal/read.c +++ b/src/terminal/read.c @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -34,6 +35,17 @@ struct { //--- void term_display_all(void) { + static int __lock = 0; + + /* ugly workaround to avoid race condition with the timer */ + cpu_atomic_start(); + if (__lock != 0) { + cpu_atomic_end(); + return; + } + __lock = 1; + cpu_atomic_end(); + /* stop the timer too avoid interrupt-loop */ if (terminal.private.timer.id >= 0) timer_pause(terminal.private.timer.id); @@ -60,6 +72,9 @@ void term_display_all(void) /* restart the timer */ if (terminal.private.timer.id >= 0) timer_start(terminal.private.timer.id); + + /* workaround end */ + __lock = 0; } //--- @@ -84,7 +99,7 @@ static void term_buffer_remove(void) if (term_rdinfo.buffer.cursor == 0) return; /* move data if needed */ - if (term_rdinfo.buffer.cursor < term_rdinfo.buffer.size - 1) { + if (term_rdinfo.buffer.cursor < (int)term_rdinfo.buffer.size - 1) { memcpy( &term_rdinfo.buffer.data[term_rdinfo.buffer.cursor - 1], &term_rdinfo.buffer.data[term_rdinfo.buffer.cursor], @@ -103,7 +118,7 @@ static int term_buffer_insert(char n) if (term_rdinfo.buffer.size + 1 >= term_rdinfo.buffer.max) return (-1); /* move data if needed */ - if (term_rdinfo.buffer.cursor < term_rdinfo.buffer.size - 1) { + if (term_rdinfo.buffer.cursor < (int)term_rdinfo.buffer.size - 1) { off_t i = term_rdinfo.buffer.size + 1; while (--i >= term_rdinfo.buffer.cursor) { term_rdinfo.buffer.data[i] = @@ -144,7 +159,7 @@ static int term_key_handle_special(key_event_t key_event) term_rdinfo.buffer.cursor -= 1; return (1); case KEY_RIGHT: - if (term_rdinfo.buffer.cursor < term_rdinfo.buffer.size - 1) + if (term_rdinfo.buffer.cursor < (int)term_rdinfo.buffer.size - 1) term_rdinfo.buffer.cursor += 1; return (1); default: @@ -216,6 +231,7 @@ int terminal_read(void *buffer, size_t nb) memset(buffer, 0x00, nb); /* save terminal information */ + term_rdinfo.cursor.visible = 1; term_rdinfo.cursor.saved = terminal.buffer.cursor; term_rdinfo.cursor.x = terminal.cursor.x; term_rdinfo.cursor.y = terminal.cursor.y; @@ -226,6 +242,8 @@ int terminal_read(void *buffer, size_t nb) /* start cursor blink timer */ if (terminal.private.timer.id >= 0) timer_start(terminal.private.timer.id); + else + term_display_all(); // force-display the cursor /* keyboard handling */ while (term_rdinfo.mode.exit == 0) { diff --git a/src/terminal/util.c b/src/terminal/util.c index 0b10883..bb3caf2 100644 --- a/src/terminal/util.c +++ b/src/terminal/util.c @@ -23,7 +23,7 @@ void terminal_buffer_insert(char *buffer, size_t nb) start = &buffer[nb - dump]; } - /* dump the buffer (be carful with the circular effect) */ + /* dump the buffer (be careful with the circular effect) */ if (terminal.buffer.cursor + dump > terminal.buffer.size) { memcpy( &terminal.buffer.data[terminal.buffer.cursor], @@ -101,7 +101,7 @@ static int terminal_line_discipline(char n) void terminal_buffer_display(void) { uint8_t *buffer; - uint16_t tmp; + char tmp[2]; int cursor; int x; int y; @@ -112,6 +112,8 @@ void terminal_buffer_display(void) terminal.cursor.x = 0; terminal.cursor.y = 0; i = terminal.buffer.cursor - 1; + if (i < 0) + i = terminal.buffer.size - 1; buffer = &terminal.buffer.data[0]; while (1) { /* decrease the cursor and avoid circular effect */ @@ -136,6 +138,7 @@ void terminal_buffer_display(void) /* Display character per character because we need to check special behaviour (like cariege return, line feed, ...) */ + tmp[1] = '\0'; terminal.cursor.x = 0; terminal.cursor.y = 0; while (1) { @@ -153,16 +156,18 @@ void terminal_buffer_display(void) x = terminal.cursor.x * terminal.winsize.ft_xpixel; y = terminal.cursor.y * terminal.winsize.ft_ypixel; if (terminal_line_discipline(buffer[i]) == 0) { - tmp = buffer[i] << 8; - dtext(x, y, terminal.private.color.fg, (void*)&tmp); + tmp[0] = buffer[i]; + dtext(x, y, terminal.private.color.fg, tmp); terminal_horizontal_update(); } if (cursor != 0) { - dline(x, + dline( + x, y + terminal.winsize.ft_ypixel, x + terminal.winsize.ft_xpixel - 2, y + terminal.winsize.ft_ypixel, - terminal.private.color.fg); + terminal.private.color.fg + ); } } }