u - boot 2 단계 빗질 시작

u - boot 시작 2 단계 프로 세 스 정리:
이 단 계 는 주로 두 개의 핵심 함수 가 있 는데, 각각 board 이다.init_f () 와 boardinit_r (), 이 두 함 수 는 모두 arch \ arm \ Lib \ Board. c 에 있 습 니 다.1.board_init_f()
1) gd_t 데이터 구조 공간 분배 2) 초기 화 함수 3) gdt 데이터 구조 초기 화 
Global_data.h arch\arm\include\Asm
typedef struct global_data {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long have_console; /* serial_init() was called */
unsigned long env_addr; /* Address of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid? */
unsigned long fb_base; /* base address of frame buffer */
#ifdef CONFIG_VFD
unsigned char vfd_type; /* display type */
#endif
#ifdef CONFIG_FSL_ESDHC
unsigned long sdhc_clk;
#endif
#ifdef CONFIG_AT91FAMILY
/* "static data" needed by at91's clock.c */
unsigned long cpu_clk_rate_hz;
unsigned long main_clk_rate_hz;
unsigned long mck_rate_hz;
unsigned long plla_rate_hz;
unsigned long pllb_rate_hz;
unsigned long at91_pllb_usb_init;
#endif
#ifdef CONFIG_ARM
/* "static data" needed by most of timer.c on ARM platforms */
unsigned long timer_rate_hz;
unsigned long tbl;
unsigned long tbu;
unsigned long long timer_reset_value;
unsigned long lastinc;
#endif
unsigned long relocaddr; /* Start address of U-Boot in RAM */
phys_size_t ram_size; /* RAM size */
unsigned long mon_len; /* monitor len */
unsigned long irq_sp; /* irq stack pointer */
unsigned long start_addr_sp;/* start_addr_stackpointer */
unsigned long reloc_off;
#if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))
unsigned long tlb_addr;
#endif
void **jt; /* jump table */
char env_buf[32]; /* buffer for getenv() before reloc. */
} gd_t;

다음은 gd 지침 을 정의 하고 이 지침 을 r8 레지스터 에 저장 합 니 다. \ #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t * gd asm ("r8") 설명: register 를 통 해 레지스터 변 수 를 표시 하고, asm ("r8") 은 변 수 를 r8 레지스터 에 저장 합 니 다.4) relocate_code (U - boot 에서 코드 를 다시 정의 합 니 다. 즉, 자동 이동)
다음은 함수 boardinit_f 의 소스 코드 분석:
이 함수 가 u - boot 전역 의 포인터 gd 를 초기 화 하 였 으 며, 마지막 으로 relocate 를 호출 하 였 습 니 다.코드 함수 가 코드 를 다시 찾 습 니 다. u - boot 를 메모리 의 고급 주소 로 옮 깁 니 다. BSS 세그먼트 코드 를 지우 고 다시 찾 은 u - boot 코드 의 board 로 이동 합 니 다.init_r () 함수 가 실행 되 기 시작 합 니 다. 
//              。
typedef int (init_fnc_t)(void);//        
init_fnc_t *init_sequence[] = {
#if defined(CONFIG_ARCH_CPU_INIT)
arch_cpu_init, /* basic arch cpu dependent setup */
//Sys_info.c arch\arm\cpu\armv7\Exynos
#endif
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
timer_init, /* initialize timer */
//Timer.c arch\arm\cpu\armv7\S5p-common
#ifdef CONFIG_FSL_ESDHC
get_clocks,
#endif
env_init, /* initialize environment */
#if defined(CONFIG_S5P6450) && !defined(CONFIG_S5P6460_IP_TEST)
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
#endif
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
//Tiny4412.c board\samsung\Tiny4412 6617 2015-08-06
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
init_func_i2c,
#endif
dram_init, /* configure available RAM banks */
//Tiny4412.c board\samsung\Tiny4412 6617 2015-08-06
#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
arm_pci_init,
#endif
NULL,
};
//C     
void board_init_f(ulong bootflag)
{
bd_t *bd;
init_fnc_t **init_fnc_ptr;
gd_t *id;
ulong addr, addr_sp;
/* Pointer is writable since we allocated a register for it */
gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
memset((void*)gd, 0, sizeof (gd_t));
gd->mon_len = _bss_end_ofs;
//               ;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang();
}
}
debug ("monitor len: %08lX
", gd->mon_len); /* * Ram is setup, size stored in gd !! */ debug ("ramsize: %08lX
", gd->ram_size); #if defined(CONFIG_SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't * get "touched" at all by U-Boot. By fixing up gd->ram_size * the Linux kernel should now get passed the now "corrected" * memory size and won't touch it either. This should work * for arch/ppc and arch/powerpc. Only Linux board ports in * arch/powerpc with bootwrapper support, that recalculate the * memory size from the SDRAM controller setup will have to * get fixed. */ gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; #endif addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size; #ifdef CONFIG_LOGBUFFER #ifndef CONFIG_ALT_LB_ADDR /* reserve kernel log buffer */ addr -= (LOGBUFF_RESERVE); debug ("Reserving %dk for kernel logbuffer at %08lx
", LOGBUFF_LEN, addr); #endif #endif #ifdef CONFIG_PRAM /* * reserve protected RAM */ i = getenv_r("pram", (char *)tmp, sizeof (tmp)); reg = (i > 0) ? simple_strtoul((const char *)tmp, NULL, 10) : CONFIG_PRAM; addr -= (reg << 10); /* size is in kB */ debug ("Reserving %ldk for protected RAM at %08lx
", reg, addr); #endif /* CONFIG_PRAM */ #if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE)) /* reserve TLB table */ addr -= (4096 * 4); /* round down to next 64 kB limit */ addr &= ~(0x10000 - 1); gd->tlb_addr = addr; debug ("TLB table at: %08lx
", addr); #endif /* round down to next 4 kB limit */ addr &= ~(4096 - 1); debug ("Top of RAM usable for U-Boot at: %08lx
", addr); #ifdef CONFIG_VFD # ifndef PAGE_SIZE # define PAGE_SIZE 4096 # endif /* * reserve memory for VFD display (always full pages) */ addr -= vfd_setmem(addr); gd->fb_base = addr; #endif /* CONFIG_VFD */ #ifdef CONFIG_LCD /* reserve memory for LCD display (always full pages) */ addr = lcd_setmem(addr); gd->fb_base = addr; #endif /* CONFIG_LCD */ /* * reserve memory for U-Boot code, data & bss * round down to next 4 kB limit */ addr -= gd->mon_len; addr &= ~(4096 - 1); #if defined(CONFIG_S5P) || defined(CONFIG_S5P6450) addr = CONFIG_SYS_LOAD_ADDR; #endif debug ("Reserving %ldk for U-Boot at: %08lx
", gd->mon_len >> 10, addr); #ifndef CONFIG_PRELOADER /* * reserve memory for malloc() arena */ addr_sp = addr - TOTAL_MALLOC_LEN; debug ("Reserving %dk for malloc() at: %08lx
", TOTAL_MALLOC_LEN >> 10, addr_sp); /* * (permanently) allocate a Board Info struct * and a permanent copy of the "global" data */ addr_sp -= sizeof (bd_t); bd = (bd_t *) addr_sp; gd->bd = bd; debug ("Reserving %zu Bytes for Board Info at: %08lx
", sizeof (bd_t), addr_sp); addr_sp -= sizeof (gd_t); id = (gd_t *) addr_sp; debug ("Reserving %zu Bytes for Global Data at: %08lx
", sizeof (gd_t), addr_sp); /* setup stackpointer for exeptions */ gd->irq_sp = addr_sp; #ifdef CONFIG_USE_IRQ addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ); debug ("Reserving %zu Bytes for IRQ stack at: %08lx
", CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp); #endif /* leave 3 words for abort-stack */ addr_sp -= 3; /* 8-byte alignment for ABI compliance */ addr_sp &= ~0x07; #else addr_sp += 128; /* leave 32 words for abort-stack */ gd->irq_sp = addr_sp; #endif debug ("New Stack Pointer is: %08lx
", addr_sp); #ifdef CONFIG_POST post_bootmode_init(); post_run(NULL, POST_ROM | post_bootmode_get(0)); #endif gd->bd->bi_baudrate = gd->baudrate; /* Ram ist board specific, so move it to board code ... */ dram_init_banksize(); display_dram_config(); /* and display it */ gd->relocaddr = addr; gd->start_addr_sp = addr_sp; gd->reloc_off = addr - _TEXT_BASE; debug ("relocation Offset is: %08lx
", gd->reloc_off); memcpy(id, (void *)gd, sizeof (gd_t)); // , uboot , 1M // DDR , iRAM //start.S arch\arm\cpu\armv7 relocate_code(addr_sp, id, addr); /* NOTREACHED - relocate_code() does not return */ }

 relocate_코드 소스 분석
relocate_code 는 arch \ arm \ cpu \ armv 7 \ start. S 파일 에서 실 현 된 어 셈 블 리 함수 입 니 다.구체 적 인 작업 은 먼저 코드 를 DDR 고급 위치 로 옮 기 고 data 세그먼트, 0 BSS 세그먼트 를 옮 기 며 마지막 으로 점프 하여 다시 위 치 를 정 한 후 u - boot 코드 중의 boardinit_r 함수 가 실 행 됩 니 다. 전체 u - boot 의 시작 과정 을 완성 할 때 까지. 
/*------------------------------------------------------------------------------*/
/* board.c     board_init_f                   
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
*/
.globl relocate_code
relocate_code:
mov r4, r0 /* save addr_sp */
mov r5, r1 /* save addr of gd */
mov r6, r2 /* save addr of destination */
/* Set up the stack       */
stack_setup:
mov sp, r4
adr r0, _start
#if defined(CONFIG_S5PC110) && defined(CONFIG_EVT1) && !defined(CONFIG_FUSED)
sub r0, r0, #16
#endif
#ifndef CONFIG_PRELOADER //    
cmp r0, r6
beq clear_bss /* skip relocation */
#endif
mov r1, r6 /* r1 

2.board_init_r()
이 함 수 는 이전 단계 의 relocatecode 후 직접 호출 합 니 다. 이 함수 도 코드 를 다시 찾 은 후에 실 행 된 첫 번 째 C 언어 함수 입 니 다.1) 캐 시 2) 보드 초기 화 3) 직렬 초기 화 4) 외부 저장 초기 화 5) 환경 변수 초기 화 6) 콘 솔 초기 화 7) 중단 8) 이 더 넷 초기 화 9) main 진입loop (), 명령 을 기다 리 거나 커 널 을 자동 으로 불 러 오 거나 커 널 을 자동 으로 불 러 옵 니 다.

좋은 웹페이지 즐겨찾기