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
This commit is contained in:
parent
d4d9c68005
commit
f90c07132a
|
@ -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()
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef __VXBOOT_HARDWARE_H__
|
||||
# define __VXBOOT_HARDWARE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* 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__*/
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,42 +1,27 @@
|
|||
#include "vxBoot/builtin.h"
|
||||
#include "vxBoot/terminal.h"
|
||||
#include "vxBoot/hardware.h"
|
||||
|
||||
#include <gint/mmu.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
#include "vxBoot/builtin.h"
|
||||
#include "vxBoot/terminal.h"
|
||||
#include "vxBoot/loader.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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));
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#include "vxBoot/hardware.h"
|
||||
|
||||
#include <gint/mmu.h>
|
||||
|
||||
|
||||
/* __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);
|
||||
}
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 <gint/gint.h>
|
||||
#include <gint/bfile.h>
|
||||
|
||||
//#include <gintrace/tracer.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <gint/keyboard.h>
|
||||
#include <gint/display.h>
|
||||
#include <gint/timer.h>
|
||||
#include <gint/cpu.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue