008——根文件系统(基于鸿蒙liteos-a内核)

目录

一、根文件系统

[1.1 鸿蒙根文件系展示](#1.1 鸿蒙根文件系展示)

[1.2 根文件系统的内容](#1.2 根文件系统的内容)

[1.3 根文件系统的制作](#1.3 根文件系统的制作)

[1.3.1 Makefile分析](#1.3.1 Makefile分析)

[1. ROOTFS目标:](#1. ROOTFS目标:)

[2. 编译APP](#2. 编译APP)

[1.3.2 演示](#1.3.2 演示)

二、正式版本的init进程

[1.1 测试版本](#1.1 测试版本)

[1.2 正式版本](#1.2 正式版本)

[1.2.1 配置文件](#1.2.1 配置文件)

[1. 分析配置文件](#1. 分析配置文件)

[2. 示例](#2. 示例)

[3. 配置文件执行过程](#3. 配置文件执行过程)


一、根文件系统

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.solibc++.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

bash 复制代码
#!/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程序,源码如下:

cpp 复制代码
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
cpp 复制代码
{
    "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的内容就是上面那些

系统移植到这就完成了

相关推荐
憧憬一下10 小时前
Pinctrl子系统中Pincontroller和client驱动程序的编写
arm开发·嵌入式·c/c++·linux驱动开发
蓝天居士10 小时前
ES8388 —— 带耳机放大器的低功耗立体声音频编解码器(4)
嵌入式·音频·es8388
田三番12 小时前
使用 vscode 简单配置 ESP32 连接 Wi-Fi 每日定时发送 HTTP 和 HTTPS 请求
单片机·物联网·http·https·嵌入式·esp32·sntp
启明智显16 小时前
AI笔筒操作说明及应用场景
人工智能·嵌入式硬件·嵌入式·ai大模型·启明智显·esp32-s3
FreakStudio1 天前
全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现
python·单片机·嵌入式·面向对象·电子diy
Dangks2 天前
[运维] 服务器本地网络可用性检查脚本
linux·运维·服务器·shell·network·系统工具
DreamADream4 天前
Shell编程中关于用户操作报错`用户无法登录`
shell
Projectsauron5 天前
【STM32】通过 DWT 实现毫秒级延时
stm32·嵌入式·dwt
云中双月5 天前
如何使用Ida Pro和Core Dump文件定位崩溃位置(Linux下无调试符号的进程专享)
linux·嵌入式·gdb·调试·gcc·崩溃·ida pro·ulimit·core dump·cross compile
L_Z_J_I7 天前
超子物联网HAL库笔记:准备篇
笔记·物联网·嵌入式