grub学习(2) 加载内核

grub_err_t grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[])
{
	struct linux_kernel_header lh;
	struct linux_kernel_params *params;
	file = grub_file_open (argv[0]);	//打开linux文件
	
	grub_file_read (file, &lh, sizeof (lh)	//读取linux header
	
	setup_sects = lh.setup_sects; //获取setup.bin占用的扇区
	
	real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
	prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;	//获取保护模式镜像大小
	
	allocate_pages (prot_size)
	=>grub_err_t allocate_pages (grub_size_t prot_size)	//为 linux_kernel_params params 和 内核镜像申请内存
	{
		/* Make sure that each size is aligned to a page boundary.  */
		real_size = GRUB_LINUX_CL_END_OFFSET;
		prot_size = page_align (prot_size);
		mmap_size = find_mmap_size ();	//确定e820内存结构数组大小
		
		real_mode_pages = ((real_size + mmap_size + efi_mmap_size) >> 12);
		prot_mode_pages = (prot_size >> 12);
		
		err = grub_relocator_alloc_chunk_addr (relocator, &ch,
					   real_mode_target,
					   (real_size + mmap_size 
					    + efi_mmap_size));	//实模式 linux_kernel_params params 结构体和e820申请内存
		real_mode_mem = get_virtual_current_address (ch);
		
		prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR;	//内核放在物理地址1MB的位置
		grub_relocator_alloc_chunk_addr (relocator, &ch,
					   prot_mode_target, prot_size);	//为保护模式内核申请内存
		prot_mode_mem = get_virtual_current_address (ch);
		
		/* 初始化linux_kernel_params params */
		params = (struct linux_kernel_params *) real_mode_mem;
		grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
		grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
		
		len = 0x400 - sizeof (lh);
		grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len)	//读取协议
		grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
		
		if (grub_memcmp (argv[i], "mem=", 4) == 0) {	//获取内存总大小
			char *val = argv[i] + 4;
			linux_mem_size = grub_strtoul (val, &val, 0);
			int shift = 0;

			switch (grub_tolower (val[0]))
			  {
				case 'g':
					shift += 10;
				case 'm':
					shift += 10;
				case 'k':
					shift += 10;
				default:
					break;
			  }
			linux_mem_size <<= shift;
		} else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0)
		{
			params->loadflags |= GRUB_LINUX_FLAG_QUIET;
		}
		
		/* Create kernel command line.  */
		grub_memcpy ((char *)real_mode_mem + GRUB_LINUX_CL_OFFSET, LINUX_IMAGE,
			  sizeof (LINUX_IMAGE));
		grub_create_loader_cmdline (argc, argv,
					  (char *)real_mode_mem + GRUB_LINUX_CL_OFFSET
					  + sizeof (LINUX_IMAGE) - 1,
					  GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
					  - (sizeof (LINUX_IMAGE) - 1));

		len = prot_size;
		grub_file_read (file, prot_mode_mem, len) != len) //加载内核

	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值