Writing GRUB Modules
Difficulty level |
---|
Master |
The whole architecture of GRUB changed as of version 2. The big new feature is modules. This lead to the elimination of Stage 1.5. It also means it is easier for you to put lot of cool functionality into your bootloader. You can now add support for new executable formats, filesystems, video drivers, kernel boot protocols, and so on.
Modules
GRUB modules are relocatable ELF32 binaries. They have the extension .mod.
Header files
All the standard GRUB header files from the source distribution can be included. If you are building out-of-tree and have not configured the source for your system, then these can still be used with a few modifications:
- define GRUB_MACHINE_PCBIOS to be 1
- define GRUB_UTIL
- define GRUB_FILE to be something appriopriate
- provide include/grub/cpu/memory.h to typedef grub_phys_addr_t to something appropriate (e.g. intptr_t)
Special Sections
Each module is required to contain three special pieces of information: the module name, the dependencies of the module (i.e. which other modules need to be loaded prior to this one) and the licence of the module. For GRUB 2, the licence is required to be GPL otherwise it will not be loaded. These need to be placed in special sections within the module. The following piece of code (GCC specific) at module scope will achieve the required functionality:
char modname[] __attribute__((section(".modname"))) = "mymodule";
/* Example dependencies */
char moddeps[] __attribute__((section(".moddeps"))) = "relocator\0video\0vbe\0multiboot\0gfxterm";
GRUB_MOD_LICENSE("GPLv3+");
Initialization
Each module has GRUB_MOD_INIT(modname) and GRUB_MOD_FINI(modname). Note that modname is not in quotes. You the need to edit /conf/common.mk. Copy one of the modules and edit it for your own needs. Note that each module is long-winded.
Functions
int EXPORT_FUNC() grub_printf(const char* func, ...); //Very similar to standard printf()
grub_extcmd_t grub_register_extcmd (const char * name, grub_extcmd_func_t func,
grub_command_flags_t flags, const char * summary, const char * description,
const struct grub_arg_option * parser); //Registers a command on the GRUB command line
grub_fs_register (struct grub_fs* fs); //Registers a filesystem with GRUB (grub_fs is a set of function pointers)
Building
Modules are object files. You therefore need to use GCC (i686-elf recommended) to build your C files, then use ld's -r option to combine your object files (if necessary). the final output needs to be named .mod.
Loading
Modules can be loaded with the insmod command, from the GRUB configuration file. For filesystem modules, this allows your OS to be booted from your FS, but requires a recognized format for your module. To solve this, you will need to add your module to core.img using grub-mkimage, which can be installed using grub-setup, or possibly grub-install (which is a shell script wrapper to mkimage and setup).