本文共 2602 字,大约阅读时间需要 8 分钟。
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 (¶ms->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) //加载内核 }}
转载地址:http://oflji.baihongyu.com/