vxGOS - v0.7.0-3 : refacto bios and board-specific sources architecture

*add*
> [vxdev]
  | [kernel] add sources handling
> [bootloader]
  | [ulib] add small as possible libc routines
  | [ulib] add calloc, memset, memcpy, free, malloc, vsnprintf

*update*
> [.nvimrc]
  | proper handle compilation flags declaration
> [scripts]
  | [checkers] add pylint checker (WIP)
  | [vxdev]
    | [cli] diable installation an uninstallation steps
    | [core] prepare kernel build support
    | [core] centralize KASLR generation
    | [bootloader] proper support libs link
    | [bootloader] proper support new board-specific architecture
    | [cmake] proper support libs
    | [cmake] disable install and uninstall steps
    | [kaslr] automatically invoke board-specific KASLR generating routine
> [bootloader]
  | [fxcg50] fragmentation BIOS primitives
  | [console] first implementation of the writing primitive
  | [console] prepare reading routine
  | [display] add some drawing primitive (dinfo, dline, dpixel)
> [vxsdk]
  | [toml] remove libc request

*fix*
> [bootloader]
  | [fxcg50] proper send argument high-level routine
This commit is contained in:
Yann MAGNIN 2023-04-27 11:42:12 +02:00
parent 74571c7882
commit ac38d420f7
45 changed files with 1396 additions and 165 deletions

39
.nvimrc
View File

@ -8,18 +8,45 @@ autocmd BufWinLeave * call clearmatches()
" indicate the compiler to use
let g:ale_asm_gcc_executable = 'sh-elf-vhex-gcc'
let g:ale_c_gcc_executable = 'sh-elf-vhex-gcc'
let g:ale_c_cc_executable = 'sh-elf-vhex-gcc'
let g:ale_c_gcc_executable = 'sh-elf-vhex-gcc'
let g:ale_c_cc_executable = 'sh-elf-vhex-gcc'
let g:ale_cpp_gcc_executable = 'sh-elf-vhex-gcc'
" Find GiteaPC include directory information
let s:_hdrflags = [
\ '-I./vxgos/bootloader/include',
\ '-I./vxgos/bootloader/boards/fxcg50/include/',
\ ]
let s:_cflags = [
\ '-DFXCG50',
\ '-std=c11',
\ '-Wall',
\ '-Wextra',
\ ]
let s:_asmflags = [
\ '-DFXCG50',
\ '-x assembler-with-cpp',
\ '-Wall',
\ '-Wextra',
\ '-m4-nofpu',
\ '-mb',
\ '-Wa,--dsp',
\ ]
" convert table into string
let s:_hdrflags = join(s:_hdrflags)
let s:_asmflags = join(s:_asmflags)
let s:_cflags = join(s:_cflags)
" Patch option
" @note
" - we setup cpp because header file is considered ad C++ file
" - we force sh-elf-vhex for assembly file only
let g:ale_asm_gcc_options = '-x assembler-with-cpp -Wall -m4-nofpu -mb -Wa,--dsp -I./vxgos/bootloader/boards/fxcg50/'
let g:ale_c_gcc_options = '-std=c11 -Wall -I./vxgos/bootloader/include/'
let g:ale_c_cc_options = '-std=c11 -Wall -I./vxgos/bootloader/include/'
let g:ale_cpp_gcc_options = '-std=c11 -Wall -I./vxgos/bootloader/include/'
let g:ale_asm_gcc_options = s:_asmflags.' '.s:_hdrflags
let g:ale_c_gcc_options = s:_cflags.' '.s:_hdrflags
let g:ale_c_cc_options = s:_cflags.' '.s:_hdrflags
let g:ale_cpp_cc_options = s:_cflags.' '.s:_hdrflags
let g:ale_cpp_gcc_options = s:_cflags.' '.s:_hdrflags
" Enable completion
let g:ale_completion_enabled = 1

View File

@ -0,0 +1,49 @@
"""
pylint - checker for vxnorm
This file does not expose an explicite VxChecker object declaration to avoid
dependencies handling, you just need to provide:
======================= ===============================================
parse_file() Parse the source file
======================= ===============================================
"""
import subprocess
#---
# Public
#---
def parse_file(checker, _, pathinfo):
""" parse the mapped file
The file is mapped using mmap() and seeked through offset 0 to avoid too
many I/O operations with classical file primitive.
@args
> checker (VxChecker) - current checker instance for this file
> mfile (mmap) - mmap instance of the file, seeked at 0
> pathname (str) - file pathname
@return
> Nothing
"""
status = subprocess.run(
['pylint', pathinfo['filepath']], capture_output=True, check=False
)
if status.returncode == 0:
return
for line in status.stdout.decode('utf8').split('\n'):
if not line:
continue
if line[0] == '*':
continue
if line[0] == '-':
break
if not (line := line.split(' ', 2)):
continue
checker.notify(
line[0].split(':', 1)[1][:-1],
f"[{line[1][:-1]}] {line[2]}",
'pylint'
)

View File

@ -4,7 +4,7 @@ Vhex kernel install script
import os
import sys
from core.cmake import cmake_install
#from core.cmake import cmake_install
__all__ = [
'install_entry'
@ -47,4 +47,5 @@ def install_entry(argv):
file=sys.stderr
)
sys.exit(84)
return cmake_install(os.environ['VXSDK_PREFIX_BUILD'], enable_verbose)
#return cmake_install(os.environ['VXSDK_PREFIX_BUILD'], enable_verbose)
return enable_verbose

View File

@ -4,7 +4,7 @@ Vhex kernel uninstall script
import os
import sys
from core.cmake import cmake_uninstall
#from core.cmake import cmake_uninstall
__all__ = [
'uninstall_entry'
@ -47,4 +47,5 @@ def uninstall_entry(argv):
file=sys.stderr
)
sys.exit(84)
return cmake_uninstall(os.environ['VXSDK_PREFIX_BUILD'], enable_verbose)
#return cmake_uninstall(os.environ['VXSDK_PREFIX_BUILD'], enable_verbose)
return enable_verbose

View File

@ -5,11 +5,14 @@ import os
import sys
from core.logger import log
from core.build.bootloader import bootloader_configure, bootloader_build
from core.build.bootloader import bootloader_configure
from core.build.kernel import kernel_configure
from core.cmake import cmake_build
from core.kaslr import kaslr_generate
from version import (
# VXGOS_OS_VERSION,
# VXGOS_KERNEL_VERSION,
VXGOS_KERNEL_VERSION,
VXGOS_BOOTLOADER_VERSION,
)
@ -63,7 +66,12 @@ class VxOSBuild():
self._prefix = {
'build' : os.environ['VXSDK_PREFIX_BUILD'],
'bootloader' : f"{self._prefix_base}/bootloader",
'kernel' : f"{self._prefix_base}/kernel",
#'kernel' : f"{self._prefix_base}/kernel",
}
self._binlist = {
'bootloader' : '',
#'kernel' : '',
#'os' : ''
}
#---
@ -96,13 +104,37 @@ class VxOSBuild():
def configure(self):
""" compile OS/kernel, bootloader and perform post-build scripts """
bootloader_configure(self, VXGOS_BOOTLOADER_VERSION)
self._binlist = {
'bootloader': bootloader_configure(self, VXGOS_BOOTLOADER_VERSION),
#'kernel' : kernel_configure(self, VXGOS_KERNEL_VERSION),
#'os' : '',
}
def build(self):
""" compile OS/kernel, bootloader and perform post-build scripts """
bootloader_path = bootloader_build(self)
""" compile OS/kernel, bootloader and perform post-build scripts
TODO
"""
binpathlist = {}
log.user("[+] compiling each OS part...")
for partname in self._binlist:
log.user(f"- {partname}...")
binpathlist[partname] = cmake_build(
partname,
f"{self.prefix['build']}/{partname}/",
self.verbose
)
blobpathlist = {}
log.user("[+] generate KASLR information...")
for bininfo in binpathlist.items():
log.user(f"- {bininfo[0]}...")
blobpathlist[bininfo[0]] = kaslr_generate(self, bininfo[1])
return self.postscript['image'](
self.prefix['build'],
bootloader_path,
blobpathlist['bootloader'],
'',
#blobpathlist['kernel'],
#blobpathlist['os']
)

View File

@ -2,20 +2,16 @@
core.build.bootloader - bootloader build abstraction
"""
import os
import sys
import glob
from core.logger import log
from core.kaslr import kaslr_generate
from core.cmake import (
cmake_generate_template,
cmake_configure,
cmake_build,
)
__all__ = [
'bootloader_configure',
'bootloader_build'
]
#---
@ -40,7 +36,7 @@ def bootloader_configure(build, version):
common_src = glob.glob(common_src, recursive=True)
log.debug(f"> common src = {common_src}")
board_src = f"{prefix}/boards/{build.target}/**/*.[csS]"
board_src = f"{prefix}/boards/{build.target}/src/**/*.[csS]"
board_src = glob.glob(board_src, recursive=True)
log.debug(f"> board src = {board_src}")
@ -56,25 +52,8 @@ def bootloader_configure(build, version):
'ldflags' : '\n '.join(os.environ['VXSDK_BUILD_LDFLAGS'].split(';')),
'cflags' : '\n '.join(os.environ['VXSDK_BUILD_CFLAGS'].split(';')),
'include' : '\n '.join(include_list),
'src' : '\n '.join(common_src + board_src)
'src' : '\n '.join(common_src + board_src),
'libs' : '\n '.join(os.environ['VXSDK_BUILD_LIBS'].split(';'))
}
cmake_generate_template(prefix, proj)
cmake_configure(prefix)
def bootloader_build(build):
""" build the bootloader
@return
> final bootloader blob (complet) path
"""
log.debug('bootloader compilation...')
binpath = f"{build.prefix['build']}/bootloader/bootloader"
log.debug('> cmake build...')
cmake_build(f"{build.prefix['build']}/bootloader/", build.verbose)
log.debug('> generate KSALR table information...')
symtab = kaslr_generate(binpath)
log.debug('> generate architecture-specific blobs...')
return build.postscript['kalsr'](binpath, symtab)
cmake_generate_template(proj, prefix)
cmake_configure(proj['name'], prefix)

View File

@ -0,0 +1,131 @@
"""
vxdev.core.build.kernel - kernel build abstraction
"""
import os
import glob
import toml
from core.logger import log
from core.cmake import (
cmake_generate_template,
cmake_configure,
)
__all__ = [
'kernel_configure',
]
#---
# Internals
#---
def _fetch_board_config(build, board_cfg_path):
""" try to find and load the board configuratio file
This routine will check the TOML boards configuration validity and return
only the 'config' section which contain most of the information needed to
fetch all kernel source files
@return
> a dictionary with all configuration information
> give up if an error is detected
"""
if not os.path.exists(board_cfg_path):
log.emergency("unable to find the kernel '{build.target}' board file")
log.debug(f"> board config = {board_cfg_path}")
board_cfg = toml.load(board_cfg_path)
if 'meta' not in board_cfg:
log.emergency(f"{build.target}: missing board 'meta' information")
if 'config' not in board_cfg:
log.emergency(f"{build.target}: missing board 'config' information")
if 'modules' not in board_cfg['config']:
log.emergency(f"{build.target}: missing board 'modules' information")
if 'drivers' not in board_cfg['config']:
log.emergency(f"{build.target}: missing board 'drivers' information")
return board_cfg['config']
def _fetch_board_sources(build, prefix):
""" fetch board specific sources files
Scan the target board source directory (<prefix>/src/) and fetch all C
and assembly file.
@return
> a list of all source file found
"""
prefix = f"{prefix}/boards/{build.target}/src"
if not os.path.exists(prefix):
return glob.glob(f"{prefix}/**/*.[csS]", recursive=True)
return []
def _fetch_common_sources(_, prefix):
""" fetch common source file
"""
return glob.glob(f"{prefix}/src/*.[csS]", recursive=False)
def _fetch_drivers_sources(build, prefix, drvlist):
""" fetch selected drivers
"""
sources = []
for drv in drvlist:
if not os.path.exists(f"{prefix}/src/drivers/{drv}"):
log.emergency(f"{build.target}: unable to find driver '{drv}'")
sources += glob.glob(
f"{prefix}/src/drivers/{drv}/**/*.[csS]",
recursive=True
)
return sources
def _fetch_modules_sources(build, prefix, modlist):
""" fetch selected kernel module
"""
sources = []
for mod in modlist:
if not os.path.exists(f"{prefix}/src/modules/{mod}"):
log.emergency(f"{build.target}: unable to find module '{mod}'")
sources += glob.glob(
f"{prefix}/src/modules/{mod}/**/*.[csS]",
recursive=True
)
return sources
#---
# Public
#---
def kernel_configure(build, version):
""" configure the kernel
TODO
"""
prefix = build.prefix['kernel']
log.debug('fetching kernel files...')
log.debug(f"> prefix = {prefix}")
board_cfg = _fetch_board_config(
build,
f"{prefix}/boards/{build.target}/board.toml"
)
sources = _fetch_board_sources(build, prefix)
sources += _fetch_common_sources(build, prefix)
sources += _fetch_drivers_sources(build, prefix, board_cfg['drivers'])
sources += _fetch_modules_sources(build, prefix, board_cfg['modules'])
log.debug("> fetched sources = {sources}")
prefix = f"{build.prefix['build']}/kernel/"
include_list = [
f"{build.prefix['kernel']}/include/",
f"{build.prefix['kernel']}/boards/{build.target}/include/"
]
proj = {
'name' : 'kernel',
'version' : version,
'linker' : f"{build.prefix['kernel']}/kernel.ld",
'ldflags' : '\n '.join(os.environ['VXSDK_BUILD_LDFLAGS'].split(';')),
'cflags' : '\n '.join(os.environ['VXSDK_BUILD_CFLAGS'].split(';')),
'include' : '\n '.join(include_list),
'src' : '\n '.join(sources),
'libs' : '\n '.join(os.environ['VXSDK_BUILD_LIBS'].split(';'))
}
cmake_generate_template(proj, prefix)
cmake_configure(proj['name'], prefix)

View File

@ -2,16 +2,15 @@
CMake abstraction
"""
import os
import sys
import subprocess
import re
from core.logger import log
__all__ = [
'cmake_generate_template',
'cmake_configure',
'cmake_build',
'cmake_install',
'cmake_uninstall',
]
#---
@ -48,15 +47,21 @@ set(VXDEV_PROJ_SOURCES
#---
add_executable({VXDEV_PROJ_NAME} ${VXDEV_PROJ_SOURCES})
target_link_libraries({VXDEV_PROJ_NAME} {VXDEV_BUILD_LIBS})
""".strip()
#---
# Pulbic
#---
def cmake_generate_template(prefix_build, proj):
""" Generate a common CMake file """
if os.path.exists(f"{prefix_build}/CMakeLists.txt"):
def cmake_generate_template(proj, prefix):
""" Generate a common CMake file
@args
> proj (dict) - project information
> prefix (str) - build prefix
"""
if os.path.exists(f"{prefix}/CMakeLists.txt"):
return
cmakefile = _CMAKE_TEMPLATE
cmakefile = re.sub('{VXDEV_PROJ_NAME}', proj['name'], cmakefile)
@ -66,63 +71,73 @@ def cmake_generate_template(prefix_build, proj):
cmakefile = re.sub('{VXDEV_BUILD_LINKER}', proj['linker'], cmakefile)
cmakefile = re.sub('{VXDEV_SOURCE_FILES}', proj['src'], cmakefile)
cmakefile = re.sub('{VXDEV_BUILD_INCLUDES}', proj['include'], cmakefile)
if not os.path.exists(prefix_build):
os.makedirs(prefix_build)
with open(f"{prefix_build}/CMakeLists.txt", 'x', encoding='ascii') as cmk:
cmakefile = re.sub('{VXDEV_BUILD_LIBS}', proj['libs'], cmakefile)
if not os.path.exists(prefix):
os.makedirs(prefix)
with open(f"{prefix}/CMakeLists.txt", 'x', encoding='ascii') as cmk:
cmk.write(cmakefile)
def cmake_configure(prefix_build):
""" Abstract cmake configuration """
def cmake_configure(name, prefix):
""" Abstract cmake configuration
@args
> name (str) - project name
> prefix (str) - build prefix
"""
toolchain_flag = ''
if toolchain_path := os.environ.get('VXSDK_HOOK_CMAKE_TOOLCHAIN'):
toolchain_flag = f"-DCMAKE_TOOLCHAIN_FILE={toolchain_path}"
shell_cmd = f"cmake {toolchain_flag} -B {prefix_build} -S {prefix_build}"
return subprocess.run(shell_cmd.split(), check=False).returncode
shell_cmd = f"cmake {toolchain_flag} -B {prefix} -S {prefix}"
if subprocess.run(shell_cmd.split(), check=False).returncode != 0:
log.emergency(f"{name}: unable to configure the projet, abord")
#def cmake_configure(prefix_build, prefix_src):
# """ Abstract cmake configuration """
# toolchain_flag = ''
# if toolchain_path := os.environ.get('VXSDK_HOOK_CMAKE_TOOLCHAIN'):
# toolchain_flag = f"-DCMAKE_TOOLCHAIN_FILE={toolchain_path}"
# shell_cmd = f"cmake {toolchain_flag} -B {prefix_build} -S {prefix_src}"
# return subprocess.run(shell_cmd.split(), check=False).returncode
def cmake_build(name, prefix, verbose):
""" Abstract cmake configuration
def cmake_build(prefix_build, verbose):
""" Abstract cmake configuration """
shell_cmd = f"cmake --build {prefix_build}"
if verbose:
shell_cmd += ' --verbose'
return subprocess.run(shell_cmd.split(), check=False).returncode
@args
> name (str) - project name
> prefix (str) - build prefix
> verbose (bool) - build verbose
def cmake_install(prefix_build, verbose):
""" Abstract cmake installation """
shell_cmd = f"cmake --install {prefix_build}"
if verbose:
shell_cmd += ' --verbose'
return subprocess.run(shell_cmd.split(), check=False).returncode
def cmake_uninstall(prefix_build, verbose):
""" Abstract cmake uninstall
Note that CMake does not offert a easy way to uninstall project, but it
generate a file which contains all installed pathname
@return
> the generated binary pathname
"""
manifile = f"{prefix_build}/install_manifest.txt"
if not os.path.exists(manifile):
print('project not installed')
return -1
shell_cmd = f"cmake --build {prefix}"
if verbose:
shell_cmd += ' --verbose'
if subprocess.run(shell_cmd.split(), check=False).returncode != 0:
log.emergency(f"{name}: unable to configure the projet, abord")
return f"{prefix}/{name}"
retcode = 0
with open(manifile, 'r', encoding='utf8') as manifest:
for pathname in manifest.readlines():
pathname = pathname.strip()
if not os.path.exists(pathname):
continue
if verbose:
print("-- Removing {pathname}")
ret = subprocess.run(f"rm {pathname}".split(), check=False)
if ret.returncode == 0:
continue
print("warning : error during removing file", file=sys.stderr)
retcode -= 1
return retcode
#def cmake_install(prefix_build, verbose):
# """ Abstract cmake installation """
# shell_cmd = f"cmake --install {prefix_build}"
# if verbose:
# shell_cmd += ' --verbose'
# return subprocess.run(shell_cmd.split(), check=False).returncode
#
#def cmake_uninstall(prefix_build, verbose):
# """ Abstract cmake uninstall
#
# Note that CMake does not offert a easy way to uninstall project, but it
# generate a file which contains all installed pathname
# """
# manifile = f"{prefix_build}/install_manifest.txt"
# if not os.path.exists(manifile):
# print('project not installed')
# return -1
#
# retcode = 0
# with open(manifile, 'r', encoding='utf8') as manifest:
# for pathname in manifest.readlines():
# pathname = pathname.strip()
# if not os.path.exists(pathname):
# continue
# if verbose:
# print("-- Removing {pathname}")
# ret = subprocess.run(f"rm {pathname}".split(), check=False)
# if ret.returncode == 0:
# continue
# print("warning : error during removing file", file=sys.stderr)
# retcode -= 1
# return retcode

View File

@ -13,8 +13,11 @@ __all__ = [
# Public
#---
def kaslr_generate(binpath):
""" generate KASLR symbols table """
def kaslr_generate(build, binpath):
""" generate KASLR symbols table
TODO
"""
ret = subprocess.run(
f"readelf -r {binpath}".split(),
capture_output=True,
@ -30,4 +33,4 @@ def kaslr_generate(binpath):
continue
log.debug(f"[{i}] {sinfo}")
symbol_table.append(sinfo)
return symbol_table
return build.postscript['kalsr'](binpath, symbol_table)

View File

@ -0,0 +1,12 @@
#include "fxcg50/asm_utils.h"
.text
!---
! Public
!---
/* _bios_dclear() (Bdisp_Fill_VRAM) : clear VRAM */
function(_bios_dclear):
mov #3, r5
syscall(0x0275)

View File

@ -0,0 +1,14 @@
#include "bootloader/bios.h"
//---
// Public
//---
/* _bios_dinfo() : get display information */
void _bios_dinfo(size_t *width, size_t *height)
{
if (width != NULL)
*width = 396;
if (height != NULL)
*height = 224;
}

View File

@ -0,0 +1,27 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "bootloader/bios.h"
//---
// Public
//---
/* _bios_dpixel() : dpixel wrapper */
void _bios_dpixel(int x, int y, int color)
{
uint16_t *vram;
__asm__ volatile (
"mov %1, r0;"
"mov %2, r1;"
"jsr @r1;"
"nop;"
"mov r0, %0"
: "=r"(vram)
: "r"(0x01e6), "r"(0x80020070)
: "pr"
);
vram[(y * 384) + x] = color;
}

View File

@ -1,19 +1,10 @@
#include "fxcg50_asm_utils.h"
#include "fxcg50/asm_utils.h"
.text
!--
!---
! Public
!--
/* _bios_dclear() (Bdisp_Fill_VRAM) : clear VRAM */
function(_bios_dclear):
mov #3, r5
syscall(0x0275)
/* _bios_udpate() (Bdisp_PutDisp_DD) : display VRAM to screen using DMA */
function(_bios_dupdate):
syscall(0x025f)
!---
/* _bios_dtext() (Bdisp_PrintMiniMini): display string */
function(_bios_dtext):

View File

@ -0,0 +1,11 @@
#include "fxcg50/asm_utils.h"
.text
!---
! Public
!---
/* _bios_udpate() (Bdisp_PutDisp_DD) : display VRAM to screen using DMA */
function(_bios_dupdate):
syscall(0x025f)

View File

@ -0,0 +1,11 @@
#include "fxcg50/asm_utils.h"
.text
!---
! Public
!---
/* _bios_free() (free) : free allocated memory */
function(_bios_free):
syscall(0x1f42)

View File

@ -0,0 +1,11 @@
#include "fxcg50/asm_utils.h"
.text
!---
! Public
!---
/* _bios_malloc() (malloc) : allocate memory */
function(_bios_malloc):
syscall(0x1f44)

View File

@ -1,4 +1,4 @@
#include "fxcg50_asm_utils.h"
#include "fxcg50/asm_utils.h"
.section .bootloader.pre_text, "ax"

View File

@ -1,4 +1,4 @@
#include "fxcg50_asm_utils.h"
#include "fxcg50/asm_utils.h"
.section .bootloader.text, "ax"
@ -77,9 +77,12 @@ setup_stack:
! TODO : stack canary
bootloader_c_invokation:
mov.l p2_addr_base, r2
mov ram_reloc_base, r4
mov image_size, r5
mov.l bootloader_main, r0
jsr @r0
nop
or r2, r4
! ---
! bootloader panic

View File

@ -1,13 +1,28 @@
#ifndef BOOTLOADER_BIOS_H
#define BOOTLOADER_BIOS_H 1
#include <stdint.h>
#include <stddef.h>
/* _bios_dinfo() : get display information */
extern void _bios_dinfo(size_t *width, size_t *height);
/* _bios_dclear() : clear VRAM */
extern void _bios_dclear(int color);
/* _bios_dtext() : draw raw text */
extern void _bios_dtext(int x, int y, int color, char *text);
/* _bios_dpixel() : draw pixel */
extern void _bios_dpixel(int x, int y, int color);
/* _bios_dudpate() : display VRAM to screen */
extern void _bios_dupdate(void);
/* _bios_free() : free allocated memory */
extern void _bios_free(void *ptr);
/* _bios_malloc() : memory allocator */
extern void *_bios_malloc(size_t size);
#endif /* BOOTLOADER_BIOS_H */

View File

@ -1,19 +1,82 @@
#ifndef BOOTLOADER_CONSOLE_H
#define BOOTLOADER_CONSOLE_H 1
/* struct console : */
struct console {
int a;
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <stdarg.h>
//---
// macros
//---
/* internal terminal hardcoded information */
#define TERM_BUFFER_NB_FRAME (2)
//---
// Types
//---
/* define console structure */
struct console
{
/* windows information */
struct {
unsigned short ws_col;
unsigned short ws_row;
unsigned short ws_xpixel;
unsigned short ws_ypixel;
unsigned short ft_xpixel;
unsigned short ft_ypixel;
} winsize;
/* cursor information */
struct {
unsigned short x;
unsigned short y;
} cursor;
/* buffer information */
struct {
uint8_t *data;
off_t cursor;
size_t size;
} buffer;
/* private information */
struct {
uint32_t watermark;
struct {
int fg;
int bg;
} color;
} _private;
};
//---
// Public API
//---
/* console_clear() : clear the console information */
extern void console_init(struct console *console);
/* console_open() : open console */
extern int console_open(struct console *console);
/* console_write() : printf-like write primitive (support line discipline) */
extern void console_write(struct console *console, char *format, ...);
extern int console_write(struct console *console, char const *format, ...);
/* console_vwrite() : printf wrapper for the terminal device with va_list */
extern int console_vwrite(struct console *console, const char *f, va_list ap);
/* console_close() : close console */
extern int console_close(struct console *console);
//---
// Low-level API
//---
/* console_buffer_insert() : insert string anywhere in the output buffer */
extern int console_buffer_insert(struct console *console, char *b, size_t nb);
/* console_buffer_write() : display the buffer on screen */
extern int console_buffer_display(struct console *console);
#endif /* BOOTLOADER_CONSOLE_H */

View File

@ -1,7 +1,31 @@
#ifndef BOOTLOADER_DISPLAY_H
#define BOOTLOADER_DISPLAY_H 1
#include <stdint.h>
#include <stddef.h>
/* color alias */
#define C_WHITE 0x0000
#define C_BLACK 0xffff
/* hardcoded font size (TODO: dynamic !) */
//#ifdef FXCG50
#define FWIDTH 10
#define FHEIGHT 11
#define DWIDTH 396
#define DHEIGHT 224
//#endif
//#ifdef FX9860G
//#define FWIDTH 3
//#define FHEIGHT 5
//#endif
//---
// Public API
//---
/* dinfo() : get display information */
extern void dinfo(size_t *width, size_t *height);
/* dclear() : clear VRAM with unified color */
extern void dclear(int color);
@ -12,6 +36,12 @@ extern void dtext(int x, int y, int color, char *text);
/* dprint() : printf-like dtext() */
extern void dprint(int x, int y, int color, char *format, ...);
/* dline() : display line */
extern void dline(int x0, int y0, int x1, int y1, int color);
/* dpixel() : draw pixel */
extern void dpixel(int x, int y, int color);
/* dupdate() : update VRAM to screen */
extern void dupdate(void);

View File

@ -0,0 +1,186 @@
#include <string.h>
#include "bootloader/console.h"
#include "bootloader/display.h"
//---
// Update the internal buffer
//---
/* console_buffer_insert() : insert string anywhere in the output buffer */
int console_buffer_insert(struct console *console, char *buffer, size_t nb)
{
size_t dump;
void *start;
/* check error */
if (console == NULL)
return -1;
/* calculate the "real" number of byte to dump into the buffer */
dump = nb;
start = &buffer[0];
if (dump > console->buffer.size) {
dump -= console->buffer.size;
start = &buffer[nb - dump];
}
/* dump the buffer (be careful with the circular effect) */
if (console->buffer.cursor + dump > console->buffer.size)
{
memcpy(
&console->buffer.data[console->buffer.cursor],
start,
console->buffer.size - console->buffer.cursor
);
dump -= console->buffer.size - console->buffer.cursor;
console->buffer.cursor = 0;
}
memcpy(&console->buffer.data[console->buffer.cursor], start, dump);
console->buffer.cursor += dump;
return 0;
}
//---
// Display the internal buffer
//---
/* console_vertical_update() - Update vertical cursor */
static void console_vertical_update(struct console *console)
{
if (console->cursor.y + 1 < console->winsize.ws_col) {
console->cursor.y = console->cursor.y + 1;
return;
}
}
/* console_horizontal_update() - Update horizotal cursor */
static int console_horizontal_update(struct console *console)
{
console->cursor.x = console->cursor.x + 1;
if (console->cursor.x >= console->winsize.ws_col)
{
console_vertical_update(console);
console->cursor.x = 0;
return 1;
}
return 0;
}
/* console_line_discipline() - Check "special" char */
static int console_line_discipline(struct console *console, char n)
{
int offset;
switch (n)
{
case '\0':
return 1;
case '\n':
console->cursor.x = 0;
console_vertical_update(console);
return 1;
case '\b':
if (console->cursor.x > 0)
console->cursor.x = console->cursor.x - 1;
return 1;
case '\v':
console_vertical_update(console);
return 1;
case '\r':
console->cursor.x = 0;
return 1;
case '\t':
/* Check if we need a new line or not. */
offset = console->cursor.x - ((console->cursor.x / 5) * 5);
offset = 5 - offset;
while (--offset >= 0)
console_horizontal_update(console);
return 1;
default:
return 0;
}
}
/* console_buffer_write() : display the buffer on screen */
int console_buffer_display(struct console *console)
{
uint8_t *buffer;
char tmp[2];
int cursor;
int x;
int y;
int i;
/* check obvious error */
if (console == NULL)
return -1;
/* Due to potential special char, we sould find the "real" starting
index for the internal buffer */
console->cursor.x = 0;
console->cursor.y = 0;
i = console->buffer.cursor - 1;
if (i < 0)
i = console->buffer.size - 1;
buffer = &console->buffer.data[0];
while (1)
{
/* decrease the cursor and avoid circular effect */
if (--i < 0)
i = console->buffer.size - 1;
/* check loop condition */
if (i == (int)console->buffer.cursor)
break;
if (buffer[i] == '\0') {
break;
}
/* handle the character (only to force update cursors) */
if (console_line_discipline(console, buffer[i] & 0x7f) == 0)
console_horizontal_update(console);
if (console->cursor.y >= console->winsize.ws_row)
break;
}
/* Display character per character because we need to check special
behaviour (like cariege return, line feed, ...) */
tmp[1] = '\0';
console->cursor.x = 0;
console->cursor.y = 0;
while (1)
{
/* update the index */
if (++i >= (int)console->buffer.size)
i = 0;
if (i == (int)console->buffer.cursor)
break;
/* get the cursor and remove the potential cursor marker */
cursor = ((buffer[i] & 0x80) != 0);
buffer[i] &= 0x7f;
/* display part (character + cursor if needed) */
x = console->cursor.x * console->winsize.ft_xpixel;
y = console->cursor.y * console->winsize.ft_ypixel;
if (console_line_discipline(console, buffer[i]) == 0)
{
tmp[0] = buffer[i];
dtext(x, y, console->_private.color.fg, tmp);
console_horizontal_update(console);
}
if (cursor != 0)
{
dline(
x,
y + console->winsize.ft_ypixel,
x + console->winsize.ft_xpixel - 2,
y + console->winsize.ft_ypixel,
console->_private.color.fg
);
}
}
return 0;
}

View File

@ -0,0 +1,17 @@
#include <stdlib.h>
#include "bootloader/console.h"
//---
// Public
//---
/* console_close(): Uninitialize the terminal */
int console_close(struct console *console)
{
if (console == NULL)
return -1;
if (console->buffer.data != NULL)
free(console->buffer.data);
return 0;
}

View File

@ -0,0 +1,39 @@
#include <string.h>
#include <stdlib.h>
#include "bootloader/console.h"
#include "bootloader/display.h"
//---
// Public
//---
/* console_open(): Initialize and open the terminal */
int console_open(struct console *console)
{
if (console == NULL)
return -1;
memset(console, 0x00, sizeof(struct console));
console->winsize.ws_xpixel = DWIDTH;
console->winsize.ws_ypixel = DHEIGHT;
console->winsize.ft_xpixel = FWIDTH + 1;
console->winsize.ft_ypixel = FHEIGHT + 1;
console->winsize.ws_col = DWIDTH / console->winsize.ft_xpixel;
console->winsize.ws_row = DHEIGHT / console->winsize.ft_ypixel;
console->buffer.size = console->winsize.ws_row;
console->buffer.size *= console->winsize.ws_col;
console->buffer.size *= TERM_BUFFER_NB_FRAME;
console->buffer.size *= sizeof(uint8_t);
console->buffer.data = calloc(sizeof(char), console->buffer.size);
if (console->buffer.data == NULL) {
console_close(console);
return -2;
}
console->_private.color.bg = C_BLACK;
console->_private.color.fg = C_WHITE;
return 0;
}

View File

@ -0,0 +1,235 @@
#if 0
#include <string.h>
#include "bootloader/console.h"
//---
// Internals
//---
/* internal structure used to store many information */
struct {
struct {
unsigned short x;
unsigned short y;
int visible;
off_t saved;
} cursor;
struct {
uint8_t alpha: 1;
uint8_t shift: 1;
uint8_t ctrl: 1;
uint8_t exit: 1;
uint8_t const: 4;
} mode;
struct {
size_t max;
size_t size;
off_t cursor;
char *data;
} buffer;
} term_rdinfo;
//---
// Display
//---
/* term_display_all() : display all*/
void term_display_all(void)
{
/* mark special characte that the cursor is here */
if (term_rdinfo.cursor.visible == 1)
term_rdinfo.buffer.data[term_rdinfo.buffer.cursor] |= 0x80;
/* restore terminal context */
terminal.cursor.x = term_rdinfo.cursor.x;
terminal.cursor.y = term_rdinfo.cursor.y;
terminal.buffer.cursor = term_rdinfo.cursor.saved;
terminal_buffer_insert(
term_rdinfo.buffer.data,
term_rdinfo.buffer.size
);
/* display management */
dclear(terminal.private.color.bg);
terminal_buffer_display();
dupdate();
/* remove cursor mark */
term_rdinfo.buffer.data[term_rdinfo.buffer.cursor] &= ~0x80;
}
//---
// buffer functions
//---
/* term_buffer_remove(): Remove character based on current cursor position */
static void term_buffer_remove(void)
{
/* check if this action is possible */
if (term_rdinfo.buffer.cursor == 0)
return;
/* move data if needed */
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],
term_rdinfo.buffer.size - term_rdinfo.buffer.cursor
);
}
/* force NULL-char and update cursor/size */
term_rdinfo.buffer.cursor = term_rdinfo.buffer.cursor - 1;
term_rdinfo.buffer.data[--term_rdinfo.buffer.size - 1] = '\0';
}
/* term_buffer_insert() - Insert character based on current cursor position */
static int term_buffer_insert(char n)
{
/* save space for the "\n\0" (EOL) */
if (term_rdinfo.buffer.size + 1 >= term_rdinfo.buffer.max)
return -1;
/* move data if needed */
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] = term_rdinfo.buffer.data[i - 1];
}
}
/* insert the character and force NULL-char */
term_rdinfo.buffer.data[term_rdinfo.buffer.cursor++] = n;
term_rdinfo.buffer.data[++term_rdinfo.buffer.size] = '\0';
return 0;
}
//---
// key handling
//---
// TODO
// - F_UP -> history
// - F_DOWN -> history
static int term_key_handle_special(key_event_t key_event)
{
switch (key_event.key)
{
case KEY_SHIFT:
term_rdinfo.mode.shift ^= 1;
return 1;
case KEY_ALPHA:
term_rdinfo.mode.alpha ^= 1;
return 1;
case KEY_OPTN:
term_rdinfo.mode.ctrl ^= 1;
return 1;
case KEY_DOT:
term_buffer_insert(' ');
return 1;
case KEY_DEL:
term_buffer_remove();
return 1;
case KEY_EXE:
/* Add End Of Line character */
term_rdinfo.buffer.data[term_rdinfo.buffer.size - 1] = '\n';
term_rdinfo.buffer.data[term_rdinfo.buffer.size] = '\0';
/* indicate that the EXE key has been pressed. */
term_rdinfo.mode.exit = 1;
return 1;
case KEY_LEFT:
if (term_rdinfo.buffer.cursor > 0)
term_rdinfo.buffer.cursor -= 1;
return 1;
case KEY_RIGHT:
if (term_rdinfo.buffer.cursor < (int)term_rdinfo.buffer.size - 1)
term_rdinfo.buffer.cursor += 1;
return 1;
default:
return 0;
}
}
/* term_buffer_update(): Update the internal buffer with the given key code */
static int term_key_buffer_update(key_event_t key_event)
{
static const uint8_t keylist_alpha[] = {
KEY_XOT, KEY_LOG, KEY_LN, KEY_SIN, KEY_COS, KEY_TAN,
KEY_FRAC, KEY_FD, KEY_LEFTP, KEY_RIGHTP, KEY_COMMA, KEY_ARROW,
KEY_7, KEY_8, KEY_9,
KEY_4, KEY_5, KEY_6, KEY_MUL, KEY_DIV,
KEY_1, KEY_2, KEY_3, KEY_PLUS, KEY_MINUS,
KEY_0, 0xff
};
static const uint8_t keylist_num[] = {
KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
KEY_5, KEY_6, KEY_7, KEY_8, KEY_9,
KEY_PLUS, KEY_MINUS, KEY_MUL, KEY_DIV,
KEY_LEFTP, KEY_RIGHTP, KEY_COMMA, KEY_POWER,
KEY_DOT, KEY_FD, KEY_ARROW, 0xff
};
static const char keylist_num_char[] = "0123456789+-x/(),^.|_";
const uint8_t *keycode_list;
char character;
int i;
/* Get the appropriate key list. */
keycode_list = keylist_alpha;
if (term_rdinfo.mode.shift == 1)
keycode_list = keylist_num;
/* Try to find the pressed key. */
i = -1;
while (keycode_list[++i] != 0xff && keycode_list[i] != key_event.key);
if (keycode_list[i] != key_event.key)
return 0;
/* handle mode then update the buffer */
if (term_rdinfo.mode.shift == 0) {
character = 'a' + i;
if (term_rdinfo.mode.alpha == 1)
character = 'A' + i;;
} else {
character = keylist_num_char[i];
}
term_buffer_insert(character);
return 1;
}
//---
// primitive
//---
/* */
int console_read(struct console *console, void *buffer, size_t nb)
{
key_event_t key;
/* check obvious error */
if (buffer == NULL || nb == 0)
return 0;
/* initialize internal data */
memset(&term_rdinfo, 0x00, sizeof(term_rdinfo));
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;
term_rdinfo.buffer.data = buffer;
term_rdinfo.buffer.size = 1;
term_rdinfo.buffer.max = nb;
/* keyboard handling */
while (term_rdinfo.mode.exit == 0)
{
/* handle pressed keys */
key = getkey_opt(GETKEY_REP_ALL | GETKEY_MENU, NULL);
if (term_key_handle_special(key) == 0)
term_key_buffer_update(key);
/* display */
term_display_all();
}
return term_rdinfo.buffer.size;
}
#endif

View File

@ -0,0 +1,41 @@
#include <stdarg.h>
#include <stdio.h>
#include "bootloader/console.h"
#include "bootloader/display.h"
//---
// Public
//---
/* console_vwrite() : printf wrapper for the terminal device with va_list */
int console_vwrite(struct console *console, const char *format, va_list ap)
{
char buffer[1024];
int nb;
/* process the format */
nb = vsnprintf(buffer, 1024, format, ap);
/* update the internal buffer */
console_buffer_insert(console, buffer, nb);
/* display the internal buffer */
dclear(console->_private.color.bg);
console_buffer_display(console);
dupdate();
return nb;
}
/* console_write() - printf wrapper for the terminal device */
int console_write(struct console *console, char const *format, ...)
{
va_list ap;
int nb;
va_start(ap, format);
nb = console_vwrite(console, format, ap);
va_end(ap);
return nb;
}

View File

@ -0,0 +1,12 @@
#include "bootloader/display.h"
#include "bootloader/bios.h"
//---
// Public
//---
/* dclear() : clear VRAM with unified color */
void dclear(int color)
{
_bios_dclear(color);
}

View File

@ -0,0 +1,15 @@
#include <stdint.h>
#include <stddef.h>
#include "bootloader/display.h"
#include "bootloader/bios.h"
//---
// Public
//---
/* dinfo() : get display information */
void dinfo(size_t *width, size_t *height)
{
_bios_dinfo(width, height);
}

View File

@ -0,0 +1,64 @@
#include <bootloader/display.h>
#include <bootloader/bios.h>
/* sgn() (without double evaluation) */
#define sgn(s) ({ \
__auto_type _s = (s); \
_s < 0 ? -1 : \
_s > 0 ? +1 : \
0; \
})
//---
// Public
//---
/* dline() : draw line */
void dline(int x1, int y1, int x2, int y2, int color)
{
int i;
int cumul;
int x = x1;
int y = y1;
int dx = x2 - x1;
int dy = y2 - y1;
int sx = sgn(dx);
int sy = sgn(dy);
dx = (dx >= 0 ? dx : -dx);
dy = (dy >= 0 ? dy : -dy);
dpixel(x1, y1, color);
if(dx >= dy)
{
/* Start with a non-zero cumul to even the overdue between the
two ends of the line (for more regularity) */
cumul = dx >> 1;
for(i = 1; i < dx; i++)
{
x += sx;
cumul += dy;
if(cumul > dx) {
cumul -= dx;
y += sy;
}
dpixel(x, y, color);
}
} else {
cumul = dy >> 1;
for(i = 1; i < dy; i++)
{
y += sy;
cumul += dx;
if(cumul > dy) {
cumul -= dy;
x += sx;
}
dpixel(x, y, color);
}
}
dpixel(x2, y2, color);
}
#undef sgn

View File

@ -0,0 +1,12 @@
#include "bootloader/display.h"
#include "bootloader/bios.h"
//---
// Public
//---
/* dpixel() : draw pixel */
void dpixel(int x, int y, int color)
{
_bios_dpixel(x, y, color);
}

View File

@ -1,25 +1,14 @@
#include <stdio.h>
#include <stdarg.h>
#include <alloca.h>
#include <stdio.h>
#include <bootloader/display.h>
#include <bootloader/bios.h>
#include "bootloader/display.h"
#include "bootloader/bios.h"
//---
// Public
//---
/* dclear() : clear VRAM with unified color */
void dclear(int color)
{
_bios_dclear(color);
}
/*dtext() : display raw text to VRAM */
void dtext(int x, int y, int color, char *text)
{
_bios_dtext(x, y, color, text);
}
/* dprint() : printf-like dtext() */
void dprint(int x, int y, int color, char *format, ...)
{
@ -37,8 +26,4 @@ void dprint(int x, int y, int color, char *format, ...)
_bios_dtext(x, y, color, buffer);
}
/* dupdate() : update VRAM to screen */
void dupdate(void)
{
_bios_dupdate();
}

View File

@ -0,0 +1,12 @@
#include "bootloader/display.h"
#include "bootloader/bios.h"
//---
// Public
//---
/*dtext() : display raw text to VRAM */
void dtext(int x, int y, int color, char *text)
{
_bios_dtext(x, y, color, text);
}

View File

@ -0,0 +1,12 @@
#include "bootloader/display.h"
#include "bootloader/bios.h"
//---
// Public
//---
/* dupdate() : update VRAM to screen */
void dupdate(void)
{
_bios_dupdate();
}

View File

@ -14,7 +14,7 @@ int bootloader_main(uintptr_t image_base_addr, size_t image_size)
//TODO : check special key pressed, if not simply boot the kernel
console_init(&console);
console_open(&console);
console_write(
&console,
"vxGOS bootloader entry\n"

View File

@ -1,6 +0,0 @@
int bootloader_c_test(void)
{
while (1);
}

View File

@ -0,0 +1,21 @@
#include <stdlib.h>
#include <string.h>
//---
// Public
//---
/* calloc() : malloc + memset */
void *calloc(size_t nmemb, size_t size)
{
unsigned int total_size;
void *mem;
if(__builtin_umul_overflow(nmemb, size, &total_size))
return NULL;
mem = malloc(total_size);
if(mem != NULL)
memset(mem, 0, total_size);
return mem;
}

View File

@ -0,0 +1,11 @@
#include "bootloader/bios.h"
//---
// Public
//---
/* free() : free allocated memory */
void free(void *ptr)
{
return _bios_free(ptr);
}

View File

@ -0,0 +1,13 @@
#include <stdlib.h>
#include "bootloader/bios.h"
//---
// Public
//---
/* malloc() : memory allocator */
void *malloc(size_t size)
{
return _bios_malloc(size);
}

View File

@ -0,0 +1,14 @@
#include <stdint.h>
#include <stddef.h>
//---
// Public
//---
/* memcpy() : copy memory arena */
void *memcpy(void *dest, const void *src, size_t count)
{
for (size_t i = 0; i < count; i = i + 1)
((uint8_t *) dest)[i] = ((uint8_t *) src)[i];
return dest;
}

View File

@ -0,0 +1,14 @@
#include <stdint.h>
#include <stddef.h>
//---
// Public
//---
/* memset() : wipe arena */
void *memset(void *s, int c, size_t n)
{
while ((int)--n >= 0)
((uint8_t *) s)[n] = c;
return s;
}

View File

@ -0,0 +1,113 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
//---
// Internals
//---
struct __snprintf_core
{
uintptr_t buffer;
uintptr_t buffer_saved;
size_t buffer_size;
};
/* __buffer_update() : inject one char if possible */
static int __buffer_inj_char(struct __snprintf_core *core, char c)
{
((char*)core->buffer)[0] = c;
core->buffer += 1;
((char*)core->buffer)[0] = '\0';
if ((core->buffer - core->buffer_saved) < core->buffer_size - 1)
return 0;
return -1;
}
/* __buffer_inj_ptr() : inject ptr */
static int __buffer_inj_ptr(struct __snprintf_core *core, uintptr_t ptr)
{
static char const * const table = "0123456789abcdef";
if (
__buffer_inj_char(core, '0') != 0
|| __buffer_inj_char(core, 'x') != 0
|| __buffer_inj_char(core, table[(ptr & 0xf0000000) >> 28]) != 0
|| __buffer_inj_char(core, table[(ptr & 0x0f000000) >> 24]) != 0
|| __buffer_inj_char(core, table[(ptr & 0x00f00000) >> 20]) != 0
|| __buffer_inj_char(core, table[(ptr & 0x000f0000) >> 16]) != 0
|| __buffer_inj_char(core, table[(ptr & 0x0000f000) >> 12]) != 0
|| __buffer_inj_char(core, table[(ptr & 0x00000f00) >> 8]) != 0
|| __buffer_inj_char(core, table[(ptr & 0x000000f0) >> 4]) != 0
|| __buffer_inj_char(core, table[(ptr & 0x0000000f) >> 0]) != 0
) {
return -1;
}
return 0;
}
/* __buffer_inj_digit() : inject number */
static int __buffer_inj_digit(struct __snprintf_core *core, int nb, bool patch)
{
if (patch && nb == 0)
return 0;
if (__buffer_inj_digit(core, nb / 10, true) != 0)
return -1;
return __buffer_inj_char(core, (nb % 10) + '0');
}
//---
// Public
//---
/* vsnprintf() : snprintf-like function */
int vsnprintf(char *buffer, size_t sz, char const *format, va_list ap)
{
struct __snprintf_core core;
int exit;
core.buffer = (uintptr_t)buffer;
core.buffer_saved = (uintptr_t)buffer;
core.buffer_size = sz;
exit = 0;
while (format[0] != '\0' && exit == 0)
{
if (format[0] != '%') {
exit = __buffer_inj_char(&core, format[0]);
format = &format[1];
continue;
}
switch (format[1])
{
case '\0':
exit = __buffer_inj_char(&core, '%') - 10;
break;
case '%':
exit = __buffer_inj_char(&core, '%');
break;
case 'p':
exit = __buffer_inj_ptr(&core, va_arg(ap, uintptr_t));
break;
case 'd':
exit = __buffer_inj_digit(&core, va_arg(ap, int), false);
break;
}
format = &format[2];
}
return (core.buffer - core.buffer_saved);
}
/* snprintf() : snprintf-like function */
int snprintf(char *buffer, size_t sz, char const *format, ...)
{
va_list ap;
int n;
va_start(ap, format);
n = vsnprintf(buffer, sz, format, ap);
va_end(ap);
return n;
}

View File

@ -1,6 +1,6 @@
#define ASM_SOURCE
#include <vhex/hardware.h>
#include "boards/fxcg50/include/hardware.h"
#include "fxcg50/hardware.h"
.text
.global _sh7305_inth_callback
@ -97,5 +97,3 @@ _sh7305_inth_callback:
.long (0xf << 4)
.vhex:
.long _vhex

View File

@ -9,7 +9,7 @@ target = [
[build]
#configure = './vxdev configure'
build = '/usr/bin/env python3 ./scripts/vxdev build --verbose'
build = '/usr/bin/env python3 ./scripts/vxdev build'
#install = '/usr/bin/env python3 ./scripts/vxdev install'
#uninstall = '/usr/bin/env python3 ./scripts/vxdev uninstall'
@ -37,25 +37,22 @@ assets_prefix = [
# '-fstack-protector-all',
]
VXSDK_PRIVATE_BUILD_LDFLAGS = [
'-static',
'-Wl,-Map=map',
'-Wl,--build-id=none',
'-Wl,--emit-relocs',
]
VXSDK_PUBLIC_BUILD_LIBS = [
VXSDK_PRIVATE_BUILD_LIBS = [
'@COMMON@',
'-Wl,--whole-archive',
'-lvxkernel',
'-Wl,--no-whole-archive',
'@sh-elf-vhex@',
'-lc',
# '-lc',
'-lgcc',
'-lssp_nonshared',
]
VXSDK_PUBLIC_BUILD_LDFLAGS = [
'-T {VXSDK_CURRENT_SOURCE_DIR}/boards/fxcg50/fxcg50.ld',
'-static',
'-Wl,-q'
]
# VXSDK_PUBLIC_BUILD_LDFLAGS = [
# '-T {VXSDK_CURRENT_SOURCE_DIR}/boards/fxcg50/fxcg50.ld',
# '-static',
# '-Wl,-q'
# ]
[sdl2]
[sdl2.env]