help-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Accessing external code or data from the 'console' kernel module: Ca


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:
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(...)
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.
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?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]