Grub2那些事 - 如何編寫一個Grub2的模組

這個章節我們將學習如何編寫一個grub模組,Grub提供了強大的擴充套件功能,在Grub配置檔案中的命令就是透過GRUB的模組實現的,所以完全可以編寫位元組的Grub模組,在這個章節不會詳細的介紹Grub模組,我們透過編寫一個簡單的模組來了解Grub模組,在Grub的程式碼中有一個Hello World模組,這裡我們參考這個模組列印一個

Hello Grub

的模組。

編寫GRUB模組

首先,我們編寫一個grub的程式碼

/* hello1。c - test module for dynamic loading *//* * GRUB —— GRand Unified Bootloader * Copyright (C) 2003,2007 Free Software Foundation, Inc。 * Copyright (C) 2003 NIIBE Yutaka * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version。 * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE。 See the * GNU General Public License for more details。 * * You should have received a copy of the GNU General Public License * along with GRUB。 If not, see 。 */#include #include #include #include #include #include #include GRUB_MOD_LICENSE (“GPLv3+”);static grub_err_tgrub_cmd_hello (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))){ grub_printf (“%s\n”, _(“Hello Grub”)); return 0;}static grub_extcmd_t cmd;GRUB_MOD_INIT(hello1){ cmd = grub_register_extcmd (“hello1”, grub_cmd_hello, 0, 0, N_(“Say `Hello Grub‘。”), 0);}GRUB_MOD_FINI(hello1){ grub_unregister_extcmd (cmd);}

這裡我們基本直接複製了Hello命令的原始碼,我們將這個原始檔儲存在Grub原始碼

grub-core/hello1/

目錄中,命名為

hello1。c

。這段程式碼使用Grub提供的輔助函式進行註冊

GRUB_MOD_INIT(name)GRUB_MOD_FINI(name)

GRUB_MOD_INIT(name)

是初始化函式,Grub啟動的時候會呼叫這個函式,而真正註冊命令的是

grub_register_extcmd

函式。

GRUB_MOD_FINI(name)

是銷燬函式,Grub清理的時候會呼叫這個函式。來看看

grub_register_extcmd

函式的原型

grub_extcmd_tgrub_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)

這裡不會詳細的介紹每個引數的含義,我們主要介紹這裡使用的引數:

name:函式的名稱

func:真正用於執行的函式指標

description:描述資訊

所以這裡我們定義個一個名為

hello1

的命令,對應執行的函式為

grub_cmd_hello

,其他的就大致和編寫C語言函式,需要注意的是我們需要使用Grub提供的標誌函式,不能呼叫libc提供的函式。這是因為Grub執行的時候libc還沒有載入。

定義好原始碼,下面就開始編譯,Grub提供了簡化的編譯方案,我們這裡定義了

hello1。module

模組,只需要修改

grub-core/Makefile。core。def

檔案即可,在檔案末尾增加以下內容

module = { name = hello1; common = hello1/hello1。c;};

配置的含義顯而易見,這裡就不再贅述。然後我們執行命令進行編譯

$ cd $grub_source$ 。/bootstrap$ 。/autogen。sh$ 。/configure ——prefix=$WORKSPACE/grub HOST_CFLAGS=’-g‘

編譯好後,這裡我們使用《Grub2那些事 - 製作一個使用BIOS的系統》中的磁碟,將Grub安裝到磁碟中

$ sudo $WORKSPACE/grubsbin/grub-install ——boot-directory=$MOUNT/boot ——modules=“part_msdos hello1” $LOOPDEV

然後執行qemu,進入Grub shell,執行hello1,將看到列印的

Hello Grub

Grub2那些事 - 如何編寫一個Grub2的模組

使用Grub模組機制,我們可以提供更加強大的引導功能,Grub本身也提供了豐富的各種模組。Grub也像Linux提供了動態載入模組的

insmod

命令,它也是透過模組實現的。Grub的材料也非常多,也無法把所有的模組都介紹一遍,對於我們而言,我們只要知道如何編寫一個新的模組以及在Linux系統引導時候Grub如何引導的就行了,下面我們將詳細的介紹用於引導Linux命令的

linux

模組。