grub-devel
[Top][All Lists]
Advanced

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

Re: Question: how to add new menu functionality


From: Colin Watson
Subject: Re: Question: how to add new menu functionality
Date: Fri, 22 Apr 2011 12:40:56 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

On Fri, Apr 22, 2011 at 06:03:41AM -0400, Stephen Torri wrote:
> I am using the released grub-1.98 code for my development.

I recommend using 1.99~rc2 or a current bzr checkout, if you can.  Not
just on general principles, but because its rewritten build system is
really a great deal easier to modify in the kinds of ways you need.
1.98's was generally a pain.

> The problem I am having is how to add new functionality to the
> 'normal' module. I would like to add a new feature to the code using
> some functions that don't presently exist in the code. When I coded
> the functions I had to manually edit def-normal.lst to get the
> compiler to be happy and successfully complete the build.

That's a sign that you've missed something; you should never have to
edit that file.

> This was not enough because when used the new grub2 loader on a drive
> I got an error saying "error: the symbol 'work' not found" is
> displayed. This error code is reported because the symbol cannot be
> found in a symbol table. So to summarize what I am asking:
> 
> 1. How do you configure the build system to compile with new files (e.g.
> new command for command line)?

In 1.98, you need to find the appropriate targets in conf/*.rmk (they'll
either be in common.rmk or a platform-specific file - you may need to
edit both), and add the new files there.

In 1.99, you need to edit grub-core/Makefile.core.def and add lines for
the files you're adding to the appropriate target block, either with
'common =' if they're platform-independent, or with a platform-specific
prefix.  Follow the patterns of the surrounding lines.

In either case, you need to run ./autogen.sh and (re-)run ./configure
before building.  This may require additional build system dependencies
beyond those required to build GRUB itself; see the INSTALL file.

It helps to work in a bzr checkout, so that you can use the usual
version control commands to keep track of what you've changed (even if
you never commit anything).

> 2. How do you configure the build system to compile with new functions
> contained in existing files?

Using new functions entirely within a single file requires no special
actions, in either 1.98 or 1.99.

If you're using functions in file A that are defined in file B, you'll
need to make sure that file A includes any necessary headers
(conventionally in include/grub/, using '#include <grub/foo.h>'), and
that any targets that involve file A also involve file B, much as you
would for any normal C project.  See my answer to your previous question
for the exact build system mechanics.

> 3. Is there a tutorial on how to develop for Grub2? If I missed that in
> my search I am sorry for not reading that first.

I've seen the odd one floating around, but they've generally had
substantial flaws (even one of the best I saw involved editing generated
build system files rather than the source files, which is unwise) and/or
not been up to date.  We recently started writing a developer manual,
which is in docs/grub-dev.texi in 1.99~rc2 (or a current bzr checkout)
although not yet on the web.  It may well not yet be what you need, but
it should be a useful start and we'd appreciate feedback from people
trying to use it.

> 4. How do you debug your Grub2 builds? The web had references to a patch
> to add in GDB functionality.

That patch is pretty old and won't apply to current builds.  I recently
started attempting to bring it up to date, although I've been very busy
and so don't have anything to show yet.  I have a few train journeys and
hotel stays in my near future, and may well hack on it then.

For most purposes, using grub_dprintf and 'set debug=all' (or a more
limited set of debug options) is good enough: add debugging output until
it shows what you need.  It helps enormously if your code can be run in
a rescue image that you can run in a virtual machine.  In a built 1.98
tree, where the 'rescue-disk' directory is one you've created with any
other files you need in the rescue image:

  ./grub-mkrescue --override-directory=. --output=grub.iso rescue-disk

In 1.99:

  ./grub-mkrescue --grub-mkimage=./grub-mkimage --override-directory=grub-core 
--output=grub.iso rescue-disk

You can then boot this in 'kvm -cdrom grub.iso' or similar.  This
greatly speeds up the debugging cycle, versus having to boot it on real
hardware.

In some cases, particularly if you're working on a failure very early
on, you need to resort to stronger techniques.  For instance, a serial
console means that you can see more debugging output, and can help if
the debugging output you need is from the video subsystem (since of
course changing video modes loses screen contents).  GDB-over-serial
will no doubt be great when we get that far.  It's also possible to use
GDB in conjunction with QEMU to debug some parts of GRUB even without
special support in GRUB, if you're sufficiently determined and can cope
with the lack of symbols.  I wrote about this on my blog recently:

  
http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/ubuntu/2011-03-14-wubi-bug-693671.html

Depending on what you're doing, you can often debug large parts of GRUB
in userspace, which makes hacking on GRUB a lot more fun.  For instance,
you can use grub-probe or grub-fstest to debug filesystem drivers, and
you can use grub-emu to debug some other things if you can live with its
eccentricities.  As general advice, it's worth spending a little time
up-front to attempt to move your problem into the most congenial
debugging environment available; GRUB offers developers several ways to
do that, and so it is rarely necessary to resort to heroic techniques
unless you are working on the lowest levels of machine-dependent code.

Cheers,

-- 
Colin Watson                                       address@hidden



reply via email to

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