Chinaunix首页 | 论坛 | 博客
  • 博客访问: 493970
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: 嵌入式

2016-09-24 20:45:46

一、Bootloader设计蓝图

1.1 Bootloader的作用
助推器->通过火箭运送航天飞机。
1.2 设计方法-模仿
行业老大->uboot。通过模仿uboot的代码,来进行学习。
1.3 U-Boot简介
U-Boot是用于多种嵌入式CPUMIPSx86ARM等)的bootloader程序,U-Boot不仅支持嵌入式Linux
系统的引导,还支持VxWorks, QNX等多种嵌入式操作系统。
两种模式:自主模式(自动启动linux)、开发模式(可以
1.3 手把手带你来操作

Source Insight使用方法:
打开软件后,选择Project>>Add and Remove Project Files>>Add all
前提是已经映射了网络驱动器(uboot的代码地址就是z:盘)
如果没有汇编文件:
Option>>Document Option >>C Source File , *c;*h;*.s;*.S
R左边的书本的符号点一下,同步函数。可以直接单击查看函数源文件内容。

shift+F8可以高亮显示字符串。

二、ARM处理器处理流程
1.启动方式
nor Flash(2MB)
nand Flash(256MB)
Nand Flash 因为不能统一编址,所以要赋值到Nor Flash 启动(4K stepping stone),4k代码中把剩下的Nand Flash赋值到内存中,再继续启动。

三、Uboot工作流程
1.程序入口
每个开发板都在Makefile中会有一个配置项
vim uboot/Makefile
  1. smdk2440_config : unconfig
  2.         @$(MKCONFIG) $(@:_config=) arm s3c24xx smdk2440 samsung s3c2440
vim config.mk中有这个,因为链接器中起始是0x00000000,但是这里TEXT_BASE设置为了30008000.从而编译出来的程序,通过反汇编得知起始地址是从TEXT_BASE开始的。所以这个优先于连接器脚本中的。
  1. LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)


在board/samsun/smdk2440/uboot.lds(uboot的连接器脚本)
  1. /*
  2.  * (C) Copyright 2005-2006
  3.  * Seung-Chull, Suh Samsung Electronics <sc.suh@samsung.com>
  4.  *
  5.  * Derived from sources by DENX Software Engineering.
  6.  *
  7.  * See file CREDITS for list of people who contributed to this
  8.  * project.
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License as
  12.  * published by the Free Software Foundation; either version 2 of
  13.  * the License, or (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23.  * MA 02111-1307 USA
  24.  */

  25. OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
  26. OUTPUT_ARCH(arm)
  27. ENTRY(_start)                            此处标明起始入口_start
  28. SECTIONS
  29. {
  30.     . = 0x00000000;
  31.     . = ALIGN(4);
  32.     .text :
  33.     {
  34.      cpu/s3c24xx/start.o    (.text)                            这里是最开始执行的文件位置,可能是start.c或者star.S
  35.      cpu/s3c24xx/s3c2440/cpu_init.o    (.text)
  36.      *(.text)
  37.     }
  38.     . = ALIGN(4);
  39.     .rodata : { *(.rodata) }
  40.     . = ALIGN(4);
  41.     .data : { *(.data) }
  42.     . = ALIGN(4);
  43.     .got : { *(.got) }

  44.     . = .;
  45.     __u_boot_cmd_start = .;
  46.     .u_boot_cmd : { *(.u_boot_cmd) }
  47.     __u_boot_cmd_end = .;

  48.     . = ALIGN(4);
  49.     .mmudata : { *(.mmudata) }

  50.     . = ALIGN(4);
  51.     __bss_start = .;
  52.     .bss : { *(.bss) }
  53.     _end = .;
  54. }
在cpu/s3c24xx/start.S中。有一个_start就是程序的入口了。

  1. #include <asm/proc/domain.h>
  2. #endif

  3. #ifndef CONFIG_ENABLE_MMU
  4. #ifndef CFG_PHY_UBOOT_BASE
  5. #define CFG_PHY_UBOOT_BASE    CFG_UBOOT_BASE
  6. #endif
  7. #endif


  8. /*
  9.  *************************************************************************
  10.  *
  11.  * Jump vector table as in table 3.1 in [1]
  12.  *
  13.  *************************************************************************
  14.  */设置中断向量表,从reset开始


  15. .globl _start
  16. _start:
  17.     b    reset
  18.     ldr    pc, _undefined_instruction
  19.     ldr    pc, _software_interrupt
  20.     ldr    pc, _prefetch_abort
  21.     ldr    pc, _data_abort
  22.     ldr    pc, _not_used
  23.     ldr    pc, _irq
  24.     ldr    pc, _fiq

  25. _undefined_instruction:
  26.     .word undefined_instruction
  27. _software_interrupt:
  28.     .word software_interrupt
  29. _prefetch_abort:
  30.     .word prefetch_abort
  31. _data_abort:
  32.     .word data_abort
  33. _not_used:
  34.     .word not_used
  35. _irq:
  36.     .word irq
  37. _fiq:
  38.     .word fiq

  39.     .balignl 16,0xdeadbeef


  40. /*
  41.  *************************************************************************
  42.  *
  43.  * Startup Code (reset vector)
  44.  *
  45.  * do important init only if we don't start from memory!
  46.  * setup Memory and board specific bits prior to relocation.
  47.  * relocate armboot to ram
  48.  * setup stack
  49.  *
  50.  *************************************************************************
  51.  */

  52. _TEXT_BASE:
  53.     .word    TEXT_BASE

  54. /*
  55.  * Below variable is very important because we use MMU in U-Boot.
  56.  * Without it, we cannot run code correctly before MMU is ON.
  57.  * by scsuh.
  58.  */
  59. _TEXT_PHY_BASE:
  60.     .word    CFG_PHY_UBOOT_BASE

  61. .globl _armboot_start
  62. _armboot_start:
  63.     .word _start

  64. /*
  65.  * These are defined in the board-specific linker script.
  66.  */
  67. .globl _bss_start
  68. _bss_start:
  69.     .word __bss_start

  70. .globl _bss_end
  71. _bss_end:
  72.     .word _end

  73. #ifdef CONFIG_USE_IRQ
  74. /* IRQ stack memory (calculated at run-time) */
  75. .globl IRQ_STACK_START
  76. IRQ_STACK_START:
  77.     .word    0x0badc0de

  78. /* IRQ stack memory (calculated at run-time) */
  79. .globl FIQ_STACK_START
  80. FIQ_STACK_START:
  81.     .word 0x0badc0de
  82. #endif


  83. /*
  84.  * the actual reset code
  85.  */

  86. reset:
  87.     /*
  88.      * set the cpu to SVC32 mode 设置CPU成SVC32模式
  89.      */
  90.     mrs    r0,cpsr
  91.     bic    r0,r0,#0x1f
  92.     orr    r0,r0,#0xd3
  93.     msr    cpsr,r0

  94. #if defined(CONFIG_S3C2443) ||defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416)
  95.     /*
  96.      * Retention IO power will be turen off whel sleep mode,
  97.      * but, when wakeup process starts, User should write '1'
  98.      * produce power on retention IO. PM check
  99.      */
  100.     ldr    r0, =0x4c00006c
  101.     ldr    r1, =0x4c000064
  102.     ldr    r2, [r0]
  103.     tst     r2, #0x8

  104.     ldreq    r2, [r1]
  105.     orreq    r2, r2, #0x10000 /* (1<<16) */
  106.     streq    r2, [r1]
  107. #endif

  108.     /*
  109.      * we do sys-critical inits only at reboot,
  110.      * not when booting from ram!
  111.      */
  112. cpu_init_crit:
  113.     /*
  114.      * flush v4 I/D caches 刷新I/D caches
  115.      */
  116.     mov    r0, #0
  117.     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
  118.     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */

  119.     /*
  120.      * disable MMU stuff and caches 关闭MMU和caches
  121.      */
  122.     mrc    p15, 0, r0, c1, c0, 0
  123.     bic    r0, r0, #0x00002300    /* clear bits 13, 9:8 (--V- --RS) */
  124.     bic    r0, r0, #0x00000087    /* clear bits 7, 2:0 (B--- -CAM) */
  125.     orr    r0, r0, #0x00000002    /* set bit 2 (A) Align */
  126.     orr    r0, r0, #0x00001000    /* set bit 12 (I) I-Cache */
  127.     mcr    p15, 0, r0, c1, c0, 0

  128. #ifdef CONFIG_ONENAND
  129.     /*
  130.      * With this check, we can change boot sequence as we want in run-time.
  131.      * XXX: must modify to use "swp" not "ldr and str".
  132.      */
  133. check_onenand_boot:
  134.     mov    r0, #0x1e400    /* check OneNAND via start buffer reg */
  135.     ldr    r1, =0xfffffffe    /* very tweaky and may occur bugs */
  136.     ldr    r2, =0x00000f02
  137.     ldr    r3, [r0]
  138.     str    r1, [r0]
  139.     ldr    r1, [r0]
  140.     str    r3, [r0]
  141.     cmp    r1, r2
  142.     bne    1024f

  143.     /* OneNAND is detected as boot device
  144.      * So, load <0x400 ~ 0xc00> to DataRam0
  145.      */
  146. fill_onenand_dr:
  147.     mov    r2, #0
  148.     ldr    r3, =0x0001e200
  149.     ldr    r5, =0x0002    /* 0x400 ~ 0x800 */
  150.     ldr    r6, =0x0001e400
  151.     ldr    r7, =0x0802    /* fill 1KB in DR0 */

  152. 100:    strh    r2, [r3]    /* block = 0, data buffer = 0 */
  153.     strh    r2, [r3, #0x2]    /* block = 0, data buffer = 0 */
  154.     strh    r5, [r3, #0xe]    /* set page, sector addr */
  155.     strh    r7, [r6]    /* set start buffer and count */
  156.     strh    r2, [r6, #0x82]    /* reset int status */
  157.     strh    r2, [r6, #0x40]    /* send LOAD command */
  158. 1:    ldrh    r8, [r6, #0x82]    /* check int status */
  159.     tst    r8, #(1<<15)
  160.     beq    1b
  161.     tst    r5, #4;
  162.     ldr    r5, =0x0004    /* 0x800 ~ 0xc00 */
  163.     add    r7, r7, #0x0200    /* fill next 1KB 0x0a02 */
  164.     beq    100b
  165.     b    1024f

  166.     .ltorg            /* without it, variables may go too far. */

  167. 1024:
  168. #endif

  169.     /*
  170.      * Go setup Memory and board specific bits prior to relocation.
  171.      */
  172.     bl    lowlevel_init    /* go setup pll,mux,memory 这个lowlevel_init函数在board/samsung/smdk2440/lowlevel_init.S中*/

  173. #ifdef CONFIG_S3C2442
  174. #ifdef CONFIG_PM
  175.     @ Check if this is a wake-up from sleep
  176.     ldr r1, PMST_ADDR
  177.     ldr r0, [r1]
  178.     tst r0, #0x2 @ PMST_SMR
  179.     bne WakeupStart
  180. #endif
  181. #endif
  182.     /* when we already run in ram, we don't need to relocate U-Boot.
  183.      * and actually, memory controller must be configured before U-Boot
  184.      * is running in ram.
  185.      */
  186. check_boot_device:
  187.     ldr    r0, =0xff000fff
  188.     bic    r1, pc, r0        /* r0 <- current base addr of code */
  189.     ldr    r2, _TEXT_BASE        /* r1 <- original base addr in ram */
  190.     bic    r2, r2, r0        /* r0 <- current base addr of code */
  191.     cmp r1, r2 /* compare r0, r1 */
  192.     beq after_copy        /* r0 == r1 then skip flash copy */

  193. #ifdef CONFIG_BOOT_MOVINAND
  194.     ldr    sp, _TEXT_PHY_BASE
  195.     bl    movi_bl2_copy
  196.     b    after_copy
  197. #endif

  198.     /* check boot device is nand or nor 复制NAND FLASH中的BL到内存中 */
  199.     ldr    r0, =0x00000000
  200.     ldr    r3, [r0]
  201.     ldr    r1, =0xfffffffe
  202.     str    r1, [r0]

  203.     ldr    r2, [r0]
  204.     str    r3, [r0]
  205.     cmp    r1, r2

  206. #if defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416)

  207. /* Now iROM on 2450 is not support eFuse */
  208. #if 1
  209.     b    nand_copy
  210. #else
  211.     beq    nand_copy
  212. #endif

  213. #else
  214.     beq    nand_copy
  215. #endif

  216. #ifdef CONFIG_ONENAND
  217.     ldr    r3, [r0, #0x400]
  218.     ldr    r1, =0xfffffffe
  219.     str    r1, [r0, #0x400]

  220.     ldr    r2, [r0, #0x400]
  221.     str    r3, [r0, #0x400]
  222.     cmp    r1, r2
  223.     beq    jump_to_onenand
  224. #endif

  225.     /* nor copy */
  226. relocate:                /* relocate U-Boot to RAM     */
  227.     adr    r0, _start        /* r0 <- current position of code */
  228. @    ldr    r1, _TEXT_BASE
  229.     ldr    r1, _TEXT_PHY_BASE    /* r1 <- destination */

  230.     ldr    r2, _armboot_start
  231.     ldr    r3, _bss_start
  232.     sub    r2, r3, r2        /* r2 <- size of armboot */
  233.     add    r2, r0, r2        /* r2 <- source end address */

  234. copy_loop:
  235.     ldmia     {r3-r10}        /* copy from source address [r0] */
  236.     stmia     {r3-r10}        /* copy to target address [r1] */
  237.     cmp    r0, r2            /* until source end addreee [r2] */
  238.     ble    copy_loop
  239.     b    after_copy

  240. nand_copy:
  241.     mov    r0, #0x1000
  242.     bl    copy_from_nand

  243. #ifdef CONFIG_ONENAND
  244.     b    after_copy

  245. jump_to_onenand:
  246.     bl    temp_copy_onenand
  247. onenand_copy:
  248.     mov    r0, #0x400
  249.     bl    copy_from_nand
  250. #endif

  251. after_copy:
  252. #ifdef CONFIG_ENABLE_MMU
  253. enable_mmu:
  254.     /* enable domain access */
  255.     ldr    r5, =0x0000ffff
  256.     mcr    p15, 0, r5, c3, c0, 0        @ load domain access register

  257.     /* Set the TTB register */
  258.     ldr    r0, _mmu_table_base
  259.     ldr    r1, =CFG_PHY_UBOOT_BASE
  260.     ldr    r2, =0xfff00000
  261.     bic    r0, r0, r2
  262.     orr    r1, r0, r1
  263.     mcr    p15, 0, r1, c2, c0, 0

  264.     /* Enable the MMU */
  265. mmu_on:
  266.     mrc    p15, 0, r0, c1, c0, 0
  267.     orr    r0, r0, #1            /* Set CR_M to enable MMU */
  268.     mcr    p15, 0, r0, c1, c0, 0
  269.     nop
  270.     nop
  271.     nop
  272.     nop
  273. #endif

  274.     /* Set up the stack      设置堆栈                   */
  275. stack_setup:
  276. #ifdef CONFIG_MEMORY_UPPER_CODE
  277.     ldr    sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
  278. #else
  279.     ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot */
  280.     sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area */
  281.     sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
  282. #ifdef CONFIG_USE_IRQ
  283.     sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
  284. #endif
  285.     sub    sp, r0, #12        /* leave 3 words for abort-stack */

  286. #endif
  287.                               清除BSS段
  288. clear_bss:
  289.     ldr    r0, _bss_start        /* find start of bss segment */
  290.     ldr    r1, _bss_end        /* stop here */
  291.     mov     r2, #0x00000000        /* clear */

  292. clbss_l:str    r2, [r0]        /* clear loop... */
  293.     add    r0, r0, #4
  294.     cmp    r0, r1
  295.     ble    clbss_l

  296.     ldr    pc, _start_armboot

  297. _start_armboot:
  298.     .word start_armboot

  299. #ifdef CONFIG_ENABLE_MMU
  300. _mmu_table_base:
  301.     .word mmu_table
  302. #endif

  303. #ifdef CONFIG_ONENAND
  304. temp_copy_onenand:
  305.     adr    r0, _start        /* r0 <- current position of code */
  306.     ldr    r1, _TEXT_PHY_BASE    /* test if we run from flash or RAM */
  307.     ldr    r2, =0xbff

  308. 1:    ldmia     {r3-r10}        /* copy from source address [r0] */
  309.     stmia     {r3-r10}        /* copy to target address [r1] */
  310.     cmp    r0, r2            /* until source end addreee [r2] */
  311.     ble    1b

  312.     adr    r0, onenand_copy
  313.     ldr    r1, _TEXT_PHY_BASE
  314.     add    r0, r0, r1
  315.     mov    pc, r0

  316.     .ltorg
  317. #endif

  318. /*
  319.  * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
  320.  * r0: size to be compared
  321.  */
  322.     .globl copy_from_nand
  323. copy_from_nand:
  324.     mov    r10, lr        /* save return address */

  325.     mov    r9, r0
  326.     /* get ready to call C functions */
  327.     ldr    sp, _TEXT_PHY_BASE    /* setup temp stack pointer */
  328.     sub    sp, sp, #12
  329.     mov    fp, #0            /* no previous frame, so fp=0 */

  330. #ifdef CONFIG_ONENAND
  331.     cmp    r9, #0x1000
  332.     bne    2f
  333.     bl    copy_uboot_to_ram
  334.     b    3f
  335. 2:    bl    onenand_cp
  336. #else
  337.     mov    r9, #0x1000
  338.     bl    copy_uboot_to_ram
  339. #endif
  340. 3:    tst     r0, #0x0
  341.     bne    copy_failed

  342. #if defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416)

  343. /* Confirm Booting Status NAND Booting or iROM NAND*/

  344.     ldr    r6, =0x40008000
  345.     ldr    r7, =0x24564236
  346.     swp    r8, r7, [r6]
  347.     swp    r5, r8, [r6]
  348.     cmp    r7, r5

  349. /* If compare value is same between r7 and r5, Booting Device is iROM */

  350.     beq    444f

  351.     mov    r0, #0        /* NAND Booting */
  352.     b    555f
  353. 444:
  354.     mov    r0, #0x40000000    /* iROM booting */

  355. #else
  356.     mov    r0, #0

  357. #endif

  358. 555:
  359.     ldr    r1, _TEXT_PHY_BASE
  360. 1:    ldr    r3, [r0], #4
  361.     ldr    r4, [r1], #4
  362.     teq    r3, r4
  363.     bne    compare_failed    /* not matched */
  364.     subs    r9, r9, #4
  365.     bne    1b

  366. 4:    mov    lr, r10        /* all is OK */
  367.     mov    pc, lr

  368. copy_failed:
  369.     nop            /* copy from nand failed */
  370.     b    copy_failed
  371. compare_failed:
  372.     nop            /* compare failed */
  373.     b    compare_failed

  374. /*
  375.  * we assume that cache operation is done before. (eg. cleanup_before_linux())
  376.  * actually, we don
3.第二阶段的初始化
由上面代码可得知,代码初始化后跳转到了内存中。即void start_armboot(void)中了。

  1. void start_armboot (void)
  2. {
  3.     init_fnc_t **init_fnc_ptr;
  4.     char *s;
  5. #ifndef CFG_NO_FLASH
  6.     ulong size;
  7. #endif

  8. #if defined(CONFIG_VFD) || defined(CONFIG_LCD)
  9.     unsigned long addr;
  10. #endif

  11. #if defined(CONFIG_BOOT_MOVINAND)
  12.     uint *magic = (uint *) (PHYS_SDRAM_1);
  13. #endif

  14.     /* Pointer is writable since we allocated a register for it */
  15. #ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
  16.     ulong gd_base;

  17.     gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);
  18. #ifdef CONFIG_USE_IRQ
  19.     gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
  20. #endif
  21.     gd = (gd_t*)gd_base;
  22. #else
  23.     gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
  24. #endif

  25.     /* compiler optimization barrier needed for GCC >= 3.4 */
  26.     __asm__ __volatile__("": : :"memory");

  27.     memset ((void*)gd, 0, sizeof (gd_t));
  28.     gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
  29.     memset (gd->bd, 0, sizeof (bd_t));

  30.     monitor_flash_len = _bss_start - _armboot_start;
  31.     /* for循环调用一个指针数组 ,初始化了串口(在指针数组中) */
  32.     for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
  33.         if ((*init_fnc_ptr)() != 0) {
  34.             hang ();
  35.         }
  36.     }

  37. #ifndef CFG_NO_FLASH
  38.     /* configure available FLASH banks */
  39.     size = flash_init ();
  40.     display_flash_config (size);
  41. #endif /* CFG_NO_FLASH */

  42. #ifdef CONFIG_VFD
  43. #    ifndef PAGE_SIZE
  44. #     define PAGE_SIZE 4096
  45. #    endif
  46.     /*
  47.      * reserve memory for VFD display (always full pages)
  48.      */
  49.     /* bss_end is defined in the board-specific linker script */
  50.     addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
  51.     size = vfd_setmem (addr);
  52.     gd->fb_base = addr;
  53. #endif /* CONFIG_VFD */

  54. #ifdef CONFIG_LCD
  55. #    ifndef PAGE_SIZE
  56. #     define PAGE_SIZE 4096
  57. #    endif
  58.     /*
  59.      * reserve memory for LCD display (always full pages)
  60.      */
  61.     /* bss_end is defined in the board-specific linker script */
  62. #ifdef LCD_FRAMEBUFFER_ADDR
  63.     addr = (void*)LCD_FRAMEBUFFER_ADDR;
  64. #else
  65.     addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
  66. #endif
  67.         /* 进行了LCD的初始化 */
  68.     size = lcd_setmem (addr);
  69.     gd->fb_base = addr;
  70. #endif /* CONFIG_LCD */

  71.     /* armboot_start is defined in the board-specific linker script */
  72. #ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
  73.     mem_malloc_init (CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE);
  74. #else
  75.     mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
  76. #endif

  77. #if defined(CONFIG_SMDK6400) || defined(CONFIG_SMDK6410) || defined(CONFIG_SMDK6430) || defined(CONFIG_SMDK2450) || defined(CONFIG_SMDK2416)

  78. #if defined(CONFIG_NAND)

  79. #ifdef FORLINX_DEBUG
  80.            printf("NandFlash Information:\n");
  81. #else
  82.            puts ("NAND: ");
  83. #endif

  84.     nand_init();        /* go init the NAND */
  85. #endif

  86. #if defined(CONFIG_ONENAND)
  87.     puts ("OneNAND: ");
  88.     onenand_init();        /* go init the One-NAND */
  89. #endif

  90. #if defined(CONFIG_BOOT_MOVINAND)
  91.     puts ("SD/MMC: ");

  92.     if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) {
  93.         printf("Boot up for burning\n");
  94.     } else {
  95.         movi_set_capacity();
  96.         movi_set_ofs(MOVI_TOTAL_BLKCNT);
  97.         movi_init();
  98.     }
  99. #endif

  100. #else

  101. #if (CONFIG_COMMANDS & CFG_CMD_NAND)
  102.     puts ("NAND: ");
  103.     nand_init();        /* go init the NAND */
  104. #endif

  105. #endif

  106. #ifdef CONFIG_HAS_DATAFLASH
  107.     AT91F_DataflashInit();
  108.     dataflash_print_info();
  109. #endif

  110.     /* initialize environment */
  111.     env_relocate ();
  112.     
  113. #ifdef CONFIG_VFD
  114.     /* must do this after the framebuffer is allocated */
  115.     drv_vfd_init();
  116. #endif /* CONFIG_VFD */

  117.     /* IP Address */
  118.     gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

  119.     /* MAC Address */
  120.     {
  121.         int i;
  122.         ulong reg;
  123.         char *s, *e;
  124.         char tmp[64];

  125.         i = getenv_r ("ethaddr", tmp, sizeof (tmp));
  126.         s = (i > 0) ? tmp : NULL;

  127.         for (reg = 0; reg < 6; ++reg) {
  128.             gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
  129.             if (s)
  130.                 s = (*e) ? e + 1 : e;
  131.         }

  132. #ifdef CONFIG_HAS_ETH1
  133.         i = getenv_r ("eth1addr", tmp, sizeof (tmp));
  134.         s = (i > 0) ? tmp : NULL;

  135.         for (reg = 0; reg < 6; ++reg) {
  136.             gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
  137.             if (s)
  138.                 s = (*e) ? e + 1 : e;
  139.         }
  140. #endif
  141.     }

  142.     devices_init ();    /* get the devices list going. */

  143. #ifdef CONFIG_CMC_PU2
  144.     load_sernum_ethaddr ();
  145. #endif /* CONFIG_CMC_PU2 */

  146.     jumptable_init ();

  147.     console_init_r ();    /* fully init console as a device */

  148. #if defined(CONFIG_MISC_INIT_R)
  149.     /* miscellaneous platform dependent initialisations */
  150.     misc_init_r ();
  151. #endif

  152.     /* enable exceptions */
  153.     enable_interrupts ();

  154.     /* Perform network card initialisation if necessary */
  155. #ifdef CONFIG_DRIVER_CS8900
  156.     //cs8900_get_enetaddr (gd->bd->bi_enetaddr);
  157. #endif

  158. #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
  159.     if (getenv ("ethaddr")) {
  160.         smc_set_mac_addr(gd->bd->bi_enetaddr);
  161.     }
  162. #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */

  163.     /* Initialize from environment */
  164.     if ((s = getenv ("loadaddr")) != NULL) {
  165.         load_addr = simple_strtoul (s, NULL, 16);
  166.     }
  167. #if (CONFIG_COMMANDS & CFG_CMD_NET)
  168.     if ((s = getenv ("bootfile")) != NULL) {
  169.         copy_filename (BootFile, s, sizeof (BootFile));
  170.     }
  171. #endif    /* CFG_CMD_NET */

  172. #ifdef BOARD_LATE_INIT
  173.     board_late_init ();
  174. #endif
  175. #if (CONFIG_COMMANDS & CFG_CMD_NET)
  176. #if defined(CONFIG_NET_MULTI)
  177.     puts ("Net: ");
  178. #endif
  179.       /* 初始化网卡 */
  180.     eth_initialize(gd->bd);
  181. #endif
  182.       /* 初始化LED */
  183.     led_init(); /*led all off --forlinx add */

  184.     /* main_loop() can return to retry autoboot, if so just run it again. 执行用户输入的命令*/
  185.     for (;;) {
  186.         main_loop ();
  187.     }

  188.     /* NOTREACHED - no way out of command loop except booting */
  189. }

  190. void hang (void)
  191. {
  192.     puts ("### ERROR ### Please RESET the board ###\n");
  193.     for (;;);
  194. }

  195. #ifdef CONFIG_MODEM_SUPPORT
  196. static inline void mdm_readline(char *buf, int bufsiz);

  197. /* called from main loop (common/main.c) */
  198. extern void dbg(const char *fmt, ...);
  199. int mdm_init (void)
  200. {
  201.     char env_str[16];
  202.     char *init_str;
  203.     int i;
  204.     extern char console_buffer[];
  205.     extern void enable_putc(void);
  206.     extern int hwflow_onoff(int);

  207.     enable_putc(); /* enable serial_putc() */

  208. #ifdef CONFIG_HWFLOW
  209.     init_str = getenv("mdm_flow_control");
  210.     if (init_str && (strcmp(init_str, "rts/cts") == 0))
  211.         hwflow_onoff (1);
  212.     else
  213.         hwflow_onoff(-1);
  214. #endif

  215.     for (i = 1;;i++) {
  216.         sprintf(env_str, "mdm_init%d", i);
  217.         if ((init_str = getenv(env_str)) != NULL) {
  218.             serial_puts(init_str);
  219.             serial_puts("\n");
  220.             for(;;) {
  221.                 mdm_readline(console_buffer, CFG_CBSIZE);
  222.                 dbg("ini%d: [%s]", i, console_buffer);

  223.                 if ((strcmp(console_buffer, "OK") == 0) ||
  224.                     (strcmp(console_buffer, "ERROR") == 0)) {
  225.                     dbg("ini%d: cmd done", i);
  226.                     break;
  227.                 } else /* in case we are originating call ... */
  228.                     if (strncmp(console_buffer, "CONNECT", 7) == 0) {
  229.                         dbg("ini%d: connect", i);
  230.                         return 0;
  231.                     }
  232.             }
  233.         } else
  234.             break; /* no init string - stop modem init */

  235.         udelay(100000);
  236.     }

  237.     udelay(100000);

  238.     /* final stage - wait for connect */
  239.     for(;i > 1;) { /* if 'i' > 1 - wait for connection
  240.                  message from modem */
  241.         mdm_readline(console_buffer, CFG_CBSIZE);
  242.         dbg("ini_f: [%s]", console_buffer);
  243.         if (strncmp(console_buffer, "CONNECT", 7) == 0) {
  244.             dbg("ini_f: connected");
  245.             return 0;
  246.         }
  247.     }

  248.     return 0;
  249. }

  250. /* 'inline' - We have to do it fast */
  251. static inline void mdm_readline(char *buf, int bufsiz)
  252. {
  253.     char c;
  254.     char *p;
  255.     int n;

  256.     n = 0;
  257.     p = buf;
  258.     for(;;) {
  259.         c = serial_getc();

  260.         /*        dbg("(%c)", c); */

  261.         switch(c) {
  262.         case '\r':
  263.             break;
  264.         case '\n':
  265.             *p = '\0';
  266.             return;

  267.         default:
  268.             if(n++ > bufsiz) {
  269.                 *p = '\0';
  270.                 return; /* sanity check */
  271.             }
  272.             *p = c;
  273.             p++;
  274.             break;
  275.         }
  276.     }
  277. }
  278. #endif    /* CONFIG_MODEM_SUPPORT */






阅读(491) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~