前言
最近在学习 V4L2 编程,刚好自己手头上有一块 Tiny4412 的板子和一个免驱的摄像头。因此想在 Tiny4412 的板子上做实验,在实践中学习。
本文做为第一篇文章,在 Tiny4412 板子上搭建 Linux 系统。
一 配置编译烧写 u-boot
1.1 获取 uboot 源码和交叉工具链
uboot 源码和交叉工具链可以在 Tiny4412 附赠的光盘中获取,没有光盘的小伙伴可以访问我的 github 仓库获取。
获取交叉工具链
user@vmware:~/tiny4412$ git clone git@github.com:tiny4412/FriendlyARM.tool.chain.git
获取 uboot 源码
user@vmware:~/tiny4412$ git clone git@github.com:tiny4412/FriendlyARM.source.code.git
这里我是直接从光盘中拷贝的,放在 ~/tiny4412
目录下。
user@vmware:~/tiny4412$ ls
arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz uboot_tiny4412-20130729.tgz
1.2 创建仓库管理 uboot 源码
在 github 上创建一个名为 FriendlyARM.uboot-2010.12
的空仓库,克隆到本地
user@vmware:~/tiny4412$ git clone git@github.com:tiny4412/FriendlyARM.uboot-2010.12.git
Cloning into 'FriendlyARM.uboot-2010.12'...
Warning: Permanently added the RSA host key for IP address '192.30.253.112' to the list of known hosts.
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
解压 uboot 源码,并将源码移动到仓库目录中进行管理
user@vmware:~/tiny4412$ tar zxvf uboot_tiny4412-20130729.tgz
user@vmware:~/tiny4412$ mv uboot_tiny4412/* FriendlyARM.uboot-2010.12/
提交第一笔提交,记录最原始的 uboot 源码状态
user@vmware:~/tiny4412$ cd FriendlyARM.uboot-2010.12/
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ make clean
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ make distclean
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git add --all
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git commit -m "init: get the u-boot source code by friendly arm"
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git push origin -u master
1.3 安装交叉编译器
这里其实也没有什么安装一说,就是将交叉编译器解压出来,后续编译 uboot 的时候,修改 uboot 编译 Makefile 指定交叉编译器用我们现在解压的这个而已
user@vmware:~/tiny4412$ tar zxvf arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz
1.4 指定 uboot 使用的交叉编译器
通过修改 arch/arm/config.mk
指定交叉编译器
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git diff
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 24f8982..a454343 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -21,7 +21,7 @@
# MA 02111-1307 USA
#
-CROSS_COMPILE ?= arm-linux-
+CROSS_COMPILE ?= /home/user/tiny4412/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-
ifeq ($(BOARD),omap2420h4)
STANDALONE_LOAD_ADDR = 0x80300000
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git add --all
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git commit -m "conf: modify the cross compiler"
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git push origin
1.5 配置编译 uboot
配置 uboot
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ make tiny4412_config
Configuring for tiny4412 board...
编译 uboot
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ make
确认到 u-boot.bin 镜像成功生成
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ ls -l u-boot.bin
-rw-rw-r-- 1 user user 276932 9月 23 22:36 u-boot.bin
1.6 给 u-boot 添加 .gitignore 文件
查看发现全是编译的中间文件,这些文件根本不需使用版本库进行管理,因此我们要忽略它们。随便找一个 kernel 源码中拷贝一个 kernel 默认的忽略规则过来就好。这里我拷贝的是 mini2440 用到的 linux-2.6.22.6 中的忽略规则。
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ cp ../../mini2440/linux-2.6.22.6/.gitignore ./
将 kernel 默认的忽略文件拷贝到 u-boot 源码中,很好,大部分的中间文件都成功忽略了,但是通过 git st 查看还是有部分中间文件没有被忽略。因此将剩余的中间文件都追加到 .gitignore 文件中。
需要追加的列表有:
# don't ignore the .gitignore file
!.gitignore
arch/arm/include/asm/arch
arch/arm/include/asm/proc
examples/standalone/hello_world
examples/standalone/hello_world.bin
examples/standalone/hello_world.srec
include/autoconf.mk
include/autoconf.mk.dep
include/config.h
include/config.mk
include/generated/
include/timestamp_autogenerated.h
include/version_autogenerated.h
tools/gen_eth_addr
tools/img2srec
tools/mkimage
u-boot
u-boot.bin
u-boot.lds
u-boot.map
u-boot.srec
将忽略规则提交
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git add --all
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git commit -m "conf: add the gitignore rule"
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ git push origin
1.7 烧写 uboot
通过 uboot 中提供的脚本可以将 uboot 烧写到 sd 卡中,之后便可以通过 sd 卡启动 uboot。
另外由于我是在虚拟机上编译的 uboot,因此,sd 卡接在 windows 上,需要在虚拟机右下角找到 sd 卡设备,断开其 windows 主机的连接,让其连接到虚拟机中。
sd 卡在虚拟机中正确识别后,在 /dev
目录下将会自动创建对应的设备节点
sd 卡未接入
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse/tiny4412$ ls /dev/sd*
/dev/sda /dev/sda1 /dev/sda2 /dev/sda5
sd 卡接入后
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse/tiny4412$ ls /dev/sd*
/dev/sda /dev/sda1 /dev/sda2 /dev/sda5 /dev/sdb /dev/sdb1
确认到 sd 卡是 /dev/sdb
节点后,就可以开始用脚本烧写了,但是烧写依赖 mkbl2
镜像,因此要先生成它。
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12$ cd sd_fuse/
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse$ ls
Makefile sd_fdisk.c tiny4412 V310-EVT1-mkbl2.c
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse$ make
gcc -o mkbl2 V310-EVT1-mkbl2.c
gcc -o sd_fdisk sd_fdisk.c
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse$ ls
Makefile mkbl2 sd_fdisk sd_fdisk.c tiny4412 V310-EVT1-mkbl2.c
执行烧写脚本烧写 uboot,使用方法为 ./sd_fusing.sh /dev/sdb
,值得注意的是,需要加 sudo
添超级权限才可以读写 sdb。
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse$ cd tiny4412/
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse/tiny4412$ ls
E4412_N.bl1.bin E4412_tzsw.bin fast_fuse.sh sd_fusing.sh
user@vmware:~/tiny4412/FriendlyARM.uboot-2010.12/sd_fuse/tiny4412$ sudo ./sd_fusing.sh /dev/sdb
/dev/sdb reader is identified.
---------------------------------------
BL1 fusing
16+0 records in
16+0 records out
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.203274 s, 40.3 kB/s
---------------------------------------
BL2 fusing
28+0 records in
28+0 records out
14336 bytes (14 kB, 14 KiB) copied, 0.444371 s, 32.3 kB/s
---------------------------------------
u-boot fusing
541+1 records in
541+1 records out
276996 bytes (277 kB, 271 KiB) copied, 1.9351 s, 143 kB/s
---------------------------------------
TrustZone S/W fusing
184+0 records in
184+0 records out
94208 bytes (94 kB, 92 KiB) copied, 0.721558 s, 131 kB/s
---------------------------------------
U-boot image is fused successfully.
Eject SD card and insert it again.
1.8 用 sd 卡启动验证是否烧录成功
将 SD 卡插入板子中,使用 SD 卡启动,出现如下打印,说明编译烧写成功,如不成功,请仔细 check 上述每一个步骤
OK
U-Boot 2010.12-00000-gcfd8b91 (Sep 23 2018 - 22:36:26) for TINY4412
CPU: S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]
APLL = 1400MHz, MPLL = 800MHz
Board: TINY4412
DRAM: 1023 MiB
vdd_arm: 1.2
vdd_int: 1.0
vdd_mif: 1.1
BL1 version: N/A (TrustZone Enabled BSP)
Checking Boot Mode ... SDMMC
REVISION: 1.1
MMC Device 0: 7460 MB
MMC Device 1: 3728 MB
MMC Device 2: N/A
*** Warning - using default environment
Net: No ethernet found.
Hit any key to stop autoboot: 0
TINY4412 #
TINY4412 #
TINY4412 #
TINY4412 #
二 配置编译烧写 linux 内核
2.1 获取 linux 源码
linux 源码可以在 Tiny4412 附赠的光盘中获取,没有光盘的小伙伴可以访问我的 github 仓库获取。
user@vmware:~/tiny4412$ git clone git@github.com:tiny4412/FriendlyARM.source.code.git
这里我是直接从光盘中拷贝的,放在 ~/tiny4412 目录下。
user@vmware:~/tiny4412$ ls
FriendlyARM.source.code FriendlyARM.tool.chain FriendlyARM.uboot-2010.12 linux-3.5-20150929.tgz opt
2.2 创建仓库管理 linux 源码
在 github 上创建一个名为 FriendlyARM.linux-3.5
的空仓库,克隆到本地
user@vmware:~/tiny4412$ git clone git@github.com:tiny4412/FriendlyARM.linux-3.5.git
Cloning into 'FriendlyARM.linux-3.5'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
解压 linux 源码,并将源码移动到仓库目录中进行管理
user@vmware:~/tiny4412$ tar zxf linux-3.5-20150929.tgz
user@vmware:~/tiny4412$ mv linux-3.5/* FriendlyARM.linux-3.5/
提交第一笔提交,记录最原始的 linux 源码状态
user@vmware:~/tiny4412$ cd FriendlyARM.linux-3.5/
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ make clean
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ make distclean
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git add --all
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git commit -m "init: get the linux source code by friendly arm"
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git push origin -u master
2.3 指定 linux 使用的交叉编译器
通过修改顶层 Makefile 指定交叉编译器
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git diff
diff --git a/Makefile b/Makefile
old mode 100644
new mode 100755
index 371e0e4..053f911
--- a/Makefile
+++ b/Makefile
@@ -194,7 +194,7 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
export KBUILD_BUILDHOST := $(SUBARCH)
#ARCH ?= $(SUBARCH)
ARCH ?= arm
-CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
+CROSS_COMPILE ?= /home/user/tiny4412/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-
# Architecture as present in compile.h
UTS_MACHINE := $(ARCH)
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git add --all
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git commit -m "conf: modify the cross compiler"
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git push origin
2.4 配置内核
修改友善之臂官网提供的配置文件,关闭 trustzone 功能
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git diff
diff --git a/tiny4412_linux_defconfig b/tiny4412_linux_defconfig
old mode 100644
new mode 100755
index 8da9719..c2b29bd
--- a/tiny4412_linux_defconfig
+++ b/tiny4412_linux_defconfig
@@ -482,7 +482,7 @@ CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
-CONFIG_ARM_TRUSTZONE=y
+# CONFIG_ARM_TRUSTZONE is not set
# CONFIG_ARM_LPAE is not set
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
CONFIG_ARM_THUMB=y
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git add --all
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git commit -m "conf: disable the trustzone"
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git push origin
使用友善之臂提供的配置文件来配置内核
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ cp tiny4412_linux_defconfig .config
2.5 编译内核
内核配置好后,直接执行 make 开始编译即可
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ make
... ...
TIMEC kernel/timeconst.h
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
/home/user/tiny4412/FriendlyARM.linux-3.5/kernel/Makefile:133: recipe for target 'kernel/timeconst.h' failed
make[1]: *** [kernel/timeconst.h] Error 255
Makefile:776: recipe for target 'kernel' failed
make: *** [kernel] Error 2
报错了,不慌,百度了解到需要做如下修改
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git add kernel/timeconst.pl
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git diff --cached
diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl
old mode 100644
new mode 100755
index eb51d76..0461239
--- a/kernel/timeconst.pl
+++ b/kernel/timeconst.pl
@@ -370,7 +370,7 @@ if ($hz eq '--can') {
}
@val = @{$canned_values{$hz}};
- if (!defined(@val)) {
+ if (!@val) {
@val = compute_values($hz);
}
output($hz, @val);user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git diff --cached
diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl
old mode 100644
new mode 100755
index eb51d76..0461239
--- a/kernel/timeconst.pl
+++ b/kernel/timeconst.pl
@@ -370,7 +370,7 @@ if ($hz eq '--can') {
}
@val = @{$canned_values{$hz}};
- if (!defined(@val)) {
+ if (!@val) {
@val = compute_values($hz);
}
output($hz, @val);
修改好后重新 make 成功了,确认到成功生成内核镜像
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ ls -l arch/arm/boot/zImage
-rwxrwxr-x 1 user user 4783472 9月 24 16:32 arch/arm/boot/zImage
2.6 给 linux 添加 .gitignore 文件
原本内核都是自带 ,gitignore
文件的,但是友善之臂提供的内核却没有,因此我们需要手动添加下忽略规则。
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ cp ../FriendlyARM.uboot-2010.12/.gitignore ./
同样,参考 uboot 中修改 ignore 规则一样,还是有部分中间文件没有被忽略。因此将剩余的中间文件都追加到 .gitignore 文件中。并将忽略规则提交
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git add --all
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git commit -m "conf: add the gitignore rule"
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ git push origin
2.7 烧写内核
通过 dd 命令将内核烧写到 SD 卡中,dd 使用格式为:
dd iflag=dsync oflag=dsync if=<烧写的文件名称> of=<指定烧写的设备> seek=<跳过块数量>
UBOOT默认情况下是从SD卡的1057块开始读取内核映像。
位置可以随意写,但是不能将前面的UBOOT代码覆盖掉。
user@vmware:~/tiny4412/FriendlyARM.linux-3.5$ sudo dd iflag=dsync oflag=dsync if=arch/arm/boot/zImage of=/dev/sdb seek=1057
[sudo] password for user:
9342+1 records in
9342+1 records out
4783472 bytes (4.8 MB, 4.6 MiB) copied, 42.1633 s, 113 kB/s
2.8 用 sd 卡启动验证是否烧录成功
将 SD 卡插入板子中,使用 SD 卡启动,出现如下打印,说明编译烧写成功,如不成功,请仔细 check 上述每一个步骤
OK
U-Boot 2010.12-00000-gbf8103b-dirty (Sep 24 2018 - 09:19:16) for TINY4412
CPU: S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]
APLL = 1400MHz, MPLL = 800MHz
Board: TINY4412
DRAM: 1023 MiB
vdd_arm: 1.2
vdd_int: 1.0
vdd_mif: 1.1
BL1 version: N/A (TrustZone Enabled BSP)
Checking Boot Mode ... SDMMC
REVISION: 1.1
MMC Device 0: 7460 MB
MMC Device 1: 3728 MB
MMC Device 2: N/A
*** Warning - using default environment
Net: No ethernet found.
Hit any key to stop autoboot: 0
reading kernel..device 0 Start 1057, Count 12288
MMC read: dev # 0, block # 1057, count 12288 ... 12288 blocks read: OK
completed
reading RFS..device 0 Count 13345, Start 2048
MMC read: dev # 0, block # 13345, count 2048 ... 2048 blocks read: OK
completed
Boot with zImage
Wrong Ramdisk Image Format
[err] boot_get_ramdisk
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
[ 0.000000] Booting Linux on physical CPU 0
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 3.5.0-FriendlyARM-gd4bb223-dirty (user@vmware) (gcc version 4.5.1 (ctng-1.8.1-FA) ) #1 SMP PREEMPT Mon Sep 24 16:31:49 CST 2018
如果此时接了屏幕的话,还可以看到屏幕上出现企鹅图标。
三 构建根文件系统
我们知道 linux 中一切皆文件,linux 的运行少不了文件文件系统中的系统文件的支持,就好比 windows 电脑如果没有 c 盘中的 windows 系统文件,windows 系统也是无法运行起来的。因此要让我们自己编译的 linux 系统运行起来,必须提供系统需要的对应的系统文件,这些系统文件包括常用的可执行程序,如 ls、cd 等我们常用的命令的其他 linux 系统服务需要用到的配置文件。
这里我们要用到 busybox 工具去生成我们自己的 linux 系统需要需要到的工具,以及通过拷贝我们使用的 ubuntu 主机上的配置文件作为我们班子上 linux 的配置文件,
3.1 获取 busybox
可以从官网下载最新版本,也可以从我的 github 仓库中获取我本文使用的 busybox-1.23.2
user@vmware:~/tiny4412$ git clone git@github.com:tiny4412/FriendlyARM.tool.chain.git
解压得到 busybox 源码
user@vmware:~/tiny4412$ tar -jxvf busybox-1.23.2.tar.bz2
user@vmware:~/tiny4412$ ls
busybox-1.23.2 FriendlyARM.uboot-2010.12 FriendlyARM.tool.chain opt
busybox-1.23.2.tar.bz2 FriendlyARM.source.code FriendlyARM.linux-3.5
3.2 创建仓库管理根文件系统
在 github 上创建一个名为 FriendlyARM.rootfs 的空仓库,克隆到本地
user@vmware:~/tiny4412$ git clone git@github.com:tiny4412/FriendlyARM.rootfs.git
Cloning into 'FriendlyARM.rootfs'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
3.3 配置编译 busybox
先配置 busybox,进入到解压目录下。敲 make menuconfig
命令进入图形配置菜单
user@vmware:~/tiny4412/busybox-1.23.2$ make menuconfig
分别进行以下配置:
配置 busybox 的编译器为
/home/user/tiny4412/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-
Busybox Settings --> Build Options --> (/home/user/tiny4412/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-) Cross Compiler prefix
配置 busybox 编译安装的目录为
/home/user/tiny4412/FriendlyARM.rootfs
Busybox Settings --> Installation Options ("make install" behavior) --> (/home/user/tiny4412/FriendlyARM.rootfs) BusyBox installation prefix
我在配置的时候,遇到 BusyBox installation prefix
无法编辑的情况,就是可以进入编辑框,但是无法删除原来的配置,退格键没有用。遇到这种情况的话,可以先执行 make menuconfig
生成 .config
配置文件,然后用文本编辑器手动修改下面两个宏为对应的值效果也是一样的。
user@vmware:~/tiny4412/busybox-1.23.2$ cat .config | grep tiny4412
CONFIG_CROSS_COMPILER_PREFIX="/home/user/tiny4412/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-"
CONFIG_PREFIX="/home/user/tiny4412/FriendlyARM.rootfs"
配置好后,开始编译安装 busybox
user@vmware:~/tiny4412/busybox-1.23.2$ make
user@vmware:~/tiny4412/busybox-1.23.2$ make install
安装好后,将会在安装目标目录,也就是 make menuconfig 中指定的 FriendlyARM.rootfs
目录中生产以下文件
user@vmware:~/tiny4412/busybox-1.23.2$ cd ../FriendlyARM.rootfs/
user@vmware:~/tiny4412/FriendlyARM.rootfs$ ls
bin linuxrc sbin usr
使用 ls -l
查看下,不难看出,这些生成的可执行文件都是到 busybox 的链接
ls -l bin/* sbin/* usr/* linuxrc
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/cat -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/chmod -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/conspy -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/cp -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/dmesg -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/echo -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/grep -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/gunzip -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/gzip -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/ln -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/ls -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/mv -> busybox
lrwxrwxrwx 1 user user 7 9月 24 22:02 bin/ping -> busybox
lrwxrwxrwx 1 user user 11 9月 24 22:02 linuxrc -> bin/busybox
3.4 制作根文件系统
完善 linux 系统根目录下的目录
user@vmware:~/tiny4412/FriendlyARM.rootfs$ mkdir -p lib dev etc/init.d home proc sys root opt tmp var mnt user@vmware:~/tiny4412/FriendlyARM.rootfs$ ls bin dev etc home lib linuxrc mnt opt proc root sbin sys tmp usr var
拷贝共享库到 rootfs/lib 目录下
user@vmware:~/tiny4412/FriendlyARM.rootfs$ cp -rfdv ../opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/lib/* lib/
拷贝分组和密码文件到 rootfs/etc 目录下
user@vmware:~/tiny4412/FriendlyARM.rootfs$ cp /etc/group etc/ user@vmware:~/tiny4412/FriendlyARM.rootfs$ cp /etc/passwd etc/
创建 fstab 文件
user@vmware:~/tiny4412/FriendlyARM.rootfs$ cp /etc/fstab etc/
创建 inittab 文件
user@vmware:~/tiny4412/FriendlyARM.rootfs$ vim etc/inittab user@vmware:~/tiny4412/FriendlyARM.rootfs$ cat etc/inittab ::sysinit:/etc/init.d/rcS console::respawn:-/bin/sh ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r
解释以上代码:
::sysinit:/etc/init.d/rcS # 定义系统上电执行的初始化文件。 console::respawn:-/bin/sh # 指定控制台的脚本解释器和进入控制台的模式。可选的模式有 # 1. askfirst 进入命令行需要按回车键确认 # 2. respawn 进入命令行不需要按回车键确认 ::ctrlaltdel:/sbin/reboot # 指定系统重启命令。 ::shutdown:/bin/umount -a -r # 指定系统关机前执行的命令
创建 etc/init.d/rcS 文件
user@vmware:~/tiny4412/FriendlyARM.rootfs$ vim etc/init.d/rcS user@vmware:~/tiny4412/FriendlyARM.rootfs$ cat etc/init.d/rcS #!/bin/sh mount -a mkdir /dev/pts mount -t devpts devpts /dev/pts echo /sbin/mdev > /proc/sys/kernel/hotplug mdev -s /bin/hostname Maziot
注意, rcS 文件是一个脚本文件,必须有可执行权限
user@vmware:~/tiny4412/FriendlyARM.rootfs$ chmod 777 etc/init.d/rcS user@vmware:~/tiny4412/FriendlyARM.rootfs$ ll etc/init.d/rcS -rwxrwxrwx 1 user user 130 10月 5 19:49 etc/init.d/rcS*
其中
mdev -s
命令会根据安装的驱动自动在 dev 目录下创建设备节点创建 etc/profile 文件
user@vmware:~/tiny4412/FriendlyARM.rootfs$ vim etc/profile user@vmware:~/tiny4412/FriendlyARM.rootfs$ cat etc/profile USER="id-un" LOGNAME=$USER PS1='[\u@\h \w]\# ' PATH=$PATH HOSTNAME='/bin/hostname' export USER LOGNAME PS1 PATH
其中 PS1 环境变量保存的是当前命令行终端提示符显示的格式
3.5 将制作好的文件系统上传到 github 管理
由于 git 默认不管理空目录,但是文件系统中一些的特定的目录结构是需要存在的,因此需要将空目录也提交的 github 上。参考立体风的博客了解到,如要想要提交空目录 mnt
到 github 上,只需要在该目录下创建 .gitkeep
文件即可。
user@vmware:~/tiny4412/FriendlyARM.rootfs$ touch dev/.gitkeep home/.gitkeep opt/.gitkeep proc/.gitkeep sys/.gitkeep tmp/.gitkeep var/.gitkeep mnt/.gitkeep
user@vmware:~/tiny4412/FriendlyARM.rootfs$ git add --all
user@vmware:~/tiny4412/FriendlyARM.rootfs$ git commit -m "conf: create the root file system"
user@vmware:~/tiny4412/FriendlyARM.rootfs$ git push origin
3.6 配置 nfs 共享目录
编辑 nfs 服务的配置文件,将 /home/user/tiny4412/FriendlyARM.rootfs
目录加入共享目录
user@vmware:~/tiny4412/FriendlyARM.rootfs$ sudo vim /etc/exports
user@vmware:~/tiny4412/FriendlyARM.rootfs$ cat /etc/exports
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/home/user/board/ *(rw,sync,no_root_squash)
/home/user/tiny4412/rootfs *(rw,no_root_squash,sync)
/home/user/tiny4412/FriendlyARM.rootfs *(rw,sync,no_root_squash)
加入后重启 nfs 服务
user@vmware:~/tiny4412/FriendlyARM.rootfs$ sudo /etc/init.d/nfs-kernel-server restart
[ ok ] Restarting nfs-kernel-server (via systemctl): nfs-kernel-server.service.
重启 nfs 服务后,本地验证下 nfs 配置是否生效
user@vmware:~/tiny4412$ sudo mount -t nfs 192.168.31.178:/home/user/tiny4412/FriendlyARM.rootfs /mnt -o nolock
user@vmware:~/tiny4412$ cd /mnt/
user@vmware:/mnt$ ls
bin dev etc home lib linuxrc opt proc root sbin sys tmp usr var
user@vmware:/mnt$ touch fs1
user@vmware:/mnt$ cd -
/home/user/tiny4412
user@vmware:~/tiny4412$ cd FriendlyARM.rootfs/
user@vmware:~/tiny4412/FriendlyARM.rootfs$ ls
bin dev etc fs1 home lib linuxrc opt proc root sbin sys tmp usr var
user@vmware:~/tiny4412/FriendlyARM.rootfs$ rm -rf fs1
确认到配置是没问题的
3.7 设置 uboot 启动参数
从 sd 启动,开机倒数计时按下 enter 进入 uboot 命令行,重新设置 bootargs 环境变量,设置为 nfs 方式挂载文件系统
Checking Boot Mode ... SDMMC
REVISION: 1.1
MMC Device 0: 7460 MB
MMC Device 1: 3728 MB
MMC Device 2: N/A
Net: No ethernet found.
Hit any key to stop autoboot: 0
TINY4412 #
TINY4412 # setenv bootargs root=/dev/nfs nfsroot=192.168.31.178:/home/user/tiny4412/FriendlyARM.rootfs ip=192.168.31.199:192.168.31.178:192.168.31.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
TINY4412 #
TINY4412 # saveenv
Saving Environment to SMDK bootable device...
done
nfsroot 语法格式为:
<服务器IP地址>:<服务器上的文件目录> ip=<开发板IP地址>:<服务器IP地址>:<网关>:<子网掩码>::eth0:off
3.8 挂载文件系统启动 linux
重启开发板,此时应该可以正常启动内核,正常情况下最后一段 log 为:
... ...
[ 7.325000] link_reset() speed: 10 duplex: 0
[ 7.335000] IP-Config: Complete:
[ 7.335000] device=eth0, addr=192.168.31.199, mask=255.255.255.0, gw=192.168.31.1
[ 7.335000] host=192.168.31.199, domain=, nis-domain=(none)
[ 7.335000] bootserver=192.168.31.178, rootserver=192.168.31.178, rootpath=
[ 7.335000] hotplug_policy_init: intialised with policy : DVFS_NR_BASED_HOTPLUG
[ 7.345000] ALSA device list:
[ 7.345000] No soundcards found.
[ 7.365000] VFS: Mounted root (nfs filesystem) on device 0:10.
[ 7.365000] Freeing init memory: 212K
[root@Maziot /]#
但是有的时候会出现问题
情况1:卡死在
No soundcards found
这里,没有成功挂载到 nfs 文件系统
这样情况需要重点检查 nfs 服务这块,nfs 服务配置是否正确,uboot 中 bootargs 是否设置正确情况2:卡死在
Freeing init memory: 212K
成功 mount 了文件系统,但是没有进入终端
说实话,我也不清除具体的原因,这里我的排查方法是用同学做好的,可以正常启动的文件系统包做交叉实验,找到自己文件系统中哪些文件配置的不对
同学做好的正常的文件系统我也放了一份到 https://github.com/tiny4412/FriendlyARM.source.code.git
仓库中,克隆下来将会得到 rootfs-huangweizhong.tar.gz
文件。先试试这个文件系统能否正常挂载
user@vmware:~/tiny4412$ tar zxvf rootfs-huangweizhong.tar.gz
user@vmware:~/tiny4412$ cd rootfs/
user@vmware:~/tiny4412/rootfs$ pwd
/home/user/tiny4412/rootfs
设置 uboot 中 bootargs 以及 nfs 共享的目录
setenv bootargs root=/dev/nfs nfsroot=192.168.31.178:/home/user/tiny4412/FriendlyARM.rootfs ip=192.168.31.199:192.168.31.178:192.168.31.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0
确认到可以正常挂载,接下来就是找不同,看看具体是哪个配置的区别导致我自己做的文件系统挂载不上。
我在制作本文文件系统中就是遇到情况2的问题,卡死在 Freeing init memory: 212K
位置,最后通过交叉实验,确认到是 fstab 的问题。需要将 fstab 修改为:
user@vmware:~/tiny4412/FriendlyARM.rootfs$ cat etc/fstab
#
# /etc/fstab
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/VolGroup-lv_root / ext4 defaults 1 1
UUID=1d8cfac6-27f4-464f-9296-04d5bad1d7b2 /boot ext4 defaults 1 2
/dev/mapper/VolGroup-lv_home /home ext4 defaults 1 2
/dev/mapper/VolGroup-lv_swap swap swap defaults 0 0
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
四 产品发布
前面提到的在 tiny4412 上搭建 linux 环境基本已经可以运行了,使用的是 SD 启动挂载 nfs 网络文件系统,这样的方式好处是可以很方便的在 ubuntu 和 tiny4412 之前传输文件,但是我们最终的产品是要卖给用户的。我们不能强制用户要求插上启动用的 SD 卡,以及网线挂载网络文件系统。因此,最终,我们要将 uboot、kernel、fs 都要烧写到 EMMC 中,并在 EMMC 引导他们启动。
4.1 将 uboot 和内核从 SD 卡中拷贝到 EMMC 中
注意:SD 中有第 0 块不可用,EMMC 第 0 块是可用的,因此从 SD 到 EMMC 中烧的任何代码都需要减去 1
SD 卡是从第一个块开始的, EMMC 是从第0个块开始的