Redboot安裝歷程
公司購(gòu)買(mǎi)了EV40開(kāi)發(fā)板:CPU AT91M40800, 內(nèi)存2M+2M(擴(kuò)展), FLASH 2M+4M(擴(kuò)展), RTl8019AS芯片, FLASH是AM29LV160TE(2M) 公司自己開(kāi)發(fā)自用的板子WX10: CPU AT91M40800, 內(nèi)存4M, FLASH 8M, RTl8019AS芯片, FLASH是AM29LV641(8M)及其他應(yīng)用功能芯片.
我主要的工作是開(kāi)發(fā)系統(tǒng)的驅(qū)動(dòng)軟件,因此需要隨時(shí)修改內(nèi)核驅(qū)動(dòng),并調(diào)試,因此裝入和啟動(dòng)的速度對(duì)工作效率是比較關(guān)鍵的.因?yàn)橛胔itool燒錄方式啟動(dòng) uclinux內(nèi)核方式需要6~10分種一次.聽(tīng)”嵌入式linux群”kingmonkey說(shuō)可以使用redboot, 因此決定試試.
二 環(huán)境建立
redboot是ecos操作系統(tǒng)的一部分,也是ecos操作系統(tǒng)最小配置的版本.因此要使用redboot,必須建立ecos操作系統(tǒng)環(huán)境. 到網(wǎng)站http://sources.redhat.com/ecos/
查找其安裝方法,按照說(shuō)明采用了其網(wǎng)絡(luò)方式安裝,使用:
# wget --passive-ftp ftp://ecos.sourceware.org/pub/ecos/ecos-install.tcl
下載安裝命令,并運(yùn)行:
# sh ecos-install.tcl
安裝了ecos 2.0.我把這個(gè)安裝在/rh80/ecos下.ECOS_REPOSITORY就是/rh80/ecos/ecos-2.0.
運(yùn)行 :
# cd /rh80/ecos
# . ecosenv.sh
設(shè)置環(huán)境變量.
由于linux操作系統(tǒng)中已經(jīng)安裝了
http://www.uclinux.org/pub/uClin ... f-tools-20030314.sh
因此我安裝ecos時(shí),沒(méi)有選擇安裝arm-elf GNU tools工具.
三 編譯redboot
由于ecos是個(gè)可配置的操作系統(tǒng),因此下載安裝的實(shí)際就是一個(gè)配置的倉(cāng)庫(kù),要編譯redboot就按照需要進(jìn)行配置.配置的方式使用配置工具ecosconfig, 也有圖形方式配置工具的,我沒(méi)有用,只用字符界面的ecosconfig.
由于EV40類(lèi)似EB40, 因此我的命令是:
# mkdir rom
# cd rom
# ecosconfig new eb40 redboot
#ecosconfig import /rh80/ecos/ecos-2.0/packages/hal/arm/at91/eb40/current/misc/redboot_ROMRAM.ecm
#ecosconfig tree
#make
結(jié)果編譯出現(xiàn)錯(cuò)誤.
因此懷疑編譯器不兼容,于是重新安裝ecos,此時(shí)選擇arm-elf工具.此時(shí)運(yùn)行. Ecosenv.sh 時(shí),新下載的工具的路徑包含在PATH中, 重新進(jìn)行了redboot生成和編譯,正確生成了install/bin/redboot.bin等文件.
將redboot.bin用hitool燒寫(xiě)到EV40的flash中,啟動(dòng),沒(méi)有任何反應(yīng).重新選擇redboot的ROM版:
# ecosconfig new eb40 redboot
#ecosconfig import /rh80/ecos/ecos-2.0/packages/hal/arm/at91/eb40/current/misc/redboot_ROM.ecm
#ecosconfig tree
#make
編譯,燒錄,運(yùn)行,仍然無(wú)反應(yīng).
四 配置硬件參數(shù)
由于EB40和EV40不完全相同,因此首先檢查硬件參數(shù)的配置,找到配置的文件是: ecos/packages/hal/arm/at91/eb40/current/include/hal_platform_ints.h
主要是AT91_EBI配置參數(shù)表, EV40是:
_InitMemory:
.long 0x01002529 @ 0x01000000, 16MB, 2 cycles added after transfer, 16-bit, 6 wait states
.long 0x020020a1 @ 0x02000000, 16MB, 0x02002121 0 cycles added after transfer, 16-bit, 1 wait state
.long 0x03002529 @ unused
.long 0x40000000 @ unused
.long 0x02202021 @ unused ,CS 4
.long 0x02302021 @ unused ,CS 5
.long 0x60000000 @ unused
.long 0x70000000 @ unused
.long 0x00000001 @ REMAP commande
.long 0x00000006 @ 7 memory regions, standard read
.long AT91_EBI @ EBI address
.long 10f // address where to jump
WX10的配置是:
_InitMemory:
.long 0x01002529 // 0x01000000, 16MB, 2 cycles after transfer, 16-bit, 6 wait states
.long 0x020020a1 // 0x02000000, 16MB, 0 cycles after transfer, 16-bit, 1 wait state
.long 0x03002529 // unused
.long 0x30000000 // unused
.long 0x40000000 // unused
.long 0x50000000 // unused
.long 0x60000000 // unused
.long 0x70000000 // unused
.long 0x00000001 // REMAP command
.long 0x00000000 // 7 memory regions, standard read
.long AT91_EBI // External Bus Interface address
.long 10f // address where to jump
這里我要說(shuō)明的一點(diǎn)是EV40和WX10的區(qū)別, EV40是用到CS6的,而WX10是不用CS6的, EV40有擴(kuò)展內(nèi)存,由CS4和CS5配置. EV40網(wǎng)卡地址是0x40010000, 而WX10的網(wǎng)卡地址是0x03210000.
修改了配置后, 編譯,燒錄,運(yùn)行,仍然無(wú)反應(yīng).
向kingmonkey討叫,kingmonkey認(rèn)為可能是ecos版本不是最新的緣故,建議用cvs下載最新的版本. 用ecos-install.tcl是最新的穩(wěn)定版,但不是最新的.
五 安裝cvs版ecos
安裝方法參考網(wǎng)站中Anonymous CVS:
# cd /rh80/ecos
# cvs -d server:anoncvs@ecos.sourceware.org:/cvs/ecos login
口令任意
# cvs -z3 -d server:anoncvs@ecos.sourceware.org:/cvs/ecos co -P ecos
這樣呢就下載的最新的ecos,目錄是/rh80/ecos/ecos, 修改ecosenv.sh中
ECOS_REPOSITORY=/rh80/ecos/ecos/packages ; export ECOS_REPOSITORY
這樣呢,就使用最新用cvs下載的ecos了.原來(lái)的ecos-2.0仍然保留,并使用其下面的ecosconfig等工具,不用重新去下載ecosconfig工具了.
六 重新編譯redboot
安裝第三節(jié)的方法重新編譯redboot,但仍然無(wú)法工作.因此只好去看資料和代碼.并且下載了網(wǎng)站上預(yù)編譯好的reboot.bin來(lái)試,仍然沒(méi)有任何反應(yīng).
仔細(xì)閱讀了ecos參考手冊(cè):
http://ecos.sourceware.org/docs-latest/ref/ecos-ref.html
中關(guān)于Installation and Testing部分中ARM/ARM7 Atmel AT91 Evaluation Boards (EBXX)的資料,它運(yùn)行redboot的方式是通過(guò)angel和arm-elf-gdb的方式的,因此我就想先按照其方式試一下.
把a(bǔ)ngel燒錄到EV40板上,然后編譯出redboot的RAM板(上面命令中redboot_ROM.ecm改成 redboot_RAM.ecm就是).然后安裝手冊(cè),成功啟動(dòng)了redboot! 結(jié)合前面看了redboot的一些代碼,懷疑缺省的EV40配置是只能在angel方式下啟動(dòng)的.
七 修改redboot配置
經(jīng)過(guò)閱讀其文件, 發(fā)現(xiàn)編譯命令文件install/lib/target.ld中:
__reserved_bootmon = 0x01000000; . = __reserved_bootmon + 0x10000;
將運(yùn)行開(kāi)始位置后移了一個(gè)0x10000, 這個(gè)可能是造成不能直接flash啟動(dòng)的原因.經(jīng)過(guò)檢查,修改了多處跟這個(gè)有關(guān)的地方:
1. ecos/packages/hal/arm/at91/eb40/current/include/hal_platform_ints.h中0x1010000 à 0x100000
2. ecos/packages/hal/arm/at91/eb40/current/include/pkgconf/mlt_arm_at91_eb40_rom.h中
#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x10000) 改成
#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x00000)
3. ecos/packages/hal/arm/at91/eb40/current/include/pkgconf/mlt_arm_at91_eb40_rom.ldi中
CYG_LABEL_DEFN(__reserved_bootmon) = 0x01000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x10000;
改成:
CYG_LABEL_DEFN(__reserved_bootmon) = 0x01000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x00000;
[mlt_arm_at91_eb40_rom.ldi就是生成rom版redboot中target.ld的依據(jù).]
然后重新配置redboot和編譯,運(yùn)行,燒錄到EV40,正常啟動(dòng)了redboot. ^_^
[此時(shí)出現(xiàn)一個(gè)非常討厭的問(wèn)題,就是EV40板子一運(yùn)行redboot,蜂鳴器不停的叫.我沒(méi)有去檢查為什么這樣!后來(lái)只好在自己公司的板子上試了.]
八 配置flash
由于EB40采用的flash芯片和EV40采用的芯片是不一樣的,因此很正常的結(jié)果是我們第七節(jié)編譯處理的redboot是不能正確識(shí)別EV40的flash芯片.因此就必須考慮修改flash驅(qū)動(dòng).
此時(shí)本人對(duì)如何修改還不是太清楚,因此只要乖乖地去看ecos的資料.正好同事買(mǎi)了一本ecos的書(shū),這樣就省了看英文資料的麻煩.
從資料上,可以知道修改配置,主要是修改cdl文件. 跟EB40有關(guān)的flash包是:
Package CYGPKG_DEVS_FLASH_EB40 (FLASH memory support for Atmel AT91/EB40):
Package CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX (Support for Atmel AT29Cxxxx flash memory):
我就把CYGPKG_DEVS_FLASH_EB40包中采用的ATMEL芯片的包改成:
CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
具體修改的文件是ecos/packages/devs/flash/arm/eb40/current/cdl/flash_eb40.cdl:
修改 requires CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX 為
requires CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
修改 cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED {
display Generic Atmel AT29CXXXX driver required
為 cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
display Generic Amd AM29XXXXX driver required
修改 implements CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED
為 implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
增加 requires CYGHWR_DEVS_FLASH_AMD_AM29LV160.
這里特別是要說(shuō)明的是最后這一行, 因?yàn)镃YGPKG_DEVS_FLASH_AMD_AM29XXXXX支持多種芯片,在配置的時(shí)候,需要指定哪些芯片可以識(shí)別,剛開(kāi)始的時(shí)候ecoscofing tree和編譯后,就是沒(méi)有看到驅(qū)動(dòng)程序包含進(jìn)去,弄了半天才搞明白,如果一種芯片也沒(méi)有選,則驅(qū)動(dòng)程序就不包含進(jìn)去.因此需要加入至少一種芯片的選擇,最后一行就是選擇AM29LV160的芯片.
同時(shí)修改 ecos/packages/ecos.db 的target eb40中:
修改 CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX
為 CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
再修改ecos/packages/devs/flash/arm/eb40/current/src/eb40_flash.c:
增加 #define CYGNUM_FLASH_WIDTH 16
修改 #i nclude cyg/io/flash_at29cxxxx.inl
為 #i nclude cyg/io/flash_am29xxxxx.inl
此時(shí),由于EV40板子亂叫的原因,我是用我們自己的板子WX10來(lái)調(diào)試了,而WX10采用的flash是AM29LV641,與AM29LV160是有區(qū)別的,因此我打開(kāi)了flash調(diào)試,自己增加了一些調(diào)試語(yǔ)句,運(yùn)行后,然后增加了AM29LV641的驅(qū)動(dòng),具體文件是 ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl, 增加了AM29LV641配置:
+ { // MBM29LV641
+ device_id : FLASHWORD(0x22d7),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
具體還是放在CYGHWR_DEVS_FLASH_AMD_AM29LV160下,這樣上面的cdl不用修改.[上面的修改中我沒(méi)有修改flash的容量,因?yàn)锳M29LV641是8M的,我還弄清楚如何改!我就先把它當(dāng)成2M使用.]
經(jīng)過(guò)上面的修改,重新編譯運(yùn)行后,redboot能夠正確識(shí)別了flash的. ^_^
九 網(wǎng)卡驅(qū)動(dòng)
google了”ecos 8019as driver”,查到了二個(gè)結(jié)果,我把二個(gè)驅(qū)動(dòng)包都下載下來(lái)了.然后分別測(cè)試了一下,但都沒(méi)有成功. 我最后選擇dp83902a這種方式重點(diǎn)研究.
首先下載其軟件包,解壓到相應(yīng)的目錄. 然后增加了CYGPKG_DEVS_ETH_RLTK_ISA8019AS 定義.
由于EB40沒(méi)有網(wǎng)卡驅(qū)動(dòng),因此只好自己增加配置.具體是redboot_ROM.ecm中增加:
package -hardware CYGPKG_DEVS_ETH_RLTK_ISA8019AS current ;
package -hardware CYGPKG_DEVS_ETH_NS_DP83902A current
package CYGPKG_IO_ETH_DRIVERS current ;
然后在文件ecos/packages/devs/eth/rltk/isa8019as/current/include/devs_eth_rltk_isa8019as.inl中修改網(wǎng)卡的起始地址和中斷:
static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
base: (cyg_uint8*) 0x03210000,
interrupt: 17,
tx_buf1: 0x40,
tx_buf2: 0x48,
rx_buf_start: 0x50,
rx_buf_end: 0x80,
hardwired_esa: false,
};
然后編譯,燒錄,運(yùn)行.但運(yùn)行到網(wǎng)卡時(shí)就沒(méi)有反應(yīng)了.網(wǎng)卡能檢測(cè)到. 此時(shí)只好調(diào)試原代碼,打開(kāi)了dp83902a驅(qū)動(dòng)的開(kāi)關(guān).發(fā)現(xiàn)發(fā)送數(shù)據(jù)包時(shí),就不動(dòng)了.經(jīng)過(guò)檢查其代碼,發(fā)現(xiàn)mac地址有二種方式,一種是從網(wǎng)卡eprom中取,另一種就是指定,于是我就把配置改成了指定:
static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
base: (cyg_uint8*) 0x03210000,
interrupt: 17,
tx_buf1: 0x40,
tx_buf2: 0x48,
rx_buf_start: 0x50,
rx_buf_end: 0x80,
hardwired_esa: true,
esa: {0x00, 0x05, 0x0c, 0x04, 0x05, 0x06},
};
但效果仍然一樣. 通過(guò)多次調(diào)試和分析, 想起了寄存器偏移量的問(wèn)題. 我在EV40板子上用uclinux驅(qū)動(dòng)網(wǎng)卡時(shí)也是同樣的問(wèn)題,后來(lái)把 所有寄存器的偏移量*2就可以了.于是動(dòng)手將全部寄存器偏移量*2.這樣呢, 網(wǎng)卡驅(qū)動(dòng)就可以了, 并能發(fā)送和接收數(shù)據(jù)包了.【這個(gè)呢,我自己也不太明白,是不是跟硬件的設(shè)置有關(guān)?】
但redboot啟動(dòng)時(shí), 經(jīng)過(guò)很長(zhǎng)時(shí)間才到redboot提示符出來(lái).原來(lái)是redboot啟動(dòng)時(shí),自動(dòng)通過(guò)bootp去取的IP地址,由于沒(méi)有bootp服務(wù)器,因此要等待一段時(shí)間才出現(xiàn)超時(shí), 讓我誤以為死機(jī)了.
建立好bootp服務(wù)器, redboot就正常啟動(dòng),并且配置了ip地址. 然后ping也通了.
此時(shí)大功告成.!!!
十 啟動(dòng)uclinux
uclinux編譯時(shí)必須注意的是: 由于 redboot運(yùn)行時(shí),必須要是使用部分內(nèi)存,你可以用version命令看出使用了什么內(nèi)存, 因此uclinux的入口地址就不能是0x2000000, 我選擇了0x2010000, 前面留了64K.
將linux.elf拷貝到bootp和tftp服務(wù)器的/tftpboot下. 運(yùn)行:
gt; load –m tftp linux.elf
gt; go 0x2010000
注意: 由于redboot串口使用38400波特率,而uclinux采用9600波特率,因此uclinux啟動(dòng)后出現(xiàn)亂碼,沒(méi)有關(guān)系,把波特率改成9600, 然后重新連接終端就可以了.
附: 修改的patch. Patch是針對(duì)WX10板子的. 由于我修改的ecos是cvs版本,每次checkout的不一定一樣.因此patch就不一定能夠直接使用, 另外呢,我的patch中也有一些我增加的調(diào)試語(yǔ)句,如果你要產(chǎn)品中使用,建議刪除好了.
評(píng)論