這個章節我們將學習如何編寫一個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
這裡我們基本直接複製了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
使用Grub模組機制,我們可以提供更加強大的引導功能,Grub本身也提供了豐富的各種模組。Grub也像Linux提供了動態載入模組的
insmod
命令,它也是透過模組實現的。Grub的材料也非常多,也無法把所有的模組都介紹一遍,對於我們而言,我們只要知道如何編寫一個新的模組以及在Linux系統引導時候Grub如何引導的就行了,下面我們將詳細的介紹用於引導Linux命令的
linux
模組。