grub2 中的boot命令
来源:互联网 发布:微信派单系统源码下载 编辑:程序博客网 时间:2024/05/22 01:37
boot命令的调用flow如下:
grub_enter_normal_mode ->grub_normal_execute->grub_show_menu->show_menu->grub_menu_execute_entry
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot", 0, 0);
}
如果前面执行没有错误,且kennel已经被装载到dram中,这个是通过grub_loader_is_loaded来判断的
grub_loader_is_loaded (void)
{
return grub_loader_loaded;
}
既判断是否为1,而是在执行linux命令的时候调用grub_loader_set来设定的
grub_loader_set (grub_err_t (*boot) (void),
grub_err_t (*unload) (void),
int flags)
{
grub_loader_loaded = 1;
}
如果都ok就调用grub_command_execute来执行boot命令
GRUB_MOD_INIT(boot)
{
cmd_boot =
grub_register_command ("boot", grub_cmd_boot,
0, N_("Boot an operating system."));
}
可见boot的回调函数是grub_cmd_boot
grub_cmd_boot (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
return grub_loader_boot ();
}
grub_loader_boot (void)
{
err = (grub_loader_boot_func) ();
for (cur = preboots_tail; cur; cur = cur->prev)
if (! err)
err = cur->preboot_rest_func ();
else
cur->preboot_rest_func ();
return err;
}
grub_loader_boot 最重要是调用grub_loader_boot_func来boot kernel,如果failed的话,就会执行preboots_tail
list中注册的函数,但是正常的flow是调用grub_loader_boot_func后就不会再返回了
grub_loader_boot_func函数也是在linux 命令中通过grub_loader_set来指定的
grub_loader_boot_func = grub_linux_boot
static grub_err_t
grub_linux_boot (void)
{
if (finalize_params_linux () != GRUB_ERR_NONE)
return grub_errno;
return (grub_arm64_uefi_boot_image((grub_addr_t)kernel_addr,
kernel_size, linux_args));
}
直接调用grub_arm64_uefi_boot_image起形参就是kernel在dram中的地址和size,以及要传给kernel的cmdline
grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, char *args)
{
grub_efi_memory_mapped_device_path_t *mempath;
grub_efi_handle_t image_handle;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_loaded_image_t *loaded_image;
int len;
b = grub_efi_system_table->boot_services;
status = b->load_image (0, grub_efi_image_handle,
(grub_efi_device_path_t *) mempath,
(void *) addr, size, &image_handle);
grub_dprintf ("linux", "linux command line: '%s'\n", args);
/* Convert command line to UCS-2 */
loaded_image = grub_efi_get_loaded_image (image_handle);
loaded_image->load_options_size = len =
(grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
loaded_image->load_options =
grub_efi_allocate_pages (0,
GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
if (!loaded_image->load_options)
return grub_errno;
loaded_image->load_options_size =
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
(grub_uint8_t *) args, len, NULL);
grub_dprintf ("linux", "starting image %p\n", image_handle);
status = b->start_image (image_handle, 0, NULL);
}
这个函数首先通过uefi的system_table找到boot_services
然后通过load_image来讲kernel image装载到dram中,在linux命令中其实病没有
真正将kernel image从flash等中copy到dram,而这里是真正调用bios的 boot_services
来做这件事情。
最后还是调用boot_services的start_image返回到bios中继续执行启动kernel的工作.
grub_enter_normal_mode ->grub_normal_execute->grub_show_menu->show_menu->grub_menu_execute_entry
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
grub_command_execute ("boot", 0, 0);
}
如果前面执行没有错误,且kennel已经被装载到dram中,这个是通过grub_loader_is_loaded来判断的
grub_loader_is_loaded (void)
{
return grub_loader_loaded;
}
既判断是否为1,而是在执行linux命令的时候调用grub_loader_set来设定的
grub_loader_set (grub_err_t (*boot) (void),
grub_err_t (*unload) (void),
int flags)
{
grub_loader_loaded = 1;
}
如果都ok就调用grub_command_execute来执行boot命令
GRUB_MOD_INIT(boot)
{
cmd_boot =
grub_register_command ("boot", grub_cmd_boot,
0, N_("Boot an operating system."));
}
可见boot的回调函数是grub_cmd_boot
grub_cmd_boot (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
return grub_loader_boot ();
}
grub_loader_boot (void)
{
err = (grub_loader_boot_func) ();
for (cur = preboots_tail; cur; cur = cur->prev)
if (! err)
err = cur->preboot_rest_func ();
else
cur->preboot_rest_func ();
return err;
}
grub_loader_boot 最重要是调用grub_loader_boot_func来boot kernel,如果failed的话,就会执行preboots_tail
list中注册的函数,但是正常的flow是调用grub_loader_boot_func后就不会再返回了
grub_loader_boot_func函数也是在linux 命令中通过grub_loader_set来指定的
grub_loader_boot_func = grub_linux_boot
static grub_err_t
grub_linux_boot (void)
{
if (finalize_params_linux () != GRUB_ERR_NONE)
return grub_errno;
return (grub_arm64_uefi_boot_image((grub_addr_t)kernel_addr,
kernel_size, linux_args));
}
直接调用grub_arm64_uefi_boot_image起形参就是kernel在dram中的地址和size,以及要传给kernel的cmdline
grub_arm64_uefi_boot_image (grub_addr_t addr, grub_size_t size, char *args)
{
grub_efi_memory_mapped_device_path_t *mempath;
grub_efi_handle_t image_handle;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_loaded_image_t *loaded_image;
int len;
b = grub_efi_system_table->boot_services;
status = b->load_image (0, grub_efi_image_handle,
(grub_efi_device_path_t *) mempath,
(void *) addr, size, &image_handle);
grub_dprintf ("linux", "linux command line: '%s'\n", args);
/* Convert command line to UCS-2 */
loaded_image = grub_efi_get_loaded_image (image_handle);
loaded_image->load_options_size = len =
(grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
loaded_image->load_options =
grub_efi_allocate_pages (0,
GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
if (!loaded_image->load_options)
return grub_errno;
loaded_image->load_options_size =
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
(grub_uint8_t *) args, len, NULL);
grub_dprintf ("linux", "starting image %p\n", image_handle);
status = b->start_image (image_handle, 0, NULL);
}
这个函数首先通过uefi的system_table找到boot_services
然后通过load_image来讲kernel image装载到dram中,在linux命令中其实病没有
真正将kernel image从flash等中copy到dram,而这里是真正调用bios的 boot_services
来做这件事情。
最后还是调用boot_services的start_image返回到bios中继续执行启动kernel的工作.
0 0
- grub2 中的boot命令
- Grub2 Configuration (boot menu)
- /boot/grub2/grub.cfg
- grub2 efi boot cdrom
- grub2 boot kernel
- u-boot中的命令
- GRUB2 Rescue Prompt Boot Instructions
- grub2学习和Boot-Repair
- Grub2终端命令介绍
- grub2的exit命令
- grub2中的参数修改
- GRUB2中的.mod文件
- 增加u-boot中的命令
- u-boot中的bdinfo命令
- u-boot中的usb命令
- u-boot中的version命令
- u-boot中的FAT命令
- u-boot中的date命令
- Angular项目构建指南 - 不再为angular构建而犹豫不决
- C++ list: How to erase a reverse iterator?
- 常用手机号,邮箱,用户名 ,昵称校验工具类
- 编写代码不生效,不进断点
- 深入分析Parquet列式存储格式
- grub2 中的boot命令
- spring boot 多环境配置
- 下拉回退 Activity,layout_behavior 还能这么玩?
- np.linspace、 np.arange、np.logspace三个函数的对比分析--python学习笔记24
- UI-Router:为什么开发者都不喜欢Angular.js内置的路由
- Unity加载模块深度解析之网格篇
- 听别人讲:技术的正宗与野路子
- codeblocks安装(自带gcc编译器)
- 项目 1 - 验证算法之(4)快速排序