SAMA5D3X-EK 嵌入式linux內核編譯啓動及通過nfs通過網絡啓動文件系統及文件系統鏡像的製作

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掛在有關的選項如下:

  1. Networking support->Networking options->IP:kernel level autoconfiguration

注意,這個選項下面的 IP:DHCP support / IP:BOOTP support / IP:RARP aupport
不能選。因爲我的開發環境中沒有安裝 DHCP server。開發板的 IP
是在內核啓動參數中指定的。

在這裏插入圖片描述

  1. 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

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SmRs1XAQ-1571718363978)(media/f2eeb4eef039ab29f0a2c9d237901059.png)]

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

  1. 修改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

相關命令說明(關於命令的解釋說明有待完善)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章