Uboot相关问题总结
开发板
底板:MYB-SAMA5D3X
核心板:SAMA5D36
U-BOOT配置相关
0 开发环境基本情况说明
0.1开发环境
系统:PC端为win10,在win10下安装virtualBox,virtaulBox里安装ubuntu16.04
主机与虚拟机网络情况如下图:
其中win10 ip:192.168.137.1
Ubuntu ip:192.168.137.72
0.2开发板情况
开发板底板:MYB-SAMA5D3X
主板:SAMA5D36
1 Uboot ping不通问题
情况说明:
主机PC
ip:192.168.137.1 netmask:255.255.255.0
烧写完uboot直接ping 192.168.137.1不通
1.1解决方法:
1.1.1 设置ethaddr
U-Boot>setenv ethaddr 12:34:56?cd:ef
1.1.2 设置ip
U-Boot>setenv ipaddr 192.168.137.3
此时如果直接ping 192.168.137.1会显示:
host 192.168.137.1 is alive,说明配置成功,PC ping仍ping不通。
1.1.3 设置serverip
U-Boot>setenv serverip 192.168.137.72
(注意因为在使用tftp中开发板是与ubuntu通信,从ubuntu中下载文件,因此这里设置serverip为192.168.137.72,而不因该是192.168.137.1,此处要特别注意)
1.1.4设置autostart
U-Boot>setenv autostart no
1.1.5 保存设置
U-Boot>saveenv
然后按reset重启开发板,此时再次ping 192.168.137.1 显示内容:host 192.168.137.1
is alive
然后PC去ping 192.168.137.3,仍然ping不通。
1.1.6 运行tftp
U-Boot>tftp
此时主机再ping 192.168.137.3发现可以ping通。
2 tftp设置
2.1 开发板tftp客户端设置
注意要设置setenv serverip 192.168.137.72
2.2 ubuntu tftp服务器端设置
接下来,就是要在开发环境上安装TFTP服务器,使开发板可以通过TFTP协议下载的uImage这个文件。在ubuntu下,可以通过下面的命令安装TFTP服务器,这个服务是通过inet监听的。
sudo apt-get install atftpd openbsd-inetd
安装完以后,需要配置一下TFTP的默认查找目录,我将其设定为/srv/tftp。确认/etc/inetd.conf文件中有如下一行:
因为TFTP服务主要是给UBOOT提供内核镜像文件,为了避免每次内核编译完以后都拷贝到/srv/tftp目录中,在/srv/tftp目录中,建立了一个符号文件,指向/opt/linux/Linux-at91/linux-at91/arch/arm/boot/uImage。
ln -s /opt/linux/Linux-at91/linux-at91/arch/arm/boot/uImage /srv/tftp/uImage
可以通过下面的命令重启inetd,保证这个supper服务器能够监听TFTP端口:
sudo service openbsd-inetd restart
可以通过查看端口确认inetd是否真的在监听TFTP端口:
root@ep-VirtualBox:~#netstat -a |grep tftp
udp 0 0 *:tftp *?
可以通过下面的命令测试一下TFTP服务是否正常工作:
root@ep-VirtualBox:~# tftp localhost
tftp>get uImage
在0.3秒内收到3578106字节。
3 编译内核,设置其可以通过NFS挂载根文件系统
对于sama5d3xek开发板提供的内核源码,解压后直接运行:
#./make_image.sh linux-512mb
对于通用的内核源码,解压后直接:
make menuconfig
关于NFS挂在有关的选项如下:
Networking support->Networking options->IP:kernel level autoconfiguration
File systems -> Network File System -> NFS client support注意,这个选项下面的 IP:DHCP support / IP:BOOTP support / IP:RARP aupport
不能选。因为我的开发环境中没有安装 DHCP server。开发板的 IP
是在内核启动参数中指定的。
File systems -> Network File System -> NFS client support for NFS version 3
File systems -> Network File System ->Root file system on NFS
4 设置nfs服务器
接下来是配置NFS服务器,用于开发板上内核启动以后挂载开发环境的ROOTFS。通过下面的命令安装nfs服务器:
sudo apt-get install nfs-kernel-server
安装完成以后,还需要修改/etc/exports文件,设置NFS共享的文件目录。我们需要将/opt/rootfs设置为NFS共享目录。
# 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)
/opt/rootfs 192.168.137.3(rw,no_root_squash,no_subtree_check)
注:192.168.137.3为开发板的ip。如果此处设置为了开发板ip,下面本机测试时将挂在deny。要想本机挂载测试成功可将ip改为*
每一次修改/etc/exports这个文件,都需要重新启动NFS服务器:
sudo service nfs-kernel-server restart
可以通过下面的命令测试NFS服务器是否设置正确:
zoulz@Seagate:/tmp$ rm a b
zoulz@Seagate:/tmp$ mkdir /tmp/a
zoulz@Seagate:/tmp$ sudo mount -t nfs -o nolock localhost:/opt/rootfs /tmp/a
zoulz@Seagate:/tmp$ ls /tmp/a
bin dev etc home lib linuxrc proc root run sbin sys tmp usr var
zoulz@Seagate:/tmp$ ls /opt/rootfs
bin dev etc home lib linuxrc proc root run sbin sys tmp usr var
也可以通过df命令查看挂载情况:
zoulz@Seagate:/tmp$ df
Filesystem 1K-blocks Used Available Use% Mounted on
localhost:/opt/rootfs 125439744 36394112 89045632 30% /tmp/a
5 uboot通过tftp加载Linux kernel,并启动
5.1 内核及.dtb文件的准备
在虚拟机的/srv/tftp目录下放入linux内核镜像uImage及sama5d36ek.dtb文件或采用本说明文档中第2部分“tftp设置”中软连接的方式。
5.2 uboot下载uImage及sama5d36ek.dtb
5.2.1 下载sama5d36ek.dtb
U-Boot>tftp 0x21000000 sama5d36ek.dtb
注:如果下载的时候找不到文件,请在ubuntu下用ls -al命令查看下文件的读权限,有可能是读权限的问题
5.2.2 下载内核镜像uImage
U-Boot>tftp 0x22000000 uImage
5.3 启动内核
U-Boot>bootm 0x22000000 – 0x21000000
注:注意使用uboot的帮助命令查看命令“help”,好像还有个bootp命令直接从网络启动内核镜像,有兴趣可以研究一下。
注:0x22000000是内核镜像下载的内存地址,0x21000000是FDT(sama5d36ek.dtb)下载的内存地址。
说明:由于通过nfs启动rootfs,需要文件系统.
6 通过NFS启动PC上制作的ROOTFS
6.1设置uboot给内核传递的启动参数bootargs
U-Boot>setenv bootargs(注:删除原有的bootargs)
U-Boot>setenv bootargs console=ttyS0,115200 root=/dev/nfs ip=192.168.137.3:::::eth0 nfsroot=192.168.137.72:/opt/rootfs,nfsvers=3 rw
setenv bootargs console=ttyS0,115200 root=/dev/nfs ip=192.168.137.3:::::eth0 nfsroot=192.168.137.72:/opt/test/embedded-linux-labs/bootloader/rootfs,nfsvers=3 rw
7 Kernel sources
7.1 获取源代码
wget/pub/linux/kernel/v4.x/linux-4.17.1.tar.xz
解压缩:
tar xvf
7.2 练习使用补丁命令patch
7.2.1 Linux patch命令
Linux patch命令用于修补文件。
patch指令让用户利用设置修补文件的方式,修改,更新原始文件。倘若一次仅修改一个文件,可直接在指令列中下达指令依序执行。如果配合修补文件的方式则能一次修补大批文件,这也是Linux系统核心的升级方法之一。
7.2.1.1 语法
patch [-bceEflnNRstTuvZ][-B <备份字首字符串>][-d <工作目录>][-D
<标示符号>][-F <监别列数>][-g <控制数值>][-i <修补文件>][-o
<输出文件>][-p <剥离层级>][-r <拒绝文件>][-V <备份方式>][-Y
<备份字首字符串>][-z <备份字尾字符串>][–backup-if
-mismatch][–binary][–help][–nobackup-if-mismatch][–verbose][原始文件
<修补文件>] 或 path [-p <剥离层级>] < [修补文件]
文件系统的制作
说明本部分此种颜色表示操作
1 使用BusyBox制作嵌入式Linux根文件系统
BusyBox源码的获取
官网网址:/
去官网下载当前最新的稳定版本busyBox
1.30.1
busybox-1.30.1.tar.bz2
将其解压到embedded-linux-labs/bootloader目录下
构建嵌入式Linux根文件系统
假设创建的rootfs目录在/opt/下,即/opt/rootfs
STEP1: 构建目录结构
#makedir ./rootfs
#cd ./rootfs
创建跟文件系统目录,主要包括以下目录
/dev /etc /lib /usr /var /proc /tmp /home /root /mnt /bin /sbin /sys
#mkdir dev etc lib usr var proc tmp home root mnt sys
1.2.2 STEP2: 使用busybox构建/bin /sbin linuxrc
进入busybox-1.30.1目录,执行
#make defconfig
#make menuconfig
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MuLvhiGR-1571718363978)(media/2ea7f9c0215182097df46de1e75e1812.png)]
以下为busybox Configuration配置
Busybox Settings---->
— Build Options----->
//1. 选择将busybox进行静态编译
[*] Build static binary (no shared libs)
//2. 指定交叉编译器为
(/opt/gcc-linaro-arm-linux-gnueabihf-4.7-.04-0415_linux/bin/arm-linux-gnueabihf-)Cross Compiler prefix
//选择生成的文件存放目录,也可以直接放在rootfs下就不用拷贝了,默认是在busybox根目录下生成_install目录
— Installation Options(“make install” behavior) ----->
(./_install) Destination path for ‘make install’
//3. 选择上Don’t use /usr
— Support –long-options ----->
[*] Don’t usr /usr
// 4. 编译出的busybox的shell命令解释器支持显示当前路径及主机信息
— Library Tuning----->
[*]Username completion
[*]Fancy shell prompts
[*]Query cursor position from terminal
保存退出
#make
#make install
在busybox目录下会看见_install目录,里面有/bin /sbin
linuxrc三个文件。将这三个文件目录或文件拷到第一步所建的rootfs文件夹下。
#cp bin/ sbin/ linuxrc /opt/rootfs -ra
切记一定要带上-a的参数,因为bin目录里大部分都是链接,如果不带-a的参数,拷过去之后会做相应的复制,不再是链接的形式
1.2.3 STEP3: 构建etc目录
1)进入根文件系统rootfs的etc目录,执行如下操作:
拷贝busybox-1.30.1/examples/bootfloopy/etc/* 到当前目录下
cp -r busybox-1.30.1/examples/bootfloppy/etc/* rootfs/etc
修改inittab文件
原始文件为:
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
tty2::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
修改后为:
(1): 开机免登陆,直接打开shell(前面数字为行号)
1 ::sysinit:/etc/init.d/rcS
2 #::respawn:-/bin/sh
3 #::respawn:-/bin/login
4 console::askfirst:-/bin/sh
5 #tty2::askfirst:-/bin/sh
6 ::ctrlaltdel:/bin/umount -a -r
(2): 开机需要登陆(前面数字为行号)
1 ::sysinit:/etc/init.d/rcS
2 #::respawn:-/bin/sh
3 ::respawn:-/bin/login
4 #console::askfirst:-/bin/sh
5 #tty2::askfirst:-/bin/sh
6 ::ctrlaltdel:/bin/umount -a -r
2)拷贝虚拟机上的/etc/passwd, /etc/group, /etc/shadow到rootfs/etc下
# cp /etc/passwd /opt/rootfs/etc
# cp /etc/group /opt/rootfs/etc
# cp /etc/shadow /opt/roofs/etc
对以下三个文件修改,只保存与root相关的项,根据具体情况内容会有所不同。
修改passwd为root❌0:0:root:/root:/bin/ash
修改group为root❌0:root
修改shadow为root:$1$x9yv1WlB$abJ2v9jOlOc9xW/y0QwPs.:14034:0:99999:7:::
登陆开发板时需输入用户名密码,同虚拟机相同
3)修改profile
PATH=/bin:/sbin:/usr/bin:/usr/sbin //可执行程序 环境变量
export LD_LIBRARY_PATH=/lib:/usr/lib //动态链接库 环境变量
/bin/hostname shizhaopeng
USER="`id -un`"
LOGNAME=$USER
HOSTNAME=’/bin/hostname’
PS1=’[\u@\h \W]#’
4)修改etc/init.d/rc.S文件
#! /bin/sh
/bin/mount -n -t ramfs ramfs /var
/bin/mount -n -t ramfs ramfs /tmp
/bin/mount -n -t sysfs none /sys
/bin/mount -n -t ramfs none /dev
/bin/mkdir /var/tmp
/bin/mkdir /var/modules
/bin/mkdir /var/run
/bin/mkdir /var/log
/bin/mkdir -p /dev/pts //telnet服务需要
/bin/mkdir -p /dev/shm //telnet服务需要
#echo /sbin/mdev > /proc/sys/kernel/hotplug //USB自动挂载需要
修改etc/fstab文件,增加以下文件/sbin/mdev -s //启动mdev在/dev下自动创建设备文件节点
/bin/mount -a
#################配置网络#########################
#/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0
/sbin/ifconfig eth0 192.168.137.3
/sbin/ifconfig eth0 netmask 255.255.255.0
/sbin/route add default gw 192.168.137.1 eth0
/sbin/ifconfig eth0 up
none /dev/pts devpts mode=0622 0 0
tmpfs /dev/shm tmpfs defaults 0 0
1.2.4 STEP4: 构建lib目录
(/opt/gcc-linaro-arm-linux-gnueabihf-4.7-.04-0415_linux/arm-linux-gnueabihf/lib我的只是把这个目录下的SO文件复制就可以了)
1)#cd /opt/gcc-linaro-arm-linux-gnueabihf-4.7-.04-0415_linux/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf
将以下动态库拷贝到rootfs/lib下
#cp *so* /opt/roofs/lib -a
2)#cd /opt/gcc-linaro-arm-linux-gnueabihf-4.7-.04-0415_linux/arm-linux-gnueabihf/lib
将以下动态库拷贝到rootfs/lib下
#cp ./libstdc++.so.* /opt/rootfs/lib -a
至此通过NFS启动的roofs文件系统制作完毕
制作UBIFS文件系统镜像
2.1制作UBS镜像,需要确定以下几个参数
MTD partition size; //对应的FLASH分区大小
flash physical eraseblock size; //FLASH物理擦除块大小
minimum flash input/output unit size; //最小的FLASH输入输出单元大小
for NAND flashes - sub-page size; //对于nand flash来说,子页大小
logical eraseblock size; //逻辑擦除块大小
参数获取的方式:
MTD partition size:从内核的分区表或cat /proc/mtd获得flash physical eraseblock size:从flash芯片手册或cat /proc/mtdminimum flash input/output unit size:
1. norflash 通常为1个字节2. nandflash 一个页面
sub-page size:通过flash手册获得
logical eraseblock
size:对于有子页的NANDFLASH来说,等于“物理擦除块大小-2页的大小”
2)也可通过ubi和mtd连接时的产生的信息获取
UBI: attaching mtd1 to ubi0
UBI: physical eraseblock size: 131072 bytes (128 KiB)
UBI: logical eraseblock size: 126976 bytes
UBI: smallest flash I/O unit: 2048
UBI: VID header offset: 2048 (aligned 2048)
UBI: data offset: 4096
UBI: max. sequence number: 0
UBI: volume 0 (“rootfs”) re-sized from 1033 to 1930 LEBs
UBI: attached mtd1 to ubi0
UBI: MTD device name: “rootfs”
UBI: MTD device size: 248 MiB
UBI: number of good PEBs: 1972
UBI: number of bad PEBs: 12
UBI: number of corrupted PEBs: 0
UBI: max. allowed volumes: 128
UBI: wear-leveling threshold: 4096
UBI: number of internal volumes: 1
UBI: number of user volumes: 1
UBI: available PEBs: 0
UBI: total number of reserved PEBs: 1972
UBI: number of PEBs reserved for bad PEB handling: 38
UBI: max/mean erase counter: 1/0
UBI: image sequence number: 538007531
atmel_spi f0004000.spi: Using dma0chan3 (tx) and dma0chan4 (rx) for DMA transfers
atmel_spi f0004000.spi: Atmel SPI Controller at 0xf0004000 (irq 18)
UBI: background thread “ubi_bgt0d” started, PID 443
UBIFS: mounted UBI device 0, volume 0, name “rootfs”
UBIFS: file system size: 243666944 bytes (237956 KiB, 232 MiB, 1919 LEBs)
UBIFS: journal size: 9023488 bytes (8812 KiB, 8 MiB, 72 LEBs)
UBIFS: media format: w4/r0 (latest is w4/r0)
UBIFS: default compressor: lzo
UBIFS: reserved for root: 0 bytes (0 KiB)
VFS: Mounted root (ubifs filesystem) on device 0:11
对于sama5d3xek来说(16进制):
MTD partition size; 0f800000(16进制 248Mb)
flash physical eraseblock size; 00020000(16进制 128Kb 131072 b)
minimum flash input/output unit size; 2048 byte
for NAND flashes - sub-page size; 2048 byte
logical eraseblock size; 126976 byte
注:131072-126976=4096
2.2使用mkfs.ubifs命令将某个文件夹制作为UBIFS镜像
具体命令为
root@ep-VirtualBox:/opt# mkfs.ubifs -r /opt/rootfs -m 2048 -e 126976 -c 1984 -o ubifs.img
以上命令的含义为将/opt/rootfs文件夹制作为UBIFS文件系统镜像,输出的镜像名为ubifs.img.
mkfs.ubifs相关参数说明:
-m 最小 I/O 单元大小,一般是页大小, 2048 byte
-r 是指定哪个文件系统作为文件系统。
-e 是可擦除逻辑块大小,一般等于“物理擦除块的大小 - 2* 页大小” =131072-2*2048=126976
-c 是最大可擦除逻辑块总数,这个是从 ubinize.cfg 里面的 vol_size / ubinize里面的 -p 参数= (960 * 1024) / 256 == 3840
-o 生成的rootfs.ubi
-F 自动调整大小。
至此,直接烧录发现用不了。
2.3 ubinize转换镜像格式
使用ubinize命令可以将使用mkfs.ubifs命令制作的UBIFS文件系统镜像转换成可以直接在FLASH上烧写的格式(带有UBI文件系统镜像卷标)
root@ep-VirtualBox:/opt# ubinize -o rootfs.ubi -m 2048 -p 128KiB -s 512 -O 2048 ubinize.cfg
ubinize.cfg文件内容如下:
[ubifs]mode=ubiimage=ubifs.imgvol_id=0vol_size=100MiBvol_type=dynamicvol_alignment=1vol_name=rootfsvol_flags=autoresize
注:vol_size不能大于248,256-8=248,
8M为boostrap,uboot,kernel用,又由于坏块等,写248也不能用,此处应写小一点,如100,在测试时232也可以。
至此制作的文件镜像rootfs.ubi烧录可用(sama5d3xek nandflash启动测试过)
启动时相关信息如下:
2 cmdlinepart partitions found on MTD device atmel_nandCreating 2 MTD partitions on "atmel_nand":0x000000000000-0x000000800000 : "bootstrap/uboot/kernel"0x000000800000-0x000010000000 : "rootfs"UBI: attaching mtd1 to ubi0UBI: physical eraseblock size: 131072 bytes (128 KiB)UBI: logical eraseblock size: 126976 bytesUBI: smallest flash I/O unit: 2048UBI: VID header offset: 2048 (aligned 2048)UBI: data offset: 4096UBI: max. sequence number: 7UBI: attached mtd1 to ubi0UBI: MTD device name: "rootfs"UBI: MTD device size: 248 MiBUBI: number of good PEBs: 1972UBI: number of bad PEBs: 12UBI: number of corrupted PEBs: 0UBI: max. allowed volumes: 128UBI: wear-leveling threshold: 4096UBI: number of internal volumes: 1UBI: number of user volumes: 1UBI: available PEBs: 0UBI: total number of reserved PEBs: 1972UBI: number of PEBs reserved for bad PEB handling: 38UBI: max/mean erase counter: 2/0UBI: image sequence number: 953068048UBIFS: recovery completedUBIFS: mounted UBI device 0, volume 0, name "rootfs"UBIFS: file system size: 124563456 bytes (121644 KiB, 118 MiB, 981 LEBs)UBIFS: journal size: 9023488 bytes (8812 KiB, 8 MiB, 72 LEBs)UBIFS: media format: w4/r0 (latest is w4/r0)UBIFS: default compressor: lzoUBIFS: reserved for root: 0 bytes (0 KiB)VFS: Mounted root (ubifs filesystem) on device 0:11
相关命令说明(关于命令的解释说明有待完善)