Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
rt-smart
动态库
RT-Smart elf 动态加载技术 : 开启 ldso 动态加载
发布于 2023-12-18 20:40:47 浏览:941
订阅该版
[tocm] ## 前言 - RT-Smart,类似于Linux,可以动态的加载运行 应用程序 elf 文件 - 应用程序 elf 文件,有的是静态链接编译的,有的是动态链接编译的,动态链接编译的,还需要加载 动态共享库 (.so) - 本篇讲解一下 RT-Smart 上 elf 动态加载功能的实现,顺便讲一下动态加载的原理 ## 环境搭建 - RT-Thread 版本: 当前 最新 master 主线版本 - BSP : `bsp/qemu-virt64-aarch64` - 开启 RT-Smart - dfs : V2 版本,开启 pagecache - 开启 ldso 动态加载 - 使用开启了 ldso 功能的 musl gcc 交叉编译工具链编译内核与应用程序 ## 开启 RT-Smart - `bsp/qemu-virt64-aarch64` 支持 RT-Smart,Linux 环境下可以直接通过 `scons --menuconfig` 开启 ![2023-12-18_195045.png](https://oss-club.rt-thread.org/uploads/20231218/413bd1f5a1008edce59461812f6b60ca.png) ## 开启 dfs v2 版本 - 当前 RT-Thread dfs 有两个版本,默认是 v1,这里需要开启 v2,支持 pagecache 功能、文件 mmap 功能 ![2023-12-18_195411.png](https://oss-club.rt-thread.org/uploads/20231218/abc0757ce31c384a67f18f5b7e08c907.png) ![2023-12-18_195423.png](https://oss-club.rt-thread.org/uploads/20231218/39d90e4bf0dd97f9ba8db98c8020c921.png) ## 开启 ldso 动态加载功能 - ldso 功能默认如果没有开启,就手动开启一下 ![2023-12-18_195549.png](https://oss-club.rt-thread.org/uploads/20231218/efa0785b7c68ebf51368a52aa4863e08.png) ![2023-12-18_195558.png](https://oss-club.rt-thread.org/uploads/20231218/83f4a4b25acfab093c1d40bf9e757532.png) ## 下载开启了 musl gcc 的 aarch64 平台交叉编译工具链 - 由于 `bsp/qemu-virt64-aarch64` 属于 ARM 64位平台(aarch64),因此需要 使用 aarch64 平台的 musl gcc 交叉编译工具链 - 由于早期的 musl gcc 交叉编译工具链 可能没有开启 ldso 动态加载功能,所以需要下载 RT-Thread 官方最新的 musl gcc aarch64 平台 交叉编译工具链 - Linux 开发平台 musl gcc 下载地址 [https://download.rt-thread.org/download/rt-smart/toolchains/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2](https://download.rt-thread.org/download/rt-smart/toolchains/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2) - Windows 开发平台 musl gcc 下载地址 [ https://download.rt-thread.org/download/rt-smart/toolchains/aarch64-linux-musleabi_for_i686-w64-mingw32_latest.zip ]( https://download.rt-thread.org/download/rt-smart/toolchains/aarch64-linux-musleabi_for_i686-w64-mingw32_latest.zip ) - 配置 musl gcc 交叉编译工具链的环境变量 - Linux 开发环境下: ```c #!/bin/bash # aarch64 musl gcc export RTT_CC=gcc export RTT_EXEC_PATH=/home/zhangsz/smart/tools/gnu_gcc/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu/bin export RTT_CC_PREFIX=aarch64-linux-musleabi- export PATH=$PATH:$RTT_EXEC_PATH ``` - Windows 开发环境下 ```c @set RTT_CC=gcc @set RTT_EXEC_PATH=%cd%\tools\gnu_gcc\aarch64-linux-musleabi_for_i686-w64-mingw32\bin @set RTT_CC_PREFIX=aarch64-linux-musleabi- @set PATH=%RTT_EXEC_PATH%;%ENV_ROOT%\tools\gnu_gcc\arm_gcc\mingw\bin;%PATH% ``` ## 编译与运行 `bsp/qemu-virt64-aarch64` - 进入 `bsp/qemu-virt64-aarch64`,然后运行 `scons -j8` 即可编译 - 运行方法: 运行 `qemu.sh` 即可运行 - 运行信息 ![2023-12-18_200603.png](https://oss-club.rt-thread.org/uploads/20231218/7dcd1c92293572350dfd16c4928ce0e5.png) ## 编写应用程序 - RT-Smart 应用 app 可以独立编译,当前测试程序文件列表如下 ![2023-12-18_202420.png](https://oss-club.rt-thread.org/uploads/20231218/cfb63f3b7facc8bbb84221daf9aecfc4.png) - `env_aarch64.sh` 设置 musl gcc 环境变量 `source env_aarch64.sh` ```c #!/bin/bash # aarch64 musl gcc export RTT_CC=gcc export RTT_EXEC_PATH=/home/zhangsz/smart/tools/gnu_gcc/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu/bin export RTT_CC_PREFIX=aarch64-linux-musleabi- export PATH=$PATH:$RTT_EXEC_PATH ``` - Makefile 文件: 用于 make 编译,当然可以使用 `scons` 编译,不过需要编译脚本 ```c all: aarch64-linux-musleabi-gcc -shared -fPIC -o libt0.so libt0.c -L./ -I./ aarch64-linux-musleabi-gcc -fPIC -o t0_s.elf t0.c -L./ -I./ -lt0 clean: rm -rf ./*.so rm -rf ./*.elf rm -rf ./*.o ``` - libt0.c :生成 `libt0.so` ```c #include "libt0.h" #include
#include
static dl_t0_t t0 = { .cmd = 0xAABBCCDD, .data = 0x8999EEFF, }; int t0_data_get(dl_t0_t *p) { if (p) { memcpy(p, &t0, sizeof(t0)); return 0; } else { printf("%s : param is null!\n", __func__); return -1; } } int t0_data_set(dl_t0_t *p) { if (p) { memset(&t0, 0, sizeof(t0)); t0.cmd = p->cmd; t0.data = p->data; return 0; } else { printf("%s : param is null!\n", __func__); return -1; } } ``` - libt0.h : libt0.so 的头文件 ```c #ifndef __LIBT0_H__ #define __LIBT0_H__ #include
struct dl_t0_s { uint32_t cmd; uint32_t data; }; typedef struct dl_t0_s dl_t0_t; /* export api */ int t0_data_get(dl_t0_t *p); int t0_data_set(dl_t0_t *p); #endif //__LIBT0_H__ ``` - t0.c 测试文件: 生成动态编译链接的应用程序 ```c #include "libt0.h" #include
#include
#include
#include
#include
static int dl_test(void) { int ret = 0; dl_t0_t ts1 = { 0 }; ret = t0_data_get(&ts1); if (ret) { printf("%s : t0_data_get error\n", __func__); return ret; } printf("%s : ------------get-----------\r\n", __func__); printf("%s : [get] ts.cmd = 0x%x\r\n", __func__, ts1.cmd); printf("%s : [get] ts.data = 0x%x\r\n", __func__, ts1.data); return 0; } int main(int argc, char **argv) { int ret = 0; printf("%s : test start\r\n", __func__); ret = dl_test(); if (ret) { printf("%s : --- dl test1 error ----\r\n", __func__); } else { printf("%s : --- dl test1 OK ----\r\n", __func__); } return 0; } ``` - `source env_aarch64.sh` 设置 musl gcc 交叉编译工具链环境变量 - `make` 编译,生成 `libt0.so` 与 `t0_s.elf` ## 复制文件 - 首先使用 `mkdir rootfs` 创建 sd.bin 镜像的挂载目录 - `sudo mount sd.bin rootfs` ,把 sd.bin 挂载到 rootfs 目录下,当前默认是 elf fat 文件系统 - `sudo mkdir rootfs/lib`, 创建 lib 目录 - 复制 app 与 so 文件 ```c sudo cp /home/zhangsz/smart/apps/libt0.so rootfs/lib/ sudo cp /home/zhangsz/smart/apps/t0_s.elf rootfs/ ``` - 复制 libc.so 到 rootfs,注意这个 libc.so 来自 musl gcc 交叉编译工具链 `sudo cp /home/zhangsz/smart/gnu_tools/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu/aarch64-linux-musleabi/lib/libc.so rootfs/lib/` - 【注意事项】:musl 动态加载时,aarch64 平台默认加载 `/lib/ld-musl-aarch64.so.1`,这个 `/lib/ld-musl-aarch64.so.1` 是 `libc.so` 的文件软链接(符号),由于 elm fat 文件系统不支持符号链接,所以可以直接把 `libc.so` 复制为 `/lib/ld-musl-aarch64.so.1` `sudo cp rootfs/libc.so rootfs/ld-musl-aarch64.so.1` : 动态加载器(libc.so) `sudo umount rootfs` 退出镜像文件挂载 ## 运行动态加载 - 再次执行 `qemu.sh` - 运行 `t0_s.elf`,查看运行信息 ![2023-12-18_203637.png](https://oss-club.rt-thread.org/uploads/20231218/b3301633f2cd328b5daff2f85ad60542.png) - 说明 RT-Smart ldso elf 文件动态加载正常运行 ## 报错信息与处理方法 - 如果没有 `/lib/ld-musl-aarch64.so.1`,复制 `libc.so` -> `/lib/ld-musl-aarch64.so.1` ![2023-12-18_203757.png](https://oss-club.rt-thread.org/uploads/20231218/906317ce84c1654e2a4c63d3d7648181.png) - 如果提示缺少库,需要把 缺少的库,放在 /lib 目录下 ![2023-12-18_203842.png](https://oss-club.rt-thread.org/uploads/20231218/5e191d0458b21cbe996d64c26fab54c5.png) ## 小结 - 本篇讲解了 RT-Smart 动态加载(动态编译链接应用程序 elf)的功能配置,当然也支持 静态编译链接的应用程序 elf - 后面抽时间讲解一下 ldso 动态加载的原理,希望对想了解 动态加载原理的同学提供一点参考
3
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
张世争
学以致用
文章
131
回答
805
被采纳
174
关注TA
发私信
相关文章
1
rt-smart发布时间
2
rt-smart qemu-vexpress-a9 编译报错
3
rt-smart分支编译rasp4-32bsp报错
4
rt-smart qemu-vexpress-a9 win10编译脚本问题
5
rt-smart qemu-vexpress-a9 linux 下crtl+c
6
rt-smart + pthread 编译报错
7
rt-smart的rt_channel实现问题
8
关于rt-smart的musl-libc
9
RT-Smart Windows 编译 qemu-vexpress-a9 出错
10
用户程序在RT-Smart存在的方式
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部