正点原子STM32MP157开发板内核启动
前言:
在这里我介绍两种STM32MP157开发板的boot启动流程及指令,第一种为外部flash(Emmc)启动,第二种为网络启动。
1.emmc启动
EMMC 是一种SOC内部存储器,通常将linux的内核、uboot、设备树以及根文件系统rootfs烧录进去,然后在启动的时候,将EMMC内部的文件通过DDR导入DARM(内存)。如果你没有修改过boot指令,那么直接将编码器拨到EMMC即可,如果你使用BOOT启动,其配置如下:
1. bootcmd配置
setenv bootcmd 'ext4load mmc 1:2 c2000000 uImage;ext4load mmc 1:2 c4000000 stm32mp157d-atk.dtb;bootm c2000000 - c400000;
解释:这些指令都是boot指令,boot指令就是用来引导内核启动的。其中前两条的意思是将emmc的镜像(uImage)以及设备树文件导入内存中,最后一条指令是启动内存这一部分的内容,也就是我们导入的linux镜像。
2.bootargs配置
setenv bootargs 'console=tty1 console=ttySTM0,115200 root=/dev/mmcblk2p3 rootwait rw'
解释:bootargs主要是向内核传递参数,当内核启动后需要挂载根文件(rootfs),这条指令就是告诉内核根文件系统在mmcblk2p3的位置,也就是第一块emmc的第三个分区。我们也可以通过boot的mmc指令来查看我们emmc的构成:
可以看到第一块emmc有三个区,第一个区名字是“ssbl”,保存的是我们的uboot镜像,;第二个区名称为“boot”,保存的是我们的内核镜像以及设备树等等文件;第三个区名称为“rootfs”,也就是保存的是我们的根文件系统。我们通过ext4ls指令可以查看各个分区的具体内容,如下,可以看到3区保存的确实是我们的根文件目录:
我们设置了上述两个boot系统变量后,就可以通过boot来启动我们的系统了,这就是通过emmc来启动内核的具体的流程。
通过网络启动内核
为什么要通过网络来启动内核呢?
如果我们修改了我们的镜像文件或者设备树文件,或者编写了一些新的驱动想要测试一下是否可用,如果像STM32等裸核单片机,直接将文件烧录到emmc或者其他的外部flash中(SD/TF卡)也是可以的,但是烧录的过程通常是非常不方便的,而且如果烧录不成功,那么我们上一版可用的系统也就没有了,因此emmc等外部flash通过保存的是可以正确运行的系统镜像。
而网络烧录的意思是,我们可以通过网络等一些工具,如NFS\TFTP等,直接将我们修改后的镜像或者设备树加载到我们的内存中,这样的话可以很方便检测、调试是否可用,通过要想通过网络加载系统,首先需要有一些网络传输的工具,在这里我介绍两个常用的,分别是NFS以及TFTP。
1. NFS(Network File System)
NFS是一种分布式文件系统协议,允许用户通过网络来访问远程文件系统,简单点将就是远程文件访问,我们可以通过NFS来向内核下载镜像文件等,同样的也可以用来向开发板挂载我们的rootfs系统(这样的话,根文件系统也不需要下载到flash中了,方便调试)
#首先进入boot指令
nfs 0xc2000000 服务器ip地址/共享文件夹地址/uImage
#比如我的Ubuntu系统为219.216.11.11,那么我下载系统镜像的指令如下:
nfs 0xc2000000 219.216.11.11:/home/zgh/nfs/uImage
#然后加载设备树文件
nfs 0xc4000000 219.216.11.11:/home/zgh/nfs/stm32mp157d-atk.dtb
2. TFTP(Trivial File Transfer Protocol)
TFTP同样也是一种通过网络传输文件工具,它是基于UDP协议传输的,其指令更加简单,我们只需要设置好客户端要访问的服务端的文件路径,使用以下命令即可传输,相对于NFS可以不需要输入服务端对应的IP地址以及路径:
tftp 0xc2000000 uImage
tftp 0xc4000000 stm32mp157d-atk.dtb
以上就是传输成功的标志了,接下来我们只需要加载rootfs并通过内核启动即可。
加载根文件系统(rootfs)
加载根文件系统到内存也主要分为两种,一种是通过emmc加载,也就是上面使用的那种方式
setenv bootargs 'console=tty1 console=ttySTM0,115200 root=/dev/mmcblk2p3 rootwait rw'
还有一种则是通过网络进行挂载,通过nfs挂载主要是指定bootargs的环境变量,其中root的值是关键,相应的格式如下:
root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[<nfs-options>]ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dnsl-ip>
<server-ip>:为服务器ip地址
<root-dir>:根文件目录在服务器上文件地址
<nfs-options>:NFS的其他可选项,一般不设置
<client-ip>:客户端的ip地址,也就是开发板的ip地址
<netmask>:网关掩码
<gw-ip>:网关地址
<hostname>:客户端的名字
<device>:设备名,也就是网卡名,一般是eth0、eth1等,正点原子的stm32mp157开发板只有一个网口,即eth0
根据上面的格式,以我的为例,设置如下:
root=dev/nfs nfsroot=219.216.80.118:/home/zgh/Linux/tool/nfs/rootfs,proto=tcp rw ip=219.216.80.111:219.216.80.118:219.216.80.249:255.255.255.0::eth0:off
进入boot的命令模式,然后重新设置bootargs的环境变量,如下:
setenv bootargs 'console=ttySTM0,115200 root=dev/nfs nfsroot=219.216.80.118:/home/zgh/Linux/tool/nfs/rootfs,proto=tcp rw ip=219.216.80.111:219.216.80.118:219.216.80.249:255.255.255.0::eth0:off //设置环境变量
saveenv //保存环境变量
设置好以后,通过“boot”启动内核即可。
总结
以上就是内核通过boot指令启动的整个流程了,主要分为外部flash(EMMC)以及网络两种方式进行内核镜像移植以及根文件系统挂载。
如果还有什么问题,大家可以私信。