1. 程式人生 > >u-boot移植(十三)---代碼修改---裁剪及環境變量 一

u-boot移植(十三)---代碼修改---裁剪及環境變量 一

相關 addition 並且 width load command 啟動程序 type 入參

一、內核裁剪

  內核的裁剪首先就是修改我們的配置文件,即 include/configs/jz2440.h 文件,裏面定義的很多宏,我們也許用不上的就要去掉。

  1 /*
  2  * (C) Copyright 2002
  3  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  4  * Marius Groeger <[email protected]>
  5  * Gary Jennejohn <[email protected]>
  6  * David Mueller <[email protected]
/* */> 7 * 8 * Configuation settings for the JZ2440 board. 9 * 10 * SPDX-License-Identifier: GPL-2.0+ 11 */ 12 13 #ifndef __CONFIG_H 14 #define __CONFIG_H 15 16 /* 17 * High Level Configuration Options 18 * (easy to change) 19 */ 20 #define CONFIG_S3C24X0 /* This is a SAMSUNG S3C24x0-type SoC */ 21
#define CONFIG_JZ2440 /* on a JZ2440 Board */ 22 #define CONFIG_S3C2440 23 24 /* 內存為64M(34000000),34000000 - 33F00000 = 100000 即為1M*/ 25 #define CONFIG_SYS_TEXT_BASE 0x33f00000 26 27 #define DEBUG 28 29 #define CONFIG_SYS_ARM_CACHE_WRITETHROUGH 30 31 /* input clock of PLL (the JZ2440 has 12MHz input clock)
*/ 32 #define CONFIG_SYS_CLK_FREQ 12000000 33 34 #define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ 35 #define CONFIG_SETUP_MEMORY_TAGS 36 #define CONFIG_INITRD_TAG 37 38 /* 39 * Hardware drivers 40 */ 41 #if 0 42 #define CONFIG_CS8900 /* we have a CS8900 on-board */ 43 #define CONFIG_CS8900_BASE 0x19000300 44 #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */ 45 #else 46 #define CONFIG_DRIVER_DM9000 47 #endif 48 49 /* 50 * select serial console configuration 51 */ 52 #define CONFIG_S3C24X0_SERIAL 53 #define CONFIG_SERIAL1 1 /* we use SERIAL 1 on JZ2440 */ 54 55 /************************************************************ 56 * USB support (currently only works with D-cache off) 57 ************************************************************/ 58 #define CONFIG_USB_OHCI 59 #define CONFIG_USB_OHCI_S3C24XX 60 #define CONFIG_USB_KEYBOARD 61 #define CONFIG_USB_STORAGE 62 #define CONFIG_DOS_PARTITION 63 64 /************************************************************ 65 * RTC 66 ************************************************************/ 67 #define CONFIG_RTC_S3C24X0 68 69 70 #define CONFIG_BAUDRATE 115200 71 72 /* 73 * BOOTP options 74 */ 75 #define CONFIG_BOOTP_BOOTFILESIZE 76 #define CONFIG_BOOTP_BOOTPATH 77 #define CONFIG_BOOTP_GATEWAY 78 #define CONFIG_BOOTP_HOSTNAME 79 80 /* 81 * Command line configuration. 82 */ 83 #define CONFIG_CMD_BSP 84 #define CONFIG_CMD_CACHE 85 #define CONFIG_CMD_DATE 86 #define CONFIG_CMD_DHCP 87 #define CONFIG_CMD_NAND 88 #define CONFIG_CMD_PING 89 #define CONFIG_CMD_REGINFO 90 #define CONFIG_CMD_USB 91 92 #define CONFIG_SYS_HUSH_PARSER 93 #define CONFIG_CMDLINE_EDITING 94 95 /* autoboot */ 96 #define CONFIG_BOOTDELAY 5 97 #define CONFIG_BOOT_RETRY_TIME -1 98 #define CONFIG_RESET_TO_RETRY 99 #define CONFIG_ZERO_BOOTDELAY_CHECK 100 101 #define CONFIG_NETMASK 255.255.255.0 102 #define CONFIG_IPADDR 10.0.0.110 103 #define CONFIG_SERVERIP 10.0.0.1 104 105 #if defined(CONFIG_CMD_KGDB) 106 #define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port */ 107 #endif 108 109 /* 110 * Miscellaneous configurable options 111 */ 112 #define CONFIG_SYS_LONGHELP /* undef to save memory */ 113 #define CONFIG_SYS_CBSIZE 256 114 /* Print Buffer Size */ 115 #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + 116 sizeof(CONFIG_SYS_PROMPT)+16) 117 #define CONFIG_SYS_MAXARGS 16 118 #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE 119 120 #define CONFIG_DISPLAY_CPUINFO /* Display cpu info */ 121 122 #define CONFIG_SYS_MEMTEST_START 0x30000000 /* memtest works on */ 123 #define CONFIG_SYS_MEMTEST_END 0x33F00000 /* 63 MB in DRAM */ 124 125 #define CONFIG_SYS_LOAD_ADDR 0x30800000 126 127 /* support additional compression methods */ 128 #define CONFIG_BZIP2 129 #define CONFIG_LZO 130 #define CONFIG_LZMA 131 132 /*----------------------------------------------------------------------- 133 * Physical Memory Map 134 */ 135 #define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ 136 #define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ 137 #define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ 138 139 #define PHYS_FLASH_1 0x00000000 /* Flash Bank #0 */ 140 141 #define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1 142 143 /*----------------------------------------------------------------------- 144 * FLASH and environment organization 145 */ 146 147 #define CONFIG_SYS_FLASH_CFI 148 #define CONFIG_FLASH_CFI_DRIVER 149 #define CONFIG_FLASH_CFI_LEGACY 150 #define CONFIG_SYS_FLASH_LEGACY_1Mx16 151 #define CONFIG_FLASH_SHOW_PROGRESS 45 152 153 #define CONFIG_SYS_MAX_FLASH_BANKS 1 154 #define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE } 155 #define CONFIG_SYS_MAX_FLASH_SECT (128) 156 157 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) 158 #define CONFIG_ENV_IS_IN_FLASH 159 #define CONFIG_ENV_SIZE 0x10000 160 /* allow to overwrite serial and ethaddr */ 161 #define CONFIG_ENV_OVERWRITE 162 163 /* 164 * Size of malloc() pool 165 * BZIP2 / LZO / LZMA need a lot of RAM 166 */ 167 #define CONFIG_SYS_MALLOC_LEN (4 * 1024 * 1024) 168 169 #define CONFIG_SYS_MONITOR_LEN (448 * 1024) 170 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE 171 172 /* 173 * NAND configuration 174 */ 175 #ifdef CONFIG_CMD_NAND 176 #define CONFIG_NAND_S3C2410 177 #define CONFIG_SYS_S3C2410_NAND_HWECC 178 #define CONFIG_SYS_MAX_NAND_DEVICE 1 179 #define CONFIG_SYS_NAND_BASE 0x4E000000 180 #endif 181 182 /* 183 * File system 184 */ 185 #define CONFIG_CMD_FAT 186 #define CONFIG_CMD_EXT2 187 #define CONFIG_CMD_UBI 188 #define CONFIG_CMD_UBIFS 189 #define CONFIG_CMD_MTDPARTS 190 #define CONFIG_MTD_DEVICE 191 #define CONFIG_MTD_PARTITIONS 192 #define CONFIG_YAFFS2 193 #define CONFIG_RBTREE 194 195 /* additions for new relocation code, must be added to all boards */ 196 #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 197 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x1000 - 198 GENERATED_GBL_DATA_SIZE) 199 200 #define CONFIG_BOARD_EARLY_INIT_F 201 202 #endif /* __CONFIG_H */

  編譯執行:

  技術分享

  do_date 對應著宏 DO_CMD_DATE,去掉此宏

  技術分享

  再次編譯執行,編譯完成。

  技術分享

  燒寫進開發板。啟動。

二、環境變量

2.1 修改分區為nand

  環境變量的設置都會存在flash中,若是未設置分區,就執行save等保存命令,可能會破壞u-boot的啟動程序。

  環境變量的設置 對應著宏

  技術分享

  不過這段我們不需要,我們需要設置自己的環境變量。

  查找save命令的設置對應的文件,saveenv

  技術分享

  技術分享

  技術分享

  我們只有nand和flash所以只對應這兩行。查看common 下的 Makefile:

  技術分享

  技術分享

  配置成保存環境變量的地方為 nand ,則需要定義宏 CONFIG_ENV_IS_IN_NAND

  進入源文件繼續查看,還需要定義宏 CMD_SAVEENV,CMD_SAVEENV宏的定義則依賴下面的程序:

  技術分享

  CONFIG_CMD_NAND 我們已經在jz2440.h中定義,所以不需要了。

  saveenv函數中同時涉及到另外兩個宏:CONFIG_ENV_RANGE和CONFIG_ENV_OFFSET,一個是ENV的擦除大小,一個是偏移地址。

  技術分享

  其中CONFIG_ENV_RANGE 的設置如上,我們可以直接參照 flash的設置,配置這幾個宏。

  技術分享

  編譯,燒寫:

  技術分享

  結果不對,打開DEBUG開關進行DEBUG

  代碼流程中執行到initr_nand,之後就開始執行initr_env,在此函數和其子函數中加入調試代碼 查看是否進入其中執行:

  技術分享

  技術分享

  在函數的頭尾加上debug函數,可以在進入的函數中都加上,然後去查函數在哪裏調用出錯了。編譯,燒錄:

  技術分享

  上面是結尾的打印信息。根據上面的信息理一下代碼

 1 board_init_r
 2     initr_env 
 3         debug("start of initr_env \n");
 4         should_load_env()
 5             debug("start of should_load_env() \n");
 6             debug("end of should_load_env() \n");
 7         env_relocate
 8             debug("start of env_relocate(void) \n");
 9             debug("in of env_relocate_spec() \n");
10             env_relocate_spec();
11                 env_relocate_spec(void)        //此函數是未定義CONFIG_ENV_OFFSET_REDUND宏的函數
12                     debug("start of env_relocate(void) \n");
13                     debug("env_relocate_spec in  set_default_env\n");
14                     set_default_env("!readenv() failed");
15                     debug("end of env_relocate(void) \n");
16             debug("end of env_relocate(void) \n");
17         debug("end of initr_env \n");

  標記紅色部分是已經執行了的,可以看出在進入env_relocate_spec時候找不到函數了,此函數並沒有進入,但是又確實執行到那一步了,看一下u-boot.dis,看是否執行過此函數

  技術分享

  查看一下 env_relocate是否調用此地址函數:

  技術分享

  這裏又調用 但是執行的時候又出錯了,進入了此函數,確沒有返回。就是程序運行的時候根本沒有進入此函數中。

  查看一下棧的設置以及autoconf.h文件,發現在其中,打開了CONFIG_SYS_MALLOC_F宏,這個宏在原先的設置中我們並沒有加入,應該是系統自動給他設定的。

  查看jz2440_defconfig文件,發現裏面確實打開了這個宏,註釋掉,這個宏在棧的設置中會用到,在crt0.S的代碼中有一段跳轉到board_init_f_mem 函數,裏面有一段代碼如下:

1 #if defined(CONFIG_SYS_MALLOC_F)
2     top -= CONFIG_SYS_MALLOC_F_LEN;
3     gd->malloc_base = top;
4 #endif

  這裏是分配給一小段內存池,使棧下移動。棧往下多移動了 1024KB

  技術分享

  同時在我們的默認的config文件中,發現關閉了 CONFIG_CMD_NAND 宏,這個宏必須要打開。

  在配置中,SPL也被打開了,必須關閉

  技術分享

  最後重新修改下crt0.S中的代碼,如下:

  1 ENTRY(_main)
  2 
  3 /*
  4  * Set up initial C runtime environment and call board_init_f(0).
  5  * 初始化C運行環境並且調用 board_init_f(0) 函數
  6  */
  7 
  8  /*
  9   * 初始化棧地址
 10   */
 11 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
 12     ldr    sp, =(CONFIG_SPL_STACK)
 13 #else
 14     /* Generic-asm-offsets.h (include\generated)
 15      * #define GENERATED_GBL_DATA_SIZE 192
 16      * JZ2440.h(include\config)
 17      * #define PHYS_SDRAM_1        0x30000000
 18      * #define CONFIG_SYS_SDRAM_BASE    PHYS_SDRAM_1
 19      * #define CONFIG_SYS_INIT_SP_ADDR    (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
 20      * 
 21      * CONFIG_SYS_INIT_SP_ADDR = 0x30000000 + 0x1000 - 192(0xc0) = 0x30000f40
 22      */
 23     ldr    sp, =(CONFIG_SYS_INIT_SP_ADDR)        /* 設置CFIG_SYS_INIT_SP_ADDR定義的地址,include/configs/jz2440.h中定義 */
 24 #endif    /* end defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)*/
 25 
 26 #if defined(CONFIG_CPU_V7M)    /* v7M forbids using SP as BIC destination */
 27     mov    r3, sp
 28     bic    r3, r3, #7
 29     mov    sp, r3
 30 #else
 31     /* sp 的8字節對齊 */
 32     bic    sp, sp, #7    /* 8-byte alignment for ABI compliance */
 33 #endif /* end defined(CONFIG_CPU_V7M) */
 34     
 35     /* 設置nand 啟動 */
 36     bl nand_init_ll    /* 跳轉到borad/samsung/jz2440/init.c 中執行 nand_init_ll 函數 */
 37     mov r0, #0
 38     ldr r1, =(CONFIG_SYS_TEXT_BASE)    /*CONFIG_SYS_TEXT_BASE=0x33f00000 程序的鏈接地址*/
 39     ldr r2, =0x80000                /* 程序大小 */    
 40     bl copy_code_to_sdram            /* 拷貝代碼到SDRAM */    
 41     bl clear_bss                    /* 清除bss */
 42 
 43     ldr pc, =call_board_init_f            /* 執行第一階段初始化 */
 44     
 45 call_board_init_f:        
 46     mov    r0, sp                    /* r0 = sp */
 47     bl    board_init_f_mem        /*跳轉到 board_init_f_mem 執行*/
 48     mov    sp, r0                    /* sp = 0x30000000*/
 49     
 50     mov    r0, #0
 51     bl    board_init_f            /* 調用單板的初始化函數,跳轉到 borad_init_f 處執行 */
 52 
 53 
 54 #if ! defined(CONFIG_SPL_BUILD)
 55 
 56 
 57 /*
 58  * Set up intermediate environment (new sp and gd) and call
 59  * relocate_code(addr_moni). Trick here is that we‘ll return
 60  * ‘here‘ but relocated.
 61  */
 62     /*
 63      * 這一段代碼是將board_init_f中設置好的start_addr_sp地址值賦給棧指針,使其指向重定位後的棧頂
 64      * 8字節對齊後,將r9設為新的GD地址( gd地址=bd地址-sizeof(gd_t))
 65      */
 66     ldr    sp, [r9, #GD_START_ADDR_SP]    /* sp = gd->start_addr_sp */
 67 
 68 #if defined(CONFIG_CPU_V7M)    /* v7M forbids using SP as BIC destination */
 69     mov    r3, sp
 70     bic    r3, r3, #7
 71     mov    sp, r3
 72 #else
 73     bic    sp, sp, #7    /* 8-byte alignment for ABI compliance */
 74 #endif /* defined(CONFIG_CPU_V7M) */
 75 
 76     ldr    r9, [r9, #GD_BD]        /* r9 = gd->bd */
 77     sub    r9, r9, #GD_SIZE        /* new GD is below bd */
 78 
 79     adr    lr, here                 /*設置返回地址為下面的here,重定位到sdram後返回here運行*/
 80     ldr    r0, [r9, #GD_RELOC_OFF]        /* r0 = gd->reloc_off 取重定位地址偏移值 */
 81     add    lr, lr, r0                /*返回地址加偏移地址等於重定位後在sdram中的here地址*/
 82 
 83 #if defined(CONFIG_CPU_V7M)
 84     orr    lr, #1                /* As required by Thumb-only */
 85 #endif
 86 #if 0
 87     ldr    r0, [r9, #GD_RELOCADDR]        /* r0 = gd->relocaddr 傳入參數為重定位地址 */
 88     b    relocate_code                /*跳到arch/arm/lib/relocate.S中執行*/
 89 #endif
 90 
 91 here:        /*返回後跳到sdram中運行    */    
 92     /*
 93       * now relocate vectors
 94       */
 95     bl    relocate_vectors
 96 
 97     /* Set up final (full) environment */
 98     bl    c_runtime_cpu_setup    /* we still call old routine here */
 99 #endif /* ! defined(CONFIG_SPL_BUILD) */
100 
101 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
102 #ifdef CONFIG_SPL_BUILD
103     /* Use a DRAM stack for the rest of SPL, if requested */
104     bl    spl_relocate_stack_gd
105     cmp    r0, #0
106     movne    sp, r0
107 #endif /* end CONFIG_SPL_BULD */
108     ldr    r0, =__bss_start    /* this is auto-relocated! */
109 
110 #ifdef CONFIG_USE_ARCH_MEMSET
111     ldr    r3, =__bss_end        /* this is auto-relocated! */
112     mov    r1, #0x00000000        /* prepare zero to clear BSS */
113 
114     subs    r2, r3, r0        /* r2 = memset len */
115     bl    memset
116 #else
117     ldr    r1, =__bss_end        /* this is auto-relocated! */
118     mov    r2, #0x00000000        /* prepare zero to clear BSS */
119 
120 clbss_l:cmp    r0, r1            /* while not at end of BSS */
121 #if defined(CONFIG_CPU_V7M)
122     itt    lo
123 #endif
124 
125     strlo    r2, [r0]        /* clear 32-bit BSS word */
126     addlo    r0, r0, #4        /* move to next */
127     blo    clbss_l
128 #endif
129 
130 #if ! defined(CONFIG_SPL_BUILD)
131     bl coloured_LED_init
132     bl red_led_on
133 #endif
134 
135     /* call board_init_r(gd_t *id, ulong dest_addr) */
136     mov     r0, r9                  /* gd_t */
137     ldr    r1, [r9, #GD_RELOCADDR]    /* dest_addr */
138 /*    ldr    r1, =CONFIG_SYS_TEXT_BASE*/
139     /* call board_init_r */
140     ldr    pc, =board_init_r    /* this is auto-relocated! */
141 
142     /* we should not return here. */
143 #endif
144 
145 ENDPROC(_main)

  再次編譯運行,同時保存環境變量,並reset。

  技術分享  技術分享

  已經運行正常了。

  reset後顯示了一個錯誤,dm9000的地址未設置。下一節在修改,此時先看看env的啟動流程。

2.2 env 的啟動流程

  uboot中env的整個架構可以分為3層:  

  (1) 命令層,如saveenv,setenv editenv這些命令的實現,還有如啟動時調用的env_relocate函數。

  (2) 中間封裝層,利用不同靜態存儲器特性封裝出命令層需要使用的一些通用函數,如env_init,env_relocate_spec,saveenv這些函數。實現文件在common/env_xxx.c

  (3) 驅動層,實現不同靜態存儲器的讀寫擦等操作,這些是uboot下不同子系統都必須的。

2.2.1 env初始化

  首先在board_init_f中調用init_sequence的env_init,這個函數是不同存儲器實現的函數,nand中的實現如下:

  技術分享

1 int env_init(void)
2 {
3     gd->env_addr    = (ulong)&default_environment[0];  /* 調用環境變量數組 */
4     gd->env_valid    = 1;                  /* 設置env標誌有效位為1 */
5     return 0;
6 }

  env_init要早於靜態存儲器的初始化,所以無法進行env的讀寫,這裏將gd中的env相關變量進行配置,默認設置env為valid。方便後面env_relocate函數進行真正的env從nand到ram的relocate。

2.2.2 initr_env

  繼續執行,在board_init_r中執行 initr_ebv

 1 static int initr_env(void)
 2 {
 3     debug("start of initr_env \n");
 4     /* initialize environment */
 5     if (should_load_env())
 6         env_relocate();
 7     else
 8         set_default_env(NULL);
 9 
10     /* Initialize from environment */
11     load_addr = getenv_ulong("loadaddr", 16, load_addr);
12     return 0;
13 }

  這是在所有存儲器初始化完成後執行的。

  調用should_load_env:

1 static int should_load_env(void)
2 {
3     return 1;
4 }

  返回 1之後執行下一句 env_relocate。

  

 1 void env_relocate(void)
 2 {
 3 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
 4     env_reloc();
 5     env_htab.change_ok += gd->reloc_off;
 6 #endif
 7     if (gd->env_valid == 0) {
 8 #if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD)
 9         /* Environment not changable */
10         debug("in of set_default_env \n");
11         set_default_env(NULL);
12 #else
13         bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM);
14         set_default_env("!bad CRC");
15 #endif
16     } else {
17         debug("in of env_relocate_spec() \n");
18         env_relocate_spec();
19     }
20 }

  由於我們的 gd->env_valid 再board_init_f 函數中已經設置為1,這裏會執行到 env_relocate_spec 函數中去。

  CONFIG_ENV_OFFSET_REDUND此宏我們未設置,運行的代碼就是如下:

 1 void env_relocate_spec(void)
 2 {
 3 #if !defined(ENV_IS_EMBEDDED)
 4     int ret;
 5     ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 6 
 7     ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);
 8     if (ret) {
 9         set_default_env("!readenv() failed");
10         return;
11     }
12     
13     env_import(buf, 1);
14     debug("end 【nand】 of env_relocate_spec 2 \n");
15 #endif /* ! ENV_IS_EMBEDDED */
16 }

  env_import 輸出環境變量信息,至此已經結束。

  

  

  

  

u-boot移植(十三)---代碼修改---裁剪及環境變量 一