主题: 1.bootloader的介绍 2.uboot的编译和烧写 3.minicom的使用 4.uboot的代码结构 5.用dnw将程序加载到uboot中执行
1. bootloader的介绍 ========================= 开发板或PC上电启动后,运行的第一个软件称为bootloader,PC的bootloader一般称为BIOS;
Bootloader类似于PC上的BIOS,其核心作用有3个: -->初始化硬件 包括EXY4412处理器,DDR内存,SD卡,eMMC等 -->提供一系列交互命令 用户可以通过串口和bootloader通信,并利用bootloader执行一些命令,比如用dnw下载应用程序执行等 -->引导linux内核
Bootloader有很多种,也可以自己写。其中最著名的一种叫uboot,是一个开源的代码项目,支持非常多的处理器和开发板。我们使用的开发板也移植了uboot。
Superboot也是bootloader的一种,是友善自行设计的,并没有开源;
2. uboot的编译和烧写 =========================== (1)uboot的解压缩 --------------------- uboot的压缩包在uboot子目录下: $>cd /home/zhang/01embed/uboot/
root@localhost tiny4412]# mkdir uboot-tiny4412 [root@localhost tiny4412]# cd uboot-tiny4412/ [root@localhost uboot-tiny4412]# ls [root@localhost uboot-tiny4412]# pwd /opt/FriendlyARM/tiny4412/uboot-tiny4412
[root@localhost uboot-tiny4412]# cp -f /opt/install/zht-01embed/uboot/uboot_tiny4412_0929.tar.gz . [root@localhost uboot-tiny4412]# ls uboot_tiny4412_0929.tar.gz
$>tar xzvf uboot_tiny4412_0929.tar.gz
(2)配置uboot并编译 -------------------- $>cd uboot_tiny4412/
如果编译0929版的uboot,需要为两个文件增加可执行权限: $>chmod 755 mkconfig $>chmod 755 tools/scripts/make-asm-offsets
$>make tiny4412_config $>make
....... /4.5.1 -lgcc -Map u-boot.map -o u-boot arm-linux-ld: warning: creating a DT_TEXTREL in object. arm-linux-objcopy -O srec u-boot u-boot.srec arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
如果编译0929版的uboot,需要为两个文件增加可执行权限: $>chmod 755 mkconfig $>chmod 755 tools/scripts/make-asm-offsets
(3)编译用于生成bl2的工具 --------------------- 进入uboot目录,编译两个和烧写sd卡相关的工具: $>cd uboot_tiny4412_0929/sd_fuse/ $>make 生成工具mkbl2和sd_fdisk
[root@localhost sd_fuse]# make gcc -o mkbl2 V310-EVT1-mkbl2.c gcc -o sd_fdisk sd_fdisk.c
(4)将uboot烧写到SD卡中 ---------------------- 首先准备一张2G或以上的SD卡; 注意!烧写uboot会破坏卡中已有的数据,因此请先对SD卡上的数据进行备份(有必要的话);
假设SD卡被Linux识别为/dev/sdb,以root权限运行以下命令: $>umount /media/xxx/ umount /media/27FB-0A91/
root@localhost sd_fuse]# ls /dev/sd* -ll brw-rw----. 1 root disk 8, 0 4月 27 08:28 /dev/sda brw-rw----. 1 root disk 8, 1 4月 27 08:28 /dev/sda1 brw-rw----. 1 root disk 8, 2 4月 27 08:28 /dev/sda2 brw-rw----. 1 root disk 8, 16 4月 27 08:34 /dev/sdb brw-rw----. 1 root disk 8, 32 4月 27 10:17 /dev/sdc brw-rw----. 1 root disk 8, 33 4月 27 10:17 /dev/sdc1
$>cd uboot_tiny4412_0929/sd_fuse/tiny4412/
root@localhost tiny4412]# pwd /opt/FriendlyARM/tiny4412/uboot-tiny4412/uboot_tiny4412_0929/sd_fuse/tiny4412
[root@localhost tiny4412]# ls sd* -ll -rw-rw-rw-. 1 xguest xguest 2174 10月 31 13:08 sd_fusing.sh [root@localhost tiny4412]# ls sd* -ll -rwxrwxrwx. 1 xguest xguest 2174 10月 31 13:08 sd_fusing.sh
$>./sd_fusing.sh /dev/sdb U-boot image is fused successfully. Eject SD card and insert it again.
//该脚本首先用上面的工具mkbl2生成bl2.bin //然后用dd将E4412_bl1.bin,bl2.bin,,u-boot.bin,E4412_tzsw.bin等4个部分分别写入/dev/sdb的指定位置
退出sd 卡
如果只想向SD卡烧写bl2.bin和u-boot.bin,可以用另一个脚本: $>cd sd_fuse/tiny4412/ $>./fast_fuse.sh /dev/sdb
插SD卡到板子,打开minicom ,开机
Checking Boot Mode ... SDMMC REVISION: 1.1 MMC Device 0: 14804 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 #
3. minicom的使用 ========================= (1)基于串口进行通讯 ------------------------ 将uboot烧写到开发板后,uboot会通过串口来收发信息,如果要和uboot交互,首先需要连接串口;
用串口线将开发板的串口和PC的串口相连,如果是台式机,则可以使用机器后面的普通串口;如果是笔记本,则可以使用开发板中配套提供的USB转串口设备;
注意!如果使用台式机后面的普通串口,在插拔串口线时,务必提前关闭开发板的电源!
连好串口线后,就可以利用串口通讯工具和uboot交流了,在windows中的串口通讯工具为超级终端,而linux中为minicom;
(2)minicom的安装和配置 ------------------------- 如果没有安装minicom,请首先配置好yum,然后按如下方法安装和配置: 安装: $>yum install minicom
第一次运行minicom时要先配置一下: $>minicom -s
进入配置界面,配置过程如下: --> 将光标定位到第三项(Serial port setup)敲Enter键进入; --> 按A键,设定串口对应的设备 如果开发板连接到PC后面的串口,则设备文件名为/dev/ttyS0; 如果使用USB转串口线连接开发板,则设备文件名为/dev/ttyUSB0 输入完成后按enter键 --> 按E键,设置串口通信的波特率为115200,8N1 --> 按F键,关闭硬件流控 --> 修改完后,选择Save setup as dfl
(3)minicom的使用 ------------------------ 再次启动minicom时,如果串口对应的设备文件名没有变化,则可以直接运行minicom; $>minicom 启动开发板后,如果uboot烧写成功,则minicom的界面中会显示uboot输出的文字,按键盘任意键,进入uboot的交互模式; 如果要退出minicom,同时按下Ctrl+A,松开后再按Z,再按X则退出;
(4)minicom运行出错 ------------------------- 如果没有正确退出,下一次启动minicom时可能会出现如下错误: $>minicom Device /dev/ttyUSB0 lock failed: 不允许的操作.
此时,可以删除minicom的锁文件: $>rm -f /var/lock/LCK*
删除后,再次启动minicom: $>minicom
4. uboot的代码结构 ========================== 作为硬件启动后最先运行的程序,要完成一个bootloader必须熟知特定arm处理器的底层细节以及启动过程; 早期的嵌入式开发中,大多数arm芯片的底层细节都是开放的,此时可以直接从网上下载最新版的uboot并移植到开发板上运行;
很遗憾,三星并未完全开放EXYNOS4412芯片的底层细节,因此,我们的课程只能使用友善移植的uboot; 下面大体介绍一下uboot的核心代码结构;
(1)board/samsung/tiny4412/ --------------------------- 目录下的代码主要完成tiny4412开发板的初始化; -->config.mk 在文件config.mk中指定了编译后的uboot的运行地址,即: CONFIG_SYS_TEXT_BASE = 0xc3e00000
这个地址是虚拟地址,如果要使用物理地址,则需要在编译uboot时关闭MMU,并将uboot的运行地址修改如下: CONFIG_SYS_TEXT_BASE = 0x43e00000
-->u-boot.lds 文件u-boot.lds指定了整个uboot的链接顺序
(2)arch/arm/cpu/armv7/ --------------------------- 该目录下的代码针对CortexA9处理器,其中最重要的是整个uboot的初始化文件start.S
(3)include/configs/tiny4412.h --------------------------- 是tiny4412开发板的配置文件,可以通过修改文件中的常量定义来改变uboot的配置; 比如可以设置uboot输出信息的提示符: #define CONFIG_SYS_PROMPT "zht4412 #"
还可以关闭对MMU的支持: //#define CONFIG_ENABLE_MMU
(4)common/ ----------------------------- 该目录下是uboot中各种命令,如dnw,tftp,go,set,save等的实现代码; 如果要实现自己定义的命令,应该把实现代码加入该目录;
5. 用dnw将程序加载到uboot中执行 =============================== 当开发板上运行uboot以后,可以通过工具dnw从pc获取可执行的bin格式应用程序,加载到开发板上运行;
(1)dnw工具的安装
[root@localhost 桌面]# cd /opt/FriendlyARM/tiny4412/ [root@localhost tiny4412]# mkdir dnw-tools [root@localhost tiny4412]# pwd /opt/FriendlyARM/tiny4412 [root@localhost tiny4412]# cd dnw-tools/ [root@localhost dnw-tools]# cp -f /opt/install/zht-01embed/tools/dnw-linux.tar.gz . [root@localhost dnw-tools]# ls dnw-linux.tar.gz [root@localhost dnw-tools]# pwd /opt/FriendlyARM/tiny4412/dnw-tools
----------------------- dnw工具在tools目录下,解压缩并安装(要有root权限): $>cd tools/ $>tar xzvf dnw-linux.tar.gz $>cd dnw-linux/ $>make $>make install
(2)利用dnw加载(load)程序 ----------------------- dnw利用usb接口加载程序,找到光盘中的usb线,一端接pc,小扁口一端则连接到板子上的mini-usb口;
minicom 中 -----
Net: No ethernet found. Hit any key to stop autoboot: 0 TINY4412 # dnw 70003000
OTG cable Connected! Now, Waiting for DNW to transmit data
首先要在uboot中运行dnw命令: zht4412 #dnw 70003000 //指定应用程序的加载位置为地址0x70003000 //当前的uboot为不支持MMU的版本
接下来在pc中运行dnw工具,将bin程序加载到板子上:
cp -rf /opt/install/zht-01embed/work/code-uboot /opt/FriendlyARM/tiny4412/. cd /opt/FriendlyARM/tiny4412/code-uboot/00cpsr/ [root@localhost 00cpsr]# make arm-linux-as start.s -o start.o arm-linux-gcc -c main.c -o main.o arm-linux-ld start.o main.o -Ttext 0x70003000 -o mycpsr arm-linux-objcopy -O binary mycpsr mycpsr.bin
[root@localhost 00cpsr]# dnw mycpsr.bin load address: 0x57E00000 Writing data... 100% 0x000001A2 bytes (0 K) speed: infM/S
$>cd code-uboot/00cpsr/ $>make $>dnw mycpsr.bin
///////minicom 窗口 出现
TINY4412 # dnw 70003000 OTG cable Connected! Now, Waiting for DNW to transmit data Download Done!! Download Address: 0x70003000, Download Filesize:0x198 Checksum is being calculated. Checksum Value => MEM:b5f5 DNW:b654 Checksum failed.
表示传输成功,自动退出等待。 如果不退出, 继续在 dnw 窗口, [root@localhost 00cpsr]# dnw mycpsr.bin 直到minicom 自动退出
(3)运行程序 ------------------------ uboot只能支持bin格式的应用程序,如果已经通过dnw加载,则可以用go命令运行应用程序: zht4412 #go 70003000 //执行地址70003000处的代码
出现问题, printf 打印不出
问题。
cd /opt/FriendlyARM/tiny4412/uboot-tiny4412/uboot_tiny4412_0929
root@localhost uboot_tiny4412_0929]# find . -name "System.map" ./System.map
gedit System.map
找到 printf地址 .... c3e11ad0 T printf ....
找到使用 printf 的程序
[root@localhost 00cpsr]# pwd /opt/FriendlyARM/tiny4412/code-uboot/00cpsr [root@localhost 00cpsr]# ls common.h main.c main.o Makefile mycpsr mycpsr.bin start.o start.s
int my_main(void) { printf("CPSR = 0x%x ", get_cpsr());
printf("===Execute cmp 4,3=== "); set_flags(4, 3); printf("CPSR = 0x%x ", get_cpsr());
printf("===Execute cmp 4,4=== "); set_flags(4, 4); printf("CPSR = 0x%x ", get_cpsr());
printf("===Execute cmp 3,4=== "); set_flags(3, 4); printf("CPSR = 0x%x ", get_cpsr()); 修改
[root@localhost 00cpsr]# gedit common.h
#ifndef _COMMON_H #define _COMMON_H
#define NULL ((void *)0) #define printf(...) (((int (*)(const char *, ...))0xc3e11ad0)(__VA_ARGS__))
#endif //_COMMON_H
重新编译
make
[root@localhost 00cpsr]# make arm-linux-ld start.o main.o -Ttext 0x70003000 -o mycpsr arm-linux-objcopy -O binary mycpsr mycpsr.bin
传到板子。 minicom窗口 dnw 70003000 回车
代码窗口 dnw mycpsr.bin 回车(可以多次)
等到 minicom窗口 退出等待
TINY4412 # go 70003000 ## Starting application at 0x70003000 ... CPSR = 0x60000113 ===Execute cmp 4,3=== CPSR = 0x20000113 ===Execute cmp 4,4=== CPSR = 0x60000113 ===Execute cmp 3,4=== CPSR = 0x80000113 ===Unmask IRQ & FIQ=== CPSR = 0x60000113 ## Application terminated, rc = 0x1
问题 :
[root@localhost 04led]# dnw arm.bin load address: 0x57E00000 Can not open /dev/secbulk0: No such file or directory
应该是你的驱动没有安装好 解决方法: 串口USB 和小usb 口 在安装是的顺序,和以后运行是的顺序不能变