鸿蒙移植i.mx6ull(十二) 根文件系统
文章目录
- 1.根文件系统内容与制作
-
- 1.1 最终结果
- 1.2 根文件系统的内容
- 1.3 根文件系统的制作
-
- 1.3.1 Makefile分析
-
- 1. ROOTFS目标:
- 2. 编译APP
- 1.3.2 演示
- 2.正式版本的init进程
-
- 2.1 测试版本
- 2.2 正式版本
-
- 2.2.1 配置文件
-
- 1. 分析配置文件
- 2. 示例
- 3. 配置文件执行过程
1.根文件系统内容与制作
1.1 最终结果
本章节做的修改会制作为补丁文件:
05_openharmony_rootfs.patch
假设目录openharmony
中是未修改的代码,从没打过补丁;
假设补丁文件放在openharmony的同级目录;
对于STM32MP157,打补丁方法如下:
$ cd openharmony$ patch -p1 < ../openharmony_100ask_v1.2.patch$ patch -p1 < ../01_openharmony_add_demo_board.patch$ patch -p1 < ../02_openharmony_memmap_stm32mp157.patch $ patch -p1 < ../03_openharmony_uart_stm32mp157.patch$ patch -p1 < ../04_openharmony_ramfs_stm32mp157.patch$ patch -p1 < ../05_openharmony_rootfs.patch
对于IMX6ULL,打补丁方法如下:
$ cd openharmony$ patch -p1 < ../openharmony_100ask_v1.2.patch$ patch -p1 < ../01_openharmony_add_demo_board.patch$ patch -p1 < ../02_openharmony_memmap_imx6ull.patch $ patch -p1 < ../03_openharmony_uart_imx6ull.patch$ patch -p1 < ../04_openharmony_ramfs_imx6ull.patch$ patch -p1 < ../05_openharmony_rootfs.patch
打上补丁后,可以如此编译(对于STM32MP157、IMX6ULL,编译命令是一样的):
$ cd kernel/liteos_a$ cp tools/build/config/debug/demochip_clang.config .config$ make clean$ make$ make rootfs
1.2 根文件系统的内容
看看一个简单的程序:
#include int main(int argc, char **argv){printf("hello, world!\n"); return 0;}
可以编译出一个APP:hello。
有几个问题要考虑:
- printf不是我们实现的,它在哪?
- hello放在板子上后,怎么启动它?能否自动启动?
解决这几个问题后,就可以知道根文件系统的内容了:
- /lib:库,比如printf函数就是在库里的
- /bin:APP,hello这样的程序放在/bin或/usr/bin这些目录里
- 至少有这些APP:
- init:内核启动的第一个APP,它会去启动其他APP,比如shell
- shell:也是一个APP,可以让我们输入各类命令
- 我们自己的APP:比如hello
- /etc:想自动启动APP怎么办?应该有配置文件,init进程根据配置文件去启动其他APP
- 比如/etc/init.cfg
- /dev:设备节点,在Liteos-a中不需要我们自己创建
1.3 根文件系统的制作
1.3.1 Makefile分析
在kernnel/liteos_a
目录执行make help
:
book@100ask:~/openharmony/kernel/liteos_a$ make help-------------------------------------------------------1.====make help: get help infomation of make2.====make: make a debug version based the .config3.====make debug: make a debug version based the .config4.====make release: make a release version for all platform5.====make release PLATFORM=xxx: make a release version only for platform xxx6.====make rootfsdir: make a original rootfs dir7.====make rootfs FSTYPE=***: make a original rootfs img8.====make test: make the testsuits_app and put it into the rootfs dir9.====make test_apps FSTYPE=***: make a rootfs img with the testsuits_app in itxxx should be one of (hi3516cv300 hi3516ev200 hi3556av100/cortex-a53_aarch32 hi3559av100/cortex-a53_aarch64)*** should be one of (jffs2)-------------------------------------------------------
可以知道:执行make rootfs
可以制作根文件系统。
分析Makefile确定它的制作过程。
1. ROOTFS目标:
$(ROOTFS): $(ROOTFSDIR)$(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/rootfsimg.sh $(ROOTFS_DIR) $(FSTYPE) ${ROOTFS_SIZE})$(HIDE)cd $(ROOTFS_DIR)/.. && zip -r $(ROOTFS_ZIP) $(ROOTFS)ifneq ($(OUT), $(LITEOS_TARGET_DIR))$(HIDE)mv $(ROOTFS_DIR) $(LITEOS_TARGET_DIR)rootfsendif$(ROOTFSDIR): prepare $(APPS)$(HIDE)$(MAKE) clean -C apps$(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/rootfsdir.sh $(OUT)/bin $(OUT)/musl $(ROOTFS_DIR))ifneq ($(VERSION),)$(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/releaseinfo.sh "$(VERSION)" $(ROOTFS_DIR))endifprepare:$(HIDE)mkdir -p $(OUT)/muslifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y)$(HIDE)cp -f $(LITEOSTOPDIR)/../../prebuilts/lite/sysroot/usr/lib/$(LLVM_TARGET)/a7_softfp_neon-vfpv4/libc.so $(OUT)/musl$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/lib/$(LLVM_TARGET)/c++/a7_softfp_neon-vfpv4/libc++.so $(OUT)/muslelse$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/target/usr/lib/libc.so $(OUT)/musl$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/arm-linux-musleabi/lib/libstdc++.so.6 $(OUT)/musl$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/arm-linux-musleabi/lib/libgcc_s.so.1 $(OUT)/musl$(STRIP) $(OUT)/musl/*endif$(APPS): $(LITEOS_TARGET)$(HIDE)$(MAKE) -C apps all
- ROOTFSDIR:使用rootfsdir.sh创建一些目录
- prepare:复制libc.so、libc++.so
- APPS:进入apps目录执行
make all
2. 编译APP
有目录:kernel/liteos_a/apps
,这个目录下有:
-
module.mk:定义了
APP_SUBDIRS += shellAPP_SUBDIRS += init
-
Makefile:
$(APPS):ifneq ($(APP_SUBDIRS), ) $(HIDE) for dir in $(APP_SUBDIRS); do $(MAKE) -C $$dir ; doneendif
就是再次进入shell、init目录,执行
make
命令,去变量shell程序、init程序。
1.3.2 演示
2.正式版本的init进程
Liteos-a中有两个init程序:
- 测试版本:
kernel\liteos_a\apps\init\src\init.c
- 正式版本:
base\startup\services\init_lite\src\main.c
2.1 测试版本
源码:kernel\liteos_a\apps\init\src\init.c
我们在kernel\liteos_a
目录下执行make rootfs
时使用的就是测试版本,
它的功能很简单:只是启动/bin/shell
程序,源码如下:
int main(int argc, char * const *argv){ int ret; const char *shellPath = "/bin/shell"; ret = fork(); if (ret < 0) { printf("Failed to fork for shell\n"); } else if (ret == 0) { (void)execve(shellPath, NULL, NULL); exit(0); } while (1) { ret = waitpid(-1, 0, WNOHANG); if (ret == 0) { sleep(1); } };}
2.2 正式版本
源码:base\startup\services\init_lite\src\main.c
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ow6qRbJy-1654659092800)(pic/10_根文件系统/01_init_main.c.png)]
怎么单独编译正式版本,尚未研究。
可以使用这样的命令去编译:python build.py ipcamera_hi3518ev300 -b debug
可以得到rootfs目录,里面有/bin/init, /etc/init.cfg
等文件。
2.2.1 配置文件
1. 分析配置文件
配置文件中内容分为两部分:
- services:定义了多个服务,它对应某些APP
- jobs:可以定义一些APP,也可去启动服务
- pre-init:预先执行的初始化
- init:初始化
- post-init:最后的初始化
2. 示例
./vendor/huawei/camera/init_configs/init_liteos_a_3516dv300.cfg./vendor/huawei/camera/init_configs/init_liteos_a_3518ev300.cfg
3. 配置文件执行过程
视频里讲解。
开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系