U - boot 분석 과 이식 (3) - U - boot stage 2 분석.
void startarmboot (void) 함수, 곧 두 개의 중요 한 데이터 구조 gd 가 나타 납 니 다.t 와 bdt
1、gd_t : global data 데이터 구조 정의, 파일 에 있 음 include/asm-arm/global_data.h.그 구성원 들 은 주로 전역 적 인 시스템 초기 화 매개 변수 이다.
1. typedef struct global_data {
2. bd_t *bd; // struct board_info<span style="font-family: ;"> , </span>
3. unsigned long flags; // <span style="font-family: ;"> , </span>
4. unsigned long baudrate;
5. unsigned long have_console; /* serial_init() was called */
6. unsigned long reloc_off; /* Relocation Offset */
7. unsigned long env_addr; /* Address of Environment struct */
8. unsigned long env_valid; /* Checksum of Environment valid? */
9. unsigned long fb_base; /* base address of frame buffer */
10. #ifdef CONFIG_VFD
11. unsigned char vfd_type; /* display type */
12. #endif
13. #if 0
14. unsigned long cpu_clk; /* CPU clock in Hz! */
15. unsigned long bus_clk;
16. unsigned long ram_size; /* RAM size */
17. unsigned long reset_status; /* reset status register at boot */
18. #endif
19. void **jt; /* jump table */
20. } gd_t;
2.、bd_t :board info
에 자리잡다,...
include/asm-arm/u-boot.h
.판 자 를 저장 합 니 다.
1. typedef struct bd_info {
2. int bi_baudrate; /* serial console baudrate */
3. unsigned long bi_ip_addr; /* IP Address */
4. unsigned char bi_enetaddr[6]; /* Ethernet adress */
5. struct environment_s *bi_env;
6. ulong bi_arch_number; /* unique id for this board <span style="font- family: ;"> </span><span style="font- family:Times New Roman;">ID</span><span style="font-family: ;"> </span>*/
7. ulong bi_boot_params; /* where this board expects params */
8. struct /* RAM configuration */
9. {
10. ulong start;
11. ulong size;
12. } bi_dram[CONFIG_NR_DRAM_BANKS];
13. #ifdef CONFIG_HAS_ETH1
14. /* second onboard ethernet port */
15. unsigned char bi_enet1addr[6];
16. #endif
17. } bd_t;
전역 데 이 터 를 저장 할 영역 을 할당 합 니 다. 주 소 는 포인터 gd 입 니 다.
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
0 을 정리 하고 공간 을 분배 합 니 다.
memset ((void*)gd, 0, sizeof (gd_t));
gd 앞 자리 에서 gd -> bd 할당 주소
1. gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));0 을 정리 하고 공간 을 분배 합 니 다.
memset (gd->bd, 0, sizeof (bd_t));
memset (gd->bd, 0, sizeof (bd_t));
일련의 초기 화 함수 실행
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
hang ();
}
for (init_fnc_ptr = init_sequence; *init_fnc_ptr;++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } }
함수 포인터 가 가리 키 는 함수 반환 값 이 0 이 아니라면 hang () 에서 순환 을 멈 추고 초기 화 에 실패 합 니 다.
void hang (void)
puts ("### ERROR ### Please RESET the board ###");
}
void hang (void) { puts ("### ERROR ### Please RESET the board ###"); for (;;); }
함수 목록 은 다음 과 같 습 니 다.
초기 화 함수 마다 정상 적 인 상황 에서 반환 값 은 0 입 니 다.
# init_fnc_t *init_sequence[] = {
# cpu_init, /* irq/fiq */
# board_init, /* */
# interrupt_init, /* */
# env_init, /* flash */
# init_baudrate, /* */
# serial_init, /* */
# console_init_f, /* */
# display_banner, /* say that we are here */
이 어 NOR FLASH, LCD, 직렬 포트, 콘 솔, sd 카드, 네트워크 카드 등 을 초기 화하 고 일일이 열거 하지 않 았 다.
드디어 중요 한 순간 이 왔 다 -- #
순환
[cpp] view plain copy print ?
for (;;)
main_loop ();
for (;;) { main_loop (); }
계속 추적
bootdelay 시간 내 에 키 를 누 르 고 명령 행 에 들 어 가 는 것 을 발견 하고 run command 로 명령 을 해석 합 니 다.
1. #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
2. s = getenv ("bootdelay");
3. bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
4.
5. debug ("### main_loop entered: bootdelay=%d
", bootdelay);
CONFIG BOOTDELAY 가 정의 되 었 다 면 s 로 환경 변수 bootdelay 를 얻 은 다음 마지막 으로 커 널 을 시작 합 니 다.
1. #ifdef CONFIG_BOOTCOUNT_LIMIT
2. if (bootlimit && (bootcount > bootlimit)) {
3. printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.
",
4. (unsigned)bootlimit);
5. s = getenv ("altbootcmd");
6. }
7. else
8. #endif /* CONFIG_BOOTCOUNT_LIMIT */
9. s = getenv ("bootcmd");
CONFIG BOOTCOUNT LIMIT 는 U - boot 시작 횟수 를 설정 하 는 제한 입 니 다.
마지막 s = getenv ("bootcmd"); 시작 매개 변 수 를 가 져 옵 니 다.
[cpp] view plain copy print ?
run_command (s, 0);
run_command (s, 0);
시작 명령 해석 run command 함수 에서 최종 실행 명령
[cpp] view plain copy print ?
/* OK - call function to do the command */
rc = -1;
/* OK - call function to do the command */if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) { rc = -1; }
이것 은 명령 구조 체 입 니 다. 원형 은 다음 과 같 습 니 다.
[cpp] view plain copy print ?
struct cmd_tbl_s {
int maxargs; /* 최대 매개 변수 개수 */
int (*cmd)(struct cmd_tbl_s *, int, int, char *[];/* 대응 하 는 함수 포인터 */
struct cmd tbl s {char * name;/* Command Name */int maxargs;/* 최대 매개 변수 개수 */int repeatable;/* 명령 중복 가능 여부 */int (* cmd) (struct cmd tbl s *, int, int, char * []);/* 대응 하 는 함수 포인터 */char * usage;/* Usage message (short) */
정상 적 인 상황 에서 U BOOT CMD 명령 을 실행 합 니 다. U BOOT CMD 매크로 는 명령 을 정의 합 니 다. 명령 매크로 의 원형 은 다음 과 같 습 니 다.
[cpp] view plain copy print ?
/* 명령 매크로 U BOOT CMD */
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}
/* 명령 매크로 U BOOT CMD */\# define U BOOT CMD (name, maxargs, rep, cmd, usage, help)\cmd tbl t u boot cmd\#\# name Struct Section = {\# name, maxargs, rep, cmd, usage, help}
만약 위 에 들 어 오 는 것 이 bootm 명령 이 커 널 을 시작 하 는 것 이 라면 해당 하 는 것 을 호출 할 것 입 니 다.
U BOOT CMD 의 do bootm 함수
[cpp] view plain copy print ?
U_BOOT_CMD(
"bootm - boot application image from memory",
"\tpassing arguments 'arg ...'; when booting a Linux kernel,"
U_BOOT_CMD( bootm, CFG_MAXARGS, 1, do_bootm, "bootm - boot application image from memory", "[addr [arg ...]] - boot application image stored in memory""\tpassing arguments 'arg ...'; when booting a Linux kernel,""\t'arg' can be the address of an initrd image"
do bootm 함수 에 서 는 switch case 로 커 널 zImage 형식, 압축 해제 방식, 운영 체제 등 을 검사 합 니 다. zImage 는 자체 적 으로 압축 을 풀 지 않 아 도 되 기 때 문 입 니 다.
[cpp] view plain copy print ?
switch (hdr->ih_os) {
case IH_OS_LINUX:
do_bootm_linux (cmdtp, flag, argc, argv,
break;
switch (hdr->ih_os) { default:/* handled by (original) Linux case */case IH_OS_LINUX: do_bootm_linux (cmdtp, flag, argc, argv, addr, len_ptr, verify); break;
마지막 으로 Armlinux. c 에 들 어 가 는 do bootm linux 함수 가 리 눅 스 커 널 U Boot 를 시작 하 는 것 도 태그 목록 을 통 해 커 널 에 파 라 메 터 를 전달 하 는 것 입 니 다.
[cpp] view plain copy print ?
#ifdef CONFIG_CMDLINE_TAG
#endif
#ifdef CONFIG_CMDLINE_TAG char *commandline = getenv ("bootargs"); #endif
CONFIG CMDLINE TAG 는 smdk2410. h 에서 정의 되 었 습 니 다.
theKernel 은 커 널 에 저 장 된 주 소 를 가리 키 고 있 습 니 다. (ARM 구조의 CPU 는 보통 0x 30008000)
/* 커 널 의 입구 함수 포인터 */
[cpp] view plain copy print ?
void (*theKernel)(int zero, int arch, uint params);
void (*theKernel)(int zero, int arch, uint params);
/* 커 널 입구 주 소 를 theKernel 에 할당 하고 hdr 는 image header t 구조 체 로 uImage 머리 를 가리 키 며 ih ep 는 커 널 의 입구 점 (Entry Point) */
[cpp] view plain copy print ?
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
/* 마지막 으로 커 널 입구 함수 호출 입 니 다. bd -> bi arch number 는 이 판 넬 기계 유형 ID 입 니 다. bd -> bi boot params 는 커 널 에 전 달 된 매개 변수 입 니 다. 태그 목록 주소 부터 */
[cpp] view plain copy print ?
theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
[cpp] view plain copy print ?
Linux 커 널 의 작 동 을 유도 하 는 데 필요 한 몇 가지 조건:
1. * CPU register settings // theKernel
2. o r0 = 0.
3. o r1 = machine type number.
4. o r2 = physical address of tagged list in system RAM.
5. * CPU mode
6. o All forms of interrupts must be disabled (IRQs and FIQs.)
7. o The CPU must be in SVC mode. (A special exception exists for Angel.)
8. * Caches, MMUs
9. o The MMU must be off.
10. o Instruction cache may be on or off.
11. o Data cache must be off and must not contain any stale data.
12. * Devices
13. o DMA to/from devices should be quiesced.
14. * The boot loader is expected to call the kernel image by jumping directly to the first instruction of the kernel image.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.