天天看點

DAVINCI DM365-DM368開發攻略——U-BOOT-2010.12及UBL的移植

原創作品,允許轉載,轉載時請務必以超連結形式标明文章  原始出處 、作者資訊和本聲明。否則将追究法律責任。 http://zjbintsystem.blog.51cto.com/964211/713240

    從盛夏走到深秋,我們繼續DAVINCI DM365-DM368的開發。說來慚愧,人家51CTO熱情支援本部落格,而本人卻一直沒有像其他部落格之星一樣頻繁更新部落格,心裡确實說不過去。管理公司确實很累,有更急的客戶的項目要做,我們成功先推出了DM6446-810MHz的核心闆( http://www.tongyetech.com ),期間深圳安防展也接見了幾個其他市的客戶,然後繼續我們的DM368開發。

  一、DM36X的BOOT過程介紹 DM36x的BOOT過程和DM6446、DM6467完全是一樣的,因為都是ARM926EJS架構,裡邊都有一個RBL,這RBL在晶片出廠的時候都燒寫在ROM裡,晶片上電複位後RBL在運作,然後讀取BOOT MODE引腳的電平狀态,決定是從NAND FLASH還是從 MMC/SD、UART 、USB、 SPI、 EMAC、HPI中之一的方式BOOT,具體見SPRS558A.pdf和SPRUSG5A.pdf的介紹,這兩個文檔對硬體工程師、軟體驅動工程師來說非常重要。

DAVINCI DM365-DM368開發攻略——U-BOOT-2010.12及UBL的移植

   本篇及以後的DM36X文章基本以DM368為主的介紹,因為DM365--- dvsdk_dm365_4_02_00_06和DM368----dvsdk_dm368_4_02_00_06的UBL,U-BOOT, KERNEL的源碼完全是一樣的,如果不考慮2A算法,DM368就是DM365的超頻超出來的高清!   二、DM36X 的UBL移植 關于UBL的移植,本人打算單獨寫一篇文章的,但是UBL和UBOOT太緊密了,是TI davinci晶片的特點,是以放到一起講。我們重點放在NAND BOOT的移植,這個UBL的版本是V1.50,在dvsdk_dm368_4_02_00_06\psp\flash-utils\DM36x和flash-utils\Common目錄下,Common目錄裡有非常多東西,包括UBL的驅動源碼、工具、腳本等等。我們主要關注arch,drivers,src,ubl。UBL的main()函數在dvsdk_dm368_4_02_00_06\psp\flash-utils\Common\ubl\src\ubl.c裡,這幾個檔案夾打開看看就明白什麼意思了,這裡不羅嗦。 DM36x下有CCS、Common,GNU三個檔案夾: CCS檔案夾: 這裡邊的程式需要在TI CCS下編譯,通過仿真器和JTAG在DM36X的闆子上調試和燒寫NAND FLASH或NOR FLASH,有燒寫Writer的應用程式,用CCS打開工程檔案,會連接配接到dvsdk_dm368_4_02_00_06\psp\flash-utils\Common\ drivers裡。 Common檔案夾:Common裡有核心的檔案device.c和device_nand.c。device.c是最重要的檔案,這裡初始化很多系統的東西,見DEVICE_init(): 1、屏蔽所有中斷; 2、清除中斷标志; 3、DEVICE_PSCInit(),Power and Sleep Controller; 4、主晶片管腳複用的設定DEVICE_pinmuxControl(),DM36X的管腳複用很多,很複雜,一共5個PINMUX寄存器需配置; 5、DEVICE_PLL1Init(),PPL1配置,見SPRUSG5A.pdf的35頁開始的介紹,使用不同的頻率的DM36X,這些值都不同,不過TI已經提供參數參考,我們的DM365核心闆是:ARM297_DDR243_OSC24,DM368核心闆是:ARM432_DDR340_OSC24; 6、DEVICE_PLL2Init(),PPL2的配置,使用同上,不同頻率的值不同; 7、DEVICE_DDR2Init()的配置,市場上不同的DDR2記憶體晶片需要不同的參數配置,就在這個函數内。 8、DEVICE_EMIFInit(),這個針對NAND FLASH接口或NOR FLASH接口的通路時序配置; 9、DEVICE_UART0Init()的配置,這個就是我們調試DM36X序列槽的設定,我們使用UART0來調試LINUX,這裡配置不好,後面的開發不用調試了。 10、DEVICE_TIMER0Init()定時器TIMER0的設定; 11、DEVICE_I2C0Init()的設定; GNU的檔案夾: 這個就是在LINUX環境下編譯UBL的環境,修改dvsdk_dm368_4_02_00_06\psp\flash-utils\DM36x\GNU\ubl下的makefile,把 #$(MAKE) -C build TYPE=nor注釋掉,隻保留$(MAKE) -C build TYPE=nand,然後是make clean和 make生産ubl_DM36x_nand.bin的檔案; 如果出現:device.c:(.text+0x2ec): undefined reference to `__aeabi_uidiv'和device.c:(.text+0x2e8): undefined reference to `__aeabi_uidivmod'的BUG,就是DDR_Get_Val()函數裡邊的除法和求餘的語句和你的編譯器不配置造成的。 result = ((parm * freq) / 10000) - 1;和if(((parm * freq) % 10000)),我們對參數的求值直接:     tRFC = xxx; //DDR_Get_Val(DDR_T_RFC, DDR_FREQ);     tRP = xxx; //DDR_Get_Val(DDR_T_RP, DDR_FREQ);     tRCD = xxx; //DDR_Get_Val(DDR_T_RCD, DDR_FREQ);     tWR = xxx; //DDR_Get_Val(DDR_T_WR, DDR_FREQ);     tRAS = xxx; //DDR_Get_Val(DDR_T_RAS, DDR_FREQ);     tRC = xxx; //DDR_Get_Val(DDR_T_RC, DDR_FREQ);     tRRD = xxx; //DDR_Get_Val(DDR_T_RRD, DDR_FREQ);     tWTR = xxx; //DDR_Get_Val(DDR_T_WTR, DDR_FREQ); 不用DDR_Get_Val()函數求值,這樣就可以編譯通過了。後來發覺TI的 http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/100/p/115574/425950.aspx裡也有人這人解決,呵呵,沒想到本人的解決辦法和一個網友一樣的。本人記得調試三星2440 UBOOT的時候,有人點到過,這裡本人忘記在什麼地方改了。   三、介紹u-boot-2010.12的特點 u-boot-2010.12的架構組織越來越向LINUX架構靠攏,這是U-BOOT的發展趨勢。DM36x的UBOOT源碼放在dvsdk_dm368_4_02_00_06\psp的下面,檔案夾叫u-boot-2010.12-rc2-psp03.01.01.39,太長了,我們直接u-boot-2010.12。這個u-boot-2010.12支援YAFFS2、UBI等檔案系統,支援SD卡、USB、VIDEO等驅動,支援lzma和lzo的核心鏡像壓縮,還有經典的linux shell指令支援模式,就是tab等的妙用,就是在”U-boot >”提示符下鍵入和LINUX 開發主機上一樣的指令,當然這個指令很少,而且有些指令是使用者自己加的。相對以前的u-boot-1.3.4版本等版本,這個新U-BOOT把很多平台的配置腳本給去掉了。   四、u-boot-2010.12的移植 DAVINCI晶片系列的UBOOT移植大同小異,比較簡單。 1、首先修改:Makefile: 第140行:#examples/standalone \ 第141行:#examples/api 第246行: #LIBS += api/libapi.o 等一下我們就可以把一些不相關的檔案夾給删除掉,給u-boot-2010.12瘦身。 第323行:ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND) u-boot.img 後面增加u-boot.img,這個u-boot.img就是我們要燒寫到NAND裡邊的BIN檔案,可以被UBL給BOOT起來的檔案,因為u-boot.img是通過u-boot-2010.12\tools下的mkimage的工具生産的,帶有頭header的檔案,這些頭資訊能被UBL給識别,是以才能燒寫到NAND FLASH或NOR FLASH裡邊去。而u-boot.bin是沒有增加檔案頭部資訊的檔案,不能被UBL直接給BOOT起來。u-boot.bin隻能使用軟體BOOT,比如: tftp 0x82080000 u-boot.bin ;go 0x82080000。 最重要的地方修改: 第350行:-a $(CONFIG_SYS_TEXT_BASE) -e 0x81080000 \ 或者-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)\ 剛開始這個-e 0是錯誤的,我們把U-BOOT-2010.12的entrypoint定義到0x81080000,這個DDR的位址是在u-boot-2010.12\board\davinci\dm365evm\config.mk CONFIG_SYS_TEXT_BASE = 0x81080000 這個-e(entrypoint)不能是0,否則無法被UBL給BOOT起來。   第953行是不需要改動的: davinci_dm365evm_config : unconfig        @$(MKCONFIG) $(@:_config=) arm arm926ejs dm365evm davinci davinci DM368也是使用同樣的dm365evm名字。   2、開始删除一些不相關的檔案夾 u-boot-2010.12\api檔案夾 u-boot-2010.12\examples u-boot-2010.12\nand_spl u-boot-2010.12\onenand_ipl u-boot-2010.12\arch\裡的隻保留arm檔案夾 u-boot-2010.12\ arch\arm\cpu檔案夾裡,隻保留arm926ejs u-boot-2010.12\ arch\arm\cpu\arm926ejs檔案夾裡,隻保留davinci檔案夾,我們隻删除檔案夾,旁邊的cpu.c和Makefile不要删除,等等; u-boot-2010.12\board裡邊,隻保留davinci檔案夾,其他統統删除掉; u-boot-2010.12\board\davinci\裡,隻保留dm365evm和common,其他删除; u-boot-2010.12\include\configs裡,隻保留davinci_dm365evm.h,其他檔案和檔案夾删除掉; 通過上面的操作,我們的u-boot-2010.12簡化多了。   3、修改最重要的davinci_dm365evm.h 在u-boot-2010.12\include\configs裡,davinci_dm365evm.h 修改#define CONFIG_SYS_NAND_MAX_CHIPS     1,把以前的2改成1,表示本系統隻支援1片NAND FLASH; 把#define CONFIG_BOOTCOMMAND       "if mmc rescan 0; then if fatload mmc 0 0x80600000 boot.scr; then source 0x80600000; else fatload mmc 0 0x80700000 uImage; bootm 80700000; fi; fi"給注釋掉,我們不想用SD卡儲存核心的BIN檔案uImage; 然後定義#define CONFIG_BOOTCOMMAND "run nand_boot",表示從NAND FLASH 讀取核心; 修改UBOOT的BOOTARGS參數:#define CONFIG_BOOTARGS \               "console=ttyS0,115200n8 mem=60M noinitrd rw ip=192.168.1.188:192.168.1.252:192.168.1.1:255.255.255.0 root=/dev/nfs nfsroot=192.168.1.252:/home/davinci/dm368/dvsdk_dm368_4_02_00_06/filesystem/dm368rootfs,nolock" 我們這裡提到mem=60M,是有根據的,我們闆子是128M-BTYE,因為後面的DVSDK4.02裡邊的encodedecode等例子需要用到CMEM,這個和DM6446類似,是以定義為60M。 見dvsdk_dm368_4_02_00_06\filesystem\dvsdk-dm368-evm-rootfs解壓後的etc\init.d\loadmodule-rc檔案: # Default DM368 EVM Memory Map

#

# Start Addr    Size    Description

# -------------------------------------------

# 0x00001000    32K     ARM TCM memory

# 0x80000000    48 MB   Linux

# 0x83000000    12 MB   Video driver memory (Linux)

# 0x83C00000    68 MB   CMEM

# 0x88000000    BOTTOM  ADDRESS load () {

    modprobe cmemk phys_start=0x83C00000 phys_end=0x88000000 allowOverlap=1 phys_start_1=0x00001000 phys_end_1=0x00008000 pools_1=1x28672 useHeapIfPoolUnavailable=1

    modprobe irqk 

    modprobe edmak

    modprobe dm365mmap

    mknod /dev/dm365mmap c `awk " \\$2==\"dm365mmap\" {print  \\$1}" /proc/devices` 0

} 有些人定義CMEM共享記憶體小一點的話,那麼這個值可以比60M大。後面的參數就是使用靜态固定IP的NFS SERVER路徑,進行NFS調試;   增加 #define CONFIG_IPADDR        192.168.1.188 #define CONFIG_SERVERIP      192.168.1.252 #define CONFIG_ETHADDR        00:03:55:88:00:00 定義闆子自己的IP和MAC,這個MAC在保證和其他網絡裝置MAC不沖突的前提下,自己調試的時候順便配置設定。SERVERIP就是我們LINUX開發環境的主機IP位址,主要用做TFTP和NFS調試。   #define CONFIG_EXTRA_ENV_SETTINGS      \ "eraseenv=nand erase 0x00060000 0x00020000\0" \ "eraseall=nand erase 0x00000000 0x08000000\0" \ "updateuboot=tftp 0x84000000 dm368_uboot.bin;nand erase 80000 80000;nand write 84000000 80000 80000\0" \ "updatecore=tftp 0x84000000 dm368_kernel.bin;nand erase 0x00100000 0x00480000;nand write 84000000 100000 300000\0" \ "nand_boot=nboot 0x80700000 0 0x100000;bootm\0" \ "tftp_boot=tftpboot 0x80700000 dm368_kernel.bin;bootm\0" 這個很精典,我以前在DM6446上面U-BOOT-2009.03的移植上說過,在u-boot->的提示下,使用run 指令,就可以批量自動做一些操作。CONFIG_EXTRA_ENV_SETTINGS這個在u-boot-2010.12\common\env_common.c 和u-boot-2010.12\common\env_embedded.c有使用。你盡管在這裡定義就可以了。 run eraseenv表示擦除u-boot的參數; run eraseall表示擦除整片NAND; run updateuboot表示通過TFTP燒寫dm368_uboot.bin到闆子上; run updatecore表示燒寫核心檔案,300000表示核心BIN的大小,我們這裡直接定死,3M的核心BIN檔案長度夠用了,當然,你可以根據核心大小的動态長度改變燒寫方法; TFTP先下載下傳BIN檔案(uImage)到DDR 的0x84000000位址,然後燒寫到自己定義的分區上,這個和核心linux-2.6.32.17的分區是一一對應的,這點很重要; "nand_boot=nboot 0x80700000 0 0x100000;bootm\0";核心放在NAND的0x100000,我們使用run nand_boot進行闆級核心啟動; "tftp_boot=tftpboot 0x80700000 dm368_kernel.bin;bootm\0"使用TFTP進行核心軟體啟動,編譯調試核心; 在run eraseenv中,我們使用0x00060000作為U-BOOT參數存放的偏移位址,長度使用128K-BYTE,是以在第183行處開始: #ifdef CONFIG_NAND_DAVINCI

#define CONFIG_ENV_SIZE   (128 << 10)   //128K-byte for evn

#define CONFIG_ENV_IS_IN_NAND

#define CONFIG_ENV_OFFSET  0x00060000

#undef CONFIG_ENV_IS_IN_FLASH

#endif   順便說一下,我們一般不建議在U-BOOT裡邊通過TFTP下載下傳和燒寫至少幾十M的檔案系統,我們盡量簡化U-BOOT的功能,因為我們産品的重點是在LINUX核心,所有的開發、應用、更新程式都是基于LINUX核心上的,是以我們建議通過LINUX核心驅動來燒寫檔案系統,這是後話。   4、使能使用tab鍵功能 這個功能就是能在U-boot->的指令提示符下使用tab鍵,是以說 在davinci_dm365evm.h裡一定要在“#define CONFIG_SYS_HUSH_PARSER”的上一行或下一行定義CONFIG_AUTO_COMPLETE; 在u-boot-2010.12\common\command.c裡,第165行,把“#if 0”改成“#if 1”; 在u-boot-2010.12\common\env_common.c裡,第247行把“#if 0”改成“#if 1”;   5、增加GPIO驅動的功能和修改一些BUG    複位外圍晶片,比如采用GPIO控制網口晶片複位,在u-boot-2010.12\board\davinci\dm365evm\dm365evm.c的board_init()函數,增加GPIO的複位驅動,對一些外圍的晶片複位一下; 在u-boot-2010.12\common\cmd_nvedit.c裡,第227行,把“((strcmp (name, "ethaddr") == 0)”用“(0”,這樣就能任意修改儲存在網口MAC位址ethaddr;   6、開始編譯     在u-boot-2010.12\arch\arm的config.mk裡 #CROSS_COMPILE ?= arm-linux- CROSS_COMPILE = arm-none-linux-gnueabi- 我們使用Code Sourcery ARM GCC Tool Chain的Sourcery G++ Lite 2009q1-203 for ARM GNU/Linux。 注意,除了UBL在UBL的檔案夾内部編譯外,其他的DVSDK的檔案包u-boot,linux,dm365mm,irq ,edma,ceexamples,dmai,還有psp_examples,等等,都是在dvsdk_dm368_4_02_00_06的目錄下編譯,具體見dvsdk_dm368_4_02_00_06的Makefile。 u-boot的編譯是:make u-boot,make u-boot_clean等等; 我們也可以在這個目錄下自己生産一個build_uboot.sh的指令 #build u-boot in dvsdk4_02 make u-boot chmod 777 /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/u-boot-2010.12/u-boot.img cp -f /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/u-boot-2010.12/u-boot.img /tftpboot/dm368_uboot.bin 或者再增加build_uboot_all.sh #build u-boot in dvsdk4_02 make u-boot_clean make u-boot chmod 777 /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/u-boot-2010.12/u-boot.img cp -f /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/u-boot-2010.12/u-boot.img /tftpboot/dm368_uboot.bin 使用sh檔案幫你做工,要多養成這樣的習慣。   基本上,你的闆子網口OK的話,可以通過TFTP把UBOOT燒進去吧,通過仿真器或者其他方式燒寫,我們公司一般不用仿真器燒寫,直接使用uart boot的方式燒寫,自己寫個uart boot的東西,好好看看dvsdk_dm368_4_02_00_06\psp\flash-utils的包裡的東西,這裡就保留吧。      到這裡,整個u-boot-2010.12移植基本完成。有不足的地方還需其他網友指正。本人維護兩個主晶片平台後,變得非常忙,但本人會堅持寫下去,下一篇是linux-2.6.32.17的移植,以前寫過三篇有關UBOOT的文章,包括S3C2440,本人的目的讓大家縮短開發這些BOOT開發的時間,因為重點的開發是在核心和基于核心的應用程式(資訊産業部也大力支援開源的linux及相關技術),讓大家的音視訊網絡産品快點出來,改善人民的生活,推進這個社會的文明,文明是靠科技來推動的,讓那些醜陋的、麻木缺德的、文明倒退的野蠻行為、愚民手段、空洞扭曲、侮辱國人智商的事情盡快暴露出來,碰到棘手的問題也能暴露出來,畢竟廣大人民的智慧是無窮無盡的,是完全有能力解決問題的。但前提是我們要有這樣的科技學術氛圍,身上沒有極其沉重的衣食住行的枷鎖,也沒把絕大部分時間浪費在外語和XX課上(看看人家德國吧),是以我們要堅持我們的技術之路。文明是靠科技來推動的,而科技需要我們千千萬萬的科技人員踏踏實實去動手做事的。      昨天才調試同TVP5158 D1的采集,終于看到圖像了。心裡很舒暢。順便曬曬我們這段時間做的兩款核心闆:DM368和DM6446-810MHz核心闆。核心闆以最大限度友善客戶進行功能擴充、內建應用,加快産品研發和上市,降低前期産品研發的風險。我們比較傾向項目合作,開發闆不是我們開發的重點。  

DAVINCI DM365-DM368開發攻略——U-BOOT-2010.12及UBL的移植

DM368核心闆

DM368核心闆硬體接口描述:

■闆載存儲器:

  - 動态存儲器(SDRAM DDR2):1Gb(128M-byte)

  - 非易失存儲器(NAND FLASH):1Gb(128M-byte)

■闆載接口:

  - 1個4位Boot模式選擇接口

  - 16-BIT YCC數字視訊輸入接口

  - 2路可程式設計輸出時鐘CLOCK0和CLOCK2

  - 1路模拟标清視訊輸出接口TVOUT

  - 1路模拟高清視訊輸出接口YPbPr

  - 1路麥克風差分輸入接口

  - 1路音頻線性輸出接口

  - 1路喇叭差分輸出 

  - 3路AD采集接口

  - 1個SD卡接口SD0

  - 1個10/100M網絡差分輸入輸出接口RX和TX

  - 2個RS232序列槽(UART0,UART1) 

  - 1個USB 2.0接口(HOST/DEVICE/OTG)

  - 1個 SPI口SPI1 

  - 1個标準 JTAG接口

  - 1個4×4鍵盤接口

 - 18個獨立GPIO口

  - 3路電源輸入接口+1.8V,+3.3V,+1.2V

■單闆尺寸:

  46mm x 46mm x 9.5mm

其中整體高度是9.5mm

DAVINCI DM365-DM368開發攻略——U-BOOT-2010.12及UBL的移植

DM6446-810MHz核心闆

DM6446-810MHz核心闆采用的是TI TMD320DM6446BZWT8的雙核晶片,ARM9的頻率達到405MHz,DSP-C64+核的頻率達到810MHz,DDR2-667操作頻率配置為189MHz,NAND FLASH為128M-BYTE。內建10M/100M網絡晶片在核心闆上,友善客戶設計底闆,70mm*47mm,整體高度9mm,比名片更小。

桐烨科技DM6446-810MHz核心闆支援硬體接口:

1、VPFE16位總線及H、V信号,完全可以接視訊采集晶片和CMOS SENSOR;

2、VPBE引出RGB24的控制信号,便于接RGB24的LCD屏;

3、CVBS模拟視訊輸出;

4、網口信号及網口LED、LINK信号;

5、I2C接口;

6、SPI接口;

7、SD卡接口;

8、ATA硬碟接口;

9、USB2.0 HOST接口;

10、ASP音頻接口;

11、3個UART接口;

12、18個獨立GPIO接口及其他複用的GPIO接口;

13、JTAG仿真器接口;

14、3個PWM控制線;

15、CLK_OUT0和CLK_OUT1可程式設計時鐘輸出信号;

16、TI的H264  ENCODE   LIB達到720P(1280*720)的實時;