1、前言
Uboot啟動后,會進入到一個倒計時,在倒計時結束之前,如果此時我們按下鍵盤的回車鍵,將進入到uboot的命令行模式,有點類似Linux系統終端模式,如果沒有按下回車鍵的話,將直接啟動Linux內核,本篇文章將介紹uboot中的一些常用命令,熟悉這些命令后,以后在適配調試uboot的時候會得心應手。
如下所示,倒計時的時候按下回車鍵后,進入到uboot的命令行模式:
在行的前面多了"=>"字符串,說明此時已經進入uboot的命令行模式了,接下來就可以進行一些命令輸入。
2、查看uboot支持的命令
在使用uboot命令之前,我們先來看看當前的uboot版本所支持的命令有哪些,可以在當前的命令函數輸入:
=> help
or
=> ?
該命令用於查看當前uboot版本所支持的所有命令,輸入后按回車即可,在我當前使用的uboot版本中所支持的命令如下:
? - alias for 'help' base - print or set address offset bdinfo - print Board Info structure bmode - sd1|sd2|qspi1|normal|usb|sata|ecspi1:0|ecspi1:1|ecspi1:2|ecspi1:3|esdhc1|esdhc2|esdhc3|esdhc4 [noreset] bmp - manipulate BMP image data boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol bootvx - Boot vxWorks from an ELF image bootz - boot Linux zImage image from memory clocks - display clocks clrlogo - fill the boot logo area with black cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation dcache - enable or disable data cache dhcp - boot image via network using DHCP/TFTP protocol dm - Driver model low level access echo - echo args to console editenv - edit environment variable env - environment handling commands erase - erase FLASH memory exit - exit script ext2load- load binary file from a Ext2 filesystem ext2ls - list files in a directory (default /) ext4load- load binary file from a Ext4 filesystem ext4ls - list files in a directory (default /) ext4size- determine a file's size ext4write- create a file in the root directory false - do nothing, unsuccessfully fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fatsize - determine a file's size fdt - flattened device tree utility commands flinfo - print FLASH memory information fstype - Look up a filesystem type fuse - Fuse sub-system go - start application at address 'addr' gpio - query and control gpio pins help - print command description/usage i2c - I2C sub-system icache - enable or disable instruction cache iminfo - print header information for application image imxtract- extract a part of a multi-image itest - return true/false on integer compare load - load binary file from a filesystem loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loadx - load binary file over serial line (xmodem mode) loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range ls - list files in a directory (default /) md - memory display mm - memory modify (auto-incrementing address) mmc - MMC sub system mmcinfo - display MMC info mw - memory write (fill) nand - NAND sub-system nboot - boot from NAND device nfs - boot image via network using NFS protocol nm - memory modify (constant address) ping - send ICMP ECHO_REQUEST to network host pmic - PMIC printenv- print environment variables protect - enable or disable FLASH write protection reset - Perform RESET of the CPU run - run commands in an environment variable save - save file to a filesystem saveenv - save environment variables to persistent storage setenv - set environment variables setexpr - set environment variable as the result of eval expression showvar - print local hushshell variables size - determine a file's size sleep - delay execution for some time source - run script from memory test - minimal test like /bin/sh tftpboot- boot image via network using TFTP protocol true - do nothing, successfully usb - USB sub-system usbboot - boot from USB device version - print monitor, compiler and linker version
對於上面的命令列表中的命令,並不是所有都能運行的,如果該命令並沒有在板級文件中使能配置的話,哪么直接在命令行中輸入后按回車鍵,將會直接提示運行不了,也就是說上面列出的命令,並沒有全部都使能了。
上面列出的命令,后面都描述了命令的功能,例如,最后一個version命令,它的功能就是用來輸出uboot編譯和鏈接的相關版本信息,除此之外,如果我們想查看某個命令的詳細用法的話,可以輸入:
=> help command_name
or
=> ? command_name
例如,我們查看bootz命令的用法,輸入如下,然后回車:
=> help bootz
or
=> ? bootz
回車后,輸出如下:
從輸出的結果可以看到,bootz命令的用法被詳細的列出來了,該命令就是用來在內存中啟動Linux內核的,對於其它命令的詳細用法,我們也可以使用這個方式進行命令的詳細使用方式進行查詢,接下來,我們了解一些常用的uboot命令用法。
3、信息查詢相關命令
在uboot的命令中,常用的信息查詢命令主要有3個,分別是bdinfo、printenv和version命令。
首先是bdinfo命令,該命令用來查詢當前板子的相關信息,在命令行模式下,直接輸入bdinfo,然后回車即可,輸出如下:
如上所示,通過該命令可以查看板子的DRAM的大小以及DRAM的起始地址、當前使用的網絡接口以及IP地址、波特率和uboot偏移地址以及偏移量等相關信息。
接下來是printenv命令,該命令用於查詢當前板子的一些相關環境變量,同樣,在命令行模式下輸入printenv並回車,輸出如下:
從上圖可以看到,命令輸入后,將會輸出一堆的環境變量,例如:當前串口的波特率baudrate、啟動參數bootargs以及啟動命令bootcmd等,這些環境變量都是字符串,能對其進行修改。
最后則是version命令,該命令用於查詢uboot版本和交叉編譯工具的相關信息,在命令模式下輸入version后並回車,輸出如下:
從輸出的信息可以看到,當前的uboot版本號為2016.03,后面接的是編譯時間,交叉編譯工具鏈為arm-linux-gnueabihf-gcc,版本號為4.9.4。
4、環境變量相關命令
環境變量常用的命令主要有兩個,分別是setenv和saveenv,setenv命令用來設置或者修改當前環境變量的值,saveenv用來保存環境變量的值,一般環境變量是存放在外部的Flash中的,例如Nand Flash中,當uboot啟動的時候,會將環境變量讀取的DRAM中,當我們使用setenv修改了環境變量的值后,需要使用saveenv命令將修改后的環境變量的值保存到Flash中,否則修改無效。
setenv命令的格式如下:
=> setenv env value
查看當前的bootdelay環境變量值為:
=> print bootdelay
輸出如下所示:
當前的bootdelay為3,我們要將bootdelay環境變量的值設置為5,可以使用下面的命令:
=> setenv bootdelay 5
=> saveenv
輸出如下:
從輸出信息可以看到,新設置的環境變量已經被保存到Nand Flash中了,這時候重啟系統,將會發現啟動倒計時變成了5秒,重新輸出bootdelay環境,如下:
需要注意的是,當我們修改環境變量有空格值的時候,例如bootcmd或者bootargs等,這個時候的環境變量值需要使用單引號括起來。
此外,setenv命令也可以用來新建環境變量,比如我們要新建一個author的環境變量並查看,可以使用下面的命令:
=> setenv author huangly => saveenv => print author
設置成功后,輸出如下:
setenv命令可以用來新建環境變量,也可以用來刪除環境變量,如下命令可以刪除author環境變量:
=> setenv author => saveenv => print
設置后,輸出如下:
從輸出可以看到,author環境變量已經被成功刪除了。
5、內存操作相關命令
內存操作的相關命令用於對DRAM內存進行讀寫操作,常用的內存操作命令有md、nm、mm、mw、cp、cmp。
(1)md命令
md命令用於顯示內存值,該命令的用法如下所示:
命令用法中的[.b, .w, .l]對應着byte、word、long,分別以1個字節、2個字節、4個字節來進行內存值顯示,address表示要查看的內存起始地址,[# of objects]表示要查看的數據長度,和顯示的數據格式有關,並且需要注意的是uboot命令中的數字都是十六進制的。
例如,當我們想要查看從地址0x8000000開始的20個字節的內存值,可以使用下面的命令顯示:
=> md.b 80000000 14
or
=> md.b 0x80000000 0x14
顯示結果如下:
(2)nm命令
nm命令用於修改指定地址的內存值,該命令的用法如下:
nm命令同樣是使用[.b, .w, .l]來指定內存的操作格式,例如,想要使用修改0x80000000地址的數據為0x77,可使用下面的命令:
=> nm.b 80000000
or
=> nm.b 0x80000000
在上述的命令中,b表示修改為1個字節,80000000表示要修改的內存地址,修改如下所示:
對內存的值修改完成后,可以使用md命令重新顯示新修改的內存值。
(3)mm命令
mm命令也是可以用來修改內存值,但是使用mm命令修改內存值的時候,地址值將會自增,使用nm命令時,地址值將不會自增。
例如,使用.b格式修改0x80000000開始的連續4個字節數據為0x12345678,使用命令如下:
=> mm.b 80000000
修改的過程中,地址會自增,修改完成后顯示如下:
修改后,要使用md命令查看修改的值,判斷是否修改成功。
(4)mw命令
mw命令用來使用一個指定的數據填充一段內存,命令的使用方法如下:
該命令同樣使用[.b, .w, .l]來指定操作格式,address表示要填充的內存起始地址,value表示要填充的數據,count是要填充的長度。
例如,使用.b格式將以0x80000000為起始地址的0x14個內存塊填充為0x33,命令如下:
=> mw.b 80000000 33 14
命令執行后如下所示:
使用mw修改完成后,要使用md命令顯示修改后的內存值,判斷是否修改成功。
(5)cp命令
cp命令是數據拷貝命令,用於將DRAM中的數據從一段內存中拷貝到另一段內存中,命令的使用格式如下所示:
該命令同樣使用[.b, .w, .l]來指定操作格式,source表示為內存源地址,target表示為目標地址,count為拷貝的長度。
例如,使用.b格式將0x80000000開始地址處的0x14個字節拷貝到0x80000100地址處,命令如下所示:
=> cp.b 80000000 80000100 14 or => cp.b 0x80000000 0x80000100 14
命令執行后輸出如下所示:
內存修改后,要使用md命令檢查內存值是否修改成功。
(6)cmp命令
cmp命令用於比較兩段內存的數據是否相等,命令的使用格式如下所示:
該命令同樣使用[.b, .w, .l]來指定操作格式,addr1為第一段內存首地址,addr2為第二段內存首地址,count表示要比較的長度。
例如,使用.b格式來比較0x80000000和0x80000100兩個地址的數據是否相等,比較的長度為0x14個字節,命令如下:
=> cmp.b 80000000 80000100 14
命令執行后顯示如下:
從上面的比較輸出結果可以看到,兩個地址處的數據是相同的。
6、emmc和sd卡相關操作命令
對於uboot來說是支持emmc或者sd卡,因此也需要提供給用戶emmc和sd卡的相關操作命令,uboot中常用於操作mmc設備的命令為"mmc",mmc是一系列的命令,它的后面可以跟不同的參數,在uboot命令行中,輸入下面的命令可以查看詳細的用法:
=> ? mmc
回車后,輸出如下所示:
從圖中可以看到,mmc后跟不同的參數可以實現不同的功能,如下:
命令 | 功能 |
mmc info | 輸出mmc設備的信息 |
mmc read | 讀取mmc設備中的數據 |
mmc write | 向mmc設備中寫入數據 |
mmc rescan | 掃描當前存在的mmc設備 |
mmc part | 列出mmc設備的分區 |
mmc dev | 切換mmc設備 |
mmc list | 列出當前的mmc設備 |
mmc hwpartition | 設置mmc設備的分區 |
mmc bootbus | 設置指定mmc設備的BOOT_BUS_WIDTH的值 |
mmc bootpart | 設置指定mmc設備的boot和RPMB分區大小 |
mmc partconf | 設置指定mmc設備的PARTITION_CONFIG的值 |
mmc rst | mmc設備復位 |
mmc setdsr | 設置mmc設備DSR寄存器的值 |
接下來,依次看一下這些命令的使用。
(1)mmc info
mmc info命令用來顯示當前選中的mmc設備的信息,直接輸入下面的命令即可:
=> mmc info
在我當前的目標板中,接入了一張Mico SD卡,其輸出信息如下:
從輸出信息可以知道,SD卡的速率為25MHz,容量為7.4GB(SD卡為8GB卡),總線的寬度為4bit。
(2)mmc rescan
mmc rescan命令用於掃描當前目標板上所有的mmc設備,包括eMMC和SD卡,命令輸入如下:
=> mmc rescan
(3)mmc list
mmc list命令可用於查看當前目標板共有多少個mmc設備,輸入命令如下:
=> mmc list
回車后,將會列出mmc設備,我當前的輸出如下:
從輸出可以知道,當前默認的設備為SD卡。
(4)mmc dev
mmc dev命令可以用來切換當前的mmc設備,命令格式如下:
mmc dev [dev] [part]
其中[dev]表示要切換的mmc設備號,[part]是mmc設備的分區號,如果不寫分區號,則默認為分區0。
例如,使用命令切換到eMMC設備:
#當0為SD卡,1為eMMC時
=> mmc dev 1
(5)mmc part
mmc part命令可以用來查看當前mmc設備的分區,例如查看當前sd卡中的分區:
=> mmc dev 0
=> mmc part
輸出結果如下:
可以看到,當前只有一個分區,開始的扇區為2048。
(6)mmc read
mmc read命令可用於讀取mmc設備的數據,它的使用格式如下所示:
mmc read addr blk# cnt
其中addr是將數據讀取到DRAM中的地址,blk是要讀取的塊起始地址,一塊為512字節,cnt則是要讀取的塊的數量。
例如,從當前的SD卡設備的第2048塊開始,讀取20個塊數據到DRAM的0x80000100地址處,該命令如下:
=> mmc list => mmc dev 0 => mmc read 80000100 800 14
讀取成功后,如下所示:
(7)mmc write
mmc write命令可以將DRAM中的數據寫入到mmc設備里面,其命令的格式如下所示:
mmc write addr blk# cnt
其中addr是要寫入到mmc設備中的數據在DRAM中的起始地址,blk是要寫入mmc的塊起始地址,cnt是要寫入的塊數量,一個塊的大小為512字節。
例如,將DRAM地址0x80000100開始的數據,從mmc設備的2048個塊開始燒寫,燒寫20個塊,命令如下:
=> mmc list => mmc part => mmc write 80000100 2048 14
命令執行后,數據寫入成功如下:
(8)mmc erase
mmc erase可以用來擦除mmc設備中指定的塊,其使用命令格式如下:
mmc erase blk# cnt
其中blk是要擦除的起始塊,cnt是要擦除的塊數量。
例如,可以使用下面的命令擦除mmc設備從2048個塊開始的20個塊:
=> mmc list => mmc part => mmc erase 800 14
塊擦除成功后,如下所示:
需要注意的是,不要隨便使用該命令擦除mmc設備的前兩個塊,它里面保存着分區表。
7、FAT格式文件系統相關操作命令
當我們需要在uboot中對SD卡或者eMMC設備中存儲的文件進行操作時,這個時候就需要用到uboot中文件系統的操作命令,對於FAT格式的文件系統操作相關的命令有fatinfo、fatls、fstype、fatload、fatwrite等,接下來,依次看看這些命令的用法。
(1)fatinfo命令
fatinfo命令用來查詢mmc設備中指定分區的文件系統信息,該命令的用法如下:
該命令的用法中,<interface> 表示要查看的接口,例如mmc,[<dev[:part]>]中的dev表示要查詢的設備號,part則表示要查詢的分區。
例如,當前我的目標板有個sd卡設備,查看sd卡中分區1的文件系統信息,可以使用下面的命令:
=> mmc list => mmc part => fatinfo mmc 0:1
命令輸入回車后,輸出如下所示:
從輸出的結果中可以看到該mmc設備的分區1的文件系統格式為FAT32的。
(2)fatls命令
fatls命令可以用於查詢FAT格式文件系統的目錄和文件信息,該命令的用法如下:
在該命令的用法中,<interface>表示要查詢的接口,[<dev[:part]>]中dev表示要查詢的設備號,part表示要查詢分區,[directory]表示要查詢的目錄,如果該參數不輸入的話,默認為根目錄。
例如,查詢我當前sd卡中分區1中的目錄和文件,可以輸入下面命令:
=> fatls mmc 0:1
命令輸入回車后,將會列舉根目錄下所有的目錄和文件,輸出如下:
當我們再想查看img/目錄下的目錄或者文件時,可以使用下面的命令:
=> fatls mmc 0:1 img/
命令輸入回車后,輸出如下:
從輸出中可以看到,該目錄下存在着1個文件和兩個目錄,其中.和../是隱藏的目錄。
(3)fstype命令
fstype命令可以用於查看mmc設備中某個分區的文件系統格式,該命令的用法如下所示:
從上面的輸出可以看到,fstyp命令具有兩個用法,第一個用來查看mmc設備分區中的文件系統類型,第二個則是用來設置文件系統類型的環境變量,對於第一個命令用法,<interface>表示接口,例如mmc,<dev>:<part>中dev則表示要查詢的設備號,part則是設備的分區。
例如,查看我當前目標板中sd設備的第一個分區的文件系統類型,可以使用下面命令:
=> fstype mmc 0:1
命令輸入后回車,輸出如下所示:
可以看到當前sd卡的第一個分區文件系統格式為fat類型的。
(4)fatload命令
fatload命令用來將指定的文件讀取到DRAM內存中,該命令的使用格式如下:
該命令的用法中,<interface>表示設備接口,例如mmc,[<dev[:part]>中的dev表示設備號,part表示mmc設備的分區,<addr>則是文件讀取到DRAM中的起始地址,<filename>則是要讀取的文件的名字,bytes表示要讀取多少字節的數據,如果該值為0或者未使用,則表示將要讀取整個文件,pos表示要讀的文件相對於文件首地址的偏移,如果為0或者未使用,則表示從文件首地址開始讀取。
例如,在我當前的目標幫中,將sd卡中第一個分區中的img/u-boot-imx6ul14x14evk_nand.imx文件讀取到DRAM中0x80000100起始地址中,可以使用下面的命令:
=> fatls mmc 0:1 img/ => fatload mmc 0:1 80000100 img/u-boot-imx6ul14x14evk_nand.imx
命令輸入后回車,輸出如下:
從輸出結果可以看到,已經將該文件讀取到了DRAM中,讀取了470016個字節,速度未6.9MiB/s。
(5)fatwrite命令
需要注意的是,當在uboot的板級配置文件中定義了#define CONFIG_CMD_FAT宏,fatinfo、fatls、fatload命令才會出現在uboot命令中,而fatwrite命令則需要定義#define CONFIG_FAT_WRITE宏才會出現,因此,如果想要在uboot中使用fatwrite命令,則需要定義宏CONFIG_FAT_WRITE。
fatwrite命令可以用於將DRAM中的數據寫入到mmc設備中去,該命令的使用格式如下:
命令格式中,<interface>表示為接口,例如mmc,<dev[:part]>中dev表示為設備號,part表示為mmc設備的分區,<addr>則為要寫入的數據在DRAM中的起始地址,<filename>表示寫入的數據文件的名字,<bytes>表示要寫入的字節數。
例如,在我的目標板系統中從DRAM地址0x80000100開始寫20個字節,在sd卡設備的分區1中生成test.bin文件,可以使用下面命令:
=> mmc list => fatls mmc 0:1 => fatwrite mmc 0:1 80000100 test.bin 14 => fatls mmc 0:1
命令輸入回車后,輸出如下:
從輸出結果可以看到,test.bin文件成功寫入到sd卡,並且大小為20字節,在Linux嵌入式調試中,可以使用該命令進行uboot或者zImage文件的更新。
8、EXT格式文件系統相關操作命令
uboot中除了有FAT格式文件系統的相關操作命令外,還有EXT格式文件系統的相關操作命令,這些命令和實現的功能如下所示:
命令 | 功能 |
ext2load | 從Ext2文件系統中加載二進制文件到DRAM中 |
ext2ls | 列舉目錄中的文件 |
ext4load | 從Ext4文件系統中加載二進制文件到DRAM中 |
ext4ls | 列舉目錄中的文件 |
ext4size | 修改文件大小 |
ext4write | 在root目錄下新創建文件 |
以上命令的使用方式和FAT格式文件系統相關命令的使用方式相同。
例如,當前我目標板上的sd卡設備中的分區2是ext2文件系統,可以使用下面命令查詢分區2中的目錄和文件:
=> mmc list => mmc part => ext2ls mmc 0:2
命令輸入后回車,輸出如下所示:
從上圖看到,列出了3個目錄和1個文件,其中lost+found目錄是在創建ext2文件系統的時候生成的,part2是測試的一個文件。
9、Nand Flash相關操作命令
uboot中除了有emmc子系統外,還具有nand子系統,所有uboot也是支持Nand Flash的,在這里,我使用的是盈鵬飛公司的CoM-P6UL核心板,板載了256MB的DRAM和256MB的Nand Flash,支持從Nand Flash中啟動,Nand Flash的分區如下:
Name | Offset | Size | 說明 |
uboot | 0x0 | 0x400000 | 4MB |
kernel | 0x400000 | 0x1000000 | 16MB |
dtb | 0x1400000 | 0x80000 | 512KB |
rootfs | 0x1480000 | 0xeb80000 | 235.5MB |
在uboot中輸入下面的命令可以查看Nand子系統所支持的所有命令:
=> ? nand
將輸出如下所示:
從上面可以看到,uboot中對於Nand Flash的命令是非常多的,接下來,對一些常使用的命令進行分析。
(1)nand info命令
nand info命令可以用來打印目標板上Nand Flash的相關信息,直接輸入下面命令回車即可:
=> nand info
在我當前目標板上,輸出如下所示:
從輸出可以看到,它打印輸出了當前Nand Flash的頁面大小和00B大小等相關信息。
(2)nand device命令
nand device命令能用於顯示Nand Flash的信息,也能用於切換目標板上的Nand Flash,如果目標板支持多塊Nand Flash的話,可以使用該命令進行切換。
(3)nand erase命令
nand erase命令可以用於擦除Nand Flash,在對Nand Flash中寫入數據之前,必須要先對寫的區域進行擦除,然后才能保證數據能寫入進擦除的區域內,nand erase命令的形式有3種,如下:
第一種形式如下:
nand erase[.spread] [clean] off size
off表示Nand Flash的偏移地址,也就是要擦除區域的起始地址,size表示要擦除的區域大小。
例如,可以使用下面的命令將Nand Flash存儲Linux內核鏡像zImage的區域進行擦除:
=> nand erase 0x400000 0x1000000
命令輸入回車后,輸出如下:
第二種形式如下:
nand erase.part [clean] partition
表示擦除指定的區域。
第三種形式如下:
nand erase.chip [clean]
該形式將會將整個Nand Flash進行擦除,nand erase命令一般是配后nand write命令進行配后使用。
(4)nand read命令
nand read命令可以用於從Nand Flash中指定的地址讀取指定大小的數據到DRAM中,該命令的使用格式如下:
nand read - addr off|partition size
命令使用格式中,addr表示DRAM的地址,off表示要讀取的Nand Flash的區域的起始地址,size表示要讀取的數據大小。
例如,可以使用下面的命令讀取Linux內核鏡像zImage文件到DRAM的0x80800000地址處:
=> nand read 0x80800000 0x400000 0x1000000
命令輸入並回車,輸出如下:
(5)nand write命令
nand write命令可以用於向Nand Flash中指定的地址寫入指定大小的數據,一般和nand erase命令結合使用,還可以用來更新Nand Flash中的uboot、kernel和dtb等文件,該命令的使用格式如下:
nand write - addr off|partition size
和nand read命令類似,addr表示要寫入的數據的開始地址,off表示Nand Flash中寫入的起始地址,size表示要寫入的數據大小。
例如,使用該命令並結合fatload命令進行Linux內核鏡像zImage和dtb文件更新,將我們需要更新的文件放入到SD卡中,使用fatload命令將需要更新的zImage和dtb寫入到DRAM中,然后使用nand write命令更新到Nand Flash中,如下:
將需要更新的zImage鏡像文件讀入到DRAM中:
=> fatload mmc 0:1 0x80800000 img/zImage
擦除Nand Flash中存儲zImage的區域,並將DRAM中的zImage更新到Nand Flash中:
=> nand erase 0x400000 0x1000000 => nand write 0x80800000 0x400000 0x1000000
使用nand write更新zImage后,輸出如下:
接下來,按照類似的方法去更新dtb:
將需要更新的dtb設備樹文件讀入到DRAM中:
=> fatload mmc 0:1 0x83000000 img/imx6ul-14x14-evk.dtb
擦除Nand Flash中存儲dtb設備樹的區域,並將DRAM中的dtb文件更新到Nand Flash中:
=> nand erase 0x1400000 0x80000 => nand write 0x83000000 0x1400000 0x80000
使用nand write更新dtb后,輸出如下:
另外,還可以使用bootz命令啟動Linux內核,使用下面命令即可:
=> bootz 0x80800000 - 0x83000000
啟動log如下:
到此,uboot中Nand子系統的常用命令就描述完畢了,更多的命令可以自行探索。
10、BOOT啟動相關操作命令
我們都知道uboot最主要的工作就是引導啟動Linux系統,因此uboot中肯定是有相關的boot啟動命令的,和boot啟動常用相關的命令有boot、bootm和bootz,接下來,我們了解一下這些命令的使用。
(1)boot命令
boot命令是用來啟動Linux系統的,該命令的用法如下:
可以看到到,該命令將會運行bootcmd,也就是boot命令將會讀取bootcmd這個環境變量,並運行這個環境變量中的命令,來看一下當前我目標板中的bootcmd環境變量內容,使用下面命令查看:
=> print bootcmd
輸出如下:
可以看到,該環境變量就是定義了一些啟動引導的命令集合,先使用nand read命令從Nand Flash中讀取kernel和dtb在DRAM內存地址中,然后使用bootz命令啟動Linux系統。
(2)bootm命令
bootm命令用於啟動uImage鏡像,該命令的用法如下:
其中addr就是uImage鏡像文件在DRAM的起始地址,另外它還有一些參數,如果要使用dtb或initrd的話,則就是在后面添加對應的DRAM地址。
(3)bootz命令
bootz命令也是用來啟動Linux系統,只不過啟動的是Linux zImage鏡像文件,該命令用法如下:
命令中的addr是DRAM內存Linux鏡像文件的起始地址,initrd是initrd文件在DRAM中的地址,fdt是設備樹在DRAM中的地址,如果沒有使用到initrd文件的話,則使用'-'進行替代,對於Linux鏡像和設備樹文件,我們可以通過讀取eMMC或Nand Flash到DRAM中,當然,如果在網絡接口可以使用的情況下,也可以使用NFS或TFTP服務將鏡像下載到DRAM中,啟動的原理是一樣的。
例如,當Nand Flash中存儲着我們需要啟動的Linux系統鏡像和設備樹文件的話,可以使用下面命令進行啟動:
先讀取Linux zImage鏡像到DRAM的0x80800000處:
=> nand read 0x80800000 0x400000 0x1000000
然后讀取設備樹文件到DRAM的0x83000000處:
=> nand read 0x83000000 0x1400000 0x80000
使用bootz啟動引導Linux系統:
=> bootz 0x80800000 - 0x83000000
命令輸入回車后,系統啟動log如下:
可以看到,使用bootz命令能啟動Linux系統了。
11、其它常用uboot命令
除了上面提及到的一些常用命令以外,uboot中還有一些另外常用的命令,例如reset、go、run和mtest等,接下來看看這些命令的使用。
(1)reset命令
reset命令能用來復位CPU,其用法如下:
直接輸入下面命令並回車,將會復位CPU:
=> reset
(2)go命令
go命令能用於跳轉到指定的內存地址處執行應用程序,該命令的使用格式如下:
命令用法中的addr就是內存的地址,將應用程序下載到該內存地址后,用go跳轉到該地址處,將會執行該應用程序。
例如,編寫一個簡單的GPIO電平控制匯編程序gpioctrl.S,代碼如下:
.global _start _start: /* 1、使能IO時鍾 */ ldr r0, =0x020c406c /* 將寄存器地址CCM_CCGR1寫入到r0 */ ldr r1, =0xffffffff /* 將gpio1時鍾使能 */ str r1,[r0] /* 2、設置GPIO1_IO08引腳IO復用為GPIO1_IO08 */ ldr r0, =0x020e007c /* 將寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO08寫入r0 */ ldr r1, =0x5 /* 設置IO引腳復用模式為GPIO1_IO08 */ str r1,[r0] /* 3、配置GPIO1_IO08引腳電氣屬性 * bit [16]: 0 關閉HYS * bit [15:14]: 00 默認下拉 * bit [13]: 0 keeper * bit [12]: 1 pull/keeper使能 * bit [11]: 0 禁止開路輸出 * bit [7:6]: 10 速度為100MHz * bit [5:3]: 110 驅動能力為R0/6 * bit [0]: 0 低擺率 */ ldr r0, =0x020e0308 /* 將寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO08寫入r0 */ ldr r1, =0x10b0 /* 設置GPIO1_IO08引腳電氣屬性 */ str r1,[r0] /* 4、配置GPIO1_IO08引腳方向為輸出 */ ldr r0, =0x0209c004 /* 將寄存器GPIO1_GDIR地址寫入r0 */ ldr r1, =0x00000100 /* 將GPIO1_IO08方向設置為輸出 */ str r1,[r0] /* 5、控制GPIO1_IO08引腳電平高低 */ ldr r0, =0x0209c000 /* 將寄存器GPIO1_DR地址寫入r0 */ ldr r1, =0x00000100 /* 將GPIO1_IO08引腳設置為高電平 */ str r1,[r0]
編寫對應的Makefile編譯腳本,如下:
all:gpioctrl.S arm-linux-gnueabihf-gcc -g -c gpioctrl.S -o gpioctrl.o arm-linux-gnueabihf-ld -Ttext 0x87800000 gpioctrl.o -o gpioctrl.elf arm-linux-gnueabihf-objcopy -O binary -S -g gpioctrl.elf gpioctrl.bin arm-linux-gnueabihf-objdump -D gpioctrl.elf > gpioctrl.dis clean: rm -rf *.o gpioctrl.bin gpioctrl.elf gpioctrl.dis
編譯產生gpioctrl.bin文件后,將.bin文件拷貝到SDCard中,在uboot中使用fatload命令加載到內存0x87800000地址處,並使用go命令執行程序:
=> fatload mmc 0:1 0x87800000 gpioctrl.bin => go 0x87800000
程序運行后,對應的GPIO電平將得到控制。
(3)run命令
run命令能用來運行環境變量中定義的命令,例如通過run bootcmd來運行bootcmd中定義的啟動命令,能將Linux系統進行啟動,該命令能運行我們自己定義的環境變量,該用法如下:
用法中的var就是定義好的環境變量。
接下來,舉例說明該命令如何使用,例如,當前目標板是Nand Flash啟動的,我們想要通過SDCard去更新Nand Flash中存儲的kernel和dtb,該怎么操作呢?可以將需要更新的固件保存到SDCard里面,然后通過fatload命令將需要更新的固件讀入到DRAM里面,再通過nand write命令更新到Nand Flash里面,命令非常多,我們可以將這些使用到的命令定義為一個環境變量,然后在uboot中run var即可,在調試Linux系統的時候將會非常方便,接下來,看看怎么操作。
SDCard的分區1里面保存了需要更新的固件kernel和dtb,如下:
接下來,在uboot中使用下面命令,創建updatecmd環境變量並將環境變量進行保存:
=> setenv updatecmd 'fatload mmc 0:1 0x80800000 zImage;nand erase 0x400000 0x1000000;nand write 0x80800000 0x400000 0x1000000;fatload mmc 0:1 0x83000000 imx6ul-14x14-evk.dtb;nand erase 0x1400000 0x80000;nand write 0x83000000 0x1400000 0x80000' => saveenv
使用print命令查看updatecmd環境變量是否創建成功:
=> print updatecmd
輸出如下,則創建成功:
接下來,將保存了需要更新固件的SDCard接入到目標板中,並使用run命令進行固件更新:
=> run updatecmd
命令運行后,固件更新成功,輸出如下:
使用該命令能很方便地在uboot中完成了kernel和dtb固件的更新。
(4)mtest命令
mtest命令能用於進行內存讀寫測試,例如可以用來測試目標板DDR的穩定性,該命令的用法如下:
命令用法中的start是DRAM內存的起始地址,end是內存的結束地址,例如我們向測試0x80000000到0x87800000這段內存,可以使用下面命令:
=> mtest 80000000 87800000
測試結果如下:
測試的時候,如果想退出測試的話,可以使用鍵盤上的"Ctrl+C"組合鍵。