On 23/06/15
17:23, Andrei Borzenkov wrote:
On Sun, Jun 21, 2015 at 10:27 PM, Luc Van Rompaey
<address@hidden> wrote:
Legacy GRUB had a 'setkey' command to remap the keyboard keys.
GRUB2 no longer has this command. Instead, it provides an 'at_keyboard'
input terminal module, which can load a GRUB keymap.
However, at least on the i386-pc platform, 'at_keyboard' is problematic, in
that it easily causes hangups.
If you could help with fixing it would be great.
Honestly, I would be super happy if I could,
but I'm only just beginning to look at the GRUB code, and I'm
first of all trying to make some sense of it.
Therefore, primarily as a learning exercise, I am trying to implement
something akin to the old 'setkey' command, which I hope to make usable with
the default 'console' input terminal.
By now, I have implemented my own keymap data structure, and I also have a
'setkey' command that can update the data structure.
I am now trying to bridge the gap between my module and the console, so that
the 'grub_console_getkey' function (in the 'console' module) can call my key
mapping function, which will use my keymap data structure to decide whether
(and how) an input key must be remapped.
However, I cannot seem to find a way to share my keymap data structure
between my 'setkey' module and the 'console' input terminal.
WHAT I HAVE ALREADY TRIED:
While I was developing my 'setkey' module, I added an entry for it to the
'grub-core/Makefile.core.def' file, like so:
module = {
name = setkey;
i386 = commands/i386/pc/setkey.c;
enable = i386;
};
Then, after I ran the 'autogen.sh' script, my 'setkey' module got created,
and I could test the operation of its 'setkey' command, to ensure that it
correctly handles the keymap data structure.
Once I was pretty confident that the code worked, I wanted to call my key
mapping function from the 'grub_console_getkey' function--e.g., something
like:
return grub_setkey_xlat (((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED);
or
return grub_setkey_xlat (return regs.eax & 0xff);
However, the linker complained that it could not find my 'setkey' module
when it attempted to create the 'console' module.
If you want to call function from one module in another module, then
"provider" module has to mark function as EXPORT_FUNC; similar
EXPORT_VAR for variable. It creates hard dependency between two
modules - every time "consumer" module is loaded, "provider" module
will be loaded as well. Also during grub image creation module
dependencies will be resolved and all required modules included in
image.
See examples of using EXPORT_FUNC/EXPORT_VAR in code.
Thanks for the clarification. This was, in
fact, exactly how I was beginning to understand this issue.
I then realised that the 'console' module is a part of the GRUB kernel, so I
assumed that I would have to add my 'setkey' module to the kernel as well.
I therefore removed my module entry from the 'grub-core/Makefile.core.def'
file, and added the following line to the 'kernel' entry instead:
i386_pc = commands/i386/pc/setkey.c;
That didn't work either.
First, the compiler complained about missing prototypes for the 'init' and
'fini' functions of my module.
When I added the missing prototypes, the build seemed to work OK, but the
'setkey' command was no longer available. It looked like the 'init' and
'fini' functions weren't invoked, and that, consequently, the 'setkey'
module was no longer recognised as such.
There are no "init" or "fini" for code included in kernel. In any case
this is rather bad idea - your code obviously is not generally
required, so it should not be part of kernel.
Thanks again. I actually didn't want to include my module into the kernel, since, as you say, it is not generally required.
I simply tested this option, in an attempt to find at least _some_ way to achieve what I was trying to do.
I can find a way to link a 'grub_setkey_xlat' function with a hard-coded
keymap data structure to the 'console', but I do not, then, have any way to
dynamically modify the keymap at run-time. Conversely, when I create a
working 'setkey' command, I cannot find a way to have the 'console' see the
keymap data structure (which, then, just sits in memory, being pretty
useless).
I'm out of inspiration now...
Is what I am trying to here even possible? And if it is, then how should I
tackle it?
Make console driver export pointer to a table. This will make it
possible for console driver to work without your module but provides
access to this table if needed.
Of course console driver will need to cope with NULL pointer (or
initialize table to something meaningful).
Hmmm... I think this is the one thing that I
have not yet tried.
If I understand correctly, I would then have to create a an
EXPORT_VAR pointer variable in the console module, and let my
'setkey' module store the appropriate value into it.
The function to remap an input key, according to the contents of
the table, would then be a part of the console driver.
I'll give that a try, and report back with the results.
|