在grub2中通过grub_register_command 来注册一个command
例如:
cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
N_("Load Linux."));
static inline grub_command_t
grub_register_command (const char *name,
grub_command_func_t func,
const char *summary,
const char *description)
{
return grub_register_command_prio (name, func, summary, description, 0);
}
grub_command_t
grub_register_command_prio (const char *name,
grub_command_func_t func,
const char *summary,
const char *description,
int prio)
{
grub_command_t cmd;
int inactive = 0;
grub_command_t *p, q;
cmd = (grub_command_t) grub_zalloc (sizeof (*cmd));
if (! cmd)
return 0;
cmd->name = name;
cmd->func = func;
cmd->summary = (summary) ? summary : "";
cmd->description = description;
cmd->flags = 0;
cmd->prio = prio;
for (p = &grub_command_list, q = *p; q; p = &(q->next), q = q->next)
{
int r;
//在grub_command_list 中找当前注册的这个cmd的name,这个name可以存在也可以不存在,存在的话就会被芯的回调函数覆盖掉
//而且在grub_command_list 中是按字母排序的
r = grub_strcmp (cmd->name, q->name);
if (r < 0)
break;//如果没有找到,就调出for循环.
if (r > 0)
continue;
//如果走到这里,说明在grub_command_list中之前已经存在这个cmd了
if (cmd->prio >= (q->prio & GRUB_COMMAND_PRIO_MASK))
{
q->prio &= ~GRUB_COMMAND_FLAG_ACTIVE;
break;
}
inactive = 1;
}
这里就到结束就是对链表进行插入操作
*p = cmd;
cmd->next = q;
if (q)
q->prev = &cmd->next;
cmd->prev = p;
if (! inactive)
cmd->prio |= GRUB_COMMAND_FLAG_ACTIVE;
return cmd;
}
明白原理后,就可以注册自己的cmd,以hello这个cmd为例.
static grub_err_t
grub_cmd_hello (grub_extcmd_context_t ctxt __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_printf ("%s\n", _("Hello World"));
return 0;
}
static grub_extcmd_t cmd;
GRUB_MOD_INIT(hello)
{
cmd = grub_register_extcmd ("hello", grub_cmd_hello, 0, 0,
N_("Say `Hello World'."), 0);
}
例如:
cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
N_("Load Linux."));
static inline grub_command_t
grub_register_command (const char *name,
grub_command_func_t func,
const char *summary,
const char *description)
{
return grub_register_command_prio (name, func, summary, description, 0);
}
grub_command_t
grub_register_command_prio (const char *name,
grub_command_func_t func,
const char *summary,
const char *description,
int prio)
{
grub_command_t cmd;
int inactive = 0;
grub_command_t *p, q;
cmd = (grub_command_t) grub_zalloc (sizeof (*cmd));
if (! cmd)
return 0;
cmd->name = name;
cmd->func = func;
cmd->summary = (summary) ? summary : "";
cmd->description = description;
cmd->flags = 0;
cmd->prio = prio;
for (p = &grub_command_list, q = *p; q; p = &(q->next), q = q->next)
{
int r;
//在grub_command_list 中找当前注册的这个cmd的name,这个name可以存在也可以不存在,存在的话就会被芯的回调函数覆盖掉
//而且在grub_command_list 中是按字母排序的
r = grub_strcmp (cmd->name, q->name);
if (r < 0)
break;//如果没有找到,就调出for循环.
if (r > 0)
continue;
//如果走到这里,说明在grub_command_list中之前已经存在这个cmd了
if (cmd->prio >= (q->prio & GRUB_COMMAND_PRIO_MASK))
{
q->prio &= ~GRUB_COMMAND_FLAG_ACTIVE;
break;
}
inactive = 1;
}
这里就到结束就是对链表进行插入操作
*p = cmd;
cmd->next = q;
if (q)
q->prev = &cmd->next;
cmd->prev = p;
if (! inactive)
cmd->prio |= GRUB_COMMAND_FLAG_ACTIVE;
return cmd;
}
明白原理后,就可以注册自己的cmd,以hello这个cmd为例.
static grub_err_t
grub_cmd_hello (grub_extcmd_context_t ctxt __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
grub_printf ("%s\n", _("Hello World"));
return 0;
}
static grub_extcmd_t cmd;
GRUB_MOD_INIT(hello)
{
cmd = grub_register_extcmd ("hello", grub_cmd_hello, 0, 0,
N_("Say `Hello World'."), 0);
}