u-boot移植(五)---代碼修改---時鍾修改、SDRAM


  最開始已經建立了新單板以及配置文件,現在就需要做的是代碼的修改,配置成適合目標板使用的u-boot。

一、時鍾修改

  在代碼流程分析中,我們知道,系統的啟動是:

  • 設置 CPU 為管理員模式
  • 關閉看門狗
  • 屏蔽中斷
  • 設置啟動參數:時鍾 FCLK:HCLK:PCLK = 1:2:4     FCLK=120MHZ
  • flush v4 I/D caches
  • disable MMU stuff and caches
  • DRAM設置

  在DRAM設置中,有如下定義說明:

  

  在這段初始化步驟中,並沒有看見系統時鍾的設置。

  在S3C2440的datesheet中時鍾那一章,我們可以看到如下定義:

  

  下面的英文的意思是:盡管 MPLL僅僅只是在一個 reset 后啟動,但是直到軟件對MPLLCON寄存器寫一個有效的設置之后,MPLL才作為系統時鍾的輸出。在有效設置之前,從外部晶振源(XTlPll或EXTCLK)獲得的時候將直接用於系統時鍾。哪怕用戶不想要改變MPLLCON寄存器的值,用戶都應該寫一個相同的值進MPLLCON寄存器。

  而我們外部時鍾源的管腳定義說明如下:

  

  

 

  實際電路如下:

        

 

 

  黃色部分為我們外部時鍾源(EXTCLK)的管腳,可以看到,外部時鍾源被3.3V電壓拉高。而管腳定義中已經說明,如果外部時鍾源沒有使用,則將此管腳拉高。

  OM[3:2]管腳都被拉低,則主時鍾源和USB時鍾源都選擇的是外部晶振,外部晶振輸入則為XTIpll管腳。晶振源為12MHz。

  再來看看CLK的定義:

  • FCLK: 為CPU核供給時鍾信號,我們所說的cpu主頻為200MHz,就是指的這個時鍾信號,相應的,1/Fclk即為cpu時鍾周期  
  • HCLK: 為AHB bus peripherals供給時鍾信號,AHB為advanced high-performance bus
  • PCLK: 為APB bus peripherals供給時鍾信號,APB為advanced peripherals bus

  分析一下時鍾源碼:

  

  CLKDIVN寄存器的定義如下:

  

    #3 = 0b0011   對應寄存器可知道

        DIVN_UPLL:UCLK = UPLL clock

        HDIVN:01  HCLK=FCLK/2

        PDIVN:0   PCLK = HCLK/2 = FCLK/4

  默認FCLK 為120MHz 則HDIVN和PDIVN都不為0,在datesheet的CLOCK CONTROL LOGIC 這一小節里面有這樣的注意:

  

  意思就是說我們的S3C2440不支持同步總線模式,我們必須改為異步模式,那么我們必須在時鍾設置上加上那段代母,修改CPU的總線模式,改后代碼如下:

 1     /* FCLK:HCLK:PCLK = 1:2:4 */
 2     /* default FCLK is 120 MHz ! */
 3     /* 設置啟動參數:時鍾 */
 4     ldr    r0, =CLKDIVN            /* r0中存放時鍾寄存器地址 */
 5     mov    r1, #3                    /* 將立即數0存放到r1中,r1 = 0x3 */
 6     str    r1, [r0]                /* 將r1中的值存放到以r0中的值為地址的存儲單元中,即 CLKDIVN = 0 */
 7 
 8     /* MMU_SetAsyncBusMode */
 9     mrc p15,0,r0,c1,c0,0
10     orr r0,r0,0xc0000000
11     mcr p15,0,r0,c1,c0,0

  同樣的,在The Clock Distribution Block Diagram (POWER MANAGEMENT )框圖中,對FCLK有如下的定義:

   

  再來看看 normal mode和 slow mode是什么意思:

  

  

  我們CPU的啟動是在normal mode中,同樣所以此時,我們是在處於normal mode。

  MPLL為鎖相環輸出頻率 ,用來給MCU提供頻率,進而再給CPU的各個模塊供應頻率。具體可以看看datesheet中的Clock Generator Block Diagram 框圖。而文檔和前面已經說過:盡管 MPLL僅僅只是在一個 reset 后啟動,但是直到軟件對MPLLCON寄存器寫一個有效的設置之后,MPLL才作為系統時鍾的輸出。在有效設置之前,從外部晶振源(XTlPll或EXTCLK)獲得的時候將直接用於系統時鍾。哪怕用戶不想要改變MPLLCON寄存器的值,用戶都應該寫一個相同的值進MPLLCON寄存器。

  而我們的源碼中,在時鍾設置后,就直接跳到cpu_init_crit 去執行,在其中又跳進lowlevel_init中執行DRAM的初始化,並且注釋中HCLK的默認頻率為60MHZ,此時的HCLK是依賴於MPLL的,因此我們必須添加上MPLL的設置:

  

  注意下面的note:當我們設置MPLL & UPLL的值的時候,我們首先必須要設置UPLL的值,然后再設置MPLL的值。

  

  同樣,在borad_f.c 中 board_early_init_f 函數里面,進行了時鍾的初始化代碼過程:

  

  我們可以將MPLL的設置放入我們的start.S中,並注釋掉這里面的MPLL設置。

  修改如下:

  start.S 

 1     /* FCLK:HCLK:PCLK = 1:4:8 */
 2     /* default FCLK is 120 MHz ! */
 3     /* 設置啟動參數:時鍾 */
 4     ldr    r0, =CLKDIVN            /* r0中存放時鍾寄存器地址 */
 5     mov    r1, #5                    /* 將立即數0存放到r1中,r1 = 0x3 */
 6     str    r1, [r0]                /* 將r1中的值存放到以r0中的值為地址的存儲單元中,即 CLKDIVN = 0 */
 7 
 8     /* MMU_SetAsyncBusMode */
 9     mrc p15,0,r0,c1,c0,0
10     orr r0,r0,0xc0000000
11     mcr p15,0,r0,c1,c0,0
12 
13     /* MPLLCON = s3c2440_MPLL_400MHZ */
14     ldr r0, =0x4c000004
15     ldr r1, =s3c2440_MPLL_400MHZ
16     str r1, [r0]
17 
18     /* 啟動ICACHE */
19     mrc p15, 0, r0, c1, c0, 0    /* read control reg */
20     orr r0, r0, #(1<<12)
21     mcr p15, 0, r0, c1, c0, 0    /* write it back */

 

  DRAM修改:lowlevel_init.S (board\samsung\jz2440) 

/* 
 * 初始化存儲控制器,經過此初始化之后,內存才可以使用
 */
 /* 地址為 0x00000eb0 */
SMRDATA:
        .long 0x22011110     //BWSCON
        .long 0x00000700     //BANKCON0
        .long 0x00000700     //BANKCON1
        .long 0x00000700     //BANKCON2
        .long 0x00000700     //BANKCON3  
        .long 0x00000740     //BANKCON4
        .long 0x00000700     //BANKCON5
        .long 0x00018005     //BANKCON6
        .long 0x00018005     //BANKCON7
        .long 0x008C04F4     //REFRESH
        .long 0x000000B1     //BANKSIZE
        .long 0x00000030     //MRSRB6
        .long 0x00000030     //MRSRB7

  board_early_init_f(Jz2440.c (board\samsung\jz2440) ):

  

二、調試

  完成修改后,進行編譯調試:

2.1 編譯

  

  編譯完成后,查看文件大小:

  

  編譯出的文件大小公有500多KB。

2.2 燒寫進jz2440開發板

 2.2.1 燒寫已經制作完成好的u-boot

  開發板撥碼開關先撥至nand flash啟動那端。

  用openjtag工具連接電腦和開發板,啟動命令行,進入uboot-bin所在目錄:

  

  啟動oflash:

  

  輸入數字0,啟動openjtag:

  

  輸入數字1,選擇S3C2440:

  

  選擇1 Nor Flash prog

  

  輸入文件名:

  

  選擇開始地址為0地址:

  

  開始燒寫。

  燒寫完成后,斷開JTAG口。(JTAG 線上有復位引腳,使用 JTAG 工具燒好程序后,一定要把 JTAG 工具和開發板之間的 JTAG 排線斷開, 並給開發板重新上電,開發板上的程序才能正常啟動。

2.2.2 燒寫新的u-boot

  連接串口線,開發板設置為nor啟動,啟動開發板。啟動過程中按空格鍵

   

  按q退出后,輸入命令查看分區大小:

  

  bootloader分區不夠,我們的新的u-boot.bin有500多K,無法用命令o來燒寫。只能使用命令來燒寫,接上USB線。

  打開dnw工具:

  

  輸入如下命令:

  

  設置dnw工具:

  點擊USB Port-》transmit->transmit,選擇新編譯的u-boot.bin。

  

  此時只是把文件發送到了內存當中。

  去掉nor flash的寫保護:

  

  從0地址開始擦除:

  

  從30000000地址把程序拷貝到nor flash的0地址。

  

  重啟開發板,查看燒寫,串口上無任何反應。

2.3 調試

  使用openjtag進行調試。連接openjtag  adapter。

  打開openOCD GUI工具 點擊connect。

  

  打開telnet:

  

  執行命令,查看信息:

  

  查看nor flash的0地址:

    

  

   執行反匯編命令,生成u-boot.dis:

  

  結合代碼查看,start.S中是執行玩了 cpu_init_crit后,跳轉到 _main中去執行:

  

  _main在u-boot.dis中的地址如下:

  

  從0地址開始運行:

  

  在telnet中設置斷點:

  

  繼續運行:

  

  由於代碼中那時候內存已經初始化,那么此時內存應該是可以訪問的:

  讀內存:

  

  寫內存,並將內存讀取出來:

  

  數據是正確的,證明我們的修改沒有問題。SDRAM 的修改沒有問題。

  此時還有一個問題是,我們的串口無任何打印。留待下一個再分析

 

  

  

  

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM