Compare commits
17 Commits
97facbed6f
...
54d5d9dca7
| Author | SHA1 | Date | |
|---|---|---|---|
| 54d5d9dca7 | |||
| 82b3c597f1 | |||
| 000cb5c35d | |||
| 616ad0d0cc | |||
| 4b917550f4 | |||
| a4ca7058d1 | |||
| e492ac7974 | |||
| 9af325cdee | |||
| 5888136db7 | |||
| 2dc68a33ab | |||
| 1b7c3b1b0d | |||
| b773439aa1 | |||
| d47260dd13 | |||
| c9a87457b8 | |||
| 474f228c98 | |||
| 64dd5d15a8 | |||
| 277d87adb0 |
@@ -7,3 +7,6 @@
|
|||||||
[submodule "lib/libfx"]
|
[submodule "lib/libfx"]
|
||||||
path = lib/libfx
|
path = lib/libfx
|
||||||
url = https://g.wash.red/wash/fx.git
|
url = https://g.wash.red/wash/fx.git
|
||||||
|
[submodule "programs/bshell"]
|
||||||
|
path = programs/bshell
|
||||||
|
url = https://g.wash.red/wash/bshell.git
|
||||||
|
|||||||
+1
-1
@@ -16,6 +16,7 @@ include(BSP)
|
|||||||
include(Arch)
|
include(Arch)
|
||||||
include(Msg-Interface)
|
include(Msg-Interface)
|
||||||
include(Templates)
|
include(Templates)
|
||||||
|
include(Service)
|
||||||
|
|
||||||
bsp_reset()
|
bsp_reset()
|
||||||
sysroot_reset()
|
sysroot_reset()
|
||||||
@@ -28,7 +29,6 @@ add_subdirectory(interface)
|
|||||||
add_subdirectory(sys)
|
add_subdirectory(sys)
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
add_subdirectory(services)
|
add_subdirectory(services)
|
||||||
add_subdirectory(runlevel)
|
|
||||||
add_subdirectory(programs)
|
add_subdirectory(programs)
|
||||||
|
|
||||||
sysroot_add_program(NAME ${kernel_name} BIN_DIR /boot)
|
sysroot_add_program(NAME ${kernel_name} BIN_DIR /boot)
|
||||||
|
|||||||
+29
-5
@@ -115,19 +115,43 @@ function(bsp_add_service)
|
|||||||
|
|
||||||
get_property(bsp_targets GLOBAL PROPERTY bsp_target_list)
|
get_property(bsp_targets GLOBAL PROPERTY bsp_target_list)
|
||||||
get_property(cfg_file TARGET ${arg_NAME} PROPERTY service_cfg_path)
|
get_property(cfg_file TARGET ${arg_NAME} PROPERTY service_cfg_path)
|
||||||
|
get_property(file_list TARGET ${arg_NAME} PROPERTY service_file_list)
|
||||||
|
get_property(target_type TARGET ${arg_NAME} PROPERTY TYPE)
|
||||||
|
|
||||||
list(LENGTH bsp_targets nr_bsp_targets)
|
list(LENGTH bsp_targets nr_bsp_targets)
|
||||||
|
list(LENGTH file_list nr_service_files)
|
||||||
if (${nr_bsp_targets} GREATER 0)
|
if (${nr_bsp_targets} GREATER 0)
|
||||||
math(EXPR serialiser_index "${nr_bsp_targets}-1")
|
math(EXPR serialiser_index "${nr_bsp_targets}-1")
|
||||||
list(GET bsp_targets ${serialiser_index} serialiser)
|
list(GET bsp_targets ${serialiser_index} serialiser)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_custom_target(${bsp_target_name}
|
set(commands
|
||||||
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
|
|
||||||
add-binary ${bsp_manifest} ${target_name}
|
|
||||||
${arg_BIN_DIR} $<TARGET_FILE:${target_name}>
|
|
||||||
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
|
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
|
||||||
add-binary ${bsp_manifest} ${target_name}-cfg
|
add-binary ${bsp_manifest} ${target_name}-cfg
|
||||||
${arg_SVC_DIR} ${cfg_file}
|
${arg_SVC_DIR} ${cfg_file})
|
||||||
|
|
||||||
|
if (target_type STREQUAL "EXECUTABLE")
|
||||||
|
set(commands ${commands}
|
||||||
|
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
|
||||||
|
add-binary ${bsp_manifest} ${target_name}
|
||||||
|
${arg_BIN_DIR} $<TARGET_FILE:${target_name}>)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (nr_service_files GREATER 0)
|
||||||
|
math(EXPR nr_service_files "${nr_service_files}-1")
|
||||||
|
foreach (i RANGE 0 ${nr_service_files} 2)
|
||||||
|
math(EXPR i2 "${i}+1")
|
||||||
|
list(GET file_list ${i} src_file)
|
||||||
|
list(GET file_list ${i2} dest_dir)
|
||||||
|
set(commands ${commands}
|
||||||
|
COMMAND ${Python_EXECUTABLE} ${bsp_tool}
|
||||||
|
add-binary ${bsp_manifest} ${target_name}-${i}
|
||||||
|
${dest_dir} ${src_file})
|
||||||
|
endforeach (i)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_custom_target(${bsp_target_name}
|
||||||
|
${commands}
|
||||||
COMMENT "Preparing bsp component: ${target_name}"
|
COMMENT "Preparing bsp component: ${target_name}"
|
||||||
DEPENDS ${target_name} ${serialiser})
|
DEPENDS ${target_name} ${serialiser})
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
function(rosetta_add_service)
|
||||||
|
set(options)
|
||||||
|
set(one_value_args NAME CFG_FILE)
|
||||||
|
set(multi_value_args SOURCES)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||||
|
"${options}"
|
||||||
|
"${one_value_args}"
|
||||||
|
"${multi_value_args}")
|
||||||
|
|
||||||
|
set(exec_name ${arg_NAME})
|
||||||
|
get_property(programs GLOBAL PROPERTY rosetta_program_list)
|
||||||
|
set_property(GLOBAL PROPERTY rosetta_program_list ${programs} ${exec_name})
|
||||||
|
|
||||||
|
message(STATUS "Building service ${exec_name}")
|
||||||
|
add_executable(${exec_name} ${arg_SOURCES})
|
||||||
|
|
||||||
|
set_target_properties(${exec_name} PROPERTIES
|
||||||
|
POSITION_INDEPENDENT_CODE ON
|
||||||
|
service_cfg_path ${arg_CFG_FILE})
|
||||||
|
install(TARGETS ${exec_name}
|
||||||
|
DESTINATION ${arg_SYSROOT_PATH})
|
||||||
|
endfunction(rosetta_add_service)
|
||||||
|
|
||||||
|
function(rosetta_add_misc_service)
|
||||||
|
set(options)
|
||||||
|
set(one_value_args NAME CFG_FILE)
|
||||||
|
set(multi_value_args SOURCES)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||||
|
"${options}"
|
||||||
|
"${one_value_args}"
|
||||||
|
"${multi_value_args}")
|
||||||
|
|
||||||
|
message(STATUS "Building service ${arg_NAME}")
|
||||||
|
add_custom_target(${arg_NAME})
|
||||||
|
|
||||||
|
set_target_properties(${arg_NAME} PROPERTIES
|
||||||
|
service_cfg_path ${arg_CFG_FILE})
|
||||||
|
endfunction(rosetta_add_misc_service)
|
||||||
|
|
||||||
|
function(rosetta_service_add_file)
|
||||||
|
set(options)
|
||||||
|
set(one_value_args NAME SRC_FILE DEST_DIR)
|
||||||
|
set(multi_value_args)
|
||||||
|
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||||
|
"${options}"
|
||||||
|
"${one_value_args}"
|
||||||
|
"${multi_value_args}")
|
||||||
|
|
||||||
|
get_property(file_list TARGET ${arg_NAME} PROPERTY service_file_list)
|
||||||
|
set(file_list ${file_list} ${arg_SRC_FILE} ${arg_DEST_DIR})
|
||||||
|
set_property(TARGET ${arg_NAME} PROPERTY service_file_list ${file_list})
|
||||||
|
endfunction(rosetta_service_add_file)
|
||||||
+30
-5
@@ -170,19 +170,44 @@ function(sysroot_add_service)
|
|||||||
|
|
||||||
get_property(sysroot_targets GLOBAL PROPERTY sysroot_target_list)
|
get_property(sysroot_targets GLOBAL PROPERTY sysroot_target_list)
|
||||||
get_property(cfg_file TARGET ${arg_NAME} PROPERTY service_cfg_path)
|
get_property(cfg_file TARGET ${arg_NAME} PROPERTY service_cfg_path)
|
||||||
|
get_property(file_list TARGET ${arg_NAME} PROPERTY service_file_list)
|
||||||
|
get_property(target_type TARGET ${arg_NAME} PROPERTY TYPE)
|
||||||
|
|
||||||
list(LENGTH sysroot_targets nr_sysroot_targets)
|
list(LENGTH sysroot_targets nr_sysroot_targets)
|
||||||
|
list(LENGTH file_list nr_service_files)
|
||||||
if (${nr_sysroot_targets} GREATER 0)
|
if (${nr_sysroot_targets} GREATER 0)
|
||||||
math(EXPR serialiser_index "${nr_sysroot_targets}-1")
|
math(EXPR serialiser_index "${nr_sysroot_targets}-1")
|
||||||
list(GET sysroot_targets ${serialiser_index} serialiser)
|
list(GET sysroot_targets ${serialiser_index} serialiser)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_custom_target(${sysroot_target_name}
|
set(commands
|
||||||
COMMAND ${Python_EXECUTABLE} ${sysroot_tool}
|
|
||||||
add-binary ${sysroot_manifest} ${target_name}
|
|
||||||
${arg_BIN_DIR} $<TARGET_FILE:${target_name}>
|
|
||||||
COMMAND ${Python_EXECUTABLE} ${sysroot_tool}
|
COMMAND ${Python_EXECUTABLE} ${sysroot_tool}
|
||||||
add-binary ${sysroot_manifest} ${target_name}-cfg
|
add-binary ${sysroot_manifest} ${target_name}-cfg
|
||||||
${arg_SVC_DIR} ${cfg_file}
|
${arg_SVC_DIR} ${cfg_file})
|
||||||
|
|
||||||
|
if (target_type STREQUAL "EXECUTABLE")
|
||||||
|
set(commands ${commands}
|
||||||
|
COMMAND ${Python_EXECUTABLE} ${sysroot_tool}
|
||||||
|
add-binary ${sysroot_manifest} ${target_name}
|
||||||
|
${arg_BIN_DIR} $<TARGET_FILE:${target_name}>)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (nr_service_files GREATER 0)
|
||||||
|
math(EXPR nr_service_files "${nr_service_files}-1")
|
||||||
|
foreach (i RANGE 0 ${nr_service_files} 2)
|
||||||
|
math(EXPR i2 "${i}+1")
|
||||||
|
list(GET file_list ${i} src_file)
|
||||||
|
list(GET file_list ${i2} dest_dir)
|
||||||
|
|
||||||
|
set(commands ${commands}
|
||||||
|
COMMAND ${Python_EXECUTABLE} ${sysroot_tool}
|
||||||
|
add-binary ${sysroot_manifest} ${target_name}-${i}
|
||||||
|
${dest_dir} ${src_file})
|
||||||
|
endforeach (i)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_custom_target(${sysroot_target_name}
|
||||||
|
${commands}
|
||||||
COMMENT "Preparing sysroot component: ${target_name}"
|
COMMENT "Preparing sysroot component: ${target_name}"
|
||||||
DEPENDS ${target_name} ${serialiser})
|
DEPENDS ${target_name} ${serialiser})
|
||||||
|
|
||||||
|
|||||||
+6
-25
@@ -32,29 +32,6 @@ function(rosetta_add_executable)
|
|||||||
DESTINATION ${arg_SYSROOT_PATH})
|
DESTINATION ${arg_SYSROOT_PATH})
|
||||||
endfunction(rosetta_add_executable)
|
endfunction(rosetta_add_executable)
|
||||||
|
|
||||||
function(rosetta_add_service)
|
|
||||||
set(options)
|
|
||||||
set(one_value_args NAME CFG_FILE)
|
|
||||||
set(multi_value_args SOURCES)
|
|
||||||
cmake_parse_arguments(PARSE_ARGV 0 arg
|
|
||||||
"${options}"
|
|
||||||
"${one_value_args}"
|
|
||||||
"${multi_value_args}")
|
|
||||||
|
|
||||||
set(exec_name ${arg_NAME})
|
|
||||||
get_property(programs GLOBAL PROPERTY rosetta_program_list)
|
|
||||||
set_property(GLOBAL PROPERTY rosetta_program_list ${programs} ${exec_name})
|
|
||||||
|
|
||||||
message(STATUS "Building service ${exec_name}")
|
|
||||||
add_executable(${exec_name} ${arg_SOURCES})
|
|
||||||
|
|
||||||
set_target_properties(${exec_name} PROPERTIES
|
|
||||||
POSITION_INDEPENDENT_CODE ON
|
|
||||||
service_cfg_path ${arg_CFG_FILE})
|
|
||||||
install(TARGETS ${exec_name}
|
|
||||||
DESTINATION ${arg_SYSROOT_PATH})
|
|
||||||
endfunction(rosetta_add_service)
|
|
||||||
|
|
||||||
function(rosetta_add_library)
|
function(rosetta_add_library)
|
||||||
set(options STATIC SHARED)
|
set(options STATIC SHARED)
|
||||||
set(one_value_args NAME)
|
set(one_value_args NAME)
|
||||||
@@ -156,7 +133,7 @@ endfunction(rosetta_add_object_library)
|
|||||||
|
|
||||||
function(rosetta_wrap_library)
|
function(rosetta_wrap_library)
|
||||||
set(options)
|
set(options)
|
||||||
set(one_value_args NAME)
|
set(one_value_args NAME SONAME PREFIX)
|
||||||
set(multi_value_args
|
set(multi_value_args
|
||||||
PUBLIC_INCLUDE_DIRS)
|
PUBLIC_INCLUDE_DIRS)
|
||||||
cmake_parse_arguments(PARSE_ARGV 0 arg
|
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||||
@@ -174,10 +151,14 @@ function(rosetta_wrap_library)
|
|||||||
PATH ${arg_PUBLIC_INCLUDE_DIRS})
|
PATH ${arg_PUBLIC_INCLUDE_DIRS})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (arg_SONAME)
|
||||||
|
target_link_options(${lib_name} PRIVATE -Wl,--soname,${arg_SONAME}.so)
|
||||||
|
endif ()
|
||||||
|
|
||||||
set_target_properties(${lib_name} PROPERTIES
|
set_target_properties(${lib_name} PROPERTIES
|
||||||
POSITION_INDEPENDENT_CODE ON
|
POSITION_INDEPENDENT_CODE ON
|
||||||
src_header_dir ${CMAKE_CURRENT_SOURCE_DIR}/include
|
src_header_dir ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
PREFIX "")
|
PREFIX "${arg_PREFIX}")
|
||||||
endfunction(rosetta_wrap_library)
|
endfunction(rosetta_wrap_library)
|
||||||
|
|
||||||
function(rosetta_add_object_library)
|
function(rosetta_add_object_library)
|
||||||
|
|||||||
+2
-1
@@ -31,9 +31,10 @@ endforeach (item)
|
|||||||
|
|
||||||
foreach (assembly ${fx_assemblies})
|
foreach (assembly ${fx_assemblies})
|
||||||
target_link_libraries(${assembly} libc libpthread)
|
target_link_libraries(${assembly} libc libpthread)
|
||||||
target_link_options(${assembly} PRIVATE -Wl,--soname,lib${assembly}.so)
|
# target_link_options(${assembly} PRIVATE -Wl,--soname,lib${assembly}.so)
|
||||||
rosetta_wrap_library(
|
rosetta_wrap_library(
|
||||||
NAME ${assembly}
|
NAME ${assembly}
|
||||||
|
SONAME lib${assembly}
|
||||||
PUBLIC_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/libfx/${module}/include)
|
PUBLIC_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/libfx/${module}/include)
|
||||||
set_target_properties(${assembly} PROPERTIES
|
set_target_properties(${assembly} PROPERTIES
|
||||||
PREFIX "lib")
|
PREFIX "lib")
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include <magenta/log.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
extern void __libc_assert_failed(
|
extern void __libc_assert_failed(
|
||||||
@@ -6,5 +8,6 @@ extern void __libc_assert_failed(
|
|||||||
const char *func,
|
const char *func,
|
||||||
const char *cond)
|
const char *cond)
|
||||||
{
|
{
|
||||||
|
kern_logf("ASSERT: %s failed (%s in %s:%d)", cond, func, file, line);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
#include <errno.h>
|
||||||
#include <magenta/log.h>
|
#include <magenta/log.h>
|
||||||
#include <rosetta/bootstrap.h>
|
#include <rosetta/bootstrap.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <sys/remote.h>
|
||||||
|
|
||||||
extern int main(int, const char **, const char **);
|
extern int main(int, const char **, const char **);
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ void *__attribute__((weak)) pthread_self(void)
|
|||||||
|
|
||||||
int __libc_init(const struct rosetta_bootstrap *bsinfo)
|
int __libc_init(const struct rosetta_bootstrap *bsinfo)
|
||||||
{
|
{
|
||||||
|
sys_remote_set(SYS_REMOTE_NSD, 0, 0);
|
||||||
(volatile void)pthread_self();
|
(volatile void)pthread_self();
|
||||||
__set_errno(SUCCESS);
|
__set_errno(SUCCESS);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ typedef struct __opaque_file FILE;
|
|||||||
extern int printf(const char *format, ...);
|
extern int printf(const char *format, ...);
|
||||||
extern int vprintf(const char *format, va_list arg);
|
extern int vprintf(const char *format, va_list arg);
|
||||||
extern int fprintf(FILE *stream, const char *format, ...);
|
extern int fprintf(FILE *stream, const char *format, ...);
|
||||||
|
extern int vfprintf(FILE *stream, const char *format, va_list arg);
|
||||||
extern int snprintf(char *buffer, size_t count, const char *format, ...);
|
extern int snprintf(char *buffer, size_t count, const char *format, ...);
|
||||||
extern int vsnprintf(
|
extern int vsnprintf(
|
||||||
char *buffer,
|
char *buffer,
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ int __libc_dir_refill(struct __opaque_dir *d)
|
|||||||
|
|
||||||
int __libc_dir_move_next(struct __opaque_dir *d)
|
int __libc_dir_move_next(struct __opaque_dir *d)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (d->d_fd < 0) {
|
if (d->d_fd < 0) {
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
int fprintf(struct __opaque_file *stream, const char *format, ...)
|
int fprintf(struct __opaque_file *stream, const char *format, ...)
|
||||||
{
|
{
|
||||||
return 0;
|
va_list arg;
|
||||||
|
va_start(arg, format);
|
||||||
|
int ret = vfprintf(stream, format, arg);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ int printf(const char *format, ...)
|
|||||||
{
|
{
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
int ret = vprintf(format, arg);
|
int ret = vfprintf(stdout, format, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
static struct __opaque_file __stderr = {
|
static struct __opaque_file __stderr = {
|
||||||
.f_fd = 2,
|
.f_fd = 2,
|
||||||
.f_flags = FILE_STATIC,
|
.f_flags = FILE_STATIC,
|
||||||
.f_buffer_mode = _IONBF,
|
/* TODO change this back to _IONBF once we're no longer using kern_log()
|
||||||
|
* in bootstrap */
|
||||||
|
.f_buffer_mode = _IOLBF,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct __opaque_file *__libc_file_stderr(void)
|
extern struct __opaque_file *__libc_file_stderr(void)
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int __libc_fctprintf(
|
||||||
|
int (*out)(char character, void *arg),
|
||||||
|
void *arg,
|
||||||
|
const char *format,
|
||||||
|
va_list va);
|
||||||
|
extern int __fputc(int c, struct __opaque_file *stream);
|
||||||
|
|
||||||
|
static inline int _out_file(char character, void *arg)
|
||||||
|
{
|
||||||
|
FILE *fp = arg;
|
||||||
|
return __fputc(character, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vfprintf(FILE *fp, const char *format, va_list arg)
|
||||||
|
{
|
||||||
|
__libc_file_lock(fp);
|
||||||
|
|
||||||
|
int ret = __libc_fctprintf(_out_file, fp, format, arg);
|
||||||
|
if (errno != SUCCESS) {
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ferror(fp)) {
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__libc_file_unlock(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
extern int __libc_fctprintf(
|
extern int __libc_fctprintf(
|
||||||
@@ -11,7 +11,7 @@ extern int __libc_fctprintf(
|
|||||||
va_list va);
|
va_list va);
|
||||||
extern int __fputc(int c, struct __opaque_file *stream);
|
extern int __fputc(int c, struct __opaque_file *stream);
|
||||||
|
|
||||||
static inline int _out_file(char character, void *arg)
|
static inline int _out_file(char character, void *arg)
|
||||||
{
|
{
|
||||||
FILE *fp = arg;
|
FILE *fp = arg;
|
||||||
return __fputc(character, fp);
|
return __fputc(character, fp);
|
||||||
@@ -19,17 +19,5 @@ static inline int _out_file(char character, void *arg)
|
|||||||
|
|
||||||
int vprintf(const char *format, va_list arg)
|
int vprintf(const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
__libc_file_lock(stdout);
|
return vfprintf(stdout, format, arg);
|
||||||
|
|
||||||
int ret = __libc_fctprintf(_out_file, stdout, format, arg);
|
|
||||||
if (errno != SUCCESS) {
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ferror(stdout)) {
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
__libc_file_unlock(stdout);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ sysroot_add_library(
|
|||||||
HEADER_DIR /usr/include
|
HEADER_DIR /usr/include
|
||||||
LIB_DIR /usr/lib)
|
LIB_DIR /usr/lib)
|
||||||
|
|
||||||
target_compile_definitions(libc-malloc PRIVATE ENABLE_GLOBAL_HEAP=1)
|
target_compile_definitions(libc-malloc PRIVATE LIBC_STATIC=1 ENABLE_GLOBAL_HEAP=1)
|
||||||
target_link_libraries(libc-malloc libc-core libmagenta)
|
target_link_libraries(libc-malloc libc-core libmagenta)
|
||||||
|
|||||||
@@ -8,6 +8,12 @@
|
|||||||
#include <magenta/vm.h>
|
#include <magenta/vm.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined(LIBC_STATIC)
|
||||||
|
#define HEAP_REGION_BASE 0x20000000000
|
||||||
|
#else
|
||||||
|
#define HEAP_REGION_BASE 0x60000000000
|
||||||
|
#endif
|
||||||
|
|
||||||
#define HEAP_REGION_SIZE 0x40000000
|
#define HEAP_REGION_SIZE 0x40000000
|
||||||
#define HEAP_EXPAND_INCREMENT 0x100000
|
#define HEAP_EXPAND_INCREMENT 0x100000
|
||||||
|
|
||||||
@@ -40,7 +46,7 @@ static kern_status_t init_heap_region(heap_t *heap)
|
|||||||
|
|
||||||
kern_status_t status = address_space_reserve(
|
kern_status_t status = address_space_reserve(
|
||||||
address_space,
|
address_space,
|
||||||
MAP_ADDRESS_ANY,
|
HEAP_REGION_BASE,
|
||||||
HEAP_REGION_SIZE,
|
HEAP_REGION_SIZE,
|
||||||
&heap->heap_base);
|
&heap->heap_base);
|
||||||
|
|
||||||
|
|||||||
+17
-11
@@ -1,5 +1,10 @@
|
|||||||
#include "liballoc.h"
|
#include "liballoc.h"
|
||||||
|
|
||||||
|
#include <magenta/config.h>
|
||||||
|
#include <magenta/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/** Durand's Amazing Super Duper Memory functions. */
|
/** Durand's Amazing Super Duper Memory functions. */
|
||||||
|
|
||||||
#define VERSION "1.1"
|
#define VERSION "1.1"
|
||||||
@@ -206,6 +211,8 @@ static struct liballoc_major *allocate_new_page(heap_t *heap, unsigned int size)
|
|||||||
return NULL; // uh oh, we ran out of memory.
|
return NULL; // uh oh, we ran out of memory.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(maj, 0x0, sizeof *maj);
|
||||||
|
|
||||||
maj->prev = NULL;
|
maj->prev = NULL;
|
||||||
maj->next = NULL;
|
maj->next = NULL;
|
||||||
maj->pages = st;
|
maj->pages = st;
|
||||||
@@ -455,13 +462,11 @@ void *PREFIX(malloc)(heap_t *heap, size_t req_size)
|
|||||||
if (diff
|
if (diff
|
||||||
>= (size + sizeof(struct liballoc_minor))) {
|
>= (size + sizeof(struct liballoc_minor))) {
|
||||||
// yay....
|
// yay....
|
||||||
min->next
|
min->next = (struct liballoc_minor
|
||||||
= (struct liballoc_minor
|
*)((uintptr_t)min
|
||||||
*)((uintptr_t)min
|
+ sizeof(
|
||||||
+ sizeof(
|
struct liballoc_minor)
|
||||||
struct
|
+ min->size);
|
||||||
liballoc_minor)
|
|
||||||
+ min->size);
|
|
||||||
min->next->prev = min;
|
min->next->prev = min;
|
||||||
min = min->next;
|
min = min->next;
|
||||||
min->next = NULL;
|
min->next = NULL;
|
||||||
@@ -506,8 +511,7 @@ void *PREFIX(malloc)(heap_t *heap, size_t req_size)
|
|||||||
new_min = (struct liballoc_minor
|
new_min = (struct liballoc_minor
|
||||||
*)((uintptr_t)min
|
*)((uintptr_t)min
|
||||||
+ sizeof(
|
+ sizeof(
|
||||||
struct
|
struct liballoc_minor)
|
||||||
liballoc_minor)
|
|
||||||
+ min->size);
|
+ min->size);
|
||||||
|
|
||||||
new_min->magic = LIBALLOC_MAGIC;
|
new_min->magic = LIBALLOC_MAGIC;
|
||||||
@@ -822,9 +826,11 @@ int liballoc_unlock(heap_t *heap)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *liballoc_alloc(heap_t *heap, size_t sz)
|
void *liballoc_alloc(heap_t *heap, size_t nr_pages)
|
||||||
{
|
{
|
||||||
return heap_expand(heap, sz);
|
size_t page_size = 0;
|
||||||
|
kern_config_get(KERN_CFG_PAGE_SIZE, &page_size, sizeof page_size);
|
||||||
|
return heap_expand(heap, nr_pages * page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int liballoc_free(heap_t *heap, void *p, size_t sz)
|
int liballoc_free(heap_t *heap, void *p, size_t sz)
|
||||||
|
|||||||
+1
-1
Submodule lib/libfx updated: 8c0a31e19b...20dc844c9d
@@ -1,5 +1,9 @@
|
|||||||
file(GLOB items *)
|
file(GLOB items *)
|
||||||
|
|
||||||
|
set(bshell_interactive 0)
|
||||||
|
set(bshell_verbose 0)
|
||||||
|
set(bshell_enable_floating_point 0)
|
||||||
|
|
||||||
foreach(item ${items})
|
foreach(item ${items})
|
||||||
if (NOT IS_DIRECTORY ${item})
|
if (NOT IS_DIRECTORY ${item})
|
||||||
continue()
|
continue()
|
||||||
@@ -7,3 +11,40 @@ foreach(item ${items})
|
|||||||
|
|
||||||
add_subdirectory(${item})
|
add_subdirectory(${item})
|
||||||
endforeach (item)
|
endforeach (item)
|
||||||
|
|
||||||
|
target_link_libraries(bshell libc libc-runtime libpthread)
|
||||||
|
target_link_libraries(bshell.core libc libpthread)
|
||||||
|
target_link_libraries(bshell.runtime libc libpthread)
|
||||||
|
|
||||||
|
sysroot_add_program(
|
||||||
|
NAME bshell
|
||||||
|
BIN_DIR /usr/bin)
|
||||||
|
bsp_add_program(
|
||||||
|
NAME bshell
|
||||||
|
BIN_DIR /usr/bin)
|
||||||
|
|
||||||
|
rosetta_wrap_library(
|
||||||
|
NAME bshell.runtime
|
||||||
|
SONAME libbshell.runtime
|
||||||
|
PREFIX lib
|
||||||
|
PUBLIC_INCLUDE_DIRS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/bshell/bshell.runtime/include)
|
||||||
|
rosetta_wrap_library(
|
||||||
|
NAME bshell.core
|
||||||
|
PREFIX lib
|
||||||
|
SONAME libbshell.core)
|
||||||
|
|
||||||
|
sysroot_add_library(
|
||||||
|
NAME bshell.runtime
|
||||||
|
HEADER_DIR /usr/include
|
||||||
|
LIB_DIR /usr/lib)
|
||||||
|
bsp_add_library(
|
||||||
|
NAME bshell.runtime
|
||||||
|
LIB_DIR /usr/lib)
|
||||||
|
|
||||||
|
sysroot_add_library(
|
||||||
|
NAME bshell.core
|
||||||
|
LIB_DIR /usr/lib)
|
||||||
|
bsp_add_library(
|
||||||
|
NAME bshell.core
|
||||||
|
LIB_DIR /usr/lib)
|
||||||
|
|||||||
Submodule
+1
Submodule programs/bshell added at 8843f2d2a9
@@ -1,12 +0,0 @@
|
|||||||
file(GLOB runlevels *.runlevel)
|
|
||||||
foreach (f ${runlevels})
|
|
||||||
get_filename_component(name ${f} NAME_WLE)
|
|
||||||
bsp_add_file(
|
|
||||||
ID runlevel-${name}
|
|
||||||
SRC_PATH ${f}
|
|
||||||
DEST_DIR /etc/herdd/runlevels)
|
|
||||||
sysroot_add_file(
|
|
||||||
ID runlevel-${name}
|
|
||||||
SRC_PATH ${f}
|
|
||||||
DEST_DIR /etc/herdd/runlevels)
|
|
||||||
endforeach (f)
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# vim ft=toml
|
|
||||||
[runlevel]
|
|
||||||
name = "single-user"
|
|
||||||
description = "Single-User"
|
|
||||||
requires = [
|
|
||||||
"nsd",
|
|
||||||
"devmd"
|
|
||||||
]
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
rosetta_add_misc_service(
|
||||||
|
NAME bshell-test
|
||||||
|
CFG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/bshell-test.service)
|
||||||
|
|
||||||
|
rosetta_service_add_file(
|
||||||
|
NAME bshell-test
|
||||||
|
SRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/test.bshell
|
||||||
|
DEST_DIR /sbin)
|
||||||
|
|
||||||
|
sysroot_add_service(
|
||||||
|
NAME bshell-test
|
||||||
|
BIN_DIR /usr/bin
|
||||||
|
SVC_DIR /etc/herdd/services)
|
||||||
|
bsp_add_service(
|
||||||
|
NAME bshell-test
|
||||||
|
BIN_DIR /usr/bin
|
||||||
|
SVC_DIR /etc/herdd/services)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# vim ft=toml
|
||||||
|
[unit]
|
||||||
|
description = "BShell Test Script"
|
||||||
|
|
||||||
|
[service]
|
||||||
|
exec = [
|
||||||
|
"/usr/bin/bshell",
|
||||||
|
"/sbin/test.bshell"
|
||||||
|
]
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
$x = "Jonh"
|
||||||
|
echo "Hello, $x!"
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
# vim ft=toml
|
# vim ft=toml
|
||||||
[unit]
|
[unit]
|
||||||
name = "devmd"
|
|
||||||
description = "Device Management Service"
|
description = "Device Management Service"
|
||||||
|
|
||||||
[service]
|
[service]
|
||||||
exec = "/usr/bin/devmd"
|
exec = [ "/usr/bin/devmd" ]
|
||||||
roles = [
|
roles = [
|
||||||
"DeviceManager"
|
"DeviceManager"
|
||||||
]
|
]
|
||||||
|
|||||||
+11
-11
@@ -1,8 +1,8 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#include "runlevel.h"
|
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "spawn.h"
|
#include "spawn.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -46,7 +46,7 @@ static int load_services(const char *dir, struct queue *out)
|
|||||||
snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name);
|
snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name);
|
||||||
tracef(" - %s\n", dent->d_name);
|
tracef(" - %s\n", dent->d_name);
|
||||||
struct service *s = NULL;
|
struct service *s = NULL;
|
||||||
int err = service_load(filepath, &s);
|
int err = service_load(dent->d_name, filepath, &s);
|
||||||
if (err != SUCCESS) {
|
if (err != SUCCESS) {
|
||||||
printf("failed to load %s (%s)\n",
|
printf("failed to load %s (%s)\n",
|
||||||
filepath,
|
filepath,
|
||||||
@@ -60,7 +60,7 @@ static int load_services(const char *dir, struct queue *out)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_runlevels(const char *dir, struct queue *out)
|
static int load_targets(const char *dir, struct queue *out)
|
||||||
{
|
{
|
||||||
DIR *d = opendir(dir);
|
DIR *d = opendir(dir);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
@@ -74,8 +74,8 @@ static int load_runlevels(const char *dir, struct queue *out)
|
|||||||
char filepath[4096];
|
char filepath[4096];
|
||||||
snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name);
|
snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name);
|
||||||
tracef(" - %s\n", dent->d_name);
|
tracef(" - %s\n", dent->d_name);
|
||||||
struct runlevel *rl = NULL;
|
struct target *rl = NULL;
|
||||||
int err = runlevel_load(filepath, &rl);
|
int err = target_load(dent->d_name, filepath, &rl);
|
||||||
if (err != SUCCESS) {
|
if (err != SUCCESS) {
|
||||||
printf("failed to load %s (%s)\n",
|
printf("failed to load %s (%s)\n",
|
||||||
filepath,
|
filepath,
|
||||||
@@ -83,7 +83,7 @@ static int load_runlevels(const char *dir, struct queue *out)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracef("runlevel: %s\n", rl->rl_description);
|
tracef("target: %s\n", rl->rl_description);
|
||||||
for (size_t i = 0; i < rl->rl_requires_count; i++) {
|
for (size_t i = 0; i < rl->rl_requires_count; i++) {
|
||||||
tracef(" requires: %s\n", rl->rl_requires[i]);
|
tracef(" requires: %s\n", rl->rl_requires[i]);
|
||||||
}
|
}
|
||||||
@@ -99,19 +99,19 @@ int main(int argc, const char *argv[], const char *envp[])
|
|||||||
{
|
{
|
||||||
sys_remote_set(SYS_REMOTE_NSD, 0, 0);
|
sys_remote_set(SYS_REMOTE_NSD, 0, 0);
|
||||||
|
|
||||||
struct queue *runlevels = global_runlevels();
|
struct queue *targets = global_targets();
|
||||||
struct queue *services = global_services();
|
struct queue *services = global_services();
|
||||||
|
|
||||||
int err = load_runlevels("/etc/herdd/runlevels", runlevels);
|
int err = load_targets("/etc/herdd/targets", targets);
|
||||||
err = load_services("/etc/herdd/services", services);
|
err = load_services("/etc/herdd/services", services);
|
||||||
|
|
||||||
struct runlevel *rl = runlevel_find("single-user");
|
struct target *rl = target_find("single-user.target");
|
||||||
if (!rl) {
|
if (!rl) {
|
||||||
log_fail("Cannot find runlevel single-user.");
|
log_fail("Cannot find target single-user.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
runlevel_activate(rl);
|
target_activate(rl);
|
||||||
#if 1
|
#if 1
|
||||||
pid_t child = fork();
|
pid_t child = fork();
|
||||||
kern_logf(" fork returned %d", child);
|
kern_logf(" fork returned %d", child);
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
#ifndef RUNLEVEL_H_
|
|
||||||
#define RUNLEVEL_H_
|
|
||||||
|
|
||||||
#include "queue.h"
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
struct runlevel {
|
|
||||||
char *rl_name;
|
|
||||||
char *rl_description;
|
|
||||||
char **rl_requires;
|
|
||||||
size_t rl_requires_count;
|
|
||||||
struct queue_entry rl_entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct queue *global_runlevels(void);
|
|
||||||
|
|
||||||
extern int runlevel_load(const char *path, struct runlevel **out);
|
|
||||||
extern struct runlevel *runlevel_find(const char *name);
|
|
||||||
extern int runlevel_activate(struct runlevel *rl);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
+29
-27
@@ -9,7 +9,6 @@
|
|||||||
#include <fx/string.h>
|
#include <fx/string.h>
|
||||||
#include <fx/stringstream.h>
|
#include <fx/stringstream.h>
|
||||||
#include <launch.h>
|
#include <launch.h>
|
||||||
#include <magenta/log.h>
|
|
||||||
#include <rosetta/bootstrap.h>
|
#include <rosetta/bootstrap.h>
|
||||||
#include <spawn.h>
|
#include <spawn.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -43,13 +42,6 @@ static int parse_service_data(fx_object *in, struct service *out)
|
|||||||
fx_hashtable *in_unit = NULL;
|
fx_hashtable *in_unit = NULL;
|
||||||
fx_value_get_object(unit_v, &in_unit);
|
fx_value_get_object(unit_v, &in_unit);
|
||||||
|
|
||||||
const fx_value *name_v = fx_hashtable_get(in_unit, &FX_CSTR("name"));
|
|
||||||
if (!name_v || !fx_value_is_type(name_v, FX_TYPE_STRING)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fx_string *name = NULL;
|
|
||||||
fx_value_get_object(name_v, &name);
|
|
||||||
|
|
||||||
const fx_value *description_v
|
const fx_value *description_v
|
||||||
= fx_hashtable_get(in_unit, &FX_CSTR("description"));
|
= fx_hashtable_get(in_unit, &FX_CSTR("description"));
|
||||||
if (!description_v
|
if (!description_v
|
||||||
@@ -60,11 +52,11 @@ static int parse_service_data(fx_object *in, struct service *out)
|
|||||||
fx_value_get_object(description_v, &description);
|
fx_value_get_object(description_v, &description);
|
||||||
|
|
||||||
const fx_value *exec_v = fx_hashtable_get(in_service, &FX_CSTR("exec"));
|
const fx_value *exec_v = fx_hashtable_get(in_service, &FX_CSTR("exec"));
|
||||||
if (!exec_v || !fx_value_is_type(exec_v, FX_TYPE_STRING)) {
|
if (exec_v && !fx_value_is_type(exec_v, FX_TYPE_ARRAY)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fx_string *exec = NULL;
|
fx_value_get_object(exec_v, &out->s_exec);
|
||||||
fx_value_get_object(exec_v, &exec);
|
fx_object_ref(out->s_exec);
|
||||||
|
|
||||||
const fx_value *roles_v
|
const fx_value *roles_v
|
||||||
= fx_hashtable_get(in_service, &FX_CSTR("roles"));
|
= fx_hashtable_get(in_service, &FX_CSTR("roles"));
|
||||||
@@ -101,24 +93,22 @@ static int parse_service_data(fx_object *in, struct service *out)
|
|||||||
}
|
}
|
||||||
fx_iterator_unref(it);
|
fx_iterator_unref(it);
|
||||||
|
|
||||||
out->s_name = fx_string_steal(name);
|
|
||||||
out->s_description = fx_string_steal(description);
|
out->s_description = fx_string_steal(description);
|
||||||
out->s_exec = fx_string_steal(exec);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int service_load(const char *path, struct service **out)
|
int service_load(const char *name, const char *path, struct service **out)
|
||||||
{
|
{
|
||||||
struct service *rl = malloc(sizeof *rl);
|
struct service *svc = malloc(sizeof *svc);
|
||||||
if (!rl) {
|
if (!svc) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fp = fopen(path, "r");
|
FILE *fp = fopen(path, "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
free(rl);
|
free(svc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,30 +118,32 @@ int service_load(const char *path, struct service **out)
|
|||||||
fx_result result = fx_serial_ctx_deserialise(ctx, in, &data, 0);
|
fx_result result = fx_serial_ctx_deserialise(ctx, in, &data, 0);
|
||||||
if (fx_result_is_error(result)) {
|
if (fx_result_is_error(result)) {
|
||||||
fx_throw(result);
|
fx_throw(result);
|
||||||
free(rl);
|
free(svc);
|
||||||
errno = EFTYPE;
|
errno = EFTYPE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fx_value_is_type(&data, FX_TYPE_HASHTABLE)) {
|
if (!fx_value_is_type(&data, FX_TYPE_HASHTABLE)) {
|
||||||
fx_value_unset(&data);
|
fx_value_unset(&data);
|
||||||
free(rl);
|
free(svc);
|
||||||
errno = EFTYPE;
|
errno = EFTYPE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_service_data(data.v_object, rl) != 0) {
|
if (parse_service_data(data.v_object, svc) != 0) {
|
||||||
free(rl);
|
free(svc);
|
||||||
errno = EFTYPE;
|
errno = EFTYPE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svc->s_name = fx_strdup(name);
|
||||||
|
|
||||||
fx_stream_unref(in);
|
fx_stream_unref(in);
|
||||||
fx_value_unset(&data);
|
fx_value_unset(&data);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
*out = rl;
|
*out = svc;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,12 +168,22 @@ int service_start(struct service *svc)
|
|||||||
log("Starting %s...", svc->s_description);
|
log("Starting %s...", svc->s_description);
|
||||||
|
|
||||||
pid_t child = 0;
|
pid_t child = 0;
|
||||||
char *const argv[] = {
|
size_t nr_args = fx_array_get_size(svc->s_exec);
|
||||||
svc->s_name,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
int err = posix_spawn(&child, svc->s_exec, NULL, NULL, argv, NULL);
|
const char **argv = calloc(nr_args + 1, sizeof *argv);
|
||||||
|
for (size_t i = 0; i < nr_args; i++) {
|
||||||
|
const fx_value *str = fx_array_get_ref(svc->s_exec, i);
|
||||||
|
fx_value_get_cstr(str, &argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = posix_spawn(
|
||||||
|
&child,
|
||||||
|
argv[0],
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(char *const *)argv,
|
||||||
|
NULL);
|
||||||
|
free(argv);
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
log_ok("Started %s.", svc->s_description);
|
log_ok("Started %s.", svc->s_description);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
|
#include <fx/collections/array.h>
|
||||||
|
|
||||||
enum service_role {
|
enum service_role {
|
||||||
SVC_ROLE_NONE = 0x00u,
|
SVC_ROLE_NONE = 0x00u,
|
||||||
SVC_ROLE_NAMESPACE_PROVIDER = 0x01u,
|
SVC_ROLE_NAMESPACE_PROVIDER = 0x01u,
|
||||||
@@ -11,14 +13,17 @@ enum service_role {
|
|||||||
struct service {
|
struct service {
|
||||||
char *s_name;
|
char *s_name;
|
||||||
char *s_description;
|
char *s_description;
|
||||||
char *s_exec;
|
fx_array *s_exec;
|
||||||
enum service_role s_roles;
|
enum service_role s_roles;
|
||||||
struct queue_entry s_entry;
|
struct queue_entry s_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct queue *global_services(void);
|
extern struct queue *global_services(void);
|
||||||
|
|
||||||
extern int service_load(const char *path, struct service **out);
|
extern int service_load(
|
||||||
|
const char *name,
|
||||||
|
const char *path,
|
||||||
|
struct service **out);
|
||||||
extern struct service *service_find(const char *name);
|
extern struct service *service_find(const char *name);
|
||||||
extern int service_start(struct service *svc);
|
extern int service_start(struct service *svc);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "runlevel.h"
|
#include "target.h"
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
@@ -14,36 +14,35 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static struct queue runlevels = QUEUE_INIT;
|
static struct queue targets = QUEUE_INIT;
|
||||||
|
|
||||||
struct queue *global_runlevels(void)
|
struct queue *global_targets(void)
|
||||||
{
|
{
|
||||||
return &runlevels;
|
return &targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_runlevel_data(fx_object *in, struct runlevel *out)
|
static int parse_target_data(fx_object *in, struct target *out)
|
||||||
{
|
{
|
||||||
if (!fx_object_is_type(in, FX_TYPE_HASHTABLE)) {
|
if (!fx_object_is_type(in, FX_TYPE_HASHTABLE)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fx_value *runlevel_v = fx_hashtable_get(in, &FX_CSTR("runlevel"));
|
const fx_value *target_v = fx_hashtable_get(in, &FX_CSTR("target"));
|
||||||
if (!runlevel_v || !fx_value_is_type(runlevel_v, FX_TYPE_HASHTABLE)) {
|
if (!target_v || !fx_value_is_type(target_v, FX_TYPE_HASHTABLE)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fx_hashtable *in_runlevel = NULL;
|
fx_hashtable *in_target = NULL;
|
||||||
fx_value_get_object(runlevel_v, &in_runlevel);
|
fx_value_get_object(target_v, &in_target);
|
||||||
|
|
||||||
const fx_value *name_v
|
const fx_value *unit_v = fx_hashtable_get(in, &FX_CSTR("unit"));
|
||||||
= fx_hashtable_get(in_runlevel, &FX_CSTR("name"));
|
if (!unit_v || !fx_value_is_type(unit_v, FX_TYPE_HASHTABLE)) {
|
||||||
if (!name_v || !fx_value_is_type(name_v, FX_TYPE_STRING)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fx_string *name = NULL;
|
fx_hashtable *in_unit = NULL;
|
||||||
fx_value_get_object(name_v, &name);
|
fx_value_get_object(unit_v, &in_unit);
|
||||||
|
|
||||||
const fx_value *description_v
|
const fx_value *description_v
|
||||||
= fx_hashtable_get(in_runlevel, &FX_CSTR("description"));
|
= fx_hashtable_get(in_unit, &FX_CSTR("description"));
|
||||||
if (!description_v
|
if (!description_v
|
||||||
|| !fx_value_is_type(description_v, FX_TYPE_STRING)) {
|
|| !fx_value_is_type(description_v, FX_TYPE_STRING)) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -52,7 +51,7 @@ static int parse_runlevel_data(fx_object *in, struct runlevel *out)
|
|||||||
fx_value_get_object(description_v, &description);
|
fx_value_get_object(description_v, &description);
|
||||||
|
|
||||||
const fx_value *deps_v
|
const fx_value *deps_v
|
||||||
= fx_hashtable_get(in_runlevel, &FX_CSTR("requires"));
|
= fx_hashtable_get(in_target, &FX_CSTR("requires"));
|
||||||
if (deps_v && !fx_value_is_type(deps_v, FX_TYPE_ARRAY)) {
|
if (deps_v && !fx_value_is_type(deps_v, FX_TYPE_ARRAY)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -87,15 +86,14 @@ static int parse_runlevel_data(fx_object *in, struct runlevel *out)
|
|||||||
}
|
}
|
||||||
fx_iterator_unref(it);
|
fx_iterator_unref(it);
|
||||||
|
|
||||||
out->rl_name = fx_string_steal(name);
|
|
||||||
out->rl_description = fx_string_steal(description);
|
out->rl_description = fx_string_steal(description);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int runlevel_load(const char *path, struct runlevel **out)
|
int target_load(const char *name, const char *path, struct target **out)
|
||||||
{
|
{
|
||||||
struct runlevel *rl = malloc(sizeof *rl);
|
struct target *rl = malloc(sizeof *rl);
|
||||||
if (!rl) {
|
if (!rl) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -124,12 +122,14 @@ int runlevel_load(const char *path, struct runlevel **out)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parse_runlevel_data(data.v_object, rl) != 0) {
|
if (parse_target_data(data.v_object, rl) != 0) {
|
||||||
free(rl);
|
free(rl);
|
||||||
errno = EFTYPE;
|
errno = EFTYPE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rl->rl_name = fx_strdup(name);
|
||||||
|
|
||||||
fx_stream_unref(in);
|
fx_stream_unref(in);
|
||||||
fx_value_unset(&data);
|
fx_value_unset(&data);
|
||||||
|
|
||||||
@@ -139,12 +139,12 @@ int runlevel_load(const char *path, struct runlevel **out)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct runlevel *runlevel_find(const char *name)
|
struct target *target_find(const char *name)
|
||||||
{
|
{
|
||||||
struct queue_entry *cur = queue_first(&runlevels);
|
struct queue_entry *cur = queue_first(&targets);
|
||||||
while (cur) {
|
while (cur) {
|
||||||
struct runlevel *rl
|
struct target *rl
|
||||||
= QUEUE_CONTAINER(struct runlevel, rl_entry, cur);
|
= QUEUE_CONTAINER(struct target, rl_entry, cur);
|
||||||
if (!strcmp(rl->rl_name, name)) {
|
if (!strcmp(rl->rl_name, name)) {
|
||||||
return rl;
|
return rl;
|
||||||
}
|
}
|
||||||
@@ -155,7 +155,7 @@ struct runlevel *runlevel_find(const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int runlevel_activate(struct runlevel *rl)
|
int target_activate(struct target *rl)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < rl->rl_requires_count; i++) {
|
for (size_t i = 0; i < rl->rl_requires_count; i++) {
|
||||||
const char *svc_name = rl->rl_requires[i];
|
const char *svc_name = rl->rl_requires[i];
|
||||||
@@ -171,6 +171,6 @@ int runlevel_activate(struct runlevel *rl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_ok("Reached runlevel %s.", rl->rl_description);
|
log_ok("Reached target %s.", rl->rl_description);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef TARGET_H_
|
||||||
|
#define TARGET_H_
|
||||||
|
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct target {
|
||||||
|
char *rl_name;
|
||||||
|
char *rl_description;
|
||||||
|
char **rl_requires;
|
||||||
|
size_t rl_requires_count;
|
||||||
|
struct queue_entry rl_entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct queue *global_targets(void);
|
||||||
|
|
||||||
|
extern int target_load(const char *name, const char *path, struct target **out);
|
||||||
|
extern struct target *target_find(const char *name);
|
||||||
|
extern int target_activate(struct target *rl);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
# vim ft=toml
|
# vim ft=toml
|
||||||
[unit]
|
[unit]
|
||||||
name = "nsd"
|
|
||||||
description = "Namespace Service"
|
description = "Namespace Service"
|
||||||
|
|
||||||
[service]
|
[service]
|
||||||
exec = "/usr/bin/nsd"
|
exec = [ "/usr/bin/nsd" ]
|
||||||
roles = [
|
roles = [
|
||||||
"NamespaceProvider"
|
"NamespaceProvider"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
file(GLOB targets *.target)
|
||||||
|
|
||||||
|
foreach (f ${targets})
|
||||||
|
get_filename_component(name ${f} NAME_WLE)
|
||||||
|
bsp_add_file(
|
||||||
|
ID target-${name}
|
||||||
|
SRC_PATH ${f}
|
||||||
|
DEST_DIR /etc/herdd/targets)
|
||||||
|
sysroot_add_file(
|
||||||
|
ID target-${name}
|
||||||
|
SRC_PATH ${f}
|
||||||
|
DEST_DIR /etc/herdd/targets)
|
||||||
|
endforeach (f)
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
# vim ft=toml
|
# vim ft=toml
|
||||||
[runlevel]
|
[unit]
|
||||||
name = "minimal"
|
|
||||||
description = "Minimal"
|
description = "Minimal"
|
||||||
|
|
||||||
|
[target]
|
||||||
requires = [
|
requires = [
|
||||||
"nsd",
|
"nsd.service",
|
||||||
"devmd"
|
"devmd.service"
|
||||||
]
|
]
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# vim ft=toml
|
||||||
|
[unit]
|
||||||
|
description = "Single-User"
|
||||||
|
|
||||||
|
[target]
|
||||||
|
requires = [
|
||||||
|
"nsd.service",
|
||||||
|
"devmd.service",
|
||||||
|
"bshell-test.service"
|
||||||
|
]
|
||||||
+23
-11
@@ -261,16 +261,24 @@ static int parse_phdr(struct elf_image *image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
static elf_sym_t *get_dynsym(struct elf_image *image, size_t index)
|
static virt_addr_t get_dynsym(struct elf_image *image, size_t index)
|
||||||
{
|
{
|
||||||
elf_sym_t *sym = (elf_sym_t *)(image->e_base + image->e_dynsym
|
elf_sym_t *sym = (elf_sym_t *)(image->e_base + image->e_dynsym
|
||||||
+ (index * image->e_dynsym_entsize));
|
+ (index * image->e_dynsym_entsize));
|
||||||
|
const char *sym_name = (const char *)(image->e_base + image->e_strtab
|
||||||
|
+ sym->st_name);
|
||||||
|
|
||||||
if (!sym->st_value) {
|
if (sym->st_value) {
|
||||||
return NULL;
|
return image->e_base + sym->st_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sym;
|
virt_addr_t sym_addr = find_global_symbol(sym_name);
|
||||||
|
if (sym_addr) {
|
||||||
|
return sym_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_tracef("cannot resolve symbol %s", sym_name);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve_symbol(unsigned int slot)
|
static void resolve_symbol(unsigned int slot)
|
||||||
@@ -289,7 +297,7 @@ static int do_rela(struct elf_image *image, elf_rela_t *rela, bool lazy)
|
|||||||
rela->r_offset);
|
rela->r_offset);
|
||||||
#endif
|
#endif
|
||||||
int type = ELF64_R_TYPE(rela->r_info);
|
int type = ELF64_R_TYPE(rela->r_info);
|
||||||
elf_sym_t *sym = NULL;
|
virt_addr_t v = 0;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case R_X86_64_JUMP_SLOT:
|
case R_X86_64_JUMP_SLOT:
|
||||||
@@ -303,13 +311,13 @@ static int do_rela(struct elf_image *image, elf_rela_t *rela, bool lazy)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case R_X86_64_GLOB_DAT:
|
case R_X86_64_GLOB_DAT:
|
||||||
sym = get_dynsym(image, ELF64_R_SYM(rela->r_info));
|
v = get_dynsym(image, ELF64_R_SYM(rela->r_info));
|
||||||
if (!sym) {
|
if (!v) {
|
||||||
return ENOEXEC;
|
return ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(uint64_t *)(image->e_base + rela->r_offset)
|
*(uint64_t *)(image->e_base + rela->r_offset)
|
||||||
= image->e_base + sym->st_value + rela->r_addend;
|
= v + rela->r_addend;
|
||||||
#if 0
|
#if 0
|
||||||
kern_tracef(
|
kern_tracef(
|
||||||
"GLOB_DAT: offset=%zx, symbol=%zu, addend=%zx",
|
"GLOB_DAT: offset=%zx, symbol=%zu, addend=%zx",
|
||||||
@@ -319,13 +327,13 @@ static int do_rela(struct elf_image *image, elf_rela_t *rela, bool lazy)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case R_X86_64_64:
|
case R_X86_64_64:
|
||||||
sym = get_dynsym(image, ELF64_R_SYM(rela->r_info));
|
v = get_dynsym(image, ELF64_R_SYM(rela->r_info));
|
||||||
if (!sym) {
|
if (!v) {
|
||||||
return ENOEXEC;
|
return ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
*(uint64_t *)(image->e_base + rela->r_offset)
|
*(uint64_t *)(image->e_base + rela->r_offset)
|
||||||
= image->e_base + sym->st_value + rela->r_addend;
|
= v + rela->r_addend;
|
||||||
#if 0
|
#if 0
|
||||||
kern_tracef(
|
kern_tracef(
|
||||||
"64: offset=%zx, symbol=%zu, addend=%zx",
|
"64: offset=%zx, symbol=%zu, addend=%zx",
|
||||||
@@ -404,6 +412,7 @@ static int relocate_rel(
|
|||||||
size_t size,
|
size_t size,
|
||||||
size_t entsize)
|
size_t entsize)
|
||||||
{
|
{
|
||||||
|
kern_tracef("relocate_rel (unsupported)");
|
||||||
return ENOEXEC;
|
return ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,16 +633,19 @@ int elf_image_load(struct elf_image *img)
|
|||||||
|
|
||||||
int e = reserve_exec_region(img);
|
int e = reserve_exec_region(img);
|
||||||
if (e != SUCCESS) {
|
if (e != SUCCESS) {
|
||||||
|
kern_log("error 1");
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = map_image(img);
|
e = map_image(img);
|
||||||
if (e != SUCCESS) {
|
if (e != SUCCESS) {
|
||||||
|
kern_log("error 2");
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = elf_image_parse_dynamic(img);
|
e = elf_image_parse_dynamic(img);
|
||||||
if (e != SUCCESS) {
|
if (e != SUCCESS) {
|
||||||
|
kern_log("error 3");
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user