在OpenstLinux根文件系统里增加自己的应用程序

文章介绍了如何处理Flash_layout文件以配置根文件系统,包括挂载ext4文件系统、将二进制文件放入bin目录以及使用交叉编译环境在STM32MP157设备上移植和运行HelloWorld程序的过程。

前言

首先打开Flash_layout布局文件,可以看到如下内容:

#Opt   Id      Name    Type    IP      Offset  Binary
-       0x01    fsbl1-boot      Binary  none    0x0     arm-trusted-firmware/tf-a-stm32mp157f-ev1-serialboot.stm32
-       0x03    ssbl-boot       Binary  none    0x0     bootloader/u-boot-stm32mp157f-ev1-trusted.stm32
P       0x04    fsbl1   Binary  mmc1    boot1   arm-trusted-firmware/tf-a-stm32mp157f-ed1-trusted.stm32
P       0x05    fsbl2   Binary  mmc1    boot2   arm-trusted-firmware/tf-a-stm32mp157f-ed1-trusted.stm32
PD      0x06    ssbl    Binary  mmc1    0x00080000      bootloader/u-boot-stm32mp157f-ed1-trusted.stm32
P       0x21    boot    System  mmc1    0x00280000      st-image-bootfs-openstlinux-eglfs-stm32mp1.ext4
P       0x22    vendorfs        FileSystem      mmc1    0x04280000      st-image-vendorfs-openstlinux-eglfs-stm32mp1.ext4
P       0x23    rootfs  FileSystem      mmc1    0x05280000      st-image-core-openstlinux-eglfs-stm32mp1.ext4
P       0x24    userfs  FileSystem      mmc1    0x33C80000      st-image-userfs-openstlinux-eglfs-stm32mp1.ext4

其中rootfs那一行就是烧录的根文件系统,制作好的根文件系统就像磁盘一样,可以随意烧录到分区上供内核使用,st-image-core-openstlinux-eglfs-stm32mp1.ext4,可以看到它的后缀是.ext4,说明文件系统格式是ext4,我们可以通过Linux上提供的mount命令来挂载文件系统:

sudo mount -t ext4 st-image-core-openstlinux-eglfs-stm32mp1.ext4 /mnt

然后我们cd到mnt目录下可以看到如下内容:

bin  boot  dev  etc  home  lib  lost+found  media  mnt  proc  run  sbin  sys  tmp  usr  var  vendor

这些文件夹都是按照Linux内核所需要的格式提供的,Linux内核启动时会需要文件系统下存在这些文件夹,用于Linux内核做初始化,这些目录结构非常眼熟和我们平时装好发行版时提供的文件夹结构是一样的。

不同的系统内核所需要的文件夹也是不同的,这里我们重点关注bin这个文件夹,这里的bin就相当于我们/usr/bin目录,这个文件夹里存放了bin文件,我们可以将我们编译好的二进制文件放入到这个文件夹里去就可以了。

这里可以看一下bin文件夹下的内容:

arping            date.coreutils     hostname.coreutils  mountpoint             sed                             tar
ash               dd                 journalctl          mountpoint.util-linux  sh                              tar.tar
base64            dd.coreutils       kill                mount.util-linux       sleep                           tempfile
bash              df                 kill.coreutils      mv                     sleep.coreutils                 tempfile.debianutils
bash.bash         dmesg              kill.procps         mv.coreutils           stat                            tftpd
busybox           dmesg.util-linux   kill.util-linux     netstat                stat.coreutils                  touch
busybox.nosuid    dnsdomainname      kmod                networkctl             stty                            touch.coreutils
busybox.suid      dumpkmap           ln                  nice                   stty.coreutils                  tracepath
cat               echo               ln.coreutils        pidof                  su                              traceroute6
cat.coreutils     echo.coreutils     login               pidof.procps           su.shadow                       true
chattr            egrep              loginctl            ping                   su.util-linux                   true.coreutils
chattr.e2fsprogs  egrep.grep         login.shadow        ping6                  sync                            udevadm
chgrp             false              ls                  ping.iputils           sync.coreutils                  umount
chgrp.coreutils   false.coreutils    ls.coreutils        printenv               systemctl                       umount.util-linux
chmod             fgrep              lsmod               ps                     systemd-ask-password            uname
chmod.coreutils   fgrep.grep         lsmod.kmod          ps.procps              systemd-escape                  uname.coreutils
chown             getopt             mkdir               pwd                    systemd-firstboot               usleep
chown.coreutils   getopt.util-linux  mkdir.coreutils     pwd.coreutils          systemd-hwdb                    vi
clockdiff         grep               mknod               rm                     systemd-inhibit                 watch
cp                grep.grep          mknod.coreutils     rm.coreutils           systemd-machine-id-setup        watch.procps
cp.coreutils      gtar               mktemp              rmdir                  systemd-notify                  zcat
cpio              gunzip             more                rmdir.coreutils        systemd-sysusers
cttyhack          gzip               more.util-linux     run-parts              systemd-tmpfiles
date              hostname           mount               run-parts.debianutils  systemd-tty-ask-password-agent

可以看到存放了一些常用命令,例如rm、ls、cp等,一般这些工具都是基于busybox制作的

什么是根文件系统

rootfs(根文件系统)是Linux内核启动时所挂载的第一个文件系统,当内核启动之后它需要去启动第一个init程序,内核需要去哪里执行呢?那么此时就需要有一个磁盘分区来存放这个init程序,同时内核只认文件系统,不认分区,所谓的文件系统就是一种存储结构,目前最新的linux内核使用的是ext4文件系统,当你把某个分区初始化为ext4文件系统之后在往这个分区里写文件,那么当Linux内核启动之后会去读取并加载文件系统下的init程序并运行。

第一个hello word程序

首先我们需要使用交叉工具链来编译我们自己的程序,因为Stm32是arm架构,需要使用arm指令集,如果使用x86的gcc是无法运行的,在此之前你需要arm的交叉编译环境,如果你是定制板一般厂商都会自己定制交叉工具链,最好是使用厂商提供的交叉环境来确保程序可以正确运行。

在Ubuntu环境上可以直接安装arm交叉编译环境

sudo apt install gcc-arm-linux-gnueabihf

如果你是定制板最好从厂商那里获得交叉工具链,首先写一个简单的c语言代码:

#include <stdio.h>
 
int main(void) {
 
    printf("hello word\n");
    return 0;
}

编译:

arm-linux-gnueabihf-gcc main.c -o hello_word

编译之后会在当前目录下生成一个hello_word的文件,把它copy到根文件系统下的bin目录下

sudo cp ./hello_word /mnt/bin

然后增加可执行权限:

chmod +x /mnt/bin/hello_word

copy进去之后在解除挂载:

umount /mnt

这样我们的应用程序就放进去了,然后重新将根文件系统烧录进去就可以了,运行时也不用担心缺失依赖库的问题,因为openstlinux已经将c语言运行环境glibc库移植好了。

重新烧录根文件系统之后并重启板子,然后进去到/bin目录下可以看到我们的hello_word应用就在里面:

root@stm32mp1:/bin# ls -lah hello_word
-rwxrwxr-x 1 1000 tracing 8.3K Feb 22  2023 hello_word

然后执行一下:

root@stm32mp1:/bin# hello_word
hello_word

可以看到正常输出hello word了,这就代表我们的应用程序移植成功了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

17岁boy想当攻城狮

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值