GRUB2 有模件建築學有支持裝貨和卸載代碼模塊如需要。 模塊在某些方面类似Linux仁模塊,但是在其他方式他們是像Mozilla的Firefox或蝕 IDE 插入。 在這個崗位我提供概要GRUB2模塊是並且顯示您如何修改一個現有的模塊增加新的功能。 使用GRUB2除草根鴯userspace仿真器,我也展示如何发展,集成和測試您自己的習慣模塊。
GRUB2 (v1.98)的最新版有159個模塊:
acpi.mod date.mod gcry_sha1.mod loopback.mod pbkdf2.mod terminfo.mod affs.mod datetime.mod gcry_sha256.mod lsmmap.mod pci.mod test.mod afs_be.mod dm_nv.mod gcry_sha512.mod ls.mod play.mod tga.mod afs.mod drivemap.mod gcry_tiger.mod lspci.mod png.mod trig.mod aout.mod echo.mod gcry_twofish.mod lvm.mod probe.mod true.mod ata.mod efiemu.mod gcry_whirlpool.mod mdraid.mod pxecmd.mod udf.mod ata_pthru.mod elf.mod gettext.mod memdisk.mod pxe.mod ufs1.mod at_keyboard.mod example_functional_test.mod gfxmenu.mod memrw.mod raid5rec.mod ufs2.mod befs_be.mod ext2.mod gfxterm.mod minicmd.mod raid6rec.mod uhci.mod befs.mod extcmd.mod gptsync.mod minix.mod raid.mod usb_keyboard.mod biosdisk.mod fat.mod gzio.mod mmap.mod read.mod usb.mod bitmap.mod font.mod halt.mod msdospart.mod reboot.mod usbms.mod bitmap_scale.mod fshelp.mod handler.mod multiboot2.mod reiserfs.mod usbtest.mod blocklist.mod functional_test.mod hashsum.mod multiboot.mod relocator.mod vbeinfo.mod boot.mod gcry_arcfour.mod hdparm.mod normal.mod scsi.mod vbe.mod bsd.mod gcry_blowfish.mod hello.mod ntfscomp.mod search_fs_file.mod vbetest.mod bufio.mod gcry_camellia.mod help.mod ntfs.mod search_fs_uuid.mod vga.mod cat.mod gcry_cast5.mod hexdump.mod ohci.mod search_label.mod vga_text.mod chain.mod gcry_crc.mod hfs.mod part_acorn.mod search.mod video_fb.mod charset.mod gcry_des.mod hfsplus.mod part_amiga.mod serial.mod video.mod cmp.mod gcry_md4.mod iso9660.mod part_apple.mod setjmp.mod videotest.mod configfile.mod gcry_md5.mod jfs.mod part_gpt.mod setpci.mod xfs.mod cpio.mod gcry_rfc2268.mod jpeg.mod part_msdos.mod sfs.mod xnu.mod cpuid.mod gcry_rijndael.mod keystatus.mod part_sun.mod sh.mod xnu_uuid.mod crc.mod gcry_rmd160.mod linux16.mod parttool.mod sleep.mod crypto.mod gcry_seed.mod linux.mod password.mod tar.mod datehook.mod gcry_serpent.mod loadenv.mod password_pbkdf2.mod terminal.mod
某些更加顯著的模塊是:
- ls,貓,回聲, cmp : 提供相似的功能給他們的Unix命令couterparts。
- ext2, iso9660, reiserfs, xfs : 為同一個名字的文件系統提供支持。
- part_sun, part_gpt, part_msdos : 為各種各樣的分開計劃提供支持。
- Linux : Linux圖像的裝載者
- vga, tga, vbe, png, jpeg : 為圖表和背景图象提供支持。
命令裝載(insmod)或卸載(rmmod)模塊入GRUB2有名字和一样在GNU/Linux。
當模塊被裝載时,或者連接在模塊的a初始化,模塊登記一個或更多命令,並且可能也登記可變物、分析器和司機。 一個GRUB2命令例如hexdump要求一映射從名字到文件/boot/grub/command.lst包含從指令名字的繪圖到模塊包含實施作用的一個具體模塊作用(和的代碼那個命令)。 這一部分的command.lst文件:
cat: minicmd chainloader: chain clear: minicmd cmp: cmp .: configfile configfile: configfile *cpuid: cpuid crc: crc date: date *drivemap: drivemap dump: minicmd *echo: echo hexdump: hexdump
在許多情况下指令名字是名字和模块名称,即hexdump和hexdump.mod一样。 在某些情况下一個装载模块也許登記多個命令,即loadenv.mod記數器load_env和save_env。 如果命令被输入(直接地或通过劇本)適當的模塊被裝載,如果命令已經沒有登記。 可變物是一映射從名字到在模塊定義的可變物。 劇本可能訪問可變物作為$name。 支持eventing模塊的可變物; 當價值被赋予到可變物时,模塊可能得到收回。
模塊實際上是矮子格式文件。 主要GRUB2文件core.img包含必要的代碼解析矮子倒栽跳水,裝載模塊並且做動態連接(即,對core.img和可變物的決心電話出口的作用供模塊使用)。 模塊可以是鑲入,即一部分的core.img或動態地裝載使用insmod或者它可以自動地被裝載,當另一個模塊通过insmod时被裝載,因為被裝載的模塊有對此的一個附庸。
附庸繪圖在文件moddep.lst被列出。 這一部分的這個文件:
video: font: bufio video hfsplus: fshelp gettext: normal gzio extcmd: normal: crypto boot terminal charset hashsum: extcmd normal crypto search: extcmd search_label search_fs_uuid search_fs_file xnu_uuid: gcry_md5 drivemap: extcmd boot mmap password: crypto normal read:
自上您能看到密碼模塊有在隱藏和正常模塊的附庸。 注意正常模塊由在起動的core.img自動地裝載和因而隱藏的模塊,起動、終端和charset那時也被裝載,因為法線有在這些模塊的附庸。
相當好地構造GRUB2的原始代码並且是主要ANSI C代碼。 自然地有一定數量是野獸的本质)的汇编码(但是數額是小的,並且您不應該有任何需要修改甚至看這樣代碼。 它在32位实址方式下跑並且single-threaded。 一般沒有要考慮的同步問題或竞争状态。
現在转向問題怎样創造和修造GRUB2模塊。 強制你好世界模塊(。/hello/hello.mod)包括有GRUB2原始代码tarball。 這這個模塊的原始代码:
/* hello.c - test module for dynamic loading */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2007 Free Software Foundation, Inc.
* Copyright (C) 2003 NIIBE Yutaka <gniibe@m17n.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
static grub_err_t
grub_cmd_hello (struct grub_extcmd *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_printf ("Hello World\n");
return 0;
}
static grub_extcmd_t cmd;
GRUB_MOD_INIT(hello)
{
cmd = grub_register_extcmd ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
0, N_("Say \"Hello World\"."), 0);
}
GRUB_MOD_FINI(hello)
{
grub_unregister_extcmd (cmd);
}
上面C語言代碼不應該是难瞭解。 GRUB_MOD_INIT和GRUB_MOD_FINI的定義在倒栽跳水dl.h。 這些作用基本上被用于登記和unregister命令,在這種情況下你好。 當您输入命令你好时在動態地装载模块hello.mod的作用grub_cmd_hello被祈求。 不要设法使用libc图书馆职能在模塊。 您應該需要的所有作用是可利用的在來源tarball和有名字和等效libc作用一样即,除了他們由grub_, strcpy grub_printf ()和的printf (), grub_strcpy ()和加前綴。 另外不要包括規則倒栽跳水例如stdio.h。
如果您不通過任何論據入命令,您必须明確地宣稱在作用聲明的這個事實如下:
function_name (struct grub_extcmd *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
必要的修造方針為你好模塊已經是存在。 在編寫和安裝GRUB2以後,您應該发现你好模塊在/boot/grub被安裝了。 在GRUB2指令提示,您能裝載和執行你好命令如下:
grub> insmod hello.mod grub> hello Hello World grub>
現在转向對hexdump命令。 這個命令的原始代码在../commands補充指南。 目前沒有傾銷文件的整個内容的選擇在這個命令,因此我决定增加這種功能。 我從以下代码片断看見hexdump可能當前採取二個任意論據:
static const struct grub_arg_option options[] = {
{"skip", 's', 0, N_("Skip offset bytes from the beginning of file."), 0, ARG_TYPE_INT},
{"length", 'n', 0, N_("Read only LENGTH bytes."), 0, ARG_TYPE_INT},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args)
{
struct grub_arg_list *state = cmd->state;
grub_ssize_t size, length;
grub_disk_addr_t skip;
....
skip = (state[0].set) ? grub_strtoull (state[0].arg, 0, 0) : 0;
length = (state[1].set) ? grub_strtoul (state[1].arg, 0, 0) : 256;
注意狀態[0]提到在選擇列陣定義的第一選擇辯論,即跳和狀態[1]提到第二選擇辯論,即長度。 因而,如果某事像- s 200通過作為命令行論據對hexdump命令,狀態[0]被設置對一個非零值。 我何時使用這個事實決定到hexdump完成文件。 這我,如果狀態[0],並且狀態[1}是設置到0。
這新的功能的原始代码:
.....
if (!grub_strcmp (args[0], "(mem)"))
hexdump (skip, (char *) (grub_addr_t) skip, length);
/* new functionality */
else if (state[0].set == 0 && state[1].set == 0)
{
file = grub_gzfile_open (args[0], 1);
if (! file)
return grub_errno;
skip = 0;
while ((size = grub_file_read (file, buf, 256)) > 0
&& key != GRUB_TERM_ESC)
{
hexdump (skip, buf, size);
skip += size;
while (grub_checkkey () >= 0 &&
(key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC)
;
}
grub_putchar (‘\n’);
grub_refresh ();
grub_file_close (file);
}
/* end new functionality */
else if ((args[0][0] == ‘(‘) && (args[0][namelen - 1] == ‘)’))
…..
代碼應該是幾乎明顯的。 注意hexdump是格式化並且顯示全部或部份的一種分開的图书馆职能什麼是buf緩衝(取决于在跳和大小的数值)。 並且,內在,當激活时圈,如果設置pagerenvironmental可變物。 在這种情况下, hexdump顯示a ---更多--- 僅提示和顯示數據下個屏幕,當鑰匙被按。 沒有需要對修造系統的變動; 您能重建GRUB2,複製hexdump.mod到/boot/grub,重新起動您的系統和測試從GRUB2指令提示的hexdump。
其次我們发展colortest一個全新的模塊從頭称。 這個模塊將顯示GRUB2支持的所有配色(它集合和一样幼蟲遺產的)為了检查他們由GRUB2恰當地顯示。
這模塊的原始代码。 因為這些只將增加反覆代碼數百條另外的線到目錄,為簡要的筆記我忽略了大多可能的配色。 原始代码被評論我認為的地方解釋被擔保。
#include <grub/env.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/font.h>
#include <grub/term.h>
#include <grub/command.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
/* takes one optional argument -c */
static const struct grub_arg_option options[] =
{
{"clear", 'c', 0, N_("Clear the screen first."), 0, 0},
{0, 0, 0, 0, 0, 0}
};
/* since argc and argv are not used within the function they */
/* must be declared unused - otherwise the build fails */
static grub_err_t
grub_cmd_colortest (grub_extcmd_t cmd,
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
struct grub_arg_list *state = cmd->state;
grub_err_t err = GRUB_ERR_NONE;
char color_normal[50];
const char *tmp;
/* save the current color string for color_normal. It is in the environment */
/* set default if none in the environment otherwise error messages in grub-emu */.
tmp = grub_env_get("color_normal");
if (*tmp)
grub_strcpy(color_normal, tmp);
else
grub_strcpy(color_normal, "light-gray/black");
/* clear the screen if -c passed on command line */
if (state[0].set)
grub_cls();
/* set the current color state to normal jsut in case it it currently highlight */
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
/* black */
/* change the color_normal setting in the environment */
grub_env_set ("color_normal", "dark-gray/black");
/* print this string in dark-gray on black. Black as background is transparent */
grub_printf (" dark-gray/black ");
grub_env_set ("color_normal", "light-blue/black");
grub_printf (" light-blue/black ");
grub_env_set ("color_normal", "light-green/black");
grub_printf (" light-green/black ");
grub_env_set ("color_normal", "light-cyan/black");
grub_printf (" light-cyan/black \n");
grub_env_set ("color_normal", "light-red/black");
grub_printf (" light-red/black ");
grub_env_set ("color_normal", "light-magenta/black");
grub_printf (" light-magenta/black ");
grub_env_set ("color_normal", "yellow/black");
grub_printf (" yellow/black ");
grub_env_set ("color_normal", "white/black");
grub_printf (" white/black \n");
/* blue */
grub_env_set ("color_normal", "dark-gray/blue");
grub_printf (" dark-gray/blue ");
grub_env_set ("color_normal", "light-blue/blue");
grub_printf (" light-blue/blue ");
grub_env_set ("color_normal", "light-green/blue");
grub_printf (" light-green/blue ");
grub_env_set ("color_normal", "light-cyan/blue");
grub_printf (" light-cyan/blue \n");
grub_env_set ("color_normal", "light-red/blue");
grub_printf (" light-red/blue ");
grub_env_set ("color_normal", "light-magenta/blue");
grub_printf (" light-magenta/blue ");
grub_env_set ("color_normal", "yellow/blue");
grub_printf (" yellow/blue ");
grub_env_set ("color_normal", "white/blue");
grub_printf (" white/blue \n");
/* revert to the original color_normal */
grub_env_set ("color_normal", color_normal);
grub_printf ("\n\n");
/* black highlight */
/* change the color_highlight setting in the environment */
grub_env_set ("color_highlight", "black/blue");
/* enable color_highlight and print a string */
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" black/blue ");
grub_env_set ("color_highlight", "black/green");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" black/green ");
grub_env_set ("color_highlight", "black/cyan");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" black/cyan ");
grub_env_set ("color_highlight", "black/red");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" black/red \n");
grub_env_set ("color_highlight", "black/magenta");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" black/magenta ");
grub_env_set ("color_highlight", "black/brown");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" black/brown ");
grub_env_set ("color_highlight", "black/light-gray");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" black/light-gray \n");
/* blue highlight */
grub_env_set ("color_highlight", "blue/green");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" blue/green ");
grub_env_set ("color_highlight", "blue/cyan");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" blue/cyan ");
grub_env_set ("color_highlight", "blue/red");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" blue/red \n");
grub_env_set ("color_highlight", "blue/magenta");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" blue/magenta ");
grub_env_set ("color_highlight", "blue/brown");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" blue/brown ");
grub_env_set ("color_highlight", "blue/light-gray");
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf (" blue/light-gray \n");
/* revert to original color_normal */
grub_env_set ("color_normal", color_normal);
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
grub_printf ("\n");
/* and exit */
return err;
}
static grub_extcmd_t cmd;
GRUB_MOD_INIT(colortest)
{
cmd = grub_register_extcmd ("colortest", grub_cmd_colortest,
GRUB_COMMAND_FLAG_BOTH,
"[-c]",
/* the _N construct is for message localization */
N_("Test supported color combinations."),
options);
}
GRUB_MOD_FINI(colortest)
{
grub_unregister_extcmd (cmd);
}
即然C代碼被寫,怎麼可以我們集成colortest現有的GRUB2修造系統,以便colortest.mod自動地被修造,當我們輸入做。 在GRUB2修造最高级目錄? 它結果是冗長,但是容易。 請增加以下線到../conf/common.mk :
# For colortest.mod.
pkglib_MODULES += colortest.mod
colortest_mod_SOURCES = commands/colortest.c
clean-module-colortest.mod.1:
rm -f colortest.mod mod-colortest.o mod-colortest.c pre-colortest.o colortest_mod-commands_colortest.o und-colortest.lst
CLEAN_MODULE_TARGETS += clean-module-colortest.mod.1
clean-module-colortest.mod-symbol.1:
rm -f def-colortest.lst
CLEAN_MODULE_TARGETS += clean-module-colortest.mod-symbol.1
DEFSYMFILES += def-colortest.lst
mostlyclean-module-colortest.mod.1:
rm -f colortest_mod-commands_colortest.d
MOSTLYCLEAN_MODULE_TARGETS += mostlyclean-module-colortest.mod.1
UNDSYMFILES += und-colortest.lst
ifneq ($(TARGET_APPLE_CC),1)
colortest.mod: pre-colortest.o mod-colortest.o $(TARGET_OBJ2ELF)
-rm -f $@
$(TARGET_CC) $(colortest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ pre-colortest.o mod-colortest.o
if test ! -z "$(TARGET_OBJ2ELF)"; then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
else
colortest.mod: pre-colortest.o mod-colortest.o $(TARGET_OBJ2ELF)
-rm -f $@
-rm -f $@.bin
$(TARGET_CC) $(colortest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin pre-colortest.o mod-colortest.o
$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
-rm -f $@.bin
endif
pre-colortest.o: $(colortest_mod_DEPENDENCIES) colortest_mod-commands_colortest.o
-rm -f $@
$(TARGET_CC) $(colortest_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ colortest_mod-commands_colortest.o
mod-colortest.o: mod-colortest.c
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -c -o $@ $<
mod-colortest.c: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
sh $(srcdir)/genmodsrc.sh 'colortest' $< > $@ || (rm -f $@; exit 1)
ifneq ($(TARGET_APPLE_CC),1)
def-colortest.lst: pre-colortest.o
$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 colortest/' > $@
else
def-colortest.lst: pre-colortest.o
$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]' | sed 's/^\([^ ]*\).*/\1 colortest/' > $@
endif
und-colortest.lst: pre-colortest.o
echo 'colortest' > $@
$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
colortest_mod-commands_colortest.o: commands/colortest.c $(commands/colortest.c_DEPENDENCIES)
$(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -MD -c -o $@ $<
-include colortest_mod-commands_colortest.d
clean-module-colortest_mod-commands_colortest-extra.1:
rm -f cmd-colortest_mod-commands_colortest.lst fs-colortest_mod-commands_colortest.lst partmap-colortest_mod-commands_colortest.lst handler-colortest_mod-commands_colortest.lst parttool-colortest_mod-commands_colortest.lst video-colortest_mod-commands_colortest.lst terminal-colortest_mod-commands_colortest.lst
CLEAN_MODULE_TARGETS += clean-module-colortest_mod-commands_colortest-extra.1
COMMANDFILES += cmd-colortest_mod-commands_colortest.lst
FSFILES += fs-colortest_mod-commands_colortest.lst
PARTTOOLFILES += parttool-colortest_mod-commands_colortest.lst
PARTMAPFILES += partmap-colortest_mod-commands_colortest.lst
HANDLERFILES += handler-colortest_mod-commands_colortest.lst
TERMINALFILES += terminal-colortest_mod-commands_colortest.lst
VIDEOFILES += video-colortest_mod-commands_colortest.lst
cmd-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) gencmdlist.sh
set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/gencmdlist.sh colortest > $@ || (rm -f $@; exit 1)
fs-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) genfslist.sh
set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genfslist.sh colortest > $@ || (rm -f $@; exit 1)
parttool-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) genparttoollist.sh
set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genparttoollist.sh colortest > $@ || (rm -f $@; exit 1)
partmap-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) genpartmaplist.sh
set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genpartmaplist.sh colortest > $@ || (rm -f $@; exit 1)
handler-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) genhandlerlist.sh
set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genhandlerlist.sh colortest > $@ || (rm -f $@; exit 1)
terminal-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) genterminallist.sh
set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genterminallist.sh colortest > $@ || (rm -f $@; exit 1)
video-colortest_mod-commands_colortest.lst: commands/colortest.c $(commands/colortest.c_DEPENDENCIES) genvideolist.sh
set -e; $(TARGET_CC) -Icommands -I$(srcdir)/commands $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(colortest_mod_CFLAGS) -E $< | sh $(srcdir)/genvideolist.sh colortest > $@ || (rm -f $@; exit 1)
colortest_mod_CFLAGS = $(COMMON_CFLAGS)
colortest_mod_LDFLAGS = $(COMMON_LDFLAGS)
多數在上面是鍋爐鋼板。 我複製了它從一個現有的目標例如在common.mk的tga並且更改了目标名称到colortest。 如果您現在執行從GRUB2修造上層目錄,它做應該包含模塊colortest.mod,在修造完成之後,如果修造是成功的。
這被用于的命令的一個詳細的目錄修造colortest.mod :
gcc -Icommands -I./commands -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/4.4.4/include \
-I./include -I. -I./include -Wall -W -Os -DGRUB_MACHINE_PCBIOS=1 -Wall -W -Wshadow \
-Wpointer-arith -Wmissing-prototypes -Wundef -Wstrict-prototypes -g -falign-jumps=1 \
-falign-loops=1 -falign-functions=1 -mno-mmx -mno-sse -mno-sse2 -mno-3dnow \
-fno-dwarf2-cfi-asm -m32 -fno-stack-protector -mno-stack-arg-probe -Werror -fno-builtin -mrtd \
-mregparm=3 -m32 -MD -c -o colortest_mod-commands_colortest.o commands/colortest.c
rm -f pre-colortest.o
gcc -m32 -nostdlib -m32 -Wl,--build-id=none -Wl,-r,-d -o pre-colortest.o colortest_mod-commands_colortest.o
nm -g --defined-only -P -p pre-colortest.o | sed 's/^\([^ ]*\).*/\1 colortest/' > def-colortest.lst
echo 'colortest' > und-colortest.lst
nm -u -P -p pre-colortest.o | cut -f1 -d' ' >> und-colortest.lst
您能下面看到, 32位矮子可重定位的雙被生產。
file colortest.mod colortest.mod: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped #
有一定數量的方式測試和核實新的colortest模塊。 您能複製colortest.mod入/boot/grub,修改/boot/grub/command.lst增加以下詞條:
colortest: colortest
並且重新起動您的系統對GRUB2指令提示。 從那裡您可能裝載colortest模塊使用insmod和通过输入命令祈求grub_colortest作用colortest或colortest - c在grub>提示。 對這個方法的一個缺點是它要求您重新起動您的系統您每次做出变化對colortest原始代码或建立環境。
如果您想要避免一再必須重新起動您的系統使用GRUB2 userspace仿真器除草根鴯,您能測試功能colortest。 注意除草根鴯沒有為系統孕穗使用; 它是您能從命令行追捕您解雇您的系統入GNU/Linux的独立公共设施。 它看齊,最好它能,但是與一些局限, GRUB2命令行的行為。
修造您需要安排ncurses解放和ncurses-devel包裹被安裝的除草根鴯。 我沒有發現关于怎样的文獻修造除草根鴯,而是發現了如何那么主要經反覆試驗做。 在最后它結果是相當簡單的。
./make clean ./configure --platform=emu ./make ./grub-emu
在一些個报警信息被顯示之後,這應該有您除草根鴯提示。 這些报警信息是正常的。 這什麼除草根鴯輸出當它祈求與时- h選擇:
# ./grub-emu -h Usage: ./grub-emu [OPTION]... GRUB emulator. -r, --root-device=DEV use DEV as the root device [default=guessed] -m, --device-map=FILE use FILE as the device map [default=/boot/grub/device.map] -d, --directory=DIR use GRUB files in the directory DIR [default=/boot/grub] -v, --verbose print verbose messages -H, --hold[=SECONDS] wait until a debugger will attach -h, --help display this message and exit -V, --version print version information and exit Report bugs to. #
順便說一句,进入出口或重新起動退出除草根鴯。 注意模塊例如normal.mod或colortest.mod沒有被修造,當修造GRUB2仿真器时。 那是,因為insmod在除草根鴯不运作並且修造模塊是多餘的。 insmod命令在那裡,但是它不可能做什么。 如果您设法使用insmod從/boot/grub裝載模塊,它將反應與一個無效曲拱獨立矮子不可思議的错误信息。 模塊是任一鑲入在修造過程期間或不是可利用的。 此时,如果您设法執行colortest從除草根鴯的內部您將有錯誤: 未知的命令『colortest』错误信息。
要得到除草根鴯认可colortest命令一定數量的文件需要被修改和除草根鴯重建。 首先,增加以下二條線到除草根鴯init.c :
grub_colortest_init (); grub_colortest_fini ();
應該增加第一條線到grub_init_all做法和對grub_fini_all做法的第二條線。 應該也增加二個適當的作用原型,塑造在其他現有的作用原型,到除草根鴯init.h。 grub_init_all的目的和grub_fini_all (参见… /util/grub-emu.c)是裝載指定的模塊在除草根鴯起動和卸載他們,當除草根鴯終止。
其次,當修造grun鴯时,您需要修改../conf/any-emu.mk增加支持連接colortest入除草根鴯。 在極小值增加命令或colortest.c到grub_emu_SOURCES名單。 當不绝對必需,我會增加grub_emu-commands_colortest.o和grub_emu-commands_colortest.d到清潔方針將去除的文件名單,即乾淨公共事業除草根emu.1 :等等。 终于,我們需要告訴任何emu.mk如何通过增加以下方針編寫包括的colortest.o在除草根鴯到文件:
grub_emu-commands_colortest.o: commands/colortest.c $(commands/colortest.c_DEPENDENCIES)
$(CC) -Icommands -I$(srcdir)/commands $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_emu_CFLAGS) -MD -c -o $@ $<
-include grub_emu-commands_colortest.d
在重建除草根鴯以后, colortest命令應該是列出的,當您输入幫助命令时。
這顯示colortest命令的結果除草根鴯screenshot。

另一個方式安全地測試一個新的模塊將主持在一臺IA32處理器仿真器的GRUB2例如 Qemu 或 Bochs。 然而,我不报道在這個崗位的那些方法。 如果我發現我將蓋他們在分開的时间在不久的將來張貼。
我停止現在書寫。 有希望地,在讀這個崗位以后,您有更好的理解對怎样寫,集成和測試GRUB2模塊。 請告诉我是否有我應該增加到這個崗位將協助瞭解的相關的问题讀者的其他有关信息。
P.S.I建立了並且測試了在X64平臺連續淺頂軟呢帽13的這個崗位包括的例子。


























