bootload启动内核

bootloader :将内核和文件系统载入内存

Linux 内核:Linux 内核由内存管理、进程管理、设备驱动程序、网络管理等组成,它是操作系统的核心,具有很多最基本的功能,决定了系统的性能和稳定性。用户空间的文件系统用来提供管理系统的各种配置,提供相应的应用程序、服务、数据交换等。

文件系统: 文件系统作为一种载体,它是用来实现用户与操作系统内核的交互

nandflash存放地址
#define IMG_BOOTLOADER	0x00000000  
#define IMG_KERNEL		0x00300000
#define IMG_ROOTFS		0x00700000
int main(void)
{	
	FATFS fs;
	int FileSize;
	RTC_Time Time = {
		2015, 1, 1, 22, 00, 0, 5
	};		
	Uart_Init();
	printf("CPU:   S3C2416@%dMHz\n", get_ARMCLK()/1000000);
	printf("       Fclk = %dMHz, Hclk = %dMHz, Pclk = %dMHz\n",
			get_FCLK()/1000000, get_HCLK()/1000000, get_PCLK()/1000000);

	NandBoot_Init();
	RTC_Init(&Time);
	f_mount(&fs, "" , 0);	

	if (DownloadSelect == 3) {  -- 将bootload\内核\文件系统写入nandflash
		// 下载选择了从sd卡自更新bootloader, kernel, rootfs
		printf("Trying to update bootloader...\n");
		FileSize = Sd_ReadFileToRam("/image/bootloader.bin", (uint8_t *)DRAM_BASE);
		if (FileSize > 0) {
			NandBoot_WriteSkipBad(0, (uint8_t *)DRAM_BASE, FileSize);
			printf("Bootloader has been updated, file size %d\n", FileSize);
		}
		printf("Trying to update kernel...\n");
		FileSize = Sd_ReadFileToRam("/image/kernel.bin", (uint8_t *)DRAM_BASE);
		if (FileSize > 0) {
			Nand_DownloadKernel((uint8_t *)DRAM_BASE, FileSize);
			printf("Kernel has been updated, file size %d\n", FileSize);
		}
		printf("Trying to update rootfs...\n");
		FileSize = Nand_DownloadRootfs("/image/rootfs.bin");
		if (FileSize > 0) {
			printf("Rootfs has been updated, file size %d\n", FileSize);
		} else {
			printf("Update rootfs error\n");
		}
		printf("Update is complete, you need to restart the system...\n");
		while (1);
	} else if (DownloadSelect == 4) {
		// 擦除整个nand flash
		Debug("Nand flash is erasing...\n");
		Nand_EraseFlash();
		printf("Erase is complete, you need to restart the system...\n");
		while (1);
	}
	
	//在这里开始启动内核
	Board_Init();
	Kernel_Boot();
	
	printf("Linux boot failed\n");
	while (1) {

	}
}

//设置启动参数

void Kernel_SetupParam(struct tag *params)
{
	// start_tag
	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);	

	设置内存标记 ATAG_MEM,标记内存的位置及大小
	params->hdr.tag = ATAG_MEM;
	params->hdr.size = tag_size (tag_mem32);
	params->u.mem.start = DRAM_BASE;
	params->u.mem.size = DRAM_SIZE; // 64M
	params = tag_next (params);	
	
	//设置命令行标记 ATAG_CMDLINE,这是一个字符串,用来控制内核的行为。如
	//"noinitrd root=/dev/mtdblock3 rootfstype=yaffs2 init=/linuxrc console=ttySAC0",表示
	//根文件系统在 MTD3 分区上,文件系统为 yaffs2,系统启动后执行的第一个程序为
	linuxrc,控制台为 ttySAC0。
	params->hdr.tag = ATAG_CMDLINE;		
	params->hdr.size = (sizeof(struct tag_header)+strlen(NandBootArgs)+1+4) >> 2;
	strcpy(params->u.cmdline.cmdline, NandBootArgs);  //根文件路径
	params = tag_next (params);
	// end tag
	params->hdr.tag = ATAG_NONE;
	params->hdr.size = 0;	
}

int Kernel_Boot(void)
{
	int Ret;
	int FileSize;
	uint32_t KernelBase;
	struct tag *params;
	void (*Kernel)(uint32_t, uint32_t, uint32_t);
	
	KernelBase = DRAM_BASE+LINUX_KERNEL_OFFSET;
	// Setup linux parameters and linux command line 
	params = (struct tag *)(DRAM_BASE+LINUX_PARAM_OFFSET);	
	
	FileSize = Nand_ReadKernelSize();
	if (FileSize > 0) {
		Ret = Nand_ReadKernel((uint8_t *)KernelBase, FileSize);
		if (Ret == -1) {
			printf("failed to read linux kernel from nand flash\n");
			return -1;
		}
	} else {
		printf("can not find kernel image in nand flash\n");
		return -1;
	}	

	if ((*(uint32_t *)(KernelBase+4*9)) != LINUX_ZIMAGE_MAGIC) {
		printf("This binary is not compressed linux kernel image\n");
	} else {
		printf("Boot with zImage magic\n");
	}	
	Kernel_SetupParam(params);  //载入参数
	//在交出 CPU 控制权之前,bootloader 需要把 CPU 恢复成初始的环境,CPU 必须禁止
	//IRQ 以及 FIQ 中断,处于特权模式,关闭 MMU,使无效并且写回 DCache 数据到主存,
	//禁止 DCache,推荐 ICache 打开。
	IRQ_Disable(); //禁止中断
	Kernel_CleanUpBeforeBoot(); 
	Kernel = (void (*)(uint32_t, uint32_t, uint32_t))KernelBase; //跳到内核载入的地址区别执行
	//bootloader 跳转到内核时,将传递三个参数给内核,对于 ARM 为 R0、R1、R2 这三
	//个寄存器。第一个参数 R0 必须为 0,第二个参数 R1 为机器码,必须与 linux 内核一致才
	//能启动,第三个参数为先前设置的内核启动参数地址位置。跳转到内核后,bootloader 完
	//全退出,由 linux 内核全权处理。	
	Kernel(0, MACH_TYPE, (uint32_t)params); // n开始启动内核
	
	return -1;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值