菜单

kaoqi
kaoqi
发布于 2026-07-22 / 5 阅读
0
0

GRUB2项目下的简易ACPI模块

由之前撰写的GRUB2项目分析可以知道,GRUB的主函数在输入来自固件的System Table的前提下,可以通过main.c中的load module(来自/core/kern/dl.c的功能)。

可以确定,module的初始化都是从符合module标准头中的init指针所代指的函数执行开始的。

module的标准头结构如下:

struct grub_dl
{
  char *name;
  grub_uint64_t ref_count;
  int persistent;
  grub_dl_dep_t dep;
  grub_dl_segment_t  segment;
  Efl_Sym *symtab;
  grub_size_t symsize;
  void (*init) (struct grub_dl *mod);
  void (*fini) (void);
  void *base;
  grub_size sz;
  struct grub_dl *next;
}

可以看到这里明显具备了执行init函数的地址,ACPI模块的代码分析,也将从这里开始。

ACPI模块位置在/grub-core/kern下的acpi.c中,按照makefile展示出来的编译逻辑,理应是生成kernel_exec_acpi.o文件后,链接生成或打包生成kernel.exec文件,其ACPI内容将会以后端/grub-core/kern/acpi.c文件以及前端/grub-core/commands/acpi.c共同搞定,此外还有一个头文件存在于/include/grub/acpi.h需要注意。

实现kernel_exec_acpi.o文件编译的完整命令:


gcc -DHAVE_CONFIG_H -I. -I..  -Wall -W  -DGRUB_MACHINE_EFI=1 -DGRUB_MACHINE=ARM64_EFI -nostdinc -isystem /usr/lib/gcc/aarch64-linux-gnu/11/include -I../include -I../include -DGRUB_FILE=\"kern/acpi.c\" -I. -I. -I.. -I.. -I../include -I../include -I../grub-core/lib/libgcrypt-grub/src/   -DGRUB_KERNEL=1  -D_FILE_OFFSET_BITS=64 -std=gnu99 -fno-common -Os -Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value  -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations -Wcast-align  -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2 -freg-struct-return -mgeneral-regs-only -fno-omit-frame-pointer -fno-dwarf2-cfi-asm -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-ident -fno-PIE -fno-pie -fno-stack-protector -Wtrampolines -Werror -mcmodel=large   -ffreestanding -fshort-wchar   -MT kern/kernel_exec-acpi.o -MD -MP -MF kern/.deps-core/kernel_exec-acpi.Tpo -c -o kern/kernel_exec-acpi.o `test -f 'kern/acpi.c' || echo './'`kern/acpi.c

ACPI的入口函数(module初始化):

GRUB_MOD_INIT(acpi)
{
  cmd = grub_register_extcmd_lockdown ("acpi", grub_cmd_acpi, 0,
                                       N_("[-1|-2] [--exclude=TABLE1,TABLE2|"
                                          "--load-only=TABLE1,TABLE2] FILE1"
                                          " [FILE2] [...]"),
                                       N_("Load host ACPI tables and tables "
                                          "specified by arguments."),
                                       options);
}

这样实际上跳转到/core/command/acpi.c中的grub_cmd_acpi函数中去执行具体的acpi相关的命令解析了。

可以通过qemu模拟执行的方式进入到grub中:

qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a72 \
  -m 4G \
  -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \
  -drive file=/dev/sde1,format=raw,if=virtio \
  -nographic

这里的QEMU问题暂时无法解决,最好使用更轻量级的efiemu来解决。


评论