grub4dos从0.4.5版开始可以运行用户自己写的外部命令了。
以下是例子是echo命令也就是相当于c语言的printf函数。
******************************************************************************
*** Running User Programs ***
******************************************************************************
From 0.4.5 on, user programs can be developed for running under grub4dos. The
executable program file must end with the 8-byte grub4dos EXEC signature:
0×05, 0×18, 0×05, 0×03, 0xBA, 0xA7, 0xBA, 0xBC
The executable must have no relocations, and the entry point is at the very
beginning of the file, just like a DOS .com file(but the grub4dos executable
is 32-bit).
Here is a sample file echo.c:
/*
* compile:
gcc -nostdlib -fno-zero-initialized-in-bss -fno-function-cse -fno-jump-tables -Wl,-N -fPIE echo.c
* disassemble: objdump -d a.out
* confirm no relocation: readelf -r a.out
* generate executable: objcopy -O binary a.out b.out
*
* and then the resultant b.out will be grub4dos executable.
*/
/*
* This is a simple ECHO command, running under grub4dos.
*/
int i = 0×66666666; /* this is needed, see the following comment. */
/* gcc treat the following as data only if a global initialization like the
* above line occurs.
*/
/* a valid executable file for grub4dos must end with these 8 bytes */
asm(“.long 0×03051805″);
asm(“.long 0xBCBAA7BA”);
/* thank goodness gcc will place the above 8 bytes at the end of the b.out
* file. Do not insert any other asm lines here.
*/
int
main()
{
void *p = &main;
return
/* the following line is calling the grub_sprintf function. */
((int (*)(char *, const char *, …))((*(int **)0×8300)[0]))
/* the following line includes arguments passed to grub_sprintf. */
(0, p - (*(int *)(p - 8)));
}
/*================ end echo.c ================*/
0×8300 is a pointer to the grub4dos system funtions(API). The system_functions
variable is defined in asm.S.
另外为了方便使用也可以把上面的函数重新定义下,我根据自己的理解整理一下的代码如下。
/* 以下两句不可更改后面也不要有其它ASM代码,文件签名EXEC */
asm(“.long 0×03051805″);
asm(“.long 0xBCBAA7BA”);
/*重新定义printf和sprintf函数*/
#define printf(format…) ((int (*)(const char *, …))((*(int **)0×8300)[0])) (0, format)
#define sprintf(buffer,format…) ((int (*)(char *,const char *, …))((*(int **)0×8300)[0])) (buffer, format)
/*程序开始*/
int
main()
{
void *p = &main;
char *arg=p - (*(int *)(p - 8)); /*p – (*(int *)(p – 8)) 是代表命令行参数 */
return printf(arg);
}
很简单吧,你也可以自己写一个可以用于GRUB4DOS的外部命令。
本文用菊子曰发布