目錄
前言
U-Boot 命令
help
信息查詢命令
bdinfo
printenv
version
環境變量操作命令
setenv 和 saveenv
修改環境變量
新建環境變量
刪除環境變量
內存操作命令
md
nm
mm
mw
cp
cmp
網絡操作命令
ping 命令
dhcp 命令
nfs 命令
tftp 命令
EMMC 和 SD 卡操作命令
mmc
mmc info 命令
mmc rescan 命令
mmc list 命令
mmc dev 命令
mmc part 命令
mmc read 命令
mmc write 命令
mmc erase 命令
前言
我們使用正點原子開發板imx6ull,在上一講實驗中:UBoot使用體驗,我們介紹了UBoot的編譯步驟、燒寫啟動流程,講解到在倒計時3秒內按下回車鍵進入命令行模式。
聰明的寶子們就會問了,命令行模式有什么作用?能夠用來做什么?本講實驗就來學習一下U-Boot 命令使用,主要包含:help、信息查詢命令(bdinfo/printenv/version)、環境變量操作命令(setenv/saveenv)、內存操作命令(md/nm/mm/mw/cp/cmp)、網絡操作命令(ping/dhcp/nfs/tftp)、操作MMC設備命令(mmc)等。
U-Boot 命令
help
進入 uboot 的命令行模式以后輸入“help”或者“?”,然后按下回車即可查看當前 uboot 所支持的命令,如圖:
Uboot 是可配置的,需要什么命令就使能什么命令。這些命令后面都跟有命令說明,用于描述此命令的作用。
輸入“help(或?) 命令名”,可以查看命令的詳細用法:
信息查詢命令
bdinfo
bdinfo 命令,此命令用于查看板子信息:
可以得出 DRAM 的起始地址和大小、啟動參數保存起始地址、波特率、sp(堆棧指針)起始地址等信息。
printenv
“printenv”用于輸出環境變量信息:
=> printenv
baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootcmd=run findfdt;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};
bootdelay=1
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
ethact=FEC1
ethprime=FEC
fdt_addr=0x83000000
fdt_file=imx6ull-14x14-emmc-4.3-480x272-c.dtb
fdt_high=0xffffffff
findfdt=if test $fdt_file = undefined; then if test $board_name = EVK && test $board_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_name = EVK && test $board_rev = 14X14; then setenv fdt_file imx6ull-14x14-evk.dtb; fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb to use; fi; fi;
image=zImage
initrd_addr=0x83800000
initrd_high=0xffffffff
ip_dyn=yes
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
logo_file=alientek.bmp
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" clk_ignore_unused
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcdev=0
mmcpart=1
mmcroot=/dev/mmcblk0p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
panel=ATK-LCD-4.3-480x272
script=boot.scr
splashimage=0x88000000
splashpos=m,m
stderr=serial
stdin=serial
stdout=serialEnvironment size: 2583/8188 bytes
uboot 中的環境變量都是字符串,是可以修改的,有專門的命令來修改環境變量的值。
version
version 用于查看 uboot 的版本號:
環境變量操作命令
setenv 和 saveenv
命令 setenv 用于設置或者修改環境變量的值。
命令 saveenv 用于保存修改后的環境變量。
一般環境變量是存放在外部 flash 中的, uboot 啟動的時候會將環境變量從 flash 讀取到 DRAM 中。所以使用命令 setenv 修改的是 DRAM中的環境變量值,修改以后要使用 saveenv 命令將修改后的環境變量保存到 flash 中,否則的話uboot 下一次重啟會繼續使用以前的環境變量值。
修改環境變量
比如我們要將環境變量 bootdelay (倒計時延時時間)改為 5,就可以使用如下所示命令:
可以看出環境變量保存到了 MMC(0)中,也就是 SD 卡中。
修改 bootdelay 以后,重啟開發板, uboot 就會變為 5 秒倒計時。嫌時間太久記得修改回來哦。
有時候我們修改的環境變量值可能會有空格, 比如 bootcmd、 bootargs 等, 這個時候環境變量值就得用單引號括起來,每組值之間用空格隔開。
比如下面修改環境變量 bootargs 的值:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv
新建環境變量
命令 setenv 也可以用于新建命令,比如我們新建一個環境變量cmdtest,將這個變量的值設為huaxuan,那么就可以使用如下命令:
setenv cmdtest huaxuan
saveenv
新建環境變量以后,需要重啟 uboot,然后使用命令 printenv 查看是否有我們新增的命令。
刪除環境變量
要刪除一個環境變量只要給這個環境變量賦空值即可,像這樣刪掉我們剛新增的命令:
setenv cmdtest
saveenv
內存操作命令
內存操作命令就是用于直接對 DRAM 進行讀寫操作的,常用的內存操作命令有 md、 nm、mm、 mw、 cp 和 cmp。
md
md 命令用于顯示內存值,格式如下:
md[.b, .w, .l] address [# of objects]
- 命令中的[.b .w .l]對應 byte、 word 和 long,也就是分別以 1 個字節、 2 個字節、 4 個字節來顯示內存值。
- address 就是要查看的內存起始地址。
- ?[# of objects]表示要查看的數據長度。
查看以 0X80000000 為起始地址的內存數據:
nm
nm 命令用于修改指定地址的內存值,命令格式如下:
nm [.b, .w, .l] address
比如想修改 0x80000000 地址的數據:
?后面就可以輸入要修改后的數據,輸入完成以后按下回車,然后再輸入‘q’即可退出。
但是可以看見使用nm命令修改地址的時候,地址不會自己遞增,一直操作的都是同一個地址。
mm
mm 命令也是修改指定地址內存值的,使用 mm 修改內存值的時候地址會自增。
mm [.b, .w, .l] address
mw
命令 mw 用于使用一個指定的數據填充一段內存,命令格式如下:
mw [.b, .w, .l] address value [count]
- mw 命令同樣可以以.b、 .w 和.l 來指定操作格式,
- address 表示要填充的內存起始地址,
- value為要填充的數據,
- count 是填充的長度。
比如使用.l 格式將以 0X80000000 為起始地址的 0x10 個內存塊(0x10 * 4=64 字節)填充為 0X0A0A0A0A
怎么知道數據填充成功沒有呢?使用命令 md 來查看:
cp
cp 是數據拷貝命令,用于將 DRAM 中的數據從一段內存拷貝到另一段內存中,或者把 Nor Flash 中的數據拷貝到 DRAM 中。命令格式如下:
cp [.b, .w, .l] source target count
- 以.b、 .w 和.l 來指定操作格式,
- source 為源地址,
- target 為目的地址,
- count為拷貝的長度。
比如使用.l 格式將 0x80000000 處的地址拷貝到 0X80000040 處,長度為 0x10 個內存塊(0x10 * 4=64 個字節):
cmp
cmp 是比較命令,用于比較兩段內存的數據是否相等,命令格式如下:
cmp [.b, .w, .l] addr1 addr2 count
我們使用.l 格式來比較 0x80000000 和 0X80000040 這兩個地址數據是否相等,比較長度為 0x10 個內存塊:
可以看出這兩段內存的數據相等。那么不相等的時候會怎么樣顯示呢?
網絡操作命令
uboot 支持大量的網絡相關命令,比如 dhcp、ping、 nfs 和 tftpboot。
在使用 uboot 的網絡功能之前先用網線將開發板的 ENET2 接口和電腦或者路由器連接起來。
還要設置表中所示的幾個環境變量:
網絡地址環境變量的設置,要確保 Ubuntu 主機和開發板的 IP地址在同一個網段內。
ping 命令
通過 ping 命令,ping 服務器的 IP 地址,來檢測兩者之間網絡是否連通。如果網絡正常,如下圖:
dhcp 命令
dhcp 用于從路由器獲取 IP 地址,前提得開發板連接到路由器上的,如果開發板是和電腦直連的,那么 dhcp 命令就會失效。
直接輸入 dhcp 命令即可通過路由器獲取到 IP 地址:
nfs 命令
nfs(Network File System)網絡文件系統,通過 nfs 可以在計算機之間通過網絡來分享資源。
uboot 中的 nfs 命令格式如下所示:
nfs [loadAddress] [[hostIPaddr:]bootfilename]
- loadAddress 是要保存的 DRAM 地址,
- [[hostIPaddr:]bootfilename]是要下載的文件地址。
在 uboot 中使用 nfs 命令,將 Ubuntu 中的 linux 鏡像和設備樹下載到開發板的 DRAM 中
,可以更方便調試 linux 鏡像和設備樹。我們之后都會使用網絡調試的方法。
首先需要開啟 Ubuntu 主機的 NFS 服務,然后新建一個 NFS 使用的目錄,以后所有要通過NFS 訪問的文件都需要放到這個 NFS 目錄中。現在nfs目錄里我已經放了一個zImage的鏡像文件。
使用 nfs 命令來將 zImage 下載到開發板 DRAM 的 0X80800000 地址處:
nfs 80800000 192.168.1.253:/home/huax/linux/nfs/zImage
- “ 80800000 ” 表 示 zImage 保 存 地 址 ,
- “192.168.1.253:/home/huax/linux/nfs/zImage”表示 zImage 在 192.168.1.253 這個主機中,對應的nfs目錄路徑。
下載過程如圖:打印done就是下載結束了。
下載完成以后可以查看 0x80800000 地址處的數據,使用命令 md.b 來查看前 0x100 個字節的數據,然后再用能查看二進制的工具比對,可以看見數據一致的。
tftp 命令
tftp 命令的作用和 nfs 命令一樣,都是用于通過網絡下載東西到 DRAM 中,只是 tftp 命令使用的 TFTP 協議, Ubuntu 主機作為 TFTP 服務器。
需要在 Ubuntu 上搭建 TFTP 服務器,需要安裝 tftp-hpa 和 tftpd-hpa,命令如下:
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd
TFTP 也需要一個文件夾tftpboot來存放文件,記得給 tftpboot 文件夾權限:
最后配置 tftp,安裝完成以后新建文件/etc/xinetd.d/tftp, 如果沒有/etc/xinetd.d 目錄的話自行創建。
?然后在里面輸入如下內容:
server tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /home/zuozhongkai/linux/tftpboot/
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
完了以后啟動 tftp 服務,命令如下:
sudo service tftpd-hpa start
打開/etc/default/tftpd-hpa 文件,將TFTP_DIRECTORY 修改為我們上面創建的 tftp 文件夾目錄,以后我們就將所有需要通過TFTP 傳輸的文件都放到這個文件夾里面,并且要給予這些文件相應的權限。
然后再重啟一次 tftp 服務器。tftp 服務器已經搭建好了。
將我們需要燒寫的zImage 鏡像文件拷貝到 tftpboot 文件夾中,并且給予 zImage 相應的權限。
uboot 中的 tftp 命令格式如下:
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
- loadAddress 是文 件在 DRAM 中的 存放 地址 ,
- [[hostIPaddr:]bootfilename]是要從 Ubuntu 中下載的文件。
將 tftpboot 文件夾里面的 zImage 文件下載到開發板 DRAM 的 0X80800000 地址處,命令如下:
tftp 80800000 zImage
EMMC 和 SD 卡操作命令
mmc
mmc 后面跟不同的參數可以實現不同的功能:
我們常用的幾個功能如下:
mmc info 命令
mmc info 命令用于輸出當前選中的 mmc info 設備的信息:
mmc rescan 命令
mmc rescan 命令用于掃描當前開發板上所有的 MMC 設備,包括 EMMC 和 SD 卡。
mmc list 命令
mmc list 命令用于來查看當前開發板一共有幾個 MMC 設備:
mmc dev 命令
mmc dev 命令用于切換當前 MMC 設備,命令格式如下:
mmc dev [dev] [part]
- [dev]用來設置要切換的 MMC 設備號,
- [part]是分區號。如果不寫分區號的話默認為分區 0。
我們現在使用的EMMC,可以使用如下命令切換到 SD 卡:
mmc part 命令
有時候 SD 卡或者 EMMC 會有多個分區,可以使用命令“mmc part”來查看其分區。
比如查看 EMMC 的分區情況,輸入如下命令:
mmc dev 1 //切換到 EMMC
mmc part //查看 EMMC 分區
由上圖可知:此時 EMMC 有兩個分區, 第一個分區起始扇區為 20480,長度為 262144 個扇區; 第二個分區起始扇區為 282624,長度為 14594048 個扇區。
如果 EMMC 里面燒寫了 Linux 系統的話, EMMC 是有 3 個分區的:
- 第 0 個分區存放 uboot,
- 第 1 個分區存放Linux 鏡像文件和設備樹,
- 第 2 個分區存放根文件系統。
如果要將 EMMC 的分區 2 設置為當前 MMC 設備,可以使用如下命令:
mmc read 命令
mmc read 命令用于讀取 mmc 設備的數據,命令格式如下:
mmc read addr blk# cnt
- addr 是數據讀取到 DRAM 中的地址,
- blk 是要讀取的塊起始地址(十六進制),一個塊是 512字節,
- cnt 是要讀取的塊數量(十六進制)。
比如從 EMMC 的第 1536(0x600)個塊開始,讀取 16(0x10)個塊的數據到 DRAM 的0X80800000 地址處,命令如下::
mmc write 命令
要將數據寫到 MMC 設備里面,可以使用命令“mmc write”,格式如下:
mmc write addr blk# cnt
- addr 是要寫入 MMC 中的數據在 DRAM 中的起始地址,
- blk 是要寫入 MMC 的塊起始地址(十六進制),
- cnt 是要寫入的塊大小,一個塊為 512 字節。
我們可以使用命令“mmc write”來升級 uboot,也就是在 uboot 中更新 uboot。這里要用到 nfs 或者 tftp 命令,通過 nfs 或者 tftp 命令將新的 u-boot.bin 下載到開發板的 DRAM 中,然后再使用命令“mmc write”將其寫入到 MMC設備中。
tftp 80800000 u-boot.imx
mmc dev 0 0
mmc write 80800000 2 2E6
使用 tftp 命令將燒寫文件下載到 0x80800000 地址處,假設u-boot.imx 大小為 379904 字節, 379904/512=742,所以我們要向 SD 卡中寫入742 個塊,如果有小數的話就要加 1 個塊。使用命令“mmc write”從 SD 卡分區 0 第 2 個塊(扇區)開始燒寫,一共燒寫 742(0x2E6)個塊。
如果要在 uboot 中更新 EMMC 對應的 uboot,可以使用如下所示命令:
mmc dev 1 0 //切換到 EMMC 分區 0
tftp 80800000 u-boot.imx //下載 u-boot.imx 到 DRAM
mmc write 80800000 2 32E //燒寫 u-boot.imx 到 EMMC 中
mmc partconf 1 1 0 0 //分區配置, EMMC 需要這一步.
mmc erase 命令
如果要擦除 MMC 設備的指定塊就是用命令“mmc erase”,命令格式如下:
mmc erase blk# cnt
- blk 為要擦除的起始塊,
- cnt 是要擦除的數量。
本講實驗就先寫到這吧,這些命令實在太多了,為了方便閱讀和復習,我覺得分為上下兩講比較好。
在下講內容里,我們會介紹:FAT 格式文件系統操作命令、EXT 格式文件系統操作命令、NAND 操作命令、BOOT 操作命令、和其它常用的命令(reset、 go、 run 和 mtest)。