Uboot 분석

34459 단어
@lib_arm/board.c
start_armboot 이 함수 의 기능 은 일련의 함 수 를 실행 하여 바 텀 하드웨어 를 초기 화 하 는 것 입 니 다. 가장 중요 한 초기 화 는 메모리 초기 화 입 니 다.
u - boot 의 gdt 와 bdt 데이터 구조 소개 bdt: 이 구조 체 는 board info 의 줄 임 말로 판 자 를 저장 하 는 정보 gd 입 니 다.t: 이 구조 체 는 global data 의 줄 임 말로 전체 데 이 터 를 저장 하 는 정보 bdt 와 gdt 는 u - boot 에서 두 가지 중요 한 데이터 구조 로 초기 화 작업 은 이 두 데이터 구조 로 저장 하거나 전달 해 야 합 니 다.bd_t. include / asm - arm / u - boot. h 에서 gd 를 정의 합 니 다.t include / asm - arm / globaldata. h 에서 bd 정의t: board info 데이터 구조 정 의 는 주로 판 자 를 저장 하 는 데 사 용 됩 니 다.
1、bd_t: board info 데이터 구조 정 의 는 주로 판 자 를 저장 하 는 데 사 용 됩 니 다.typedef struct bd_info {int bi baudrate; / * serial console baudrate 직렬 단말기 포트 율 * / unsigned long bi ip addr; / * IP Address IP 주소 * / ulong bi arch number; / * unique id for this board 개발 판 ID 이 변 수 는 모든 개발 판 과 관련 된 ID 를 표시 합 니 다. 이 값 은 내부 핵 에 전 달 됩 니 다. 이 매개 변수 가 커 널 설정 과 다 르 면 커 널 시작 압축 해제 가 완료 되면 나 옵 니 다.현재 "Error: a" 오류 가 발생 했 습 니 다. 개발 판 ID 는 커 널 arch / arm / tools / mach - types 에서 볼 수 있 습 니 다 * /
ulong bi boot params; / * where this board expects params u - boot 가 커 널 에 전달 하 는 매개 변수 저장 주소 * / struct / * RAM configuration 메모리 의 시작 주소 및 크기 * / {ulong start; ulong size;} bi dram [CONFIG NR DRAM BANKS];} bd t;
2. gd t: global data 데이터 구조 정의, 그 구성원 은 주로 전역 적 인 시스템 초기 화 매개 변수 입 니 다. gd t 를 사용 할 때 매크로 정의 로 설명 해 야 합 니 다. \ # define DECLARE GLOBAL DATA PTR register volatile gd t * gd asm ("r8") 은 레지스터 R8 을 사용 하여 컴 파일 러 가 r8 을 다른 변수 에 배분 하 는 것 을 피 할 수 있 습 니 다. typedef struct global data{bd t * bd; / / 판 과 관련 된 구 조 는 unsigned long flags 와 같 습 니 다. / / 지시 표지, 예 를 들 어 장치 가 표지 등 unsigned long baudrate 를 초기 화 했 습 니 다. / / 직렬 포트 포트 율 unsigned long have console; / * serial init ()was called * / / 직렬 포트 초기 화 플래그 \ # ifdef CONFIG PRE CONSOLE BUFFER / / 매크로 가 정의 되 지 않 은 long precon buf idx;ed long fb base; / * base address of frame buffer * / / frame buffer 기본 주소 \ # ifdef CONFIG FSL ESDHC / / 매크로 는 판 관련 헤더 파일 에 unsigned long sdhc clk 를 정의 하지 않 았 습 니 다. \ # endif \ # ifdef CONFIG AT91FAMILY / 매크로 는 판 관련 헤더 파일 에 정의 되 지 않 았 습 니 다 / * "static data"at 91 의 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 / / 매크로 정의 되 지 않 음 / * "정적 데이터"needed by most of timer. c on ARM platforms * / unsigned long timer rate hz; unsigned long tbl; unsigned long tbu; unsigned long timer reset value; unsigned long lastinc; \ # endif \ # ifdef CONFIG IXP 425 / / 宏 이 보드 관련 헤더 파일 에 서명 되 지 않 은 긴 타임 스탬프 를 정의 하지 않 았 습 니 다. \ # endif 서명 되 지 않 은 긴 재배 치; / * RAM 에서 U - Boot 의 시작 주소 * / / u - boot메모리 로 옮 긴 후 시작 주소 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 ICACHE OFF) & defined (CONFIG SYS DCACHE OFF))/ / 매크로 가 지정 되 지 않 은 긴 tlb addr; \ # endif const void * fdt blob; / * 우리 의 장치 트 리, NULL if none * / void * jt; / * jump table * / char env buf [32]; / getenv () 에 대한 버퍼 를 다시 시작 하기 전에. * / \ # if defined (CONFIG POST) | | defined (CONFIG LOGBUFFER)/ / 매크로 가 지정 되 지 않 은 긴 post log word; / * POST 액 티 비 티 기록 * / 서명 되 지 않 은 긴 post log res; / * POST 테스트 성공 * / 서명 되 지 않 은 긴 post init f time; / * post init f 가 시 작 된 경우 * / \ # endif} gd t;
/*
void start armboot (void) {init fnc t * * init fnc ptr; char * s; \ # if defined (CONFIG VFD) | defined (CONFIG LCD) / / 이 조건 이 성립 되 지 않 습 니 다. 아래 코드 는 unsigned long addr 를 실행 하지 않 습 니 다. \ # endif
/* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)); /* 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));
gd->flags |= GD_FLG_RELOC;
monitor_flash_len = _bss_start - _armboot_start;
for (init fnc ptr = init sequence; * init fnc ptr; + init fnc ptr) {if ((* init fnc ptr) ()! = 0) {hang ();} @ 이것 은 함수 의 초기 화 순환 입 니 다. 순환 함수 로 일련의 함 수 를 실행 합 니 다}
/ * armboot start is defined in the board - specific linker script * / mem malloc init ( armboot start - CONFIG SYS MALLOC LEN, CONFIG SYS MALLOC LEN); / / malloc 와 env 의 메모리 초기 화 \ # ifndef CONFIG SYS NO FLASH / 조건 이 성립 되 지 않 으 며 다음 코드 는 실행 되 지 않 습 니 다.
@ include / configs / smdkc 100. h 에서 정의 하 는 매크로 는 1 \ # define CONFIG SYS NO FLASH 1 / * configure available FLASH banks * / display flash config (flash init (); \ # endif / * CONFIG SYS 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); vfd setmem (addr); gd->fb_base = addr; #endif /* CONFIG_VFD */
\ # ifdef CONFIG LCD / 매크로 가 정의 되 지 않 았 습 니 다. 아래 코드 는 실행 되 지 않 습 니 다. / * board init may have inited fb base * / if (! gd - > fb base) {\ # 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 * / addr = ( bss end + (PAGE SIZE - 1) & (PAGE SIZE - 1); lcd_setmem (addr); gd->fb_base = addr; } #endif /* CONFIG_LCD */
\ # if defined (CONFIG CMD NAND) / / 이 매크로 는 정의 되 지 않 고 조건 이 성립 되 지 않 으 며 뒤의 코드 는 puts ("NAND:") 를 실행 하지 않 습 니 다. nand init (); / * go init the NAND * / \ # endif
\ # if defined (CONFIG CMD ONENAND) / / 이 매크로 는 다음 코드 로 onenand init () 를 실행 할 수 있 습 니 다. \ # 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 * /
\ # ifdef CONFIG SERIAL MULTI / / 이 매크로 는 다음 코드 는 serial initialize () 를 실행 할 수 있 습 니 다. \ # endif
/* IP Address */ gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
stdio_init (); /* get the devices list going. */
jumptable_init ();
\ # if defined (CONFIG API) / / 매크로 가 정의 되 지 않 았 습 니 다. 조건 이 성립 되 지 않 습 니 다. / * API 초기 화 * / api init (); \ # endif
console_init_r (); /* fully init console as a device */
\ # if defined (CONFIG ARCH MISC INIT) / / 조건 이 성립 되 지 않 습 니 다. 아래 코드 는 실행 되 지 않 습 니 다. / * miscellaneous arch dependent initialisations * / arch misc init (); \ # endif \ # if defined (CONFIG MISC INIT R) / 조건 이 성립 되 지 않 습 니 다. 아래 코드 는 성립 되 지 않 습 니 다. / * miscellaneous platform dependent initialisations * / misc init r (); \ # endif defined
/* enable exceptions */ enable_interrupts ();
* / / \ # ifdef CONFIG DRIVER TI EMAC / / 매크로 가 정의 되 지 않 고 조건 이 성립 되 지 않 는 경우 네트워크 카드 초기 화 를 수행 합 니 다. / * XXX: 이 작업 은 보드 초기 로 이동 해 야 합 니 다 * / / / / \ # ifdef CONFIG DRIVER TI EMAC / / / 매크로 가 정의 되 지 않 고 조건 이 성립 되 지 않 습 니 다. / * XXX: 이 작업 을 실행 하려 면 다음 을 실행 해 야 합 니 다. * / / / / / / / / / / / # ifdef CONFIG DRIVER DRIVER MAC MAC addr (const u int8 t * addr); if ("ethenv (" ethaddr ")) {uchar enetaddr [6]; eth r); } #endif
\ # if defined (CONFIG DRIVER SMC 91111) | | define(CONFIG DRIVER LAN91C 96) / / / 매크로 가 정의 되 지 않 고, 아래 코드 가 실행 되 지 않 습 니 다 / * XXX: this needs to be movto board init * / if (getenv ("ethaddr") {uchar enetaddr [6]; eth getenv enetaddr ("ethaddr", enetaddr); smc set mac addr (enetaddr);} \ # # endif / * CONFIG DRIVER SMC 91111 | | CONFIG DRIVER DRIVER SMC 91111 SMC 91111 SMC 91111) | | | 정 의 를 정의 (CONFIG DRIVG DRIVER LAN91C 96 * /
/ * Initialize from environment * / if (s = getenv ("loaddr")! = NULL) {load addr = simple strtoul (s, NULL, 16);} \ # if defined (CONFIG CMD NET) / / 매크로 가 정의 되 지 않 았 고 뒤의 코드 는 if ((s = getenv ("bootfile") 를 실행 하지 않 습 니 다! = NULL) {copy filename (BootFile, s, size of (BootFile);} \ # endif
\ # ifdef BOARD LATE INIT / / 매크로 가 정의 되 지 않 고 코드 가 board late init () 를 실행 하지 않 습 니 다. \ # endif
\ # ifdef CONFIG GENERIC MMC / / 매크로 가 정의 되 지 않 고 코드 가 puts ("MMC:") 를 실행 하지 않 습 니 다. mmc initialize (gd - > bd); \ # endif
\ # ifdef CONFIG BITBANGMII / / 매크로 가 정의 되 지 않 았 습 니 다. 코드 가 bb miiphy init () 를 실행 하지 않 습 니 다.; \ # endif \ (CONFIG CMD NET) / / / 매크로 정의 가 정의 되 지 않 았 습 니 다. 코드 가 실행 되 지 않 습 니 다 \ # if defined (CONFIG NET MULTI) puts ("Net:"); \ # # endif eth initialize (gd- > bd); eth init (gd - > bd); \ # # if def정의 (CONFIG RESET PHY R) 디버그 ("Reset Ethernet PHY"); reset php php php php php y (); \ # endif \ # endif / * 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 ###"); for (;;); }
*********************************************************************************************************
u - boot 에서 typedef 응용 해석 init fnc t * init sequence []       
********************************************************************************************************* /* init_fnc_t * , int 。
*/

typedef int (init_fnc_t) (void);
/*init_sequence , init_fnc_t */
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
dram_init, /* configure available RAM banks */
display_dram_config,
#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2)
checkboard,
#endif
NULL,
};

/*init_fnc_ptr */
init_fnc_t **init_fnc_ptr;
/*init_fnc_ptr init_sequence , NULL */
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {/*(*init_fnc_ptr)() C */
hang ();
}
}

스스로 test 프로그램 을 2 개 썼 습 니 다.
type: def int (test fnc t) (void);
type: def int (* test fnc t) (void);#include<stdio.h>

int test0 (void);
int test1 (void);

typedef int (*test_fnc_t) (void);

test_fnc_t test_sequence[] = {
test0,
test1,
NULL,
};


//int _tmain(int argc, _TCHAR* argv[])

int main()
{
test_fnc_t *test_fnc_ptr;

for (test_fnc_ptr = test_sequence; *test_fnc_ptr; ++test_fnc_ptr) {
if ((*test_fnc_ptr)() != 0) {
printf("error here!");
}
}

return 0;
}

int test0 (void)
{
printf("test0
"
);
return 0;
}

int test1 (void)
{
printf("test1
"
);
return 0;
}
#include<stdio.h>

int test0 (void);
int test1 (void);


typedef int (test_fnc_t) (void);

test_fnc_t *test_sequence[] = {
test0,
test1,
NULL,
};


//int _tmain(int argc, _TCHAR* argv[])

int main()
{
test_fnc_t **test_fnc_ptr;

for (test_fnc_ptr = test_sequence; *test_fnc_ptr; ++test_fnc_ptr) {
if ((*test_fnc_ptr)() != 0) {
printf("error here!");
}
}

return 0;
}

int test0 (void)
{
printf("test0
"
);
return 0;
}

int test1 (void)
{
printf("test1
"
);
return 0;
}

좋은 웹페이지 즐겨찾기