博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
xloader启动流程
阅读量:4216 次
发布时间:2019-05-26

本文共 4861 字,大约阅读时间需要 16 分钟。

Xloader是在rom code和uboot之间的一个小的BootLoader,其启动分析如下:从下面lds文件中可以看到xloader的入口函数x-loader/board/omap1710h3/x-load.ldsOUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{	. = 0x00000000;	. = ALIGN(4);	.text	:	{	  cpu/arm926ejs/start.o	(.text)	  *(.text)	}	. = ALIGN(4);	.rodata : { *(.rodata) }	. = ALIGN(4);	.data : { *(.data) }	. = ALIGN(4);	.got : { *(.got) } 	. = ALIGN(4);	__bss_start = .;	.bss : { *(.bss) }	_end = .;}其中start.s的分析如下:入口函数首先执行resetreset:	/*	 * set the cpu to SVC32 mode	 */	mrs	r0,cpsr	bic	r0,r0,#0x1f	orr	r0,r0,#0xd3	msr	cpsr,r0  #关掉watchdog	/*	 * turn off the watchdog, unlock/diable sequence	 */	mov	r1, #0xF5	ldr	r0, =WDTIM_MODE	strh	r1, [r0]	mov	r1, #0xA0	strh	r1, [r0]	/*	 * mask all IRQs by setting all bits in the INTMR - default	 */	mov	r1, #0xffffffff	ldr	r0, =REG_IHL1_MIR	str	r1, [r0]	ldr	r0, =REG_IHL2_MIR	str	r1, [r0] 	/*	 * we do sys-critical inits at reboot, 	 */ 	bl	cpu_init_crit   	/* 	 * relocate exception vectors to SRAM where ROM code expects	 */#ifdef CFG_BOOT_CS0	adr	r0, _start		/* r0 <- current position of code   */ 	add     r0, r0, #4	/* skip reset vector			*/	mov	r2, #36		/* r2 <- size of data (8+1 words)            */	add	r2, r0, r2		/* r2 <- source end address         */	mov r1, #0x20000000next:	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */	cmp	r0, r2			/* until source end address [r2]    */	ble	next#endif #执行重定位relocate:				/* relocate X-Loader to RAM	    */	adr	r0, _start		/* r0 <- current position of code   */	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */	cmp     r0, r1                  /* don't reloc during debug         */	/*beq     stack_setup*/	ldr	r2, _armboot_start	ldr	r3, _bss_start	sub	r2, r3, r2		/* r2 <- size of armboot            */	add	r2, r0, r2		/* r2 <- source end address         */	/* Set up the stack						    */stack_setup:	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated X-Loader   */  	sub	sp, r0, #128		/* leave 32 words for abort-stack    */#清bssclear_bss:	ldr	r0, _bss_start		/* find start of bss segment        */	add	r0, r0, #4		/* start at first byte of bss       */	ldr	r1, _bss_end		/* stop here                        */	mov 	r2, #0x00000000		/* clear                            */clbss_l:str	r2, [r0]		/* clear loop...                    */	add	r0, r0, #4	cmp	r0, r1	bne	clbss_l#最终执行c的函数_start_armboot 	ldr	pc, _start_armboot_start_armboot:	.word  start_armboot其中_start_armboot 函数实现如下:lib/board.c:105:void start_armboot (void)void start_armboot (void){  	init_fnc_t **init_fnc_ptr; 	int i;	uchar *buf;	char boot_dev_name[8];	u32 boot_device = 0; #首先初始化一些信息   	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {		if ((*init_fnc_ptr)() != 0) {			hang ();		}	}#ifdef START_LOADB_DOWNLOAD	strcpy(boot_dev_name, "UART");	do_load_serial_bin (CFG_LOADADDR, 115200);#else#从寄存器中得到当前是从nand/emmc/sd 等device boot	/* Read boot device from saved scratch pad */	boot_device = __raw_readl(0x480029c0) & 0xff;	buf = (uchar*) CFG_LOADADDR;	switch(boot_device) {	case 0x03:		strcpy(boot_dev_name, "ONENAND");#if defined(CFG_ONENAND)		for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++) {			if (!onenand_read_block(buf, i))				buf += ONENAND_BLOCK_SIZE;			else				goto error;		}#endif		break;	case 0x02:	default:		strcpy(boot_dev_name, "NAND");#if defined(CFG_NAND)		for (i = NAND_UBOOT_START; i < NAND_UBOOT_END;				i+= NAND_BLOCK_SIZE) {			if (!nand_read_block(buf, i))				buf += NAND_BLOCK_SIZE; /* advance buf ptr */		}#endif		break;#加入我们从mmc中boot的话,这里会将uboot 从emmc 中读取到dram中	case 0x05:		strcpy(boot_dev_name, "EMMC");#if defined(CONFIG_MMC)		if (mmc_read_bootloader(1, 0) != 0)			goto error;#else		goto error;#endif		break;	case 0x06:		strcpy(boot_dev_name, "MMC/SD1");#if defined(CONFIG_MMC) && defined(CFG_CMD_FAT)		if (mmc_read_bootloader(0, 1) != 0)			goto error;#else		goto error;#endif		break;	};#endif#开始跳入到uboot中执行,正常情况下后面的code 都不会执行	/* go run U-Boot and never return */	printf("Starting OS Bootloader from %s ...\n", boot_dev_name); 	((init_fnc_t *)CFG_LOADADDR)();	/* should never come here */#if defined(CFG_ONENAND) || defined(CONFIG_MMC)error:#endif#如果失败的话,则挂载这里	printf("Could not read bootloader!\n");	hang();}其中从emmc中读取uboot的code如下:int mmc_read_bootloader(int dev, int part){	long size;	unsigned long offset = CFG_LOADADDR;	block_dev_desc_t *dev_desc = NULL;	unsigned char ret = 0;#首先初始化emmc 控制器	ret = mmc_init(dev);	if (ret != 0){		printf("\n MMC init failed \n");		return -1;	}#然后从emmc中读取uboot	if (part) {	/* FAT Read for extenal SD card */		dev_desc = mmc_get_dev(dev);		size = file_fat_read("u-boot.bin", (unsigned char *)offset, 0);		if (size == -1)			return -1;	} else {	/* RAW read for EMMC */		ret = mmc_read(dev, 0x400, (unsigned char *)offset, 0x60000);		if (ret != 1)			return -1;	}	return 0;}

转载地址:http://tcnmi.baihongyu.com/

你可能感兴趣的文章
ARC MRC 变换
查看>>
Swift cell的自适应高度
查看>>
【linux】.fuse_hiddenXXXX 文件是如何生成的?
查看>>
【LKM】整合多个LKM为1个
查看>>
【Windows C++】调用powershell上传指定目录下所有文件
查看>>
Java图形界面中单选按钮JRadioButton和按钮Button事件处理
查看>>
小练习 - 排序:冒泡、选择、快排
查看>>
SparkStreaming 如何保证消费Kafka的数据不丢失不重复
查看>>
Spark Shuffle及其调优
查看>>
数据仓库分层
查看>>
常见数据结构-TrieTree/线段树/TreeSet
查看>>
Hive数据倾斜
查看>>
TopK问题
查看>>
Hive调优
查看>>
HQL排查数据倾斜
查看>>
DAG以及任务调度
查看>>
LeetCode——DFS
查看>>
MapReduce Task数目划分
查看>>
ZooKeeper分布式锁
查看>>
3126 Prime Path
查看>>