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 (), 명령 을 기다 리 거나 커 널 을 자동 으로 불 러 오 거나 커 널 을 자동 으로 불 러 옵 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
u - boot 2 단계 빗질 시작\ #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t * gd asm ("r8") 설명: register 를 통 해 레지스터 변 수 를 표시 하고, asm ("r8")...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.