移植最新u-boot(裁剪和修改默認參數)


 【參考】韋東山 教學筆記

==================================================

最簡單的bootloader的編寫步驟:

1. 初始化硬件:關看門狗、設置時鍾、設置SDRAM、初始化NAND FLASH
2. 如果bootloader比較大,要把它重定位到SDRAM
3. 把內核從NAND FLASH讀到SDRAM
4. 設置"要傳給內核的參數"
5. 跳轉執行內核

改進:
1. 提高CPU頻率, 200MHZ ==> 400MHZ
2. 啟動ICACHE

===================================================

 具體步驟如下:

1、下載、建立source insight工程、編譯、燒寫、如果無運行分析原因
  tar xjf u-boot-2012.04.01.tar.bz2
  cd u-boot-2012.04.01
  make smdk2410_config
  make


2. 分析u-boot: 通過鏈接命令分析組成文件、閱讀代碼分析啟動過程

  a. 初始化硬件:關看門狗、設置時鍾、設置SDRAM、初始化NAND FLASH
  b. 如果bootloader比較大,要把它重定位到SDRAM
  c. 把內核從NAND FLASH讀到SDRAM
  d. 設置"要傳給內核的參數"
  e. 跳轉執行內核

2.1 set the cpu to SVC32 mode
2.2 turn off the watchdog
2.3 mask all IRQs by setting all bits in the INTMR
2.4 設置時鍾比例
2.5 設置內存控制器
2.6 設置棧,調用C函數board_init_f
2.7 調用函數數組init_sequence里的各個函數
2.7.1 board_early_init_f : 設置系統時鍾、設置GPIO
......
2.8 重定位代碼:
2.8.1 從NOR FLASH把代碼復制到SDRAM
2.8.2 程序的鏈接地址是0,訪問全局變量、靜態變量、調用函數時是使"基於0地址編譯得到的地址"
現在把程序復制到了SDRAM
需要修改代碼,把"基於0地址編譯得到的地址"改為新地址
2.8.3 程序里有些地址在鏈接時不能確定,要到運行前才能確定:fixabs
2.9 clear_bss
2.10 調用C函數board_init_r:第2階段的代碼

 


可以修改配置定義CONFIG_S3C2440


3. 修改U-BOOT代碼
3.1 建一個單板
  cd board/samsung/
  cp smdk2410 smdk2440 -rf
  cd ../../include/configs/
  cp smdk2410.h smdk2440.h
修改boards.cfg:
仿照
  smdk2410 arm arm920t - samsung s3c24x0
添加:
  smdk2440 arm arm920t - samsung s3c24x0

3.2 燒寫看結果
3.3 調試:
a. 閱讀代碼發現不足:UBOOT里先以60MHZ的時鍾計算參數來設置內存控制器,但是MPLL還未設置
處理措施: 把MPLL的設置放到start.S里,取消board_early_init_f里對MPLL的設置

編譯出來的uboot非常大,可以先燒寫主光盤里的u-boot.bin到nor,然后用這個uboot來燒寫新的uboot

3.4 亂碼,查看串口波特率的設置,發現在get_HCLK里沒有定義CONFIG_S3C2440
處理措施:include/configs/smdk2440.h: 去掉CONFIG_S3C2410
  #define CONFIG_S3C2440
  //#define CONFIG_CMD_NAND
3.5 修改UBOOT支持NAND啟動
原來的代碼在鏈接時加了"-pie"選項, 使得u-boot.bin里多了"*(.rel*)", "*(.dynsym)"
使得程序非常大,不利於從NAND啟動(重定位之前的啟動代碼應該少於4K)
3.5.1 去掉 "-pie"選項
  arch/arm/config.mk:75:LDFLAGS_u-boot += -pie 去掉這行

3.5.2 參考"畢業班第1課"的start.S, init.c來修改代碼
把init.c放入board/samsung/smdk2440目錄, 修改Makefile
修改CONFIG_SYS_TEXT_BASE為0x33f80000
修改start.S
3.5.3 修改board_init_f, 把relocate_code去掉
3.5.4 修改鏈接腳本: 把start.S, init.c, lowlevel.S等文件放在最前面
  ./arch/arm/cpu/u-boot.lds:

  board/samsung/smdk2440/libsmdk2440.o

3.6 修改UBOOT支持NOR FLASH
  drivers\mtd\jedec_flash.c 加上新的型號
  #define CONFIG_SYS_MAX_FLASH_SECT (128)

修復了重定時留下來的BUG:SP要重新設置


3.7 修改UBOOT支持NAND FLASH
修改:include/configs/smdk2440.h: #define CONFIG_CMD_NAND

把drivers\mtd\nand\s3c2410_nand.c復制為s3c2440_nand.c

分析過程:
  nand_init
  nand_init_chip
  board_nand_init
  設置nand_chip結構體, 提供底層的操作函數
  nand_scan
  nand_scan_ident
  nand_set_defaults
  chip->select_chip = nand_select_chip;
  chip->cmdfunc = nand_command;
  chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;

  nand_get_flash_type
  chip->select_chip
  chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
  nand_command() // 即可以用來發命令,也可以用來發列地址(頁內地址)、行地址(哪一頁)
  chip->cmd_ctrl
  s3c2440_hwcontrol

  chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
  *maf_id = chip->read_byte(mtd);
  *dev_id = chip->read_byte(mtd);


3.8 修改UBOOT支持DM9000網卡
  eth_initialize
  board_eth_init
  cs8900_initialize

  *** ERROR: `ethaddr' not set
  set ipaddr 192.168.1.17
  set ethaddr 00:0c:29:4d:e4:f4
  set serverip 192.168.1.3

 

4. 易用性修裁剪及制作補丁

內核打印出來的分區信息
  0x00000000-0x00040000 : "bootloader"
  0x00040000-0x00060000 : "params"
  0x00060000-0x00260000 : "kernel"
  0x00260000-0x10000000 : "root"

  nand erase 60000 200000
  nand write 30000000 60000 200000

  tftp 30000000 uImage
  nand erase.part kernel
  nand write 30000000 kernel

燒寫JFFS2
  tftp 30000000 fs_mini_mdev.jffs2
  nand erase.part rootfs
  nand write.jffs2 30000000 0x00260000 5b89a8

  set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2

燒寫YAFFS
  tftp 30000000 fs_mini_mdev.yaffs2
  nand erase.part rootfs
  nand write.yaffs 30000000 260000 889bc0

  如果亂碼,執行

    set bootargs console=ttySAC0,115200 root=/dev/mtdblock3

更新UBOOT(NORFlash):
  tftp 30000000 u-boot_new.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000

  【cp.b  按位copy;30000000 源地址;0 目的地址; 40000 大小】


制作補丁:
  diff -urN u-boot-2012.04.01 u-boot-2012.04.01_100ask > u-boot-2012.04.01_100ask.patch

分析"重定位之修改代碼為新地址":
  #ifndef CONFIG_SPL_BUILD
  /*
  * fix .rel.dyn relocations
  */
  ldr r0, _TEXT_BASE /* r0 <- Text base */
  // r0=0, 代碼基地址

  sub r9, r6, r0 /* r9 <- relocation offset */
  // r9 = r6-r0 = 0x33f41000 - 0 = 0x33f41000

  ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */
  // r10 = 00073608

  add r10, r10, r0 /* r10 <- sym table in FLASH */
  // r10 = 00073608 + 0 = 00073608

  ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */
  // r2=0006b568

  add r2, r2, r0 /* r2 <- rel dyn start in FLASH */
  // r2=r2+r0=0006b568

  ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */
  // r3=00073608

  add r3, r3, r0 /* r3 <- rel dyn end in FLASH */
  // r3=r3+r0=00073608

  fixloop:
  ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
  1. r0=[0006b568]=00000020

  add r0, r0, r9 /* r0 <- location to fix up in RAM */
  1. r0=r0+r9=00000020 + 0x33f41000 = 0x33f41020

  ldr r1, [r2, #4]
  1. r1=[0006b568+4]=00000017

  and r7, r1, #0xff
  1. r7=r1&0xff=00000017

  cmp r7, #23 /* relative fixup? */
  1. r7 == 23(0x17)

  beq fixrel
  cmp r7, #2 /* absolute fixup? */

  beq fixabs
  /* ignore unknown type of fixup */
  b fixnext
  fixabs:
  /* absolute fix: set location to (offset) symbol value */
  mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */

  add r1, r10, r1 /* r1 <- address of symbol in table */

  ldr r1, [r1, #4] /* r1 <- symbol value */

  add r1, r1, r9 /* r1 <- relocated sym addr */

  b fixnext
  fixrel:
  /* relative fix: increase location by offset */
  ldr r1, [r0]
  1. r1=[00000020]=000001e0

  add r1, r1, r9
  1. r1=r1+r9=000001e0 + 0x33f41000 = 33F411E0

  fixnext:
  str r1, [r0]
  1. [0x33f41020] = 33F411E0

  add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
  1. r2=r2+8=0006b568+8=6B570

  cmp r2, r3
  1.

  blo fixloop
  #endif


免責聲明!

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



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