尝试增加/proc

This commit is contained in:
zhangzheng
2025-03-24 22:42:55 +08:00
parent 54b6bc9c24
commit 7f9da10e19
15 changed files with 98 additions and 91 deletions

View File

@@ -1,6 +1,6 @@
message("========use armv7_8.cmake")
set(CMAKE_C_FLAGS "-mcpu=${CONFIG_ARCH} -Ofast -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS \
set(CMAKE_C_FLAGS "-mcpu=${CONFIG_ARCH} -Os -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS \
-std=gnu11 -ffunction-sections -fdata-sections -fno-builtin -u=_printf_float -Wall \
-nostartfiles -nodefaultlibs -nostdlib -nostdinc \
-fno-stack-protector -Wno-unused-but-set-variable -Wno-unused-function -Wno-parentheses -Wno-volatile-register-var -Wno-unused-variable -Wno-maybe-uninitialized\
@@ -8,14 +8,14 @@ set(CMAKE_C_FLAGS "-mcpu=${CONFIG_ARCH} -Ofast -g3 -mfloat-abi=${CONFIG_FLOAT_TY
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "-mcpu=${CONFIG_ARCH} -Ofast -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS -std=c++11 \
set(CMAKE_CXX_FLAGS "-mcpu=${CONFIG_ARCH} -Os -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS -std=c++11 \
-fmessage-length=0 -Xlinker --print-map -Wall -W -fno-stack-protector -Wall \
-u=_printf_float -D__ARM_ARCH_7M__ \
-ffunction-sections -fdata-sections -fno-builtin -nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker \
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \
" CACHE STRING "" FORCE)
set(CMAKE_ASM_FLAGS "-mcpu=${CONFIG_ARCH} -Ofast -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS \
set(CMAKE_ASM_FLAGS "-mcpu=${CONFIG_ARCH} -Os -g3 -mfloat-abi=${CONFIG_FLOAT_TYPE} -mthumb -DMKRTOS \
-u=_printf_float -std=gnu11 -ffunction-sections -fdata-sections -fno-builtin -Wall \
-nostartfiles -nodefaultlibs -nostdlib -nostdinc -Xlinker -fno-stack-protector -D__ARM_ARCH_7M__ \
-include ${CMAKE_SOURCE_DIR}/build/autoconf.h \

View File

@@ -1,7 +1,7 @@
#!/bin/bash
export TOOLCHAIN=/home/zhangzheng/toolchain/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/bin/
export TOOLCHAIN_LIB=/home/zhangzheng/toolchain/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v7-m/nofp
export TOOLCHAIN=/home/zhangzheng/toolchain/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi/bin/
export TOOLCHAIN_LIB=/home/zhangzheng/toolchain/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp
# export TOOLCHAIN=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/bin/
# export TOOLCHAIN_LIB=/Users/zhangzheng/gcc-arm-none-eabi-10.3-2021.10/lib/gcc/arm-none-eabi/10.3.1/thumb/v7-m/nofp

View File

@@ -18,12 +18,10 @@ typedef struct ns_node
node_type_t type; //!< 节点类型
struct ns_node *parent; //!< 父节点
struct ns_node *next; //!< 下一个
// union
// {
struct ns_node *sub; //!< 子树
obj_handler_t svr_hd; //!< 服务节点
// };
int ref; //!< 引用计数
struct ns_node *sub; //!< 子树
obj_handler_t svr_hd; //!< 服务节点
int belong_pid; //!< 属于哪个pid
int ref; //!< 引用计数
} ns_node_t;
typedef struct ns
{

View File

@@ -14,6 +14,7 @@
#include "u_rpc_svr.h"
#include "u_slist.h"
#include "u_types.h"
#include "u_mutex.h"
typedef struct watch_entry
{
pid_t watch_pid;//!<被监控的pid
@@ -30,6 +31,7 @@ typedef struct pm
{
rpc_svr_obj_t svr_obj;
slist_head_t watch_head;
u_mutex_t lock;
} pm_t;
#define PM_CREATE_DUMMY_TASK 0x1
@@ -59,7 +61,7 @@ static inline pm_flags_t pm_flags_init(uint8_t mem_block, uint8_t flags, pid_t p
};
}
void pm_svr_obj_init(pm_t *pm);
int pm_svr_obj_init(pm_t *pm);
int pm_rpc_run_app(const char *path, pm_flags_t pm_flags, char *params, int params_len_or_app_size, char *env, int envs_len);
int pm_rpc_kill_task(int src_pid, int pid, int flags, int exit_code);

View File

@@ -28,8 +28,7 @@ RPC_GENERATION_OP6(pm_t, PM_PROT, PM_RUN_APP, run_app,
rpc_ref_array_uint32_t_uint8_t_96_t, rpc_array_uint32_t_uint8_t_96_t, RPC_DIR_IN, RPC_TYPE_DATA, params,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, params_len,
rpc_ref_array_uint32_t_uint8_t_64_t, rpc_array_uint32_t_uint8_t_64_t, RPC_DIR_IN, RPC_TYPE_DATA, envs,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, envs_len
)
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, envs_len)
{
int16_t ret = -1;
@@ -38,17 +37,17 @@ RPC_GENERATION_OP6(pm_t, PM_PROT, PM_RUN_APP, run_app,
path->data[path->len - 1] = 0;
}
ret = pm_rpc_run_app((char *)path->data, pm_flags_init_raw(pm_flags->data),
(char *)params->data, params_len->data, (char *)envs->data, envs_len->data);
(char *)params->data, params_len->data, (char *)envs->data, envs_len->data);
return ret;
}
RPC_GENERATION_DISPATCH6(pm_t, PM_PROT, PM_RUN_APP, run_app,
rpc_ref_array_uint32_t_uint8_t_64_t, rpc_array_uint32_t_uint8_t_64_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, pm_flags,
rpc_ref_array_uint32_t_uint8_t_96_t, rpc_array_uint32_t_uint8_t_96_t, RPC_DIR_IN, RPC_TYPE_DATA, params,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, params_len,
rpc_ref_array_uint32_t_uint8_t_64_t, rpc_array_uint32_t_uint8_t_64_t, RPC_DIR_IN, RPC_TYPE_DATA, envs,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, envs_len)
rpc_ref_array_uint32_t_uint8_t_64_t, rpc_array_uint32_t_uint8_t_64_t, RPC_DIR_IN, RPC_TYPE_DATA, path,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, pm_flags,
rpc_ref_array_uint32_t_uint8_t_96_t, rpc_array_uint32_t_uint8_t_96_t, RPC_DIR_IN, RPC_TYPE_DATA, params,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, params_len,
rpc_ref_array_uint32_t_uint8_t_64_t, rpc_array_uint32_t_uint8_t_64_t, RPC_DIR_IN, RPC_TYPE_DATA, envs,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, envs_len)
/*kill_task*/
RPC_GENERATION_OP3(pm_t, PM_PROT, PM_KILL_TASK, kill_task,
@@ -114,6 +113,7 @@ RPC_GENERATION_OP2(pm_t, PM_PROT, PM_WATCH_PID, del_watch_pid,
RPC_GENERATION_DISPATCH2(pm_t, PM_PROT, PM_WATCH_PID, del_watch_pid,
rpc_umword_t_t, rpc_umword_t_t, RPC_DIR_IN, RPC_TYPE_DATA, pid,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, flags)
/*dispatch*/
RPC_DISPATCH4(pm_t, PM_PROT, typeof(PM_RUN_APP),
PM_RUN_APP, run_app,
@@ -121,8 +121,13 @@ RPC_DISPATCH4(pm_t, PM_PROT, typeof(PM_RUN_APP),
PM_WATCH_PID, watch_pid,
PM_COPY_DATA, copy_data)
void pm_svr_obj_init(pm_t *pm)
int pm_svr_obj_init(pm_t *pm)
{
int ret;
rpc_svr_obj_init(&pm->svr_obj, rpc_pm_t_dispatch, PM_PROT);
slist_init(&pm->watch_head);
ret = u_mutex_init(&pm->lock, handler_alloc());
return ret;
}

View File

@@ -25,6 +25,8 @@
#include "sig_svr.h"
#include "u_sema.h"
#include "u_task.h"
#include <ns_cli.h>
#ifdef CONFIG_USING_SIG
static sig_t sig_obj;
@@ -104,5 +106,13 @@ void sig_init(void)
assert(sema_wait_hd != HANDLER_INVALID);
tag = facotry_create_sema(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, sema_wait_hd), 0, 1);
assert(msg_tag_get_val(tag) >= 0);
char proc_path[20];
umword_t pid;
task_get_pid(TASK_THIS, &pid);
snprintf(proc_path, sizeof(proc_path), "/proc/%d", pid);
assert(ns_register(proc_path, sig_ipc, 0)>=0 && "task proc init failed.\n");
}
#endif

View File

@@ -66,9 +66,10 @@ int main(int argc, char *args[])
pm_init();
parse_cfg_init();
fs_ns_mkdir("/dev");
fs_ns_mkdir("/sys");
fs_ns_mkdir("/dev/shm");
fs_ns_mkdir("/dev", TASK_THIS);
fs_ns_mkdir("/sys", TASK_THIS);
fs_ns_mkdir("/proc", TASK_THIS);
fs_ns_mkdir("/dev/shm", TASK_THIS);
#if defined(MKRTOS_TEST_MODE)
printf("test_main..\n");
test_main();

View File

@@ -71,9 +71,10 @@ static int fs_svr_unlink(const char *path)
static int fs_svr_mkdir(char *path)
{
int ret;
int pid = thread_get_src_pid();
u_mutex_lock(&ns_lock, 0, NULL);
ret = fs_ns_mkdir(path);
ret = fs_ns_mkdir(path, pid);
u_mutex_unlock(&ns_lock);
return ret;
}
@@ -110,14 +111,14 @@ static int fs_svr_symlink(const char *src, const char *dst)
int namespace_register(const char *path, obj_handler_t hd, int type)
{
int ret;
int pid = thread_get_src_pid();
if (path[0] == '\0' || (path[0] == '/' && path[1] == '\0'))
{
return -EISDIR;
}
u_mutex_lock(&ns_lock, 0, NULL);
ret = ns_mknode(path, hd, NODE_TYPE_SVR);
ret = ns_mknode(path, hd, NODE_TYPE_SVR, pid);
if (ret < 0)
{
handler_free_umap(hd);

View File

@@ -14,17 +14,17 @@ int nsfs_mkdir_test(void)
{
int ret;
ret = fs_ns_mkdir("/bin/tst/");
ret = fs_ns_mkdir("/bin/tst/", 1);
assert(ret < 0);
ret = fs_ns_mkdir("/bin/");
ret = fs_ns_mkdir("/bin/", 1);
assert(ret >= 0);
ret = fs_ns_mkdir("/bin2");
ret = fs_ns_mkdir("/bin2", 1);
assert(ret >= 0);
ret = fs_ns_mkdir("/bin/tst/");
ret = fs_ns_mkdir("/bin/tst/", 1);
assert(ret >= 0);
ret = fs_ns_remove("/bin/tst");
ret = fs_ns_remove("/bin/tst", 1);
assert(ret < 0);
ret = fs_ns_rmdir("/bin/tst");
ret = fs_ns_rmdir("/bin/tst", 1);
assert(ret >= 0);
return 0;
}
@@ -33,7 +33,7 @@ int nsfs_scan_dir_test(void)
{
#define TEST_CN 10
int ret;
ret = fs_ns_mkdir("/bin/");
ret = fs_ns_mkdir("/bin/", 1);
assert(ret >= 0);
for (int i = 0; i < TEST_CN; i++)
@@ -41,7 +41,7 @@ int nsfs_scan_dir_test(void)
char dir_name[32];
snprintf(dir_name, sizeof(dir_name), "/bin/tst%d", i);
ret = fs_ns_mkdir(dir_name);
ret = fs_ns_mkdir(dir_name, 1);
assert(ret >= 0);
}
int fd;
@@ -103,9 +103,9 @@ int nsfs_mksvr_node(void)
int ret;
struct dirent dir;
ret = fs_ns_mkdir("/bin/");
ret = fs_ns_mkdir("/bin/", 1);
assert(ret >= 0);
ret = ns_mknode("/bin/tst1", 10, NODE_TYPE_SVR);
ret = ns_mknode("/bin/tst1", 10, NODE_TYPE_SVR, 1);
assert(ret >= 0);
int fd;
@@ -128,7 +128,7 @@ int nsfs_mksvr_node(void)
int nsfs_query_svr_node(void)
{
int ret;
ret = fs_ns_mkdir("/bin/");
ret = fs_ns_mkdir("/bin/", 1);
assert(ret >= 0);
ns_node_t *node;
ns_node_t *pnode;
@@ -139,7 +139,7 @@ int nsfs_query_svr_node(void)
assert(node == NULL && ret < 0);
#define SVR_NODE "/svr_tst"
ret = ns_mknode(SVR_NODE, 10, NODE_TYPE_SVR);
ret = ns_mknode(SVR_NODE, 10, NODE_TYPE_SVR, 1);
assert(ret >= 0);
node = ns_node_find_full_file(SVR_NODE, &ret, &cur_inx);
@@ -150,13 +150,13 @@ int nsfs_query_svr_node(void)
assert(node != NULL && ret >= 0);
assert(cur_inx == strlen(SVR_NODE) + 1);
ret = fs_ns_mkdir(SVR_NODE "/1");
ret = fs_ns_mkdir(SVR_NODE "/1", 1);
assert(ret < 0);
#undef SVR_NODE
ret = fs_ns_remove("/svr_tst");
assert(ret >= 0);
#define SVR_NODE "/bin/svr_tst"
ret = ns_mknode(SVR_NODE, 10, NODE_TYPE_SVR);
ret = ns_mknode(SVR_NODE, 10, NODE_TYPE_SVR, 1);
assert(ret >= 0);
node = ns_node_find_full_file(SVR_NODE, &ret, &cur_inx);
assert(node != NULL && ret >= 0);
@@ -180,7 +180,7 @@ int nsfs_stat_test(void)
struct stat fst;
int fd;
ret = fs_ns_mkdir("/tstdir/");
ret = fs_ns_mkdir("/tstdir/", 1);
assert(ret >= 0);
fd = fs_ns_open("/tstdir/", O_RDWR, 0777);
assert(fd >= 0);

View File

@@ -103,7 +103,7 @@ static int ns_node_del(ns_node_t *tree, ns_node_t *del_node)
}
return -1;
}
static ns_node_t *node_create(const char *name, node_type_t type)
static ns_node_t *node_create(const char *name, node_type_t type, int pid)
{
ns_node_t *tmp;
@@ -119,6 +119,7 @@ static ns_node_t *node_create(const char *name, node_type_t type)
strncpy(tmp->name, name, NS_NODE_NAME_LEN);
tmp->name[NS_NODE_NAME_LEN - 1] = 0;
tmp->type = type;
tmp->belong_pid = pid;
return tmp;
}
ns_node_t *ns_node_get_inx(ns_node_t *tree, int inx)
@@ -390,7 +391,7 @@ int ns_find_svr_obj(const char *path, obj_handler_t *svr_hd)
* 创建一个节点
* 只能在前置节点全部为dummy的节点里面创建节点
*/
int ns_mknode(const char *path, obj_handler_t svr_hd, node_type_t type)
int ns_mknode(const char *path, obj_handler_t svr_hd, node_type_t type, int pid)
{
ns_node_t *dir_node;
ns_node_t *new_node;
@@ -418,7 +419,7 @@ int ns_mknode(const char *path, obj_handler_t svr_hd, node_type_t type)
ns_node_strcpy(name, path + p_inx + 1, NS_NODE_NAME_LEN);
new_node = node_create(name, NODE_TYPE_DUMMY);
new_node = node_create(name, NODE_TYPE_DUMMY, pid);
if (new_node == NULL)
{
return -ENOMEM;

View File

@@ -28,12 +28,10 @@ typedef struct ns_node
node_type_t type; //!< 节点类型
struct ns_node *parent; //!< 父节点
struct ns_node *next; //!< 下一个
// union
// {
struct ns_node *sub; //!< 子树
obj_handler_t svr_hd; //!< 服务节点
// };
int ref; //!< 引用计数
struct ns_node *sub; //!< 子树
obj_handler_t svr_hd; //!< 服务节点
int belong_pid; //!< 属于哪个pid
int ref; //!< 引用计数
} ns_node_t;
#else
#include <u_types.h>
@@ -47,7 +45,7 @@ ns_node_t *ns_node_find_svr_file(const char *path, int *ret, int *cur_inx);
int ns_nodes_count(ns_node_t *tree);
ns_node_t *ns_node_get_inx(ns_node_t *tree, int inx);
int ns_delnode(const char *path);
int ns_mknode(const char *path, obj_handler_t svr_hd, node_type_t type);
int ns_mknode(const char *path, obj_handler_t svr_hd, node_type_t type, int pid);
static inline ns_node_t *ns_node_get_next(ns_node_t *tree_node, ns_node_t *cur_node)
{
assert(cur_node);

View File

@@ -405,10 +405,10 @@ int fs_ns_readdir(int fd, struct dirent *_dir)
}
return sizeof(*_dir);
}
int fs_ns_mkdir(char *path)
int fs_ns_mkdir(char *path, int pid)
{
int ret;
ret = ns_mknode(path, HANDLER_INVALID, NODE_TYPE_DUMMY);
ret = ns_mknode(path, HANDLER_INVALID, NODE_TYPE_DUMMY, pid);
return ret;
}
int fs_ns_open_init(void)

View File

@@ -14,6 +14,6 @@ int fs_ns_stat(const char *path, struct kstat *st);
int fs_ns_close(int fd);
int fs_ns_remove(const char *name);
int fs_ns_readdir(int fd, struct dirent *_dir);
int fs_ns_mkdir(char *path);
int fs_ns_mkdir(char *path, int pid);
int fs_ns_rmdir(const char *name);
int fs_ns_open_init(void);

View File

@@ -23,6 +23,8 @@
#include "nsfs.h"
#include "sig_cli.h"
#include "tty.h"
#include "u_task.h"
#include "u_factory.h"
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
@@ -32,10 +34,18 @@ static pm_t pm;
void pm_init(void)
{
pm_svr_obj_init(&pm);
assert(pm_svr_obj_init(&pm) >= 0);
meta_reg_svr_obj(&pm.svr_obj, PM_PROT);
// printf("pm runing..\n");
}
void pm_lock(void)
{
u_mutex_lock(&pm.lock, 0, NULL);
}
void pm_unlock(void)
{
u_mutex_unlock(&pm.lock);
}
/**
* @brief pid值是不是一个task
*
@@ -67,7 +77,7 @@ bool_t pm_pid_is_task(pid_t pid)
* @param pid
* @return watch_entry_t*
*/
watch_entry_t *pm_watch_lookup(pm_t *pm, pid_t src_pid, pid_t listen_pid)
static watch_entry_t *pm_watch_lookup(pm_t *pm, pid_t src_pid, pid_t listen_pid)
{
watch_entry_t *pos;
@@ -88,7 +98,7 @@ watch_entry_t *pm_watch_lookup(pm_t *pm, pid_t src_pid, pid_t listen_pid)
* @param pm
* @param pid 要删除的pid
*/
void pm_del_watch_by_pid(pm_t *pm, pid_t pid)
static void pm_del_watch_by_pid(pm_t *pm, pid_t pid)
{
watch_entry_t *pos;
@@ -119,8 +129,10 @@ int pm_rpc_watch_pid(pm_t *pm, obj_handler_t sig_rcv_hd, pid_t pid, int flags)
{
return -EINVAL;
}
pm_lock();
if (pm_watch_lookup(pm, src_pid, pid))
{
pm_unlock();
handler_free_umap(sig_rcv_hd);
return -EEXIST;
}
@@ -128,6 +140,7 @@ int pm_rpc_watch_pid(pm_t *pm, obj_handler_t sig_rcv_hd, pid_t pid, int flags)
if (!entry)
{
pm_unlock();
handler_free_umap(sig_rcv_hd);
return -ENOMEM;
}
@@ -140,6 +153,7 @@ int pm_rpc_watch_pid(pm_t *pm, obj_handler_t sig_rcv_hd, pid_t pid, int flags)
entry->flags = flags;
slist_init(&entry->node);
slist_add_append(&pm->watch_head, &entry->node);
pm_unlock();
printf("[pm] watch pid:%d, sig hd:%d.\n", pid, sig_rcv_hd);
return 0;
}
@@ -201,6 +215,7 @@ int pm_rpc_kill_task(int src_pid, int pid, int flags, int exit_code)
printf("pid is error.\n");
return -EINVAL;
}
pm_lock();
// ns_node_del_by_pid(pid, flags); TODO: //!< 从ns中删除
#if IS_ENABLED(CONFIG_USING_SIG)
if (src_pid != pid)
@@ -211,11 +226,11 @@ int pm_rpc_kill_task(int src_pid, int pid, int flags, int exit_code)
pm_send_sig_to_task(&pm, pid, KILL_SIG); //!< 给watch者发送sig
#endif
pm_del_watch_by_pid(&pm, pid); //!< 从watch中删除
pm_unlock();
printf("[pm] kill pid:%d code:%d.\n", pid, exit_code);
return 0;
}
#include "u_task.h"
#include "u_factory.h"
/**
* @return >0 pid <0 错误码
*/
@@ -349,27 +364,3 @@ int pm_rpc_copy_data(pid_t src_pid, pid_t dst_pid, umword_t src_addr, umword_t d
return msg_tag_get_val(tag);
}
#if 0
/**
* @brief 等待某个进程死亡
*/
int pm_waitpid(obj_handler_t sig_rcv_hd, pid_t pid)
{
pid_t src_pid = thread_get_src_pid();
watch_entry_t *pos;
/*TODO:检测sig_rcv_hd的类型*/
slist_foreach_not_next(pos, &pm->watch_head, node)
{
watch_entry_t *next = slist_next_entry(pos, &pm->watch_head, node);
if (pos->watch_pid == pid && src_pid == pos->src_pid)
{
pos->notify_sem_hd = sig_rcv_hd;
break;
}
pos = next;
}
return 0;
}
#endif

View File

@@ -1,7 +1,7 @@
cd /mnt
tcc -nostdinc -nostdlib -c /bin/main.c -o main.o -pie
tcc -nostdinc -nostdlib -c /bin/cons.c -o cons.o -pie
as -mthumb -mcpu=cortex-m3 /bin/start.S -o start.o -pie
as -mthumb -mcpu=cortex-m3 /bin/syscall.S -o syscall.o -pie
ld start.o main.o cons.o syscall.o -T/bin/link_pie.lds -o a.out --section-start .text=0x20144000 -pie
tcc -nostdinc -nostdlib -c /bin/main.c -o main.o
tcc -nostdinc -nostdlib -c /bin/cons.c -o cons.o
as -mthumb -mcpu=cortex-m3 /bin/start.S -o start.o
as -mthumb -mcpu=cortex-m3 /bin/syscall.S -o syscall.o
ld start.o main.o cons.o syscall.o -T/bin/link_pie.lds -o a.out --section-start .text=0x20144000
objcopy -O binary -S a.out a.bin