uboot移植1-新建單板,時鐘和串口的修改

目標:串口成功打印信息。

前提條件:

1、uboot版本:u-boot-2012.04.01.tar.bz2;

2、交叉編譯器:arm-linux-gcc-4.3.2.tar(如何更換交叉編譯器參考https://blog.csdn.net/WangHuiShou/article/details/102092801

3、部署uboot(代碼利用官方的)
   1.解壓源碼
   tar xjf u-boot-2012.04.01.tar.bz2
   2.清除源碼中的配置文件和目標文件,上一次編譯的結果
   make distclean
   3.針對具體的CPU和開發板進行配置源碼
      make smdk2410_config  //smdk2410_config  配置選項來自 Makefile
   4.make//編譯,結果u-boot.bin
   5.燒寫(JTAG,USB,SD,UART)
   6.涉及代碼的修改:重點關注一個頭文件:
   include/configs/smdk2410.h //全是開發板的硬件配置信息

一、boot啓動過程:

初始化硬件(關看門狗、設置時鐘、設置SDRAM、初始化NAND FLASH等)——>加載完整uboot到SDRAM——>跳轉到第二階段入口開始執行(把內核從NAND FLASH讀到SDRAM——>設置"要傳給內核的參數"——>跳轉執行內核),整個過程最重要的兩個文件:  

  /arch/arm/cpu/arm920t/start.S,涉及到特定硬件設備的讀寫寄存器操作以及特定體系結構的彙編語言(中斷、時鐘等)。

  board/samsung/smdk2440/lowlevel_init.S,完成底層的初始化(內存控制器等)。

具體流程如下:

1 set the cpu to SVC32 mode
2 turn off the watchdog
3 mask all IRQs by setting all bits in the INTMR
4 設置時鐘比例
5 設置內存控制器
6 設置棧,調用C函數board_init_f
7 調用函數數組init_sequence裏的各個函數
7.1 board_early_init_f : 設置系統時鐘、設置GPIO
......
8 重定位代碼:
8.1 從NOR FLASH把代碼複製到SDRAM
8.2 程序的鏈接地址是0,訪問全局變量、靜態變量、調用函數時是使"基於0地址編譯得到的地址"
      現在把程序複製到了SDRAM
      需要修改代碼,把"基於0地址編譯得到的地址"改爲新地址
8.3 程序裏有些地址在鏈接時不能確定,要到運行前才能確定:fixabs
9   clear_bss
10 調用C函數board_init_r:第2階段的代碼

二、新建板級(完成串口信息的打印)

  • 編譯:make smdk2410_config && make
  • 源碼修改,移植到JZ2440開發板:

           1、新建單板(根據類似單板進行新建)

            1.1、拷貝文件

                   cp -rf board/samsung/smdk2410  board/samsung/smdk2440
         cp include/configs/smdk2410.h  include/configs/smdk2440.h

1.2、修改boards.cfg ,仿照2410增加:  (較新版的u-boot源碼已經去掉boadrs.cfg,而是使用make menuconfig配置,config文件在configs目錄下)
仿照
smdk2410                     arm         arm920t     -                   samsung        s3c24x0
添加:
smdk2440                     arm         arm920t     -                   samsung        s3c24x0

1.3、重新編譯燒錄文件make smdk2440_config ==》make,沒有打印信息

   閱讀代碼發現不足:UBOOT裏先以60MHZ的時鐘計算參數來設置內存控制器(lowlevel_init函數的SDRAM),但是MPLL還未設置,導致設置初始化SDRAM時不成功


   處理措施: 把MPLL的設置放到start.S裏(設置),取消SDRAM前設置時鐘,board_early_init_f裏對MPLL的設置,修改如下:

  修改start.s(arch/arm/cpu/arm920t/):

#if 0
	/* FCLK:HCLK:PCLK = 1:2:4 */
	/* default FCLK is 120 MHz ! */
	ldr	r0, =CLKDIVN
	mov	r1, #3
	str	r1, [r0]
#else
	
	/*設置時鐘 */
	ldr r0, =0x4c000014
	//	mov r1, #0x03;			  // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
	mov r1, #0x05;			  // FCLK:HCLK:PCLK=1:4:8
	str r1, [r0]

	/* 如果HDIVN非0,CPU的總線模式應該從“fast bus mode”變爲“asynchronous bus mode” */
	mrc	p15, 0, r1, c1, c0, 0		/* 讀出控制寄存器 */ 
	orr	r1, r1, #0xc0000000			/* 設置爲“asynchronous bus mode” */
	mcr	p15, 0, r1, c1, c0, 0		/* 寫入控制寄存器 */

        /*MPLL(FCLK) = (2*m*fin) / (p * 2^s)*/
        /*m = MDIV + 8, p = PDIV + 2, s = SDIV, fin = 12MHz*/
        /*MPLL寄存器,[19:12]MDIV,[9:4]PDIV,[1:0]SDIV*/
	#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))
	ldr r0, =0x4c000004
	ldr r1, =S3C2440_MPLL_400MHZ
	str r1, [r0]

	/* 啓動ICACHE */
	mrc p15, 0, r0, c1, c0, 0	@ read control reg
	orr r0, r0, #(1<<12)
	mcr	p15, 0, r0, c1, c0, 0   @ write it back
#endif

內存值替換成我們的:lowlevel_init(board/samsung/smdk2440/)

SMRDATA:
#if 0
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0x32
    .word 0x30
    .word 0x30
#else
		
		.long 0x22011110	 //BWSCON
		.long 0x00000700	 //BANKCON0
		.long 0x00000700	 //BANKCON1
		.long 0x00000700	 //BANKCON2
		.long 0x00000700	 //BANKCON3  
		.long 0x00000700	 //BANKCON4
		.long 0x00000700	 //BANKCON5
		.long 0x00018005	 //BANKCON6
		.long 0x00018005	 //BANKCON7
		.long 0x008C04F4	 // REFRESH
		.long 0x000000B1	 //BANKSIZE
		.long 0x00000030	 //MRSRB6
		.long 0x00000030	 //MRSRB7
#endif

刪除board_init_f==>board_early_init_f(arch/arm/lib/board.c)對MPLL的設置:

#if 0
	/* to reduce PLL lock time, adjust the LOCKTIME register */
	writel(0xFFFFFF, &clk_power->locktime);

	/* configure MPLL */
	writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,
	       &clk_power->mpllcon);

	/* some delay between MPLL and UPLL */
	pll_delay(4000);

	/* configure UPLL */
	writel((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV,
	       &clk_power->upllcon);
#endif

重新編譯少些程序,通過usb燒寫(將正常使用boot燒錄到norflash後使用dnw燒寫),燒寫命令如下:

   usb 1 30000000
   protect off all 
   erase 0 7ffff
   cp.b 30000000 0 80000
燒錄完成後打印信息爲亂碼,分析應該是串口波特率設置問題

通過串口初始化發現(serial_init->serial_init_dev->_serial_setbrg->get_PCLK->get_HCLK):

get_HCLK發現沒有定義CONFIG_S3C2440,它用2410的那套,那麼在include/configs3c2440.h中去掉#define CONFIG_S3C2410改成#define CONFIG_S3C2440。編譯make,編譯後發現出現一下錯誤。

錯誤出自於nandflash,到s3c2410_nand.c的72行分析得知,結構體s3c2410_nand只有在宏CONFIG_S3C2410定義時有效,CONFIG_S3C2410和CONFIG_S3C2440不能同時定義。

解決方案:暫時去除nandflash的編譯。include/configs3c2440.h中刪除//#define CONFIG_CMD_NAND。

再次編譯make,編譯成功,燒錄查看打印信息。

到此,2440單板成功打印正常。

下一節介紹如何從nandflash啓動並從nandflash重定位到SDRAM

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章