|
From: | Luc Van Rompaey |
Subject: | Re: Accessing external code or data from the 'console' kernel module: Can it be done? |
Date: | Thu, 25 Jun 2015 21:23:59 +0200 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.7.0 |
On 24/06/15
08:37, Andrei Borzenkov wrote:
I'm afraid I cannot get this to work, even though I'm trying to mimic some other code that appears to use the same mechanism.On Tue, Jun 23, 2015 at 8:35 PM, Luc Van Rompaey <address@hidden> wrote: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.It can also be a function pointer. So code in console driver would reduce to if (grub_setkey_xlat) grub_setkey_xlat(...) Here's what I'm doing: In console.c (i.e., 'grub-core/term/i386/pc/console.c'), I define the grub_setkey_xlat function pointer: int (*grub_setkey_xlat) (int key) = NULL; Later on in the code, I do the "if (grub_setkey_xlat) blahblahblah" stuff as you suggested. These are the only changes to the 'console.c' source code, exactly as what happens in 'grub-core/kern/device.c' with the 'grub_net_open' variable. Then, in my 'setkey.h' header file, I declare the following: extern int (*EXPORT_VAR (grub_setkey_xlat)) (int key); (just as the 'net.h' header file declares 'grub_net_open'). Then, similar to what 'net.c' does, in the 'GRUB_MOD_INIT(setkey)' function in my 'setkey.c' source file, I assign the appropriate value to the function pointer variable: grub_setkey_xlat = grub_setkey_xlat_real; and in the 'GRUB_MOD_FINI(setkey)' function, I reset the variable to NULL: grub_setkey_xlat = NULL; but when I try to build the software with these changes, it fails to build the 'moddep.lst' target. The 'make' command ends with the following output: mv syminfo.lst.new syminfo.lst cat syminfo.lst | sort | gawk -f ./genmoddep.awk > moddep.lst || (rm -f moddep.lst; exit 1) grub_setkey_xlat in setkey is not defined Makefile:42257: recipe for target 'moddep.lst' failed make[3]: *** [moddep.lst] Error 1 make[3]: Leaving directory '/home/luvr/grubbuildx/grub/grub-core' Makefile:23425: recipe for target 'all' failed make[2]: *** [all] Error 2 make[2]: Leaving directory '/home/luvr/grubbuildx/grub/grub-core' Makefile:10695: recipe for target 'all-recursive' failed make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory '/home/luvr/grubbuildx/grub' Makefile:3091: recipe for target 'all' failed I have no idea what I am missing here. When I grep the syminfo.lst file, I can see that 'grub_net_open' is defined in the kernel: $ grep 'grub_net_open' 'grub/grub-core/syminfo.lst' defined kernel grub_net_open undefined net grub_net_open However, a definition for 'grub_setkey_xlat' is missing: $ grep 'grub_setkey_xlat' 'grub/grub-core/syminfo.lst' undefined setkey grub_setkey_xlat Even so, the occurrences of both strings in the source files are perfectly comparable. The following output was obtained on a cleaned source directory (though I left out the occurrences in the ChangeLog): $ find -type f -print0 | xargs --null grep --fixed-strings 'grub_net_open' ./grub/grub-core/net/net.c:grub_net_open_real (const char *name) ./grub/grub-core/net/net.c: grub_net_open = grub_net_open_real; ./grub/grub-core/net/net.c: grub_net_open = NULL; ./grub/grub-core/kern/device.c:grub_net_t (*grub_net_open) (const char *name) = NULL; ./grub/grub-core/kern/device.c: if (grub_net_open && grub_errno == GRUB_ERR_UNKNOWN_DEVICE) ./grub/grub-core/kern/device.c: dev->net = grub_net_open (name); ./grub/include/grub/net.h:extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); ./grub/include/grub/net.h:grub_net_open_tcp (char *address, grub_uint16_t port); $ find -type f -print0 | xargs --null grep --fixed-strings 'grub_setkey_xlat' ./grub/grub-core/commands/i386/pc/setkey.c:static int grub_setkey_xlat_real (int grub_key) ./grub/grub-core/commands/i386/pc/setkey.c: grub_setkey_xlat = grub_setkey_xlat_real; ./grub/grub-core/commands/i386/pc/setkey.c: grub_setkey_xlat = NULL; ./grub/grub-core/term/i386/pc/console.c:int (*EXPORT_VAR (grub_setkey_xlat)) (int key) = NULL; ./grub/grub-core/term/i386/pc/console.c: return grub_setkey_xlat ? grub_setkey_xlat (regs.eax & 0xff) : (int) (regs.eax & 0xff); ./grub/include/grub/setkey.h:extern int (*EXPORT_VAR (grub_setkey_xlat)) (int key); Looks to me that, at the source-code level, I appear to be doing exactly the same things as the 'net' and 'device' sources are doing. Still, I must be missing SOMETHING. Any ideas about what I'm doing wrong? |
[Prev in Thread] | Current Thread | [Next in Thread] |