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文件中有如下一行:
#:BOOT:TFTP服務主要用於啓動。大多數網站 #僅在充當“啓動服務器”的計算機上運行。 tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp |
---|
因爲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
注意,這個選項下面的 IP:DHCP support / IP:BOOTP support / IP:RARP aupport
不能選。因爲我的開發環境中沒有安裝 DHCP server。開發板的 IP
是在內核啓動參數中指定的。
- File systems -> Network File System -> NFS client support
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 https://cdn.kernel.org/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源碼的獲取
官網網址:https://busybox.net/
去官網下載當前最新的穩定版本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-2013.04-20130415_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自動掛載需要
/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
- 修改etc/fstab文件,增加以下文件
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-2013.04-20130415_linux/arm-linux-gnueabihf/lib我的只是把這個目錄下的SO文件複製就可以了)
1)#cd /opt/gcc-linaro-arm-linux-gnueabihf-4.7-2013.04-20130415_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-2013.04-20130415_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/mtd
- minimum 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=ubi
image=ubifs.img
vol_id=0
vol_size=100MiB
vol_type=dynamic
vol_alignment=1
vol_name=rootfs
vol_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_nand
Creating 2 MTD partitions on "atmel_nand":
0x000000000000-0x000000800000 : "bootstrap/uboot/kernel"
0x000000800000-0x000010000000 : "rootfs"
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: 7
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: 2/0
UBI: image sequence number: 953068048
UBIFS: recovery completed
UBIFS: 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: lzo
UBIFS: reserved for root: 0 bytes (0 KiB)
VFS: Mounted root (ubifs filesystem) on device 0:11
相關命令說明(關於命令的解釋說明有待完善)