【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)

概述

迅为iTOP-4412开发板采用的CPU芯片为三星的exynos4412,开发板分为三种:(1)POP封装+1GB内存(2)SCP封装+1GB内存(3)SCP封装+2GB内存。笔者用的是SCP 1GB精英版(elite)。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第1张图片

 【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第2张图片

迅为开发板自带的光盘里面,有Android系统、QT系统、Qtopia系统和Ubuntu系统的源代码和镜像,但是却唯独没有Linux最小系统的源码和镜像

操作系统 uboot所在文件夹 linux内核所在文件夹 根文件系统所在文件夹
Android 镜像3,源码6 镜像3,源码6 镜像3,源码7
QT 镜像4,源码6 镜像4,源码6 镜像4,源码8
Qtopia 镜像3或4,源码6 镜像4,源码6 源码8
Ubuntu 镜像5,源码6 镜像5,源码6 镜像5
iTOP-4412开发板配套光盘资料

01_PCB_SCH_DATASHEET
	--配套原理图、PCB、Datasheet
02_编译器以及烧写工具
	--uboot、kernel以及QtE文件系统交叉编译工具
	--烧写工具fastboot
	--USB转串口驱动、ADB驱动
03_镜像_Android4.0.3文件系统
	--二进制文件:Android4.0.3文件系统
	--二进制文件:文件系统对应的uboot和kernel
04_镜像_QT文件系统
	--二进制文件:QtE4.7文件系统
	--二进制文件:文件系统对应的uboot和kernel
05_镜像_Ubuntu文件系统
	--二进制文件:Ubuntu文件系统(arm)
	--二进制文件:文件系统对应的uboot和kernel
06_源码_uboot和kernel
	--源码:uboot以及kerne源码
07_源码_Android文件系统
	--源码:Android4.0.3文件系统
08_源码_QtE文件系统
	--源码:QtE4.7文件系统
	--补丁包:QtE4.7对应的tslib触摸库
iTOP-4412开发板之xxx使用手册_Vx.x.pdf
	--开发板配套使用手册,xxx代表精英版或者全能版;Vx.x表示版本,以用户拿到的版本为准
光盘目录说明.txt

迅为的百度网盘资料里面倒是有一个文件夹叫做搭建最小linux系统,他搭建的是根文件系统,但是他说uboot和linux内核使用和QT系统一样的uboot和内核即可。而QT系统用的uboot是Android4.0.3的uboot。所以这个搭建出来的所谓的linux最小系统就是个“四不像”。uboot是for android的,linux内核是QT系统的(而且是老版本,不支持设备树),只有根文件系统是用busybox原生编译出来的,只能暂且称他为最小QT系统!

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第3张图片

因此,笔者特意写了本教程,教大家如何在迅为exynos4412开发板上搭建原生uboot+linux内核+busybox根文件系统。如何在开发板上的eMMC Flash为空的情况下,用linux系统的dd命令将uboot、linux内核和根文件系统烧写到开发板中,烧写的文件名和目标扇区是什么。最小linux系统运行起来后,笔者还会教大家如何运行hello world C程序,如何操作GPIO点亮开发板上的两个LED灯,读取按键的状态,以及读取ADC转换结果,如何移植电脑linux系统里面的软件包到开发板上运行,如何让我们的最小linux系统利用板上的有线网口连上网络。

项目 版本 文件名 目标扇区 烧写命令 编译命令
uboot 2017.11 u-boot-iTOP-4412.bin 1 sudo dd iflag=dsync oflag=dsync if=u-boot-iTOP-4412.bin of=/dev/sdb seek=1 (1) make menuconfig
(2) make
(3) dd if=/dev/zero of=env.bin count=16
(4) cat E4412_N.bl1.bin itop4412-spl.bin env.bin u-boot.bin > u-boot-iTOP-4412.bin
linux内核 4.14.2 uImage 4096(可自定义) sudo dd iflag=dsync oflag=dsync if=arch/arm/boot/uImage of=/dev/sdb seek=4096 (1) make exynos_defconfig
(2) make menuconfig
(3) make uImage LOADADDR=0x40007000
linux设备树 4.14.2 myexynos4412-itop-elite.dtb 2048(可自定义) sudo dd iflag=dsync oflag=dsync if=arch/arm/boot/dts/myexynos4412-itop-elite.dtb of=/dev/sdb seek=2048 make dtbs
busybox根文件系统 1.26.2 busybox编译完成后
将_install文件夹里面的所有文件复制到SD卡的一个ext4分区里
内核启动时直接挂载这个分区
(1) make defconfig
(2) make menuconfig ARCH=arm
(3) make
(4) make install

 注:
(1)SD卡每个扇区的大小为512字节,起始扇区为0。
(2)迅为提供的linux内核为3.0版本,是不支持设备树的版本,所以只需要烧写uboot+linux内核+文件系统即可。
         我们这里用的linux内核为4.14版本,是支持设备树的,所以需要烧写uboot+linux内核+linux设备树+文件系统这四样东西。
(3)内核镜像既可以选择烧写uImage,也可以选择烧写zImage。若选择了uImage,那么uboot的内核启动命令是bootm;若选择了zImage,那么uboot的内核启动命令是bootz。

给SD卡分区

迅为教程里面是用fastboot工具,插micro USB线,在线烧写uboot、linux内核和根文件系统。由于fastboot是安卓里面的工具,一旦我们擦除了安卓系统内核,安装了linux最小系统,fastboot工具就没了。并且本文讨论的是如何搭建最小linux系统,不能跟安卓扯上关系,所以本文不使用fastboot作为烧写工具。迅为给SD卡分区,是要板子成功启动linux内核后,在命令行里面执行fdisk命令。

一开始,我们板子上的eMMC是空白的,没有任何内容,板子是无法启动的。eMMC为空,就没有fastboot,现在micro USB线插上去也用不了。我们可以准备一张SD卡,事先在电脑上分好区,烧写好uboot、linux内核、linux设备树和busybox文件系统,然后插到板子上,让板子从SD卡启动。

笔者电脑虚拟机里面装的是Fedora 34系统,用的是GNOME桌面环境。现在最新版本的Ubuntu也是用的GNOME桌面环境。Ubuntu和Fedora用的软件包管理工具是不一样的。Ubuntu用的是apt-get,而Fedora用的是dnf。除了这一点,其他方面都差不多,笔者比较习惯用Fedora系统。
笔者用的SD卡的容量为32GB。用一个USB读卡器,将SD卡插在电脑上,然后插入虚拟机。在GNOME桌面环境里面有一个名叫Disks的分区软件,如下图所示。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第4张图片

打开软件后,找到我们的32GB的内存卡,如下图所示,是31 GB Drive,Generic STORAGE DEVICE。这张内存卡整个被一个31GB的FAT32分区占据。确保这里面没有重要的资料,点击减号按钮,将这个分区删除。
为什么要删除这个分区呢?这是因为,exynos4412选择SD卡启动后,一开机,他读的就是SD卡的1号扇区,这是我们无法改变的。因此我们必须把uboot烧写到1号扇区这里。为了使用1号扇区,以及后面的空间,我们只好把这个最大的分区删除掉。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第5张图片

确认删除最大的那个分区:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第6张图片

现在整张内存卡没有分区了,变成了Free Space。我们点击加号按钮,新建分区:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第7张图片

建立一个1.5GB的分区(大小可以根据自己的需要调整)。这个分区要用来保存uboot(1号扇区处)、linux设备树(2048号扇区处)和linux内核(4096号扇区处),所以我们不要格式化这个分区,文件系统要选择No Filesystem:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第8张图片

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第9张图片

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第10张图片

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第11张图片

然后,在后面建立一个ext4分区,用于挂载根文件系统,最后再添加一个FAT32分区。这两个分区的容量可以根据自己的需要随意调整。FAT32分区是供Windows系统使用的,可要可不要。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第12张图片

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第13张图片

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第14张图片

这里的FAT其实指的是FAT32:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第15张图片

最终分好区后是这样的:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第16张图片

三个分区的设备名分别为/dev/sdb1、/dev/sdb2和/dev/sdb3,所以这张SD卡在这个Linux虚拟机里面的名称就叫/dev/sdb。

选择交叉编译器

下载交叉编译器的网站有两个:
(1)GNU Toolchain | GNU-A Downloads – Arm Developer
(2)Linaro Releases

通常,交叉编译器是在arm的网站里面下载。如果这个网站里面找不到自己CPU的编译器,那么就去第二个网站linaro里面下载。linaro里面的编译器种类比较全,而且近几年所有的版本都在里面,如下图所示。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第17张图片

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第18张图片

经过笔者测试,arm网站和linaro网站都有能用于exynos4412的编译器。linaro网站里面的gcc-linaro-7.5.0-2019.12-i686_arm-eabi.tar.gz是可以用于编译exynos4412的uboot和linux内核的。
我们优先选择arm网站里面的编译器,打开arm网站后,出现的画面如下:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第19张图片

请大家一定要看仔细了,上面一定要选择GNU-A,不要选到GNU-RM那里去了。我们的exynos4412芯片是ARM-A系列的芯片,像stm32那种单片机才是ARM-M类型的芯片。
目前最新的编译器版本是10.3-2021.07。对于不同的编译环境,运行环境,网站里面都有相应的编译器可供选择。
Windows (mingw-w64-i686) hosted cross compilers栏目里面的编译器适用于Windows 64位编译环境,也就是电脑是Windows 64位的。
x86_64 Linux hosted cross compilers栏目里面的编译器适用于Linux 64位编译环境。
AArch64 Linux hosted cross compilers栏目里面的编译器适用于直接在ARM芯片上编译的编译环境,也就是直接在板子上编译程序,这就很神奇了。
Sources栏目是编译器的源码。

可以看到,这里面是没有适用于32位编译环境的编译器的。如果电脑是32位的话,那就只有去linaro的网站里面看看了。
对于Windows电脑,其实不用安装虚拟机,就可以使用Windows (mingw-w64-i686) hosted cross compilers栏目里面的编译器,在命令行里面直接编译exynos4412的程序,如下图所示。然后把程序复制到SD卡里面,板子插好SD卡后开机,就能运行程序。
(笔者试过了,32位的Windows 7电脑上,也能使用这个编译器)

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第20张图片

不过我们通常的做法是在Windows的电脑里装一个Linux的虚拟机,然后选择Linux的编译器来编译代码。
笔者安装的Linux虚拟机是64位的Fedora 34,于是去x86_64 Linux hosted cross compilers栏目里面寻找,如下图所示。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第21张图片

hosted表示的是在哪个系统下编译程序,x86_64 Linux hosted cross compilers的中文意思是:编译环境为64位Linux系统的交叉编译器。
target表示的是编译出来的程序要在哪个平台下运行。
AArch32 bare-metal target (arm-none-eabi) 是说运行环境是32位的ARM芯片,且编译的是裸机(bare-metal)程序。
AArch32 target with hard float (arm-linux-none-gnueabihf) 同样是运行环境为32位的ARM芯片,但他带了linux字样,说明是用于编译linux下的应用程序的。
AArch64 ELF bare-metal target (aarch64-none-elf) 是编译64位ARM芯片的裸机程序的。
AArch64 GNU/Linux target (aarch64-none-linux-gnu) 是编译64位ARM芯片的Linux应用程序的。
AArch64 GNU/Linux target (aarch64_be-none-linux-gnu) 也是编译64位ARM芯片的Linux应用程序的,但是程序采用的字节序为大端序(be是big endian的缩写)。

上面所说的编译器里面,不带linux字样的,只能编译裸机程序。uboot、linux内核、linux模块属于裸机程序。
带linux字样的,既可以编译裸机程序,又可以编译linux应用程序。也就是说uboot、linux内核、linux驱动、busybox文件系统里面的程序,都能编译。

exynos4412是32位小端序(little endian)的CPU,所以我们最终选择了gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz这个编译器。下面那个asc文件大小只有几十字节,只是一个校验和,不用下载。
下载下来后解压,我们后面要用到的就是bin文件夹下的arm-none-linux-gnueabihf-gcc。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第22张图片

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第23张图片

编译并运行uboot

uboot的移植过程比较复杂,要修改很多代码,我们直接采用这位CSDN博主的成果:iTop-4412精英版的u-boot-2017.11移植教程(一)_hyyoxhk的博客-CSDN博客

下载下来后的文件名是u-boot-2017.11-itop4412-2.0.0.tar.gz,解压,然后打开u-boot-2017.11/Makefile文件,将我们用的编译器的路径填到CROSS_COMPILE上面去:
CROSS_COMPILE := /home/oct1158/Downloads/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第24张图片

然后用u-boot文件夹下的build.sh脚本编译uboot:

[oct1158@fedora u-boot]$ pwd
/home/oct1158/Downloads/u-boot-2017.11-itop4412-2.0.0/u-boot
[oct1158@fedora u-boot]$ ./build.sh
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  SHIPPED scripts/kconfig/zconf.tab.c
  SHIPPED scripts/kconfig/zconf.lex.c
  SHIPPED scripts/kconfig/zconf.hash.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
scripts/kconfig/conf  --silentoldconfig Kconfig
  CHK     include/config.h
  UPD     include/config.h
  CFG     u-boot.cfg
  GEN     include/autoconf.mk.dep
  CFG     spl/u-boot.cfg
  GEN     include/autoconf.mk
  GEN     spl/include/autoconf.mk
  CHK     include/config/uboot.release
  CHK     include/generated/timestamp_autogenerated.h
  HOSTCC  scripts/dtc/dtc.o
  UPD     include/generated/timestamp_autogenerated.h
  HOSTCC  scripts/dtc/flattree.o
  UPD     include/config/uboot.release
  HOSTCC  scripts/dtc/fstree.o
  HOSTCC  scripts/dtc/data.o
  HOSTCC  scripts/dtc/livetree.o
  CHK     include/config.h
  CFG     u-boot.cfg
  HOSTCC  scripts/dtc/treesource.o
  CHK     include/generated/version_autogenerated.h
  UPD     include/generated/version_autogenerated.h
  CC      lib/asm-offsets.s
  HOSTCC  scripts/dtc/srcpos.o
  CC      arch/arm/lib/asm-offsets.s
  HOSTCC  scripts/dtc/checks.o
  HOSTCC  scripts/dtc/util.o
  CHK     include/generated/generic-asm-offsets.h
  UPD     include/generated/generic-asm-offsets.h
  CHK     include/generated/asm-offsets.h
  UPD     include/generated/asm-offsets.h
  SHIPPED scripts/dtc/dtc-lexer.lex.c
  SHIPPED scripts/dtc/dtc-parser.tab.h
  SHIPPED scripts/dtc/dtc-parser.tab.c
  HOSTCC  scripts/dtc/dtc-lexer.lex.o
  HOSTCC  scripts/dtc/dtc-parser.tab.o
  LDS     u-boot.lds
  HOSTLD  scripts/dtc/dtc
/usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x10): multiple definition of `yylloc'; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
make[2]: *** [scripts/Makefile.host:108: scripts/dtc/dtc] Error 1
make[1]: *** [scripts/Makefile.build:425: scripts/dtc] Error 2
make: *** [Makefile:493: scripts] Error 2
cp: cannot stat 'u-boot.bin': No such file or directory
copy u-boot.bin done.
notice: not found itop4412-spl.bin !
[oct1158@fedora u-boot]$ 

提示multiple definition of `yylloc'。解决方案是在刚才的Makefile里面添加一句HOSTCFLAGS  += -fcommon,如下图所示。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第25张图片

现在就能编译成功了:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第26张图片

然后,执行sudo ./mkuboot.sh /dev/sdb命令,将uboot烧写到SD卡的一号扇区。/dev/sdb就是我们的SD卡的设备名称。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第27张图片

在Linux系统中安全弹出SD卡,然后拔掉读卡器,将SD卡插到开发板上。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第28张图片

请注意板上的红色拨码开关的设置。1和2设置的是启动方式,3和4选择的是屏幕接口。
当1拨到上面,2拨到下面时是从SD卡启动。当1拨到下面,2拨到上面时是从eMMC启动。我们现在是要从SD卡启动。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第29张图片

打开开发板电源后,我们可以从UART2看到uboot输出的调试信息:

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第30张图片

备注:Tera Term的字体设置是SimSun-ExtB Regular 12。

【教程】迅为iTOP-4412精英版exynos4412开发板搭建原生Linux最小系统(一)_第31张图片

我们来讲一下exynos4412的内存编址。
exynos4412芯片内有一个64KB的iROM(只读)和一个256KB的iRAM,芯片外可以扩展两个DRAM,每个DRAM容量不能超过1.5GB。如下表所示。
SCP 1G板子上,只插了DRAM0,内存类型为DDR3,容量为1GB。

名称 地址范围 大小 说明
iROM 0x00000000~0x0000ffff 64KB 只读,存放的是BL0程序
iRAM 0x02020000~0x0205ffff 256KB 可读写
DRAM0 0x40000000~0x9fffffff 1.5GB
DRAM1 0xa0000000~0xffffffff 1.5GB

exynos4412芯片的启动过程(假设OM引脚选的是SD卡):
(1) 运行iROM中的BL0程序:将SD卡的第1~16扇区(共8KB)存放的BL1程序(E4412_N.bl1.bin)复制到iRAM中(0x02021400~0x020233ff)。BL1是三星公司提供的,无源码。
(2) 运行iRAM中的BL1程序:将SD卡的第17~48扇区(共16KB)存放的BL2_SPL程序(itop4412-spl.bin)复制到iRAM中(0x02023400~0x020273ff)。BL2_SPL是我们自己的uboot程序的SPL部分。然后,检查BL2_SPL程序第14332字节(14KB-4)处的4字节校验和是否正确(见Android_Exynos4412_iROM_Secure_Booting_Guide_Ver.1.00.01.pdf的3 INTERNAL MEMORY MAP那一节说明)。也就是说,BL2_SPL程序不能超过14332字节。
(3) 运行iRAM中的BL2_SPL程序(即uboot spl,全称是Secondary Program Loader):
     程序入口为arch/arm/cpu/armv7/vectors.S的_start标号。
     通过“b reset"指令跳转到arch/arm/cpu/armv7/start.S的reset标号。
     再通过“bl _main”指令跳转到arch/arm/lib/crt0.S的_main标号。
     接着通过“mov r0, #0”和“bl board_init_f”调用C语言函数board_init_f(0),board_init_f函数位于arch/arm/mach-exynos/spl_boot.c
     调用copy_uboot_to_ram()函数,将uboot的完整版内容(完整的BL2程序:u-boot.bin)从SD卡复制到DDR3内存的0x43e00000地址处,然后跳转到DDR3内存中执行完整的uboot程序:(*uboot)()
(4) 运行DDR3内存中的BL2程序:
     程序入口为arch/arm/cpu/armv7/vectors.S的_start标号。
     通过“b reset"指令跳转到arch/arm/cpu/armv7/start.S的reset标号。
     再通过“bl _main”指令跳转到arch/arm/lib/crt0.S的_main标号。
     接着通过“mov r0, #0”和“bl board_init_f”指令调用C语言函数board_init_f(0),board_init_f函数位于common/board_f.c。在board_init_f函数中通过initcall_run_list(init_sequence_f)语句调用了init_sequence_f函数指针数组里面的所有函数。(最后board_init_f函数会返回,不会hang(),不要被代码迷惑了)
     接下来,将uboot代码从DDR3内存的低地址拷贝到顶端地址,然后跳转到拷贝后的位置继续运行uboot。这个过程叫做relocation。(也就是换个地方继续运行剩余的代码)
     最后通过“ldr pc, =board_init_r”指令调用C语言函数board_init_r函数,board_init_r函数位于common/board_r.c。在board_init_r函数中通过initcall_run_list(init_sequence_r)语句调用了init_sequence_r函数指针数组里面的所有函数,其中最后一个函数就是run_main_loop(进入uboot命令行)。
(5) uboot的5秒倒计时完毕后,执行uboot bootcmd环境变量中存储的命令:使用mmc read命令将SD卡的第4096扇区存放的Linux内核、以及第2048扇区存放的Linux设备树复制到DDR3内存中,然后用bootm或bootz命令运行内核。

其中,BL0和BL1是三星公司提供的两段不开放源代码的程序,BL2_SPL就是我们的uboot的spl部分。我们编译出来的u-boot-iTOP-4412.bin文件是“BL1+BL2_SPL+uboot环境变量存储区+BL2”的组合,所以,我们必须将这个文件烧写到SD卡的第一个扇区处。Linux内核和设备树的存放位置分别为第4096和第2048扇区,这两个位置是由uboot的bootcmd环境变量决定的,是可以修改的。

build.sh脚本的内容如下:

#!/bin/bash

cd ../u-boot-2017.11/

if [ ! -f .config ]
then
	make itop4412_defconfig
fi

make -j4

cp u-boot.bin ../u-boot/
echo "copy u-boot.bin done."

cd spl/
if [ ! -f itop4412-spl.bin ] ; then
	echo "notice: not found itop4412-spl.bin !"
	exit 0
else
	echo "copying itop4412-spl.bin..."
fi

cp itop4412-spl.bin ../../u-boot/
echo "copy u-boot-spl.bin done."

echo "build success !!!"

其中最重要的两条命令,就是make itop4412_defconfig和make -j4(四线程编译)。

mkuboot.sh脚本的内容如下:

#!/bin/bash

if [ ! -f E4412_N.bl1.bin ] ; then
	echo "not find files: E4412_N.bl1.bin !!!"
	exit 0
fi

if [ ! -f env.bin ] ; then
	echo "not find files: env.bin !!!"
	exit 0
fi

cat E4412_N.bl1.bin itop4412-spl.bin env.bin u-boot.bin > u-boot-iTOP-4412.bin

if [ -f u-boot-iTOP-4412.bin ] ; then
	echo "created u-boot-iTOP-4412.bin success!!!"
else
	echo "created u-boot-iTOP-4412.bin failed!!!"
	exit 0
fi

echo "writting ..."

if [ -z $1 ] ; then
	dd iflag=dsync oflag=dsync if=u-boot-iTOP-4412.bin of=/dev/sdb seek=1
else
	dd iflag=dsync oflag=dsync if=u-boot-iTOP-4412.bin of=$1 seek=1
fi

echo "writting success"

脚本中先用cat命令将几个bin文件(BL1和BL2_SPL,以及env.bin和BL2)合并成一个文件,然后用dd命令烧写到SD卡的1号扇区(请注意SD卡的起始扇区是0号扇区,不是1号扇区)。
dd命令的if参数是要烧写的文件名,of参数是目标设备,seek参数表示从哪一个扇区开始烧写。我们的u-boot-iTOP-4412.bin文件大小为400864字节,占了783个扇区,所以dd命令实际烧写是扇区1~783。
env.bin的内容为全0,大小为8192字节(8KB),这个区域是用来存放uboot环境变量的。只要这些数据不能通过CRC校验,uboot就会采用源码头文件include/configs/itop4412.h里面的环境变量值。若能通过CRC校验,就采用env.bin里面的环境变量值。

在uboot中,可以使用help命令查看uboot支持的所有命令:

u-boot # help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootefi - Boots an EFI payload from memory
bootelf - Boot from an ELF image in memory
bootm   - boot application image from memory
bootvx  - Boot vxWorks from an ELF image
bootz   - boot Linux zImage image from memory
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
dcache  - enable or disable data cache
dfu     - Device Firmware Upgrade
dm      - Driver model low level access
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
erase   - erase FLASH memory
exit    - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls  - list files in a directory (default /)
ext4load- load binary file from a Ext4 filesystem
ext4ls  - list files in a directory (default /)
ext4size- determine a file's size
ext4write- create a file in the root directory
false   - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
fatsize - determine a file's size
fatwrite- write file into a dos filesystem
fdt     - flattened device tree utility commands
flinfo  - print FLASH memory information
fstype  - Look up a filesystem type
go      - start application at address 'addr'
gpt     - GUID Partition Table
help    - print command description/usage
icache  - enable or disable instruction cache
iminfo  - print header information for application image
itest   - return true/false on integer compare
load    - load binary file from a filesystem
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loadx   - load binary file over serial line (xmodem mode)
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
ls      - list files in a directory (default /)
md      - memory display
mii     - MII utility commands
mm      - memory modify (auto-incrementing address)
mmc     - MMC sub system
mmcinfo - display MMC info
mw      - memory write (fill)
nm      - memory modify (constant address)
part    - disk partition related commands
printenv- print environment variables
protect - enable or disable FLASH write protection
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
save    - save file to a filesystem
saveenv - save environment variables to persistent storage
setenv  - set environment variables
setexpr - set environment variable as the result of eval expression
showvar - print local hushshell variables
size    - determine a file's size
source  - run script from memory
test    - minimal test like /bin/sh
thordown- TIZEN "THOR" downloader
true    - do nothing, successfully
ums     - Use the UMS [USB Mass Storage]
version - print monitor, compiler and linker version

这个uboot比迅为提供的那个for android的uboot支持的命令多得多。迅为那个for android的uboot只有零星几个命令,连mmc read这么重要的命令都不支持的。

用version命令可以看到编译uboot的编译器的版本,以及编译时间:

u-boot # version
U-Boot 2017.11 (Aug 26 2021 - 23:02:28 +0800) for itop-4412

arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 10.3.1 20210621
GNU ld (GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29)) 2.36.1.20210621

用printenv命令可以打印出所有的环境变量的值,其中bootcmd是最重要的环境变量,他决定了开机5秒倒计时过去后要执行怎样的命令启动Linux内核。

u-boot # printenv
arch=arm
baudrate=115200
board=itop4412
board_name=itop4412
bootargs=console=ttySAC2,115200n8 earlyprintk
bootcmd=if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadbootenv; then echo Loaded environment from ${bootenv};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;if run loadbootscript; then run bootscript; fi; fi;mmc read ${loadaddr} 0x1000 0x4000; mmc read ${dtb_addr} 0x800 0xa0; bootm ${loadaddr} - ${dtb_addr}load mmc ${mmcdev} ${loadaddr} uImage; load mmc ${mmcdev} ${dtb_addr} ${dtb_name}; bootm ${loadaddr} - ${dtb_addr}
bootdelay=5
bootenv=uEnv.txt
bootscript=echo Running bootscript from mmc${mmcdev} ...; source ${loadaddr}
console=ttySAC2,115200n8
cpu=armv7
dtb_addr=0x41000000
dtb_name=exynos4412-itop-4412.dtb
fdtcontroladdr=7feb1640
importbootenv=echo Importing environment from mmc ...; env import -t $loadaddr $filesize
kerneladdr=0x40007000
loadaddr=0x40007000
loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}
loadbootscript=load mmc ${mmcdev} ${loadaddr} boot.scr
mmcdev=0
ramdiskaddr=0x48000000
rdaddr=0x48000000
soc=exynos
vendor=samsung

Environment size: 1174/8188 bytes

[下一篇]


笔者推荐一下xhr_embedded这位csdn大佬,他移植了2020年新版本的u-boot-2020.07、linux-5.8.5和BusyBox-1.31.1,比笔者用的版本新的多。
他移植的uboot还支持emmc启动。
[2020.09.12 - xhr4412] 移植 u-boot-2020.07 & linux-5.8.5 & BusyBox-1.31.1 到 iTOP-4412 汇总

你可能感兴趣的:(Linux,linux,itop4412,exynos4412,uboot,busybox)