歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

飛凌OK6410開發板之u-boot-2011.06-rc2移植之愚見

最近,對UBOOT產生了點興趣,以前一直用的都是飛凌官方自帶的uboot1.16版本,記得當時的這個版本還不支持板載的DM9000網卡,後來就在其基礎上學著去移植DM9000網卡驅動,雖然移植是成功了,但是說起來移植也是慚愧,完全是參照網上別人的教程,一條一條的去改相關文件的代碼,完全就是依葫蘆劃瓢,哎,一點成就感也沒有,為什麼要去這麼改,根本就不清楚,突然,就有種是被嵌入式在玩,而不是玩嵌入式的感覺,雖然我只是個嵌入式業余愛好者,剛開始接觸是很困難,何況又是由S3C6410直接起步,但是我一直堅信,只要自己肯下功夫,肯用心,就沒有學不好的東西,呵呵,廢話感覺說的有點多了,還是切入正題吧!

     看到網上基於SAMSUNG-SOC-S3C6410的UBOOT移植文章很多,基本上都是基於6410開發板的講解,但是基於飛凌OK6410開發板的很少,而且基於u-boot較新版本的移植的就更少,而且絕大多數都是在講如何如何去操作,例如該CD哪個文件夾該MKDIR哪個文件夾,該RM哪些不要的東西,該CP哪些文件代碼等等,沒有一個很系統的講解,總讓人操作完後還是沒有個啥概念,為此特地花了幾天時間用自己手頭上的OK6410開發板去移植了一下UBOOT,親自實踐後才整理出的這篇文章,當然我也只是個菜鳥,希望這篇文章對那些想學UBOOT移植的人有點幫助,網上看到也有些人對OK6410的UBOOT移植有困惑的,希望對你們有用。

     對於開發環境的搭建,在這我就不用多說了啊,畢竟網上多的去了,在這先貼出我的開發環境供參考。

    我的開發環境:

         1,筆記本主機系統WINDOWS XP SP3系統  

         2,虛擬機采用的是 VMware Workstation ACE版本

         3,虛擬機內采用的LINUX系統是Ubuntu10.10版本

         4,交叉編譯工具是CROSS_COMPILE4.2.2版本

 

     要移植UBOOT,首先得下載一個版本,這裡是uboot_DNEX團隊的官方地址下載  ftp://ftp.denx.de/pub/u-boot/

     對於技術我是比較喜歡最新的,所以前幾天就下載了最新的UBOOT版本u-boot-2011.06-rc2版本對其開工,當然在我寫這篇文章的時候,前後就短短幾天時間又更新到了UBOOT版本u-boot-2011.06-rc3,哎,看來這個更新真的是很快啊

     下載下來後就是u-boot-2011.06-rc2.tar.bz2,大約8.09M,但是解壓後差不多80多M的樣子。將這個下載下來的bz2文件放進linux系統的目錄下,至於這個目錄隨便,我的是在UBUNTU下的/SHARE下,然後tar jxvf u-boot-2011.06-rc2.tar.bz2,對其解壓縮,之後便得到了我們能夠操作的的u-boot-2011.06-rc2,cd 進入u-boot-2011.06-rc2,然後就可以看到整個文件架構安排了,好了,移植工作也正式開始了。

 

 

  


 
 對於UBOOT移植,首先,腦袋裡得有個總體概念,第一步該干嘛,然後幾步又該如何去做,經過本人昨天晚上的OK6410運行情況,發現還是可行的,特地總結出來,以供大家參考。對於UBOOT移植,嚴格上來說,應該范圍比較廣,有CPU核架構級別的移植例如OK6410屬於ARM1176架構的,CPU芯片級別的移植例如OK6410屬於S3C6410SOC,還有基於板級移植的例如OK6410單板,而我們日常生活中大家說的移植,一般也都是這種板級移植,這種移植也是最簡單的,所以大家搞UBOOT移植的時候就由板級——》CPU芯片級——》CPU核架構級去看,如果有相近的板級資源做參考,這樣會事半功倍,由於本人能力有限,這裡講的也是基於板級移植的,希望大家勿噴,呵呵,所以當你拿到一個UBOOT源代碼的時候,最好第一件事就是先進BOARD目錄裡面看看,看是否已經有你那款板子的或是相近板子的代碼在裡面,這樣可以做到心裡先有個數,如果有,那麼你已經成功了一小半,呵呵。
    對於UBOOT的移植學習,我建議大家還是好好看看README這個文件,這裡面寫的好多東西都很用的,對於你移植代碼很有幫助的,當然這個不在今天的重點裡面。對於上圖中的那些文件和文件夾以及遞歸的文件等等可能會使人覺得頭暈,我已開始也是這種感覺,但是當你真正自己親自獨立移植成功之後,就會感覺一目了然了,好了,這裡就以我的OK6410單板來說吧。
   第一步,我CD 進入u-boot-2011.06-rc2源代碼根目錄,然後進入BOARD/SAMSUNG
  
 
 發現了該版本自帶SMDK6400,恩OK,基本成功了一小半了,這裡我要給大家說明一點三星公司自家生產的開發板一般都是SMDK開頭,例如SMDK2410,SMDK6400等等,既然板級資源已經找到,那麼後面的CPU芯片級和核架構級得資源就肯定對路了,由於SMDK6400單板采用的是S3C6400SOC,與S3C6410SOC大部分資源差不多,就是在多媒體,省電方面,主頻方面還有少數寄存器地址方面等等有點區別,絕大部分還是通用的,而且SMDK6400也是與OK6410最相近的一塊板子了,畢竟采用的都是ARM1176的核,況且兩款CPU也相近,那就拿SMDK6400開刀了。而且通過我看兩2款芯片的DATASHEET比較,2者很相近,然後通過對比UBOOT1.16裡面的CPU級別的初始化代碼,發現絕大部分代碼是通用的,所以,我有個大膽的猜測,直接將SMDK6400的u-boot-2011.06編譯產生的U-BOOT.BIN通過DNW加載到OK6410的內存中,應該能夠跑起來,呵呵,但是經過後來的實踐驗證,跑不起來
               
 
這個是DNW的加載UBOOT的截圖,校驗和OK之後就沒反應了,看來我的猜測還是有BUG啊,呵呵,但是我的猜測大部分應該是對的,只不過可能離成功還差那麼一點,那麼看來是相關代碼需要更改了,既然需要改代碼,所以建議大家還是另起爐灶,切忌不要在SMDK6400代碼裡面亂改一通,然後放到自己的開發板上,咦,可以跑起來了,移植OK,這樣是個很不好的習慣,因為這樣你就破壞了別個的代碼,我們既然借鑒了別人的勞動成果,就不應該再去破壞別人的代碼,況且,這樣你的代碼估計也會很亂。
  第二步,剛才看到了既然有SMDK6400,那麼我們可以先將這個編譯一遍,看是否可以編譯成功,為以後的移植做好准備。在根目下使用命令 make smdk6400_config,然後使用make,如果不出意外,7到8分鐘就可以編譯成功,然後在根目下就會產生u-boot.bin,當然對於編譯SMDK6400來說,幾乎都是編譯不通過的,總是出現._end未定義,但是SMDK2410很順利,呵呵,這是為什麼呢?其實這個應該是UBOOT的一個BUG吧,不用擔心,你只用在/u-boot-2011.06-rc2/board/samsung/smdk6400/u-boot-nand.lds文件裡.bss __rel_dyn_start (OVERLAY) : {前面加上_end = .;就行了,這個是必須的哦,呵呵,參考/u-boot-2011.06-rc2/nand_spl/board/samsung/smdk6400/u-boot.lds,加完後保存,然後再編譯一遍,這次OK。
  第三步,剛剛第一步已經說了,這樣編譯的代碼是無法加載到OK6410的板載內存裡面運行的,因此需要修改相應的代碼,為了避免破壞他人的勞動成果,還是另起爐灶,那就開始吧,在這之前,先介紹下幾個移植需要重點關注的文件夾,一個是/u-boot-2011.06-rc2/board/文件夾,它代表板級相關代碼資源,一個是/u-boot-2011.06-rc2/arch/文件夾,它代表CPU架構級資源,還有一個就是/u-boot-2011.06-rc2/nand_spl/文件夾,那就以我的OK6410為例來說明吧:
   1,在/u-boot-2011.06-rc2/board/下新建文件夾:mkdir feilin/ok6410(飛凌)
   2,將/u-boot-2011.06-rc2/board/samsung/smdk6400/所有文件復制到/u-boot-2011.06-rc2/board/feilin/ok6410下,cp  ../../samsung/smdk6400/* ./
   3,將smdk6400.c改名為ok6410.c ,mv smdk6400.c ok6410.c
將smdk6400_nand_spl.c改名為ok6410_nand_spl.c  mv smdk6400_nand_spl.c   ok6410_nand_spl.c  將Makefile 打開,用vi 或是gedit都行,更改COBJS-y := ok6410.o,
  4,在/u-boot-2011.06-rc2/nand_spl/board/下新建文件夾:mkdir feilin/ok6410
  5,將/u-boot-2011.06-rc2/nand_spl/board/samsung/smdk6400/所有文件復制到/u-boot-2011.06-rc2/nand_spl/board/feilin/ok6410/, cp ../../samsung/smdk6400/* ./ ,並更改Makefile內與板級有關的部分,截圖為
 
 
 6,將u-boot-2011.06-rc2/include/configs/smdk6400.h 復制一份並更名為ok6410.h,mv smdk6400.h ok6410.h這個是必需的哦,要不然無法完成編譯,這上面全是板級配置資源,現在不必修改
7,將u-boot-2011.06-rc2/arch/arm/include/asm/arch-s3c64xx/s3c6400.h復制一份,並更名為s3c6410.h   mv s3c6400.h  s3c6410.h,可能有人會問干嘛復制這個文件呢,其實這個文件代表的就是CPU_S3C6410的資源代碼,必定會與CPU_S3C6400有所不同,方便以後修改,不破壞SMDK6400的,所以在這裡就需要將3條裡面的ok6410.c裡面用用到的頭文件換成s3c6410.h,凡事遇到s3c6400.h的地方都換成s3c6410.h
8,也是這一步中的最後一個環節了,就是修改u-boot-2011.06-rc2/根目錄下的Makefile文件,這個是主導make文件,資源配置都是靠它的,修改截圖1

並在其後添加
CROSS_COMPILE = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
export CROSS_COMPILE ,也就是指定自己的交叉編譯器,最後就是找到arm1176systems

smdk6400_noUSB_config /
smdk6400_config : unconfig
 @mkdir -p $(obj)include $(obj)board/samsung/smdk6400
 @mkdir -p $(obj)nand_spl/board/samsung/smdk6400
 @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 @if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then   /
  echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;/
 else          /
  echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;/
 fi
 @$(MKCONFIG) smdk6400 arm arm1176 smdk6400 samsung s3c64xx
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
修改為
ok6410_noUSB_config /
ok6410_config : unconfig
 @mkdir -p $(obj)include $(obj)board/feilin/ok6410
 @mkdir -p $(obj)nand_spl/board/feilin/ok6410
 @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
 @if [ -z "$(findstring ok6410_noUSB_config,$@)" ]; then   /
  echo "RAM_TEXT = 0x57e00000" >> $(obj)board/feilin/ok6410/config.tmp;/
 else          /
  echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/feilin/ok6410/config.tmp;/
 fi
 @$(MKCONFIG) ok6410 arm arm1176 ok6410 feilin s3c64xx
 @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
    以上第三步看起來步驟很多,其實則不然,歸根到底就是COPY,將SMDK6400的板載資源代碼復制一份到自己建的OK6410中,看是OK6410,其實用的還是SMDK6400的代碼,呵呵,只不過現在改動就不要緊了,相當於是在一份副本上修改了,對吧,所以到目前為止,我們做的工作還是停留在COPY階段,當然,這個時候最好先make ok6410_config 然後在make ,如果編譯無問題,那恭喜你,已經離成功很近了,當然了,其實這個時候你編譯的代碼U-BOOT.BIN其實還是SMDK6400的,所以和你第二步編譯的是一個代碼,仍無法在OK6410上跑起來。好了,既然我們已經有了SMDK6400的副本了,就該為它做點啥子修改了,要不然可就對不住自己前面的那一番折騰啊,對吧。
     第四步:先來說說我到這一步當時的想法吧,由於手頭沒有啥子SDRAM內程序調試工具,就只有個串口,也只能借助串口來調試了,關鍵是現在串口根本就沒有輸出,不知道是UBOOT沒跑起來,還是OK6410板子上的串口沒有初始化,網上找了好久也沒找出個問題所在,關鍵還是要靠自己啊 ,沒辦法,只好去參考哈UBOOT1.16內的代碼了,但是那麼多的東西,該看啥呢,呵呵,對了,這個也是需要好好琢磨的,所以多看哈子源代碼會很有用的,通過代碼大致翻閱最終被我鎖定在了/u-boot-2011.06-rc2/board/feilin/ok6410/lowlevel_init.S這個文件上,其實這個文件就是板載資源底層初始化,發現其內缺少UBOOT內存搬運代碼以及串口初始化部分的代碼有點問題,畢竟這個是SMDK6400的板載代碼,現在是OK6410,所以需要修改,於是參考UBOOT1.16內的部分代碼:第一處
 
第二處
 
 在其後加上
//<-add by hwq
 ldr r1, =0x2222
 str    r1, [r0, #GPBCON_OFFSET]
 ldr r0, =ELFIN_UART_CONSOLE_BASE  @0x7F005000
 mov r1, #0x0
 str r1, [r0, #UFCON_OFFSET]
 str r1, [r0, #UMCON_OFFSET]
 mov r1, #0x3                 @was 0.
 str r1, [r0, #ULCON_OFFSET]
#if defined(CONFIG_CLKSRC_CLKUART)
 ldr r1, =0xe45   /* UARTCLK SRC = 11 => EXT_UCLK1*/
#else
 ldr r1, =0x245   /* UARTCLK SRC = x0 => PCLK */
#endif
 str r1, [r0, #UCON_OFFSET]
#if defined(CONFIG_UART_50)
 ldr r1, =0x1A
#elif defined(CONFIG_UART_66)
 ldr r1, =0x22
#else
 ldr r1, =0x1A
#endif
 str r1, [r0, #UBRDIV_OFFSET]
#if defined(CONFIG_UART_50)
 ldr r1, =0x3
#elif defined(CONFIG_UART_66)
 ldr r1, =0x1FFF
#else
 ldr r1, =0x3
#endif
 str r1, [r0, #UDIVSLOT_OFFSET]
 ldr r1, =0x4f4f4f4f
 str r1, [r0, #UTXH_OFFSET]  @'O'
//->
,通過修改後,再次編譯,成功,然後將其u-boot.bin再一次通過DNW加載進OK6410的SDRAM內運行,奇跡出現了,呵呵,截圖如下:
 
截圖顯示FLASH 失敗,其實是由於還沒有移植FLASH驅動的緣故,基本這個移植版本還是雛形,啥子也做不了,因為驅動都還沒搞定,但是說明UBOOT可以跑了畢竟看上面的時間還是我昨晚1點43分才測試好的,呵呵,哎寫這篇文章又花了不少時間,覺得既然有心得體會,還是寫出來供大家交流,後面有時間會逐步去完善的,當然了後期的工作量估計會更大啊,呵呵。

Copyright © Linux教程網 All Rights Reserved