一、
Bootloader设计蓝图
1.1 Bootloader的作用
助推器->通过火箭运送航天飞机。
1.2 设计方法
-模仿
行业老大->uboot。通过模仿uboot的代码,来进行学习。
1.3 U-Boot简介
U-Boot是用于多种嵌入式
CPU(
MIPS、
x86、
ARM等)的
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
-
smdk2440_config : unconfig
-
@$(MKCONFIG) $(@:_config=) arm s3c24xx smdk2440 samsung s3c2440
vim config.mk中有这个,因为链接器中起始是0x00000000,但是这里TEXT_BASE设置为了30008000.从而编译出来的程序,通过反汇编得知起始地址是从TEXT_BASE开始的。所以这个优先于连接器脚本中的。
-
LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
在board/samsun/smdk2440/uboot.lds(uboot的连接器脚本)
-
/*
-
* (C) Copyright 2005-2006
-
* Seung-Chull, Suh Samsung Electronics <sc.suh@samsung.com>
-
*
-
* Derived from sources by DENX Software Engineering.
-
*
-
* See file CREDITS for list of people who contributed to this
-
* project.
-
*
-
* This program is free software; you can redistribute it and/or
-
* modify it under the terms of the GNU General Public License as
-
* published by the Free Software Foundation; either version 2 of
-
* the License, or (at your option) any later version.
-
*
-
* This program is distributed in the hope that it will be useful,
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-
* GNU General Public License for more details.
-
*
-
* You should have received a copy of the GNU General Public License
-
* along with this program; if not, write to the Free Software
-
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-
* MA 02111-1307 USA
-
*/
-
-
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-
OUTPUT_ARCH(arm)
-
ENTRY(_start) 此处标明起始入口_start
-
SECTIONS
-
{
-
. = 0x00000000;
-
. = ALIGN(4);
-
.text :
-
{
-
cpu/s3c24xx/start.o (.text) 这里是最开始执行的文件位置,可能是start.c或者star.S
-
cpu/s3c24xx/s3c2440/cpu_init.o (.text)
-
*(.text)
-
}
-
. = ALIGN(4);
-
.rodata : { *(.rodata) }
-
. = ALIGN(4);
-
.data : { *(.data) }
-
. = ALIGN(4);
-
.got : { *(.got) }
-
-
. = .;
-
__u_boot_cmd_start = .;
-
.u_boot_cmd : { *(.u_boot_cmd) }
-
__u_boot_cmd_end = .;
-
-
. = ALIGN(4);
-
.mmudata : { *(.mmudata) }
-
-
. = ALIGN(4);
-
__bss_start = .;
-
.bss : { *(.bss) }
-
_end = .;
-
}
在cpu/s3c24xx/start.S中。有一个_start就是
程序的入口了。
-
#include <asm/proc/domain.h>
-
#endif
-
-
#ifndef CONFIG_ENABLE_MMU
-
#ifndef CFG_PHY_UBOOT_BASE
-
#define CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE
-
#endif
-
#endif
-
-
-
/*
-
*************************************************************************
-
*
-
* Jump vector table as in table 3.1 in [1]
-
*
-
*************************************************************************
-
*/设置中断向量表,从reset开始
-
-
-
.globl _start
-
_start:
-
b reset
-
ldr pc, _undefined_instruction
-
ldr pc, _software_interrupt
-
ldr pc, _prefetch_abort
-
ldr pc, _data_abort
-
ldr pc, _not_used
-
ldr pc, _irq
-
ldr pc, _fiq
-
-
_undefined_instruction:
-
.word undefined_instruction
-
_software_interrupt:
-
.word software_interrupt
-
_prefetch_abort:
-
.word prefetch_abort
-
_data_abort:
-
.word data_abort
-
_not_used:
-
.word not_used
-
_irq:
-
.word irq
-
_fiq:
-
.word fiq
-
-
.balignl 16,0xdeadbeef
-
-
-
/*
-
*************************************************************************
-
*
-
* Startup Code (reset vector)
-
*
-
* do important init only if we don't start from memory!
-
* setup Memory and board specific bits prior to relocation.
-
* relocate armboot to ram
-
* setup stack
-
*
-
*************************************************************************
-
*/
-
-
_TEXT_BASE:
-
.word TEXT_BASE
-
-
/*
-
* Below variable is very important because we use MMU in U-Boot.
-
* Without it, we cannot run code correctly before MMU is ON.
-
* by scsuh.
-
*/
-
_TEXT_PHY_BASE:
-
.word CFG_PHY_UBOOT_BASE
-
-
.globl _armboot_start
-
_armboot_start:
-
.word _start
-
-
/*
-
* These are defined in the board-specific linker script.
-
*/
-
.globl _bss_start
-
_bss_start:
-
.word __bss_start
-
-
.globl _bss_end
-
_bss_end:
-
.word _end
-
-
#ifdef CONFIG_USE_IRQ
-
/* IRQ stack memory (calculated at run-time) */
-
.globl IRQ_STACK_START
-
IRQ_STACK_START:
-
.word 0x0badc0de
-
-
/* IRQ stack memory (calculated at run-time) */
-
.globl FIQ_STACK_START
-
FIQ_STACK_START:
-
.word 0x0badc0de
-
#endif
-
-
-
/*
-
* the actual reset code
-
*/
-
-
reset:
-
/*
-
* set the cpu to SVC32 mode 设置CPU成SVC32模式
-
*/
-
mrs r0,cpsr
-
bic r0,r0,#0x1f
-
orr r0,r0,#0xd3
-
msr cpsr,r0
-
-
#if defined(CONFIG_S3C2443) ||defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416)
-
/*
-
* Retention IO power will be turen off whel sleep mode,
-
* but, when wakeup process starts, User should write '1'
-
* produce power on retention IO. PM check
-
*/
-
ldr r0, =0x4c00006c
-
ldr r1, =0x4c000064
-
ldr r2, [r0]
-
tst r2, #0x8
-
-
ldreq r2, [r1]
-
orreq r2, r2, #0x10000 /* (1<<16) */
-
streq r2, [r1]
-
#endif
-
-
/*
-
* we do sys-critical inits only at reboot,
-
* not when booting from ram!
-
*/
-
cpu_init_crit:
-
/*
-
* flush v4 I/D caches 刷新I/D caches
-
*/
-
mov r0, #0
-
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
-
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
-
-
/*
-
* disable MMU stuff and caches 关闭MMU和caches
-
*/
-
mrc p15, 0, r0, c1, c0, 0
-
bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */
-
bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */
-
orr r0, r0, #0x00000002 /* set bit 2 (A) Align */
-
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
-
mcr p15, 0, r0, c1, c0, 0
-
-
#ifdef CONFIG_ONENAND
-
/*
-
* With this check, we can change boot sequence as we want in run-time.
-
* XXX: must modify to use "swp" not "ldr and str".
-
*/
-
check_onenand_boot:
-
mov r0, #0x1e400 /* check OneNAND via start buffer reg */
-
ldr r1, =0xfffffffe /* very tweaky and may occur bugs */
-
ldr r2, =0x00000f02
-
ldr r3, [r0]
-
str r1, [r0]
-
ldr r1, [r0]
-
str r3, [r0]
-
cmp r1, r2
-
bne 1024f
-
-
/* OneNAND is detected as boot device
-
* So, load <0x400 ~ 0xc00> to DataRam0
-
*/
-
fill_onenand_dr:
-
mov r2, #0
-
ldr r3, =0x0001e200
-
ldr r5, =0x0002 /* 0x400 ~ 0x800 */
-
ldr r6, =0x0001e400
-
ldr r7, =0x0802 /* fill 1KB in DR0 */
-
-
100: strh r2, [r3] /* block = 0, data buffer = 0 */
-
strh r2, [r3, #0x2] /* block = 0, data buffer = 0 */
-
strh r5, [r3, #0xe] /* set page, sector addr */
-
strh r7, [r6] /* set start buffer and count */
-
strh r2, [r6, #0x82] /* reset int status */
-
strh r2, [r6, #0x40] /* send LOAD command */
-
1: ldrh r8, [r6, #0x82] /* check int status */
-
tst r8, #(1<<15)
-
beq 1b
-
tst r5, #4;
-
ldr r5, =0x0004 /* 0x800 ~ 0xc00 */
-
add r7, r7, #0x0200 /* fill next 1KB 0x0a02 */
-
beq 100b
-
b 1024f
-
-
.ltorg /* without it, variables may go too far. */
-
-
1024:
-
#endif
-
-
/*
-
* Go setup Memory and board specific bits prior to relocation.
-
*/
-
bl lowlevel_init /* go setup pll,mux,memory 这个lowlevel_init函数在board/samsung/smdk2440/lowlevel_init.S中*/
-
-
#ifdef CONFIG_S3C2442
-
#ifdef CONFIG_PM
-
@ Check if this is a wake-up from sleep
-
ldr r1, PMST_ADDR
-
ldr r0, [r1]
-
tst r0, #0x2 @ PMST_SMR
-
bne WakeupStart
-
#endif
-
#endif
-
/* when we already run in ram, we don't need to relocate U-Boot.
-
* and actually, memory controller must be configured before U-Boot
-
* is running in ram.
-
*/
-
check_boot_device:
-
ldr r0, =0xff000fff
-
bic r1, pc, r0 /* r0 <- current base addr of code */
-
ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */
-
bic r2, r2, r0 /* r0 <- current base addr of code */
-
cmp r1, r2 /* compare r0, r1 */
-
beq after_copy /* r0 == r1 then skip flash copy */
-
-
#ifdef CONFIG_BOOT_MOVINAND
-
ldr sp, _TEXT_PHY_BASE
-
bl movi_bl2_copy
-
b after_copy
-
#endif
-
-
/* check boot device is nand or nor 复制NAND FLASH中的BL到内存中 */
-
ldr r0, =0x00000000
-
ldr r3, [r0]
-
ldr r1, =0xfffffffe
-
str r1, [r0]
-
-
ldr r2, [r0]
-
str r3, [r0]
-
cmp r1, r2
-
-
#if defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416)
-
-
/* Now iROM on 2450 is not support eFuse */
-
#if 1
-
b nand_copy
-
#else
-
beq nand_copy
-
#endif
-
-
#else
-
beq nand_copy
-
#endif
-
-
#ifdef CONFIG_ONENAND
-
ldr r3, [r0, #0x400]
-
ldr r1, =0xfffffffe
-
str r1, [r0, #0x400]
-
-
ldr r2, [r0, #0x400]
-
str r3, [r0, #0x400]
-
cmp r1, r2
-
beq jump_to_onenand
-
#endif
-
-
/* nor copy */
-
relocate: /* relocate U-Boot to RAM */
-
adr r0, _start /* r0 <- current position of code */
-
@ ldr r1, _TEXT_BASE
-
ldr r1, _TEXT_PHY_BASE /* r1 <- destination */
-
-
ldr r2, _armboot_start
-
ldr r3, _bss_start
-
sub r2, r3, r2 /* r2 <- size of armboot */
-
add r2, r0, r2 /* r2 <- source end address */
-
-
copy_loop:
-
ldmia {r3-r10} /* copy from source address [r0] */
-
stmia {r3-r10} /* copy to target address [r1] */
-
cmp r0, r2 /* until source end addreee [r2] */
-
ble copy_loop
-
b after_copy
-
-
nand_copy:
-
mov r0, #0x1000
-
bl copy_from_nand
-
-
#ifdef CONFIG_ONENAND
-
b after_copy
-
-
jump_to_onenand:
-
bl temp_copy_onenand
-
onenand_copy:
-
mov r0, #0x400
-
bl copy_from_nand
-
#endif
-
-
after_copy:
-
#ifdef CONFIG_ENABLE_MMU
-
enable_mmu:
-
/* enable domain access */
-
ldr r5, =0x0000ffff
-
mcr p15, 0, r5, c3, c0, 0 @ load domain access register
-
-
/* Set the TTB register */
-
ldr r0, _mmu_table_base
-
ldr r1, =CFG_PHY_UBOOT_BASE
-
ldr r2, =0xfff00000
-
bic r0, r0, r2
-
orr r1, r0, r1
-
mcr p15, 0, r1, c2, c0, 0
-
-
/* Enable the MMU */
-
mmu_on:
-
mrc p15, 0, r0, c1, c0, 0
-
orr r0, r0, #1 /* Set CR_M to enable MMU */
-
mcr p15, 0, r0, c1, c0, 0
-
nop
-
nop
-
nop
-
nop
-
#endif
-
-
/* Set up the stack 设置堆栈 */
-
stack_setup:
-
#ifdef CONFIG_MEMORY_UPPER_CODE
-
ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
-
#else
-
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
-
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
-
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
-
#ifdef CONFIG_USE_IRQ
-
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
-
#endif
-
sub sp, r0, #12 /* leave 3 words for abort-stack */
-
-
#endif
-
清除BSS段
-
clear_bss:
-
ldr r0, _bss_start /* find start of bss segment */
-
ldr r1, _bss_end /* stop here */
-
mov r2, #0x00000000 /* clear */
-
-
clbss_l:str r2, [r0] /* clear loop... */
-
add r0, r0, #4
-
cmp r0, r1
-
ble clbss_l
-
-
ldr pc, _start_armboot
-
-
_start_armboot:
-
.word start_armboot
-
-
#ifdef CONFIG_ENABLE_MMU
-
_mmu_table_base:
-
.word mmu_table
-
#endif
-
-
#ifdef CONFIG_ONENAND
-
temp_copy_onenand:
-
adr r0, _start /* r0 <- current position of code */
-
ldr r1, _TEXT_PHY_BASE /* test if we run from flash or RAM */
-
ldr r2, =0xbff
-
-
1: ldmia {r3-r10} /* copy from source address [r0] */
-
stmia {r3-r10} /* copy to target address [r1] */
-
cmp r0, r2 /* until source end addreee [r2] */
-
ble 1b
-
-
adr r0, onenand_copy
-
ldr r1, _TEXT_PHY_BASE
-
add r0, r0, r1
-
mov pc, r0
-
-
.ltorg
-
#endif
-
-
/*
-
* copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
-
* r0: size to be compared
-
*/
-
.globl copy_from_nand
-
copy_from_nand:
-
mov r10, lr /* save return address */
-
-
mov r9, r0
-
/* get ready to call C functions */
-
ldr sp, _TEXT_PHY_BASE /* setup temp stack pointer */
-
sub sp, sp, #12
-
mov fp, #0 /* no previous frame, so fp=0 */
-
-
#ifdef CONFIG_ONENAND
-
cmp r9, #0x1000
-
bne 2f
-
bl copy_uboot_to_ram
-
b 3f
-
2: bl onenand_cp
-
#else
-
mov r9, #0x1000
-
bl copy_uboot_to_ram
-
#endif
-
3: tst r0, #0x0
-
bne copy_failed
-
-
#if defined(CONFIG_S3C2450) || defined(CONFIG_S3C2416)
-
-
/* Confirm Booting Status NAND Booting or iROM NAND*/
-
-
ldr r6, =0x40008000
-
ldr r7, =0x24564236
-
swp r8, r7, [r6]
-
swp r5, r8, [r6]
-
cmp r7, r5
-
-
/* If compare value is same between r7 and r5, Booting Device is iROM */
-
-
beq 444f
-
-
mov r0, #0 /* NAND Booting */
-
b 555f
-
444:
-
mov r0, #0x40000000 /* iROM booting */
-
-
#else
-
mov r0, #0
-
-
#endif
-
-
555:
-
ldr r1, _TEXT_PHY_BASE
-
1: ldr r3, [r0], #4
-
ldr r4, [r1], #4
-
teq r3, r4
-
bne compare_failed /* not matched */
-
subs r9, r9, #4
-
bne 1b
-
-
4: mov lr, r10 /* all is OK */
-
mov pc, lr
-
-
copy_failed:
-
nop /* copy from nand failed */
-
b copy_failed
-
compare_failed:
-
nop /* compare failed */
-
b compare_failed
-
-
/*
-
* we assume that cache operation is done before. (eg. cleanup_before_linux())
-
* actually, we don
3.第二阶段的初始化
由上面代码可得知,代码初始化后跳转到了内存中。即void start_armboot(void)中了。
-
void start_armboot (void)
-
{
-
init_fnc_t **init_fnc_ptr;
-
char *s;
-
#ifndef CFG_NO_FLASH
-
ulong size;
-
#endif
-
-
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
-
unsigned long addr;
-
#endif
-
-
#if defined(CONFIG_BOOT_MOVINAND)
-
uint *magic = (uint *) (PHYS_SDRAM_1);
-
#endif
-
-
/* Pointer is writable since we allocated a register for it */
-
#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
-
ulong gd_base;
-
-
gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);
-
#ifdef CONFIG_USE_IRQ
-
gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
-
#endif
-
gd = (gd_t*)gd_base;
-
#else
-
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
-
#endif
-
-
/* compiler optimization barrier needed for GCC >= 3.4 */
-
__asm__ __volatile__("": : :"memory");
-
-
memset ((void*)gd, 0, sizeof (gd_t));
-
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
-
memset (gd->bd, 0, sizeof (bd_t));
-
-
monitor_flash_len = _bss_start - _armboot_start;
-
/* for循环调用一个指针数组 ,初始化了串口(在指针数组中) */
-
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-
if ((*init_fnc_ptr)() != 0) {
-
hang ();
-
}
-
}
-
-
#ifndef CFG_NO_FLASH
-
/* configure available FLASH banks */
-
size = flash_init ();
-
display_flash_config (size);
-
#endif /* CFG_NO_FLASH */
-
-
#ifdef CONFIG_VFD
-
# ifndef PAGE_SIZE
-
# define PAGE_SIZE 4096
-
# endif
-
/*
-
* reserve memory for VFD display (always full pages)
-
*/
-
/* bss_end is defined in the board-specific linker script */
-
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
-
size = vfd_setmem (addr);
-
gd->fb_base = addr;
-
#endif /* CONFIG_VFD */
-
-
#ifdef CONFIG_LCD
-
# ifndef PAGE_SIZE
-
# define PAGE_SIZE 4096
-
# endif
-
/*
-
* reserve memory for LCD display (always full pages)
-
*/
-
/* bss_end is defined in the board-specific linker script */
-
#ifdef LCD_FRAMEBUFFER_ADDR
-
addr = (void*)LCD_FRAMEBUFFER_ADDR;
-
#else
-
addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
-
#endif
-
/* 进行了LCD的初始化 */
-
size = lcd_setmem (addr);
-
gd->fb_base = addr;
-
#endif /* CONFIG_LCD */
-
-
/* armboot_start is defined in the board-specific linker script */
-
#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
-
mem_malloc_init (CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE);
-
#else
-
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
-
#endif
-
-
#if defined(CONFIG_SMDK6400) || defined(CONFIG_SMDK6410) || defined(CONFIG_SMDK6430) || defined(CONFIG_SMDK2450) || defined(CONFIG_SMDK2416)
-
-
#if defined(CONFIG_NAND)
-
-
#ifdef FORLINX_DEBUG
-
printf("NandFlash Information:\n");
-
#else
-
puts ("NAND: ");
-
#endif
-
-
nand_init(); /* go init the NAND */
-
#endif
-
-
#if defined(CONFIG_ONENAND)
-
puts ("OneNAND: ");
-
onenand_init(); /* go init the One-NAND */
-
#endif
-
-
#if defined(CONFIG_BOOT_MOVINAND)
-
puts ("SD/MMC: ");
-
-
if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) {
-
printf("Boot up for burning\n");
-
} else {
-
movi_set_capacity();
-
movi_set_ofs(MOVI_TOTAL_BLKCNT);
-
movi_init();
-
}
-
#endif
-
-
#else
-
-
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
-
puts ("NAND: ");
-
nand_init(); /* go init the NAND */
-
#endif
-
-
#endif
-
-
#ifdef CONFIG_HAS_DATAFLASH
-
AT91F_DataflashInit();
-
dataflash_print_info();
-
#endif
-
-
/* initialize environment */
-
env_relocate ();
-
-
#ifdef CONFIG_VFD
-
/* must do this after the framebuffer is allocated */
-
drv_vfd_init();
-
#endif /* CONFIG_VFD */
-
-
/* IP Address */
-
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
-
-
/* MAC Address */
-
{
-
int i;
-
ulong reg;
-
char *s, *e;
-
char tmp[64];
-
-
i = getenv_r ("ethaddr", tmp, sizeof (tmp));
-
s = (i > 0) ? tmp : NULL;
-
-
for (reg = 0; reg < 6; ++reg) {
-
gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
-
if (s)
-
s = (*e) ? e + 1 : e;
-
}
-
-
#ifdef CONFIG_HAS_ETH1
-
i = getenv_r ("eth1addr", tmp, sizeof (tmp));
-
s = (i > 0) ? tmp : NULL;
-
-
for (reg = 0; reg < 6; ++reg) {
-
gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
-
if (s)
-
s = (*e) ? e + 1 : e;
-
}
-
#endif
-
}
-
-
devices_init (); /* get the devices list going. */
-
-
#ifdef CONFIG_CMC_PU2
-
load_sernum_ethaddr ();
-
#endif /* CONFIG_CMC_PU2 */
-
-
jumptable_init ();
-
-
console_init_r (); /* fully init console as a device */
-
-
#if defined(CONFIG_MISC_INIT_R)
-
/* miscellaneous platform dependent initialisations */
-
misc_init_r ();
-
#endif
-
-
/* enable exceptions */
-
enable_interrupts ();
-
-
/* Perform network card initialisation if necessary */
-
#ifdef CONFIG_DRIVER_CS8900
-
//cs8900_get_enetaddr (gd->bd->bi_enetaddr);
-
#endif
-
-
#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
-
if (getenv ("ethaddr")) {
-
smc_set_mac_addr(gd->bd->bi_enetaddr);
-
}
-
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
-
-
/* Initialize from environment */
-
if ((s = getenv ("loadaddr")) != NULL) {
-
load_addr = simple_strtoul (s, NULL, 16);
-
}
-
#if (CONFIG_COMMANDS & CFG_CMD_NET)
-
if ((s = getenv ("bootfile")) != NULL) {
-
copy_filename (BootFile, s, sizeof (BootFile));
-
}
-
#endif /* CFG_CMD_NET */
-
-
#ifdef BOARD_LATE_INIT
-
board_late_init ();
-
#endif
-
#if (CONFIG_COMMANDS & CFG_CMD_NET)
-
#if defined(CONFIG_NET_MULTI)
-
puts ("Net: ");
-
#endif
-
/* 初始化网卡 */
-
eth_initialize(gd->bd);
-
#endif
-
/* 初始化LED */
-
led_init(); /*led all off --forlinx add */
-
-
/* main_loop() can return to retry autoboot, if so just run it again. 执行用户输入的命令*/
-
for (;;) {
-
main_loop ();
-
}
-
-
/* NOTREACHED - no way out of command loop except booting */
-
}
-
-
void hang (void)
-
{
-
puts ("### ERROR ### Please RESET the board ###\n");
-
for (;;);
-
}
-
-
#ifdef CONFIG_MODEM_SUPPORT
-
static inline void mdm_readline(char *buf, int bufsiz);
-
-
/* called from main loop (common/main.c) */
-
extern void dbg(const char *fmt, ...);
-
int mdm_init (void)
-
{
-
char env_str[16];
-
char *init_str;
-
int i;
-
extern char console_buffer[];
-
extern void enable_putc(void);
-
extern int hwflow_onoff(int);
-
-
enable_putc(); /* enable serial_putc() */
-
-
#ifdef CONFIG_HWFLOW
-
init_str = getenv("mdm_flow_control");
-
if (init_str && (strcmp(init_str, "rts/cts") == 0))
-
hwflow_onoff (1);
-
else
-
hwflow_onoff(-1);
-
#endif
-
-
for (i = 1;;i++) {
-
sprintf(env_str, "mdm_init%d", i);
-
if ((init_str = getenv(env_str)) != NULL) {
-
serial_puts(init_str);
-
serial_puts("\n");
-
for(;;) {
-
mdm_readline(console_buffer, CFG_CBSIZE);
-
dbg("ini%d: [%s]", i, console_buffer);
-
-
if ((strcmp(console_buffer, "OK") == 0) ||
-
(strcmp(console_buffer, "ERROR") == 0)) {
-
dbg("ini%d: cmd done", i);
-
break;
-
} else /* in case we are originating call ... */
-
if (strncmp(console_buffer, "CONNECT", 7) == 0) {
-
dbg("ini%d: connect", i);
-
return 0;
-
}
-
}
-
} else
-
break; /* no init string - stop modem init */
-
-
udelay(100000);
-
}
-
-
udelay(100000);
-
-
/* final stage - wait for connect */
-
for(;i > 1;) { /* if 'i' > 1 - wait for connection
-
message from modem */
-
mdm_readline(console_buffer, CFG_CBSIZE);
-
dbg("ini_f: [%s]", console_buffer);
-
if (strncmp(console_buffer, "CONNECT", 7) == 0) {
-
dbg("ini_f: connected");
-
return 0;
-
}
-
}
-
-
return 0;
-
}
-
-
/* 'inline' - We have to do it fast */
-
static inline void mdm_readline(char *buf, int bufsiz)
-
{
-
char c;
-
char *p;
-
int n;
-
-
n = 0;
-
p = buf;
-
for(;;) {
-
c = serial_getc();
-
-
/* dbg("(%c)", c); */
-
-
switch(c) {
-
case '\r':
-
break;
-
case '\n':
-
*p = '\0';
-
return;
-
-
default:
-
if(n++ > bufsiz) {
-
*p = '\0';
-
return; /* sanity check */
-
}
-
*p = c;
-
p++;
-
break;
-
}
-
}
-
}
-
#endif /* CONFIG_MODEM_SUPPORT */
阅读(491) | 评论(0) | 转发(0) |