目录
一、根文件系统
1.1 鸿蒙根文件系展示
两步走先创建一个文件夹存放我们必须的系统库,可执行文件等然后把这个文件夹做成映像文件,这样才能烧入到flash里。
1.2 根文件系统的内容
看看一个简单的程序:
#include <stdio.h> 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
:
可以知道:执行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)rootfs
endif
$(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))
endif
prepare:
$(HIDE)mkdir -p $(OUT)/musl
ifeq ($(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)/musl
else
$(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
make -C 目录 目标 : 进入这个目录去执行对应目标
makefile会使用tool目录下的脚本去制作根文件系统
linux内核只能用上面的那个文件系统,突然发现之前哭错坟了。我在移植openhamony,去hamonyOS那里去问问题,我说今天仔细一看怎么社区里都是基于java写的代码。
2. 编译APP
有目录:kernel/liteos_a/apps
,这个目录下有:
-
module.mk:定义了
APP_SUBDIRS += shell APP_SUBDIRS += init
-
Makefile:
$(APPS): ifneq ($(APP_SUBDIRS), ) $(HIDE) for dir in $(APP_SUBDIRS); do $(MAKE) -C $$dir ; done endif
就是再次进入shell、init目录,执行
make
命令,去变量shell程序、init程序。
1.3.2 演示
我们之前用内存模拟了flash,假设根文件系统2MB这里还有剩余的8MB内存没初始化,要么就用uboot去都写上全F要么就把8MB的全F填充到2MB的后面。老师说mp157不好使用uboot做这个操作,原因不详,反正6ull和mp157两个板子一个用一种方式。
这面编译没问题呢
他现在是10MB的,但是我们不想他是10MB看看咋回事
脚本里把这个扩充成了10MB,这里的大小是我们之前在makefile中定义的,makefile用这个脚本时第三个参数指定了大小。
文件系统我们改回jffs2
.bin是给157用的因为它只支持后缀名是bin的。
忘记改名字了还是10MB,再来修改一下shell
#!/bin/bash
#
# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set -e
system=$(uname -s)
ROOTFS_DIR=$1
FSTYPE=$2
ROOTFS_SIZE=$3
ROOTFS_IMG=${ROOTFS_DIR}".img"
ROOTFS_JFFS2=${ROOTFS_DIR}".jffs2"
JFFS2_TOOL=$(dirname $(readlink -f "$0"))/../../fsimage/mkfs.jffs2
WIN_JFFS2_TOOL=$(dirname $(readlink -f "$0"))/../../fsimage/win-x86/mkfs.jffs2.exe
if [ "${ROOTFS_DIR}" = "*rootfs" ]; then
chmod -R 755 ${ROOTFS_DIR}
chmod 700 ${ROOTFS_DIR}/bin/init 2> /dev/null
chmod 700 ${ROOTFS_DIR}/bin/shell 2> /dev/null
fi
if [ "${FSTYPE}" = "jffs2" ]; then
if [ "${system}" != "Linux" ] ; then
${WIN_JFFS2_TOOL} -q -o ${ROOTFS_IMG} -d ${ROOTFS_DIR} --pagesize=4096
else
chmod +x ${JFFS2_TOOL}
echo ${JFFS2_TOOL} -q -o ${ROOTFS_IMG} -d ${ROOTFS_DIR} --pagesize=4096 --pad=${ROOTFS_SIZE}
${JFFS2_TOOL} -q -o ${ROOTFS_IMG} -d ${ROOTFS_DIR} --pagesize=4096 --pad=${ROOTFS_SIZE}
${JFFS2_TOOL} -q -o ${ROOTFS_JFFS2} -d ${ROOTFS_DIR} --pagesize=4096
cp ${ROOTFS_JFFS2} ${ROOTFS_DIR}".jffs2"
cp ${ROOTFS_IMG} ${ROOTFS_DIR}".jffs2.bin"
fi
elif [ "${FSTYPE}" = "vfat" ]; then
if [ "${system}" != "Linux" ] ; then
echo "Unsupported fs type!"
else
BLK_SIZE=512
CLT_SIZE=2048
FAT_TAB_NUM=2
CLT_CNT=$(( ${CLT_SIZE} / ${BLK_SIZE} ))
if [ $# -eq 3 ]; then
IMG_SIZE=$3
else
FAT32_ITEM_SIZE=4
RESV_CNT=38
IMG_MIN_SIZE=1048576
DIR_SIZE=$(( $(echo $(du -s ${ROOTFS_DIR} | awk '{print $1}')) * 1024 ))
IMG_SIZE=$(( ${DIR_SIZE} / (1 - ${FAT_TAB_NUM} * ${FAT32_ITEM_SIZE} / ${CLT_SIZE}) + ${RESV_CNT} * ${BLK_SIZE}))
if [ ${IMG_SIZE} -le ${IMG_MIN_SIZE} ]; then
IMG_SIZE=${IMG_MIN_SIZE}
fi
fi
IMG_CNT=$(( (${IMG_SIZE} + ${BLK_SIZE} - 1) / ${BLK_SIZE} ))
echo mtools_skip_check=1 >> ~/.mtoolsrc
dd if=/dev/zero of=${ROOTFS_IMG} count=${IMG_CNT} bs=${BLK_SIZE}
mkfs.vfat ${ROOTFS_IMG} -s ${CLT_CNT} -f ${FAT_TAB_NUM} -S ${BLK_SIZE} > /dev/null
mcopy -i ${ROOTFS_IMG} ${ROOTFS_DIR}/* -/ ::/
fi
else
echo "Unsupported fs type!"
fi
现在就ok了只有1019k了
名字不对原来,cp报错了没看到
这次没毛病了
二、正式版本的init进程
Liteos-a中有两个init程序:
-
测试版本:
kernel\liteos_a\apps\init\src\init.c
-
正式版本:
base\startup\services\init_lite\src\main.c
我之前在杭州实习的时候还研究过linux的init进程之前写过一篇文章,有好多东西当时记得后面离职了一个多月再回来写都忘记了。
简单来说就是init-》sysV init-》systemd
1.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);
}
};
}
1.2 正式版本
源码:base\startup\services\init_lite\src\main.c
怎么单独编译正式版本,尚未研究。 可以使用这样的命令去编译:python build.py ipcamera_hi3518ev300 -b debug
可以得到rootfs目录,里面有/bin/init, /etc/init.cfg
等文件。
1.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
{
"jobs" : [{
"name" : "pre-init",
"cmds" : [
"mkdir /storage/data/log",
"chmod 0755 /storage/data/log",
"chown 4 4 /storage/data/log",
"mkdir /storage/data/softbus",
"chmod 0700 /storage/data/softbus",
"chown 7 7 /storage/data/softbus",
"mkdir /sdcard",
"chmod 0777 /sdcard",
"mount vfat /dev/mmcblk0 /sdcard rw,umask=000",
"mount vfat /dev/mmcblk1 /sdcard rw,umask=000"
]
}, {
"name" : "init",
"cmds" : [
"start shell",
"start apphilogcat",
"start foundation",
"start bundle_daemon",
"start appspawn",
"start media_server",
"start wms_server"
]
}, {
"name" : "post-init",
"cmds" : [
"chown 0 99 /dev/dev_mgr",
"chown 0 99 /dev/hdfwifi",
"chown 0 99 /dev/gpio",
"chown 0 99 /dev/i2c-0",
"chown 0 99 /dev/i2c-1",
"chown 0 99 /dev/i2c-2",
"chown 0 99 /dev/i2c-3",
"chown 0 99 /dev/i2c-4",
"chown 0 99 /dev/i2c-5",
"chown 0 99 /dev/i2c-6",
"chown 0 99 /dev/i2c-7",
"chown 0 99 /dev/uartdev-0",
"chown 0 99 /dev/uartdev-1",
"chown 0 99 /dev/uartdev-2",
"chown 0 99 /dev/uartdev-3",
"chown 0 99 /dev/spidev0.0",
"chown 0 99 /dev/spidev1.0",
"chown 0 99 /dev/spidev2.0",
"chown 0 99 /dev/spidev2.1"
]
}
],
"services" : [{
"name" : "foundation",
"path" : "/bin/foundation",
"uid" : 7,
"gid" : 7,
"once" : 0,
"importance" : 1,
"caps" : [10, 11, 12, 13]
}, {
"name" : "shell",
"path" : "/bin/shell",
"uid" : 2,
"gid" : 2,
"once" : 0,
"importance" : 0,
"caps" : [4294967295]
}, {
"name" : "appspawn",
"path" : "/bin/appspawn",
"uid" : 1,
"gid" : 1,
"once" : 0,
"importance" : 0,
"caps" : [2, 6, 7, 8, 23]
}, {
"name" : "apphilogcat",
"path" : "/bin/apphilogcat",
"uid" : 4,
"gid" : 4,
"once" : 1,
"importance" : 0,
"caps" : []
}, {
"name" : "media_server",
"path" : "/bin/media_server",
"uid" : 5,
"gid" : 5,
"once" : 1,
"importance" : 0,
"caps" : []
}, {
"name" : "wms_server",
"path" : "/bin/wms_server",
"uid" : 0,
"gid" : 0,
"once" : 1,
"importance" : 0,
"caps" : []
}, {
"name" : "bundle_daemon",
"path" : "/bin/bundle_daemon",
"uid" : 8,
"gid" : 8,
"once" : 0,
"importance" : 0,
"caps" : [0, 1]
}
]
}
这种配置文件都是这种键值对的形式,我现在也分不清应该叫他哈希还是json了
3. 配置文件执行过程
各种dojob,job的内容就是上面那些
系统移植到这就完成了