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的这个岗位包括的例子。


























