4. BootLoader第二阶段
vivi Bootloader的第二阶段又分成了八个小阶段,在main函数中别离调用这几个小阶段的相关函数:
int main(int argc, char *argv[]) { int ret; /* reset_handler(); /* /* /* /* /* Step 5: /* Step 6: /* Step 7: init_builtin_cmds(); /* Step 8: return 0; |
STEP1的putstr(vivi_banner)句子在串口输出一段字符阐明vivi的版别、作者等信息,vivi_banner界说为:
const char *vivi_banner = “VIVI version ” VIVI_RELEASE ” (” VIVI_COMPILE_BY “@” VIVI_COMPILE_HOST “) (” VIVI_COMPILER “) ” UTS_VERSION “\r\n”; |
reset_handler进行相应的复位处理:
void reset_handler(void) { int pressed; pressed = is_pressed_pw_btn(); if (pressed == PWBT_PRESS_LEVEL) { |
hard_reset_handle会clear内存,而软件复位处理则什么都不做:
static void hard_reset_handle(void) { clear_mem((unsigned long)USER_RAM_BASE, (unsigned long)USER_RAM_SIZE); } |
STEP2进行板初始化,设置时刻和可编程I/O口:
int board_init(void) { init_time(); set_gpios(); return 0; |
STEP3进行内存映射及MMU初始化:
void mem_map_init(void) { #ifdef CONFIG_S3C2410_NAND_BOOT mem_map_nand_boot(); #else mem_map_nor(); #endif cache_clean_invalidate(); tlb_invalidate(); } |
S3C2410A的MMU初始化只需要调用通用的arm920 MMU初始化函数:
static inline void arm920_setup(void) { unsigned long ttb = MMU_TABLE_BASE; __asm__( |
STEP4设置仓库;STEP5进行mtd设备的初始化,记载MTD分区信息;STEP6设置私有数据;STEP7初始化内建指令。
STEP8发动一个SHELL,等候用户输出指令并进行相应处理。在SHELL退出的情况下,发动操作系统:
#define DEFAULT_BOOT_DELAY 0x30000000 void boot_or_vivi(void) { char c; int ret; ulong boot_delay; boot_delay = get_param_value(“boot_delay”, &ret); /* return; |
SHELL中读取用户从串口输出的指令字符串,履行该指令:
void vivi_shell(void) { #ifdef CONFIG_SERIAL_TERM serial_term(); #else #error there is no terminal. #endif } void serial_term(void) { char cmd_buf[MAX_CMDBUF_SIZE]; for (;;) { getcmd(cmd_buf, MAX_CMDBUF_SIZE); /* execute a user command */ |
5.电路板调试
在电路板的调试过程中,咱们首要要在ADT新建的工程中增加第一阶段的汇编代码head.S文件,修正Link脚本,将代码和数据映射到S3C2410A自带的0x40000000开端的4KB内存空间内:
SECTIONS { . = 0x40000000; .text : { *(.text) } Image_RO_Limit = .; Image_RW_Base = .; .data : { *(.data) } .rodata : { *(.rodata) } Image_ZI_Base = .; .bss : { *(.bss) } Image_ZI_Limit = .; __bss_start__ = .; __bss_end__ = .; __EH_FRAME_BEGIN__ = .; __EH_FRAME_END__ = .; PROVIDE (__stack = .); end = .; _end = .; .debug_info 0 : { *(.debug_info) } .debug_line 0 : { *(.debug_line) } .debug_abbrev 0 : { *(.debug_abbrev)} .debug_frame 0 : { *(.debug_frame) } } |
凭借万用表、示波器等仪器仪表,调通SDRAM,并将vivi中自带的串口、NAND FLASH驱动增加到工程中,调试经过板上的串口和FLASH。假如板电路的原理与三星公司DEMO板有距离,则vivi中硬件的操作要进行相应的修正。 悉数调试经往后,修正vivi源代码,从头编译vivi,将其烧录入NAND FLASH就可以在复位后发动这个Bootloader了。
调试板上的新增硬件时,宜在ADT中增加相应的代码,在不加载操作系统的情况下,单纯地操作这些硬件。假如电路板规划有误,要进行飞线和割线等处理。
6.小结
本章讲解了ARM汇编、Bootloader的功用,Bootloader的调试环境及ARM电路板的调试办法。