Hi, First of all, we can still keep rescue and normal command. But instead of depending on normal.mod, normal command depends on module arg, which is an option parser. Also, these two type of commands are of the same command set. In fact, module arg is implemented as a pre parser, which goes through the list of arguments and extract the options. In the case of rescue command, the pre parser field is null, which means it wants to parse options itself.
Then, I think of a new structure to represent all configurable handlers of grub. Different types of handler have different fields, but they all share a command header: struct grub_handler { .next, .name, .init, .fini }; Same type of handlers are linked together. We first define an enum to list all types. For example: enum { GRUB_HANDLER_INPUT, GRUB_HANDLER_OUTPUT, GRUB_HANDLER_CONSOLE, GRUB_HANDLER_MENU, GRUB_HANDLER_SCRIPT, GRUB_HANDLER_NUM }; Then, we define an array to point to the head of handler linked list: grub_handler[GRUB_HANDLER_NUM]; Head is the default selection. When we insert a new handler module, it would automatically become the new default, although we can switch back to old handler using a command. Here are more details about different handlers: input: This is the input component of terminal: struct grub_handler_input { .next, .name, .init, .fini, .checkkey, .getkey .flags, }; output: This is the output component of terminal: struct grub_handler_output { .next, .name, .init, .fini, .putchar, .getcharwidth, .getxy, .gotoxy, .cls, .setcolorstate, .setcursor, .flags, }; console interface: It represent the grub console, users type commands and execute them line by line. struct grub_handler_console { .next, .name, .init, .fini, .run }; menu interface: It represent the menu, users select a menu item and execute it. struct grub_handler_menu { .next, .name, .init, .fini, .run }; script engine: It's responsible for parsing config file to get the menu list, and execution of commands. struct grub_handler_script { .next, .name, .init, .fini, .readconfig .getmenu .execute }; The handlers are independent of each other. When they need something, they called specific function of the default handler. For example, to read a key from the console, we can use grub_handler[GRUB_HANDLER_INPUT]->getkey. Also, to get the list of items to be displayed on screen, the menu handler can call grub_handler[GRUB_HANDLER_SCRIPT]->getmenu. -- Bean _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel