uclinux很久前笔记5

/u-boot/lib_arm/board.c
void start_armboot (void)
{
……
	gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
/********************************************************************
* 	堆栈结构:
* 	_TEXT_BASE
* 	malloc area
* 	bdinfo			//gd就为bdinfo高地址-gd大小的首地址
* 	CONFIG_STACKSIZE_IRQ
* 	CONFIG_STACKSIZE_FIQ
* 	#12
* 	SP
*********************************************************************/
	memset ((void*)gd, 0, sizeof (gd_t));  		// gd数据清零
	gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));	
	memset (gd->bd, 0, sizeof (bd_t));
	/*********************
*	bdinfo的结构:
*	gd    //在bdinfo高地址处向下
*	bd	
*	……
*********************/
	monitor_flash_len = _bss_start - _armboot_start;  //u-boot映像大小
	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
		if ((*init_fnc_ptr)() != 0) {  //依次调用数组中的初始化函数
			hang ();
		}
	}
……
	/* 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 */
}
typedef int (init_fnc_t) (void);
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)
	checkboard,
#endif
	NULL,
};
/u-boot/common/cmd_bootm.c
image_header_t header;
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	……
	image_header_t *hdr = &header;
	……
	if (argc < 2) {		//只有一个参数时(即bootm 无参数)
		addr = load_addr;
	} else {			//有两个参数时(即bootm argv[1]),该argv[1]在44b0中为0x50000
		addr = simple_strtoul(argv[1], NULL, 16);
	}
	SHOW_BOOT_PROGRESS (1);
	printf ("## Booting image at %08lx ...\n", addr);
	……
	memmove (&header, (char *)addr, sizeof(image_header_t));
	//将addr处sizeof(image_header_t)大小的数据拷贝到header中。
	//接下来就解析image_header_t结构体
/*typedef struct image_header {
	uint32_t	ih_magic;					/* Image Header Magic Number	*/
	uint32_t	ih_hcrc;					/* Image Header CRC Checksum	*/
	uint32_t	ih_time;					/* Image Creation Timestamp		*/
	uint32_t	ih_size;					/* Image Data Size				*/
	uint32_t	ih_load;					/* Data	 Load  Address		*/
	uint32_t	ih_ep;					/* Entry Point Address			*/
	uint32_t	ih_dcrc;					/* Image Data CRC Checksum	*/
	uint8_t		ih_os;				/* Operating System			*/
	uint8_t		ih_arch;				/* CPU architecture				*/
	uint8_t		ih_type;				/* Image Type					*/
	uint8_t		ih_comp;				/* Compression Type			*/
	uint8_t		ih_name[IH_NMLEN];	/* Image Name				*/
} image_header_t;*/
	if (ntohl(hdr->ih_magic) != IH_MAGIC)  //首先解析ih_magic
	{ ……}
	SHOW_BOOT_PROGRESS (2);
	/*下面进行整个镜像校验处理*/
	data = (ulong)&header;
	len  = sizeof(image_header_t);
	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = 0;
	if (crc32 (0, (char *)data, len) != checksum) {
		puts ("Bad Header Checksum\n");
		SHOW_BOOT_PROGRESS (-2);
		return 1;
	}
	SHOW_BOOT_PROGRESS (3);
	print_image_hdr ((image_header_t *)addr);
	//打印下面的相关信息
   Image Name:   uClinux_test_cqy
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    226491 Bytes = 221 kB = 0 MB
   Load Address: c0008000
   Entry Point:  c0008000
   /*下面进行内核校验处理*/
	data = addr + sizeof(image_header_t);
	len  = ntohl(hdr->ih_size);
	if (verify) {
		puts ("   Verifying Checksum ... ");
		if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
			printf ("Bad Data CRC\n");
			SHOW_BOOT_PROGRESS (-3);
			return 1;
		}
		puts ("OK\n");
	}
	SHOW_BOOT_PROGRESS (4);
	len_ptr = (ulong *)data;  //内核首地址
SHOW_BOOT_PROGRESS (5);
	/*下面解析内核类型*/
	switch (hdr->ih_type) {
	……
	case IH_TYPE_KERNEL:
		name = "Kernel Image";
		break;
	……}
	SHOW_BOOT_PROGRESS (6);
	/*解析压缩类型*/
	switch (hdr->ih_comp) {
	……
	case IH_COMP_GZIP:
		printf ("   Uncompressing %s ... ", name);
		if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,
			    (uchar *)data, (int *)&len) != 0) {
			puts ("GUNZIP ERROR - must RESET board to recover\n");
			SHOW_BOOT_PROGRESS (-6);
			do_reset (cmdtp, flag, argc, argv);
		}
		break;
	……}
	puts ("OK\n");
	SHOW_BOOT_PROGRESS (7);
	/*下面解析os类型*/
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);	//跳转到do_bootm_linux准备linux启动参数
	break;
	……}
	return 1;
}
/u-boot/lib_arm/ armlinux.c   //设置传递给linux的参数并启动linux
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
		     ulong addr, ulong *len_ptr, int verify){
	……
	void (*theKernel)(int zero, int arch, uint params);
	bd_t *bd = gd->bd;
#ifdef CONFIG_CMDLINE_TAG
	char *commandline = getenv ("bootargs");
#endif
	theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
	……
	setup_start_tag (bd);
#ifdef CONFIG_SETUP_MEMORY_TAGS
	setup_memory_tags (bd);
#endif
#ifdef CONFIG_CMDLINE_TAG
	setup_commandline_tag (bd, commandline);
#endif
	setup_end_tag (bd);
	/* we assume that the kernel is in place */
	printf ("\nStarting kernel ...\n\n");
	cleanup_before_linux ();
	theKernel (0, bd->bi_arch_number, bd->bi_boot_params); 
//跳转到linux内核运行,linux启动
}
static void setup_start_tag (bd_t *bd)
{
	params = (struct tag *) bd->bi_boot_params;   //是在board_init函数中被赋值的
	params->hdr.tag = ATAG_CORE;
	params->hdr.size = tag_size (tag_core);
	params->u.core.flags = 0;
	params->u.core.pagesize = 0;
	params->u.core.rootdev = 0;
	params = tag_next (params);
}
static void setup_memory_tags (bd_t *bd)
{
	int i;
	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
		params->hdr.tag = ATAG_MEM;
		params->hdr.size = tag_size (tag_mem32);
		params->u.mem.start = bd->bi_dram[i].start; //是在dram_init函数中被赋值的
		params->u.mem.size = bd->bi_dram[i].size;
		params = tag_next (params);
	}
}
static void setup_commandline_tag (bd_t *bd, char *commandline)
{
	char *p;
	if (!commandline)
		return;
	/* eat leading white space */
	for (p = commandline; *p == ' '; p++);
	/* skip non-existent command lines so the kernel will still
	 * use its default command line.*/
	if (*p == '\0')return;
	params->hdr.tag = ATAG_CMDLINE;
	params->hdr.size =(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
	strcpy (params->u.cmdline.cmdline, p);
	params = tag_next (params);
}
static void setup_end_tag (bd_t *bd)
{
	params->hdr.tag = ATAG_NONE;
	params->hdr.size = 0;
}
/u-boot/borad/$(BOARDDIR)/s3c44b0.c
int board_init (void)
{
	DECLARE_GLOBAL_DATA_PTR;
	……
	/* arch number MACH_TYPE_MBA44B0 */
	gd->bd->bi_arch_number = 178;
	/* location of boot parameters */
	gd->bd->bi_boot_params = 0x0c000100;
	return 0;
}
int dram_init (void)
{
	DECLARE_GLOBAL_DATA_PTR;
	gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 
	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
	return (0);
}
// PHYS_SDRAM是在ITSN_s3c44b0.h中被定义的
#define PHYS_SDRAM_1		0x0c000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE	0x00800000 /* 8 MB */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值