Compare commits

...

16 Commits

Author SHA1 Message Date
Glenn Washburn
29f3131a36 INSTALL: Fix a grammatical error
Also, add more documentation mentioning that the tests require
a "specially crafted environment" to run. Just running as root
is not enough.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-21 20:35:13 +01:00
Glenn Washburn
0a31df119d bootstrap: Condense and simplify LINGUAS generation
Remove unnecessary subshells. Loop over autogenerated po files only once.
Use existing LINGUAS created by bootstrap instead of finding po files
again.

Add wget as a soft requirement now that we are using bootstrap's code
for updating translation files. This should only be needed if updated
translations are desired, which is the default. There should be older
translation files already, and wget is not necessary if those will
suffice.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-21 20:31:55 +01:00
Glenn Washburn
0dfec2945a bootstrap: Migrate linguas.sh into bootstrap.conf
Bootstrap has infrastructure for downloading/updating project po files
and generating the LINGUAS file. It uses wget instead of rsync, but
provides the same functionality, namely that only po files that have
a modification date before the corresponding one on the server will get
redownloaded. Bootstrap creates a pristine copy of the po files in
po/.reference, so update .gitignore to ignore that directory.

Bootstrap also creates the po/LINGUAS file, but it does not know to add
in GRUB's autogenerated po files. So move that code from linguas.sh into
the bootstrap epilogue.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-21 20:30:11 +01:00
Glenn Washburn
8a6ea7ab7b bootstrap: Run linguas.sh in bootstrap epilogue
Heretofore, linguas.sh had to be run by the user and a common mistake
made when building GRUB was to not run the command. By adding it to
the bootstrap epilogue it will by default get run at the end of the
bootstrap script. The user no longer needs to remember to run it.
If the --skip-po option is passed to bootstrap, do not run linguas.sh.
This allows for bootstrap to be run without updating the translations,
which might be desired in the future if we track po files so that
translations can be used as they were at time of release.

Update INSTALL file to reflect that it is no longer necessary to run
linguas.sh. Also, fix a list numbering error.

Fixes: 9f73ebd49b (* INSTALL: Document linguas.sh.)

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-21 20:27:25 +01:00
Avnish Chouhan
cb811bdf05 normal/cmdline: Add grub_calloc() failure check and fix hist_lines state loss
If grub_calloc() fails hist_lines becomes NULL. It means we loose the
reference to the previously allocated hist_lines and leak memory. With
this change on failure hist_lines still points to the old memory. So,
no leak, no state corruption.

Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-21 20:15:38 +01:00
Michael Chang
8a850f47d0 blsuki: Fix grub_errno leakage in blsuki_is_default_entry()
The grub_strtol() call in blsuki_is_default_entry() can set grub_errno
to either GRUB_ERR_BAD_NUMBER or GRUB_ERR_OUT_OF_RANGE if the input
string is invalid or out of range.

This grub_errno value is currently left uncleared, which can lead to
unexpected behavior in subsequent functions that rely on checking
current state of grub_errno.

Clear grub_errno unconditionally when grub_strtol() reports error so
that we can plug the leak.

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 17:46:08 +01:00
Glenn Washburn
a8b2beedf6 Revert "tests: Remove -w param from mkfs.hfsplus command"
The original commit removes testing of GRUB's support for HFS+
wrapping and replaces it with testing that is an exact duplicate of
another test, namely HFS+ without wrapping. To start, the change is
misleading in that it suggests that the testing of HFS+ wrapping is
still taking place, when it is not. If it was desired to remove support
for testing the HFS+ wrapping, then the test should have been removed
entirely. Second, having a series of tests that are exactly the same is
just a waste of testing resources. And third, the justification for the
change is nonsensical. Just because a required program may not have
a required feature on a particular distro is not a reason that a test
should be removed. Reducing test coverage because some distros do not
have the tools GRUB needs to run certain tests goes against the testing
priority to have test coverage be as broad as possible. The fact is
that Debian, the officially supported distro for running the tests, does
have a mkfs.hfsplus that supports the -w parameter.

This reverts commit 2bc0929a2 (tests: Remove -w param from mkfs.hfsplus command).

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 17:41:05 +01:00
Glenn Washburn
1437647052 Revert "tests: Skip tests if required tools are not available"
As explained in commit a21618c8a (tests: Test aborts due to missing
requirements should be marked as error instead of skipped) and in the
Automake manual[1], skipped tests are tests that should not be run, e.g.
running the ohci test on the powerpc-ieee1275 as there are no native ohci
drivers for that platform. Test that fail for reasons other than there is
a bug in GRUB code that is causing the test to fail are hard errors.
Commonly this is because the test is run in an improperly configured
environment, like required programs are missing. If a hard error condition
is identified with a SKIP return code, the person running the tests can not
know without investigating every skip if a SKIP in the tests was because
the test does not apply to the target being tested or because the user had
a misconfigured environment that was causing the test not to run. By
ensuring that a test is skipped only when it should not run, the person
running the test can be sure that there is no need to investigate why the
test was skipped.

This reverts commit bf13fed5f (tests: Skip tests if required tools are not available).

[1] https://www.gnu.org/software/automake/manual/automake.html#Generalities-about-Testing

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 17:38:15 +01:00
Sudhakar Kuppusamy
07c250487f osdep/linux/ofpath: Add missing strdup() failure checks
Segmentation faults or undefined behaviour may result from a NULL pointer
dereference in strip_trailing_digits() and grub_util_devname_to_ofpath()
if strdup() fails. Therefore, I added a NULL check to fix this.

Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Srish Srinivasan <ssrish@linux.ibm.com>
Reviewed-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 17:37:32 +01:00
Vladimir Serbinenko
ae69b464be lib/relocator: Fix dereference after NULL check
In the function free_subchunk(), after checking that subchu->post isn't NULL,
grub_memset() is called on subchu->pre->freebytes but it should be called on
subchu->post->freebytes. If subchu->pre is NULL but subchu->post isn't NULL,
then this could lead to a NULL pointer dereference.

Fixes: CID 473882

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 17:28:00 +01:00
Nicholas Vinson
1a5417f39a configure: Check linker for --image-base support
In several scenarios, configure tests assume it's safe to use
"-Wl,-Ttext,<address>", but starting with ld.lld-21, blindly using that
flag may result in configure-test failures due to ld.lld failing to
link. The failure is because ld.lld-21 no longer allows the specified
address is less than the base address.

However, ld.lld-21+ and ld.bfd-2.44+ both provide support for the
--image-base flag making it preferable over the older -Ttext flag.

Fixes: https://savannah.gnu.org/bugs/?67662

Signed-off-by: Nicholas Vinson <nvinson234@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 17:03:27 +01:00
Glenn Washburn
f41c896d23 INSTALL: Make note that Linux kernel 6.12.x or earlier is needed for reiserfs testing
Also, remove wording suggesting that tests may be skipped if prerequisites
are not installed. Tests should never be skipped because of an environment
misconfiguration, instead they should return a hard error (code 99).

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 16:54:27 +01:00
Glenn Washburn
591e02bc6e docs: Reorganize test section and add section on writing tests
Rename the main section to Tests and put the existing test section into
a subsection. A new subsection called "Writing tests" is added to give
a brief overview and make clear the difference in returning a SKIP code
versus a HARD ERROR code.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 16:50:25 +01:00
Glenn Washburn
db16859e8e docs: Add note and explanation that the privileged user is required for properly running the tests
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 16:46:52 +01:00
Glenn Washburn
7d885513ff docs: Fix spelling, grammatical and usage issues with new Porting section
There are some other fixes outside of this section as well.

Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 16:43:30 +01:00
Glenn Washburn
56ecdfc1a5 util/grub-mkrescue: Fix spelling mistakes
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
2025-11-20 16:41:05 +01:00
41 changed files with 229 additions and 124 deletions

34
INSTALL
View File

@@ -25,6 +25,7 @@ configuring the GRUB.
* Flex 2.5.35 or later
* pkg-config
* GNU patch
* wget (for downloading updated translations)
* Other standard GNU/Unix tools
* a libc with large file support (e.g. glibc 2.1 or later)
@@ -66,7 +67,7 @@ More cross compiling toolchains can be found at the following trusted sites:
* https://mirrors.kernel.org/pub/tools/crosstool/
* https://toolchains.bootlin.com/
Prerequisites for make-check:
Prerequisites for running make-check successfully:
* qemu, specifically the binary "qemu-system-ARCH" where ARCH is the
architecture GRUB has been built for; the "qemu-system" package on Debian
@@ -86,6 +87,8 @@ Prerequisites for make-check:
reiserfs, udf, xfs
- On newer kernels, the exfat kernel modules may be used instead of the
exfat FUSE filesystem
- Kernel version 6.12.x was the last series to include reiserfs support,
so later kernels will fail the reiser filesystem test.
* The following are Debian named packages required mostly for the full
suite of filesystem testing (but some are needed by other tests as well):
- btrfs-progs, dosfstools, e2fsprogs, erofs-utils, exfatprogs, exfat-fuse,
@@ -96,8 +99,8 @@ Prerequisites for make-check:
- attr, cpio, g++, gawk, parted, recode, tar, util-linux
Note that `make check' will run and many tests may complete successfully
with only a subset of these prerequisites. However, some tests may be
skipped or fail due to missing prerequisites.
with only a subset of these prerequisites. However, some tests may fail
due to missing prerequisites.
To build the documentation you'll need:
* texinfo, for the info and html documentation
@@ -140,15 +143,12 @@ The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code.
2. Skip this and following step if you use release tarball and proceed to
step 4. If you want translations type `./linguas.sh'.
3. Type `./bootstrap'.
2. Type `./bootstrap'.
The autogen.sh (called by bootstrap) uses python. By default autodetect
it, but it can be overridden by setting the PYTHON variable.
The autogen.sh (called by bootstrap) uses python. By default it is
autodetected, but it can be overridden by setting the PYTHON variable.
4. Type `./configure' to configure the package for your system.
3. Type `./configure' to configure the package for your system.
If you're using `csh' on an old version of System V, you might
need to type `sh ./configure' instead to prevent `csh' from trying
to execute `configure' itself.
@@ -156,19 +156,19 @@ The simplest way to compile this package is:
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
6. Type `make' to compile the package.
4. Type `make' to compile the package.
7. Optionally, type `make check' to run any self-tests that come with
the package. Note that many of the tests require root privileges in
order to run.
5. Optionally, type `make check' to run any self-tests that come with
the package. Note that many of the tests require root privileges and
a specially crafted environment in order to run.
8. Type `make install' to install the programs and any data files and
6. Type `make install' to install the programs and any data files and
documentation.
9. Type `make html' or `make pdf' to generate the html or pdf
7. Type `make html' or `make pdf' to generate the html or pdf
documentation. Note, these are not built by default.
10. You can remove the program binaries and object files from the
8. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is

View File

@@ -79,6 +79,11 @@ AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
[AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses])
AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
[cat > conftest.c <<\EOF
asm (
".globl start, _start, __start\n"
".ifdef cmain; .set start = _start = __start = cmain\n.endif\n"
".ifdef _cmain; .set start = _start = __start = _cmain\n.endif\n"
);
void cmain (void);
void
cmain (void)

View File

@@ -63,8 +63,6 @@ checkout_only_file=
copy=true
vc_ignore=
SKIP_PO=t
# Build prerequisites
buildreq="\
autoconf 2.64
@@ -108,4 +106,23 @@ bootstrap_post_import_hook () {
bootstrap_epilogue () {
mv INSTALL.grub INSTALL
if [ "x$SKIP_PO" = "x" ]; then
# Generate LINGUAS with all supported languages. Bootstrap will
# generate a LINGUAS, but it will not contain the autogenerated
# languages.
autogenerated="en@quot en@hebrew de@hebrew en@cyrillic en@greek en@arabic en@piglatin de_CH"
{
# NOTE: xargs has no POSIX compliant way to avoid running the program
# given as an argument when there are no input lines. So ensure that
# basename is always run with at least one argument, the empty string,
# and ignore the first line of output.
ls po/*.po | xargs -L 100 basename -s .po -a "" | tail -n +2
for x in $autogenerated; do
rm -f "po/$x.po"
echo "$x"
done
} | sort | uniq | xargs >po/LINGUAS
fi
}

View File

@@ -1461,7 +1461,6 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
TARGET_IMG_CFLAGS=
else
TARGET_APPLE_LINKER=0
@@ -1469,7 +1468,6 @@ else
TARGET_IMG_LDSCRIPT=
TARGET_IMG_LDFLAGS='-Wl,-N'
TARGET_IMG_LDFLAGS_AC='-Wl,-N'
TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
TARGET_IMG_CFLAGS=
fi
@@ -1795,6 +1793,18 @@ LIBS=""
grub_ASM_USCORE
grub_PROG_TARGET_CC
if test "x$TARGET_APPLE_LINKER" != x1 ; then
AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
[TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
[TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"],
[],
[AC_LANG_SOURCE([
asm (".globl start; start:");
asm (".globl _start; _start:");
asm (".globl __start; __start:");
void __main (void);
void __main (void) {}
int main (void);
])])
grub_PROG_OBJCOPY_ABSOLUTE
fi
grub_PROG_LD_BUILD_ID_NONE

View File

@@ -77,7 +77,7 @@ This edition documents version @value{VERSION}.
* Coding style::
* Finding your way around::
* Contributing Changes::
* Setting up and running test suite::
* Tests::
* Updating External Code::
* Debugging::
* Porting::
@@ -485,8 +485,17 @@ If your intention is to just get started, please do not submit a inclusion
request. Instead, please subscribe to the mailing list, and communicate first
(e.g. sending a patch, asking a question, commenting on another message...).
@node Tests
@chapter Tests
@menu
* Setting up and running test suite::
* Writing new tests::
@end menu
@node Setting up and running test suite
@chapter Setting up and running test suite
@section Setting up and running test suite
GRUB is basically a tiny operating system with read support for many file
systems and which has been ported to a variety of architectures. As such, its
@@ -495,6 +504,47 @@ These dependencies are currently documented in the
@uref{https://git.savannah.gnu.org/cgit/grub.git/tree/INSTALL, INSTALL}
file in the source repository. Once installed, the test suite can be started
by running the @command{make check} command from the GRUB build directory.
To properly run all the tests, the test suite must be run as the privileged
user, for instance to run the filesystem tests, which require mounting
filesystem images. Of course, virtualization or containers may be used, but
this requires extra configuration outside the scope of this document.
@node Writing new tests
@section Writing new tests
There are two kinds of tests in the GRUB test suite: native and non-native.
Native tests are those which run on the build architecture and non-native
run on the target architecture. The non-native tests are run in a QEMU
virtual machine using the grub-shell script in tests/util. When writing a
new test, first determine if it should run on the host or the target and
then look at the existing tests as examples of how to they should be written.
The GRUB test suite uses automake (@uref{https://www.gnu.org/software/automake/manual/automake.html#Tests, see documention here}). One thing of importance
to note is that tests have 4 classes of return codes: SKIP (77), HARD ERROR
(99), PASS (0), and FAIL (all other codes). A
@uref{https://www.gnu.org/software/automake/manual/automake.html#index-test-skip, SKIP return code}
should be returned when this test cannot be performed and thus should be
skipped. Typically this is because the target does not support the test,
such as the ohci USB test for the powerpc-ieee1275 target because there
are no native drivers for that target. A
@uref{https://www.gnu.org/software/automake/manual/automake.html#index-Distinction-between-errors-and-failures-in-testsuites, HARD ERROR return code}
should be returned when a failure in something other than what is intended
to be tested happens. This is commonly returned when the test cannot be
properly run because of deficiencies in the test environment, eg. when
testing the xfs filesystem, but the kernel has no support for mounting xfs
volumes. A SKIP should never be returned for a HARD ERROR condition
because at best the person running the test does not know if the test was
skipped because it doesn't apply to the target or because the tester failed
to setup the environment properly. At worst, the tester will believe that
everything is okay without realizing that the tests are not covering all
the code that it should.
Keep portability in mind while creating a new tests so that the tests can be
run on a variety of systems and shells. Do not use bashisms. Also try to avoid
using utilities that would unecessarily add software dependencies. Sometimes
this is unavoidable. Copy or adapt existing test implementations where feasible.
If the test is native and requires root, make sure to check that the test is
run with the root user and return HARD ERROR if it is not.
@node Updating External Code
@chapter Updating external code
@@ -900,26 +950,26 @@ is to be run in a GDB session running with the @file{gdb_grub} GDB script.
@node Porting
@chapter Porting
GRUB2 is designed to be easily portable accross platforms. But because of the
GRUB2 is designed to be easily portable across platforms. But because of the
nature of bootloader every new port must be done separately. Here is how I did
MIPS (loongson and ARC) and Xen ports. Note than this is more of suggestions,
not absolute truth.
MIPS (loongson and ARC) and Xen ports. Note that this is more of a suggestion,
and not absolute truth.
First of all grab any architecture specifications you can find in public
(please avoid NDA).
First of all, grab any architecture specifications you can find in the public
domain (please avoid NDA).
First stage is ``Hello world''. I've done it outside of GRUB for simplicity.
Your task is to have a small program which is loadable as bootloader and
clearly shows its presence to you. If you have easily accessible console
you can just print a message. If you have a mapped framebuffer you know address
clearly shows its presence to you. If you have an easily accessible console
you can just print a message. If you have a mapped framebuffer you know the address
of, you can draw a square. If you have a debug facility, just hanging without
crashing might be enough. For the first stage you can choose to load the
bootloader across the network since format for network image is often easier
crashing might be enough. For the first stage, you can choose to load the
bootloader across the network since the format for a network image is often easier
than for local boot and it skips the need of small intermediary stages and
nvram handling. Additionally you can often have a good idea of the needed
format by running ``file'' on any netbootable executable for given platform.
nvram handling. Additionally, you can often have a good idea of the needed
format by running ``file'' on any netbootable executable for the given platform.
This program should probably have 2 parts: an assembler and C one. Assembler one
This program should probably have 2 parts: an assembler and C one. The assembler one
handles BSS cleaning and other needed setup (on some platforms you may need
to switch modes or copy the executable to its definitive position). So your code
may look like (x86 assembly for illustration purposes)
@@ -961,12 +1011,12 @@ Sometimes you need a third file: assembly stubs for ABI-compatibility.
Once this file is functional it's time to move it into GRUB2. The startup
assembly file goes to grub-core/kern/$cpu/$platform/startup.S. You should also
include grub/symbol.h and replace call to entry point with call to
include grub/symbol.h and replace the call to entry point with call to
EXT_C(grub_main). The C file goes to grub-core/kern/$cpu/$platform/init.c
and its entry point is renamed to void grub_machine_init (void). Keep final
infinite loop for now. Stubs file if any goes to
infinite loop for now. Stub files if any goes to
grub-core/kern/$cpu/$platform/callwrap.S. Sometimes either $cpu or $platform
is dropped if file is used on several cpus respectivelyplatforms.
is dropped if file is used on several cpus respectively or platforms.
Check those locations if they already have what you're looking for.
Then modify in configure.ac the following parts:
@@ -984,10 +1034,10 @@ esac
@end example
Sometimes CPU have additional architecture names which don't influence booting.
You might want to have some canonical name to avoid having bunch of identical
You might want to have some canonical name to avoid having a bunch of identical
platforms with different names.
NOTE: it doesn't influence compile optimisations which depend solely on
NOTE: It doesn't influence compile optimisations which depend solely on
chosen compiler and compile options.
@example
@@ -1049,7 +1099,7 @@ AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platf
@end example
Next stop is gentpl.py. You need to add your platform to the list of supported
ones (sorry that this list is duplicated):
ones (unfortunately, this list is duplicated):
@example
GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
@@ -1059,21 +1109,21 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
"mips_qemu_mips", "s390_mainframe" ]
@end example
You may also want already to add new platform to one or several of available
Now you may also want to add a new platform to one or several of available
groups. In particular we always have a group for each CPU even when only
one platform for given CPU is available.
Then comes grub-core/Makefile.core.def. In the block ``kernel'' you'll need
to define ldflags for your platform ($cpu_$platform_ldflags). You also need to
declare startup asm file ($cpu_$platform_startup) as well as any other files
(e.g. init.c and callwrap.S) (e.g. $cpu_$platform = kern/$cpu/$platform/init.c).
At this stage you will also need to add dummy dl.c and cache.S with functions
declare a startup asm file ($cpu_$platform_startup) as well as any other files,
like init.c or callwrap.S (e.g. $cpu_$platform = kern/$cpu/$platform/init.c).
At this stage, you will also need to add a dummy dl.c and cache.S with functions
grub_err_t grub_arch_dl_check_header (void *ehdr), grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c) and
void grub_arch_sync_caches (void *address, grub_size_t len) (cache.S). They
won't be used for now.
You will need to create directory include/$cpu/$platform and a file
You will need to create a directory include/$cpu/$platform and a file
include/$cpu/types.h. The latter following this template:
@example
@@ -1097,7 +1147,7 @@ include/$cpu/types.h. The latter following this template:
You will also need to add a dummy file to datetime and setjmp modules to
avoid any of it having no files. It can be just completely empty at this stage.
You'll need to make grub-mkimage.c (util/grub_mkimage.c) aware of the needed
You'll need to make grub-mkimage (in util/grub_mkimage.c) aware of the needed
format. For most commonly used formats like ELF, PE, aout or raw the support
is already present and you'll need to make it follow the existant code paths
for your platform adding adjustments if necessary. When done compile:
@@ -1108,47 +1158,47 @@ for your platform adding adjustments if necessary. When done compile:
make > /dev/null
@end example
And create image
And create an image:
@example
./grub-mkimage -d grub-core -O $format_id -o test.img
@end example
And it's time to test your test.img.
And now it's time to test your test.img.
If it works next stage is to have heap, console and timer.
If it works, the next stage is to have a heap, console and timer.
To have the heap working you need to determine which regions are suitable for
heap usage, allocate them from firmware and map (if applicable). Then call
grub_mm_init_region (void *start, grub_size_t s) for every of this region.
As a shortcut for early port you can allocate right after _end or have
a big static array for heap. If you do you'll probably need to come back to
heap usage, allocate them from the firmware and map them, if applicable.
Then call grub_mm_init_region (void *start, grub_size_t s) for each region.
As a shortcut for an early port, you can allocate right after _end or have
a big static array for heap. If you do, you'll probably need to come back to
this later. As for output console you should distinguish between an array of
text, terminfo or graphics-based console. Many of real-world examples don't
text, terminfo or graphics-based console. Many real-world examples don't
fit perfectly into any of these categories but one of the models is easier
to be used as base. In second and third case you should add your platform to
to be used as base. In the second and third case, you should add your platform to
terminfokernel respectively videoinkernel group. A good example of array of
text is i386-pc (kern/i386/pc/init.c and term/i386/pc/console.c).
Of terminfo is ieee1275 (kern/ieee1275/init.c and term/ieee1275/console.c).
Of video is loongson (kern/mips/loongson/init.c). Note that terminfo has
text is i386-pc (kern/i386/pc/init.c and term/i386/pc/console.c),
of terminfo is ieee1275 (kern/ieee1275/init.c and term/ieee1275/console.c),
and of video is loongson (kern/mips/loongson/init.c). Note that terminfo has
to be inited in 2 stages: one before (to get at least rudimentary console
as early as possible) and another after the heap (to get full-featured console).
For the input there are string of keys, terminfo and direct hardware. For string
of keys look at i386-pc (same files), for terminfo ieee1275 (same files) and for
hardware loongson (kern/mips/loongson/init.c and term/at_keyboard.c).
For the input, there is a string of keys (eg. i386-pc, same files), terminfo
(ieee1275, same files), and hardware (loongson, see kern/mips/loongson/init.c
and term/at_keyboard.c).
For the timer you'll need to call grub_install_get_time_ms (...) with as sole
argument a function returning a grub_uint64_t of a number of milliseconds
For the timer, you'll need to call grub_install_get_time_ms (...) with the
sole argument a function returning a grub_uint64_t number of milliseconds
elapsed since arbitrary point in the past.
Once these steps accomplished you can remove the inifinite loop and you should
Once these steps are accomplished, you can remove the inifinite loop and you should
be able to get to the minimal console. Next step is to have module loading
working. For this you'll need to fill kern/$cpu/dl.c and kern/$cpu/cache.S
working. For this, you'll need to fill kern/$cpu/dl.c and kern/$cpu/cache.S
with real handling of relocations and respectively the real sync of I and D
caches. Also you'll need to decide where in the image to store the modules.
Usual way is to have it concatenated at the end. In this case you'll need to
modify startup.S to copy modules out of bss to let's say ALIGN_UP (_end, 8)
before cleaning out bss. You'll probably find useful to add total_module_size
before cleaning out bss. You'll probably find it useful to add total_module_size
field to startup.S. In init.c you need to set grub_modbase to the address
where modules can be found. You may need grub_modules_get_end () to avoid
declaring the space occupied by modules as usable for heap. You can test modules
@@ -1164,9 +1214,9 @@ Once this works, you should think of implementing disk access. Look around
disk/ for examples.
Then, very importantly, you probably need to implement the actual loader
(examples available in loader/)
(examples available in loader/).
Last step to have minimally usable port is to add support to grub-install to
The last step to have a minimally usable port is to add support to grub-install to
put GRUB in a place where firmware or platform will pick it up.
Next steps are: filling datetime.c, setjmp.S, network (net/drivers),
@@ -1175,15 +1225,15 @@ video (video/), halt (lib/), reboot (lib/).
Please add your platform to Platform limitations and Supported kernels chapter
in user documentation and mention any steps you skipped which result in reduced
features or performance. Here is the quick checklist of features. Some of them
are less important than others and skipping them is completely ok, just needs
are less important than others and skipping them is completely ok, it just needs
to be mentioned in user documentation.
Checklist:
@itemize
@item Is heap big enough?
@item Which charset is supported by console?
@item Does platform have disk driver?
@item Do you have network card support?
@item Is the heap big enough?
@item Which charset is supported by the console?
@item Does the platform have disk driver?
@item Is there network card support?
@item Are you able to retrieve datetime (with date)?
@item Are you able to set datetime (with date)?
@item Is serial supported?
@@ -1209,16 +1259,16 @@ GRUB?
@node Error Handling
@chapter Error Handling
Error handling in GRUB 2 is based on exception handling model. As C language
Error handling in GRUB 2 is based on exception handling model. As the C language
doesn't directly support exceptions, exception handling behavior is emulated
in software.
in software.
When exception is raised, function must return to calling function. If calling
When an exception is raised, the function must return to the calling function. If the calling
function does not provide handling of the exception it must return back to its
calling function and so on, until exception is handled. If exception is not
handled before prompt is displayed, error message will be shown to user.
calling function and so on, until the exception is handled. If the exception is not
handled before a prompt is displayed, error message will be shown to user.
Exception information is stored on @code{grub_errno} global variable. If
Exception information is stored in the @code{grub_errno} global variable. If
@code{grub_errno} variable contains value @code{GRUB_ERR_NONE}, there is no active
exception and application can continue normal processing. When @code{grub_errno} has
other value, it is required that application code either handles this error or

View File

@@ -2950,7 +2950,7 @@ Heavily limited platforms:
Lightly limited platforms:
@itemize
@item *-xen: limited only by adress space and RAM size.
@item *-xen: limited only by address space and RAM size.
@item i386-qemu: kernel.img (.text + .data + .bss) is limited by 392704 bytes.
(core.img would be limited by ROM size but it's unlimited on qemu
@item All EFI platforms: limited by contiguous RAM size and possibly firmware bugs

View File

@@ -1360,6 +1360,10 @@ blsuki_is_default_entry (const char *def_entry, grub_blsuki_entry_t *entry, int
return true;
def_idx = grub_strtol (def_entry, &def_entry_end, 0);
/* Clear grub_errno so we can plug the leak. */
grub_errno = GRUB_ERR_NONE;
if (*def_entry_end != '\0' || def_idx < 0 || def_idx > GRUB_INT_MAX)
return false;

View File

@@ -398,9 +398,9 @@ free_subchunk (const struct grub_relocator_subchunk *subchu)
if (subchu->post)
{
int off = subchu->start + subchu->size - fend;
grub_memset (subchu->pre->freebytes,
0xff, sizeof (subchu->pre->freebytes) - off / 8);
subchu->pre->freebytes[off / 8] |= ((1 << (8 - (off % 8))) - 1);
grub_memset (subchu->post->freebytes,
0xff, sizeof (subchu->post->freebytes) - off / 8 - 1);
subchu->post->freebytes[sizeof (subchu->post->freebytes) - off / 8 - 1] |= ((1 << (8 - (off % 8))) - 1);
check_leftover (subchu->post);
}
#endif

View File

@@ -42,7 +42,14 @@ grub_err_t
grub_set_history (int newsize)
{
grub_uint32_t **old_hist_lines = hist_lines;
hist_lines = grub_calloc (newsize, sizeof (grub_uint32_t *));
if (hist_lines == NULL)
{
/* We need to restore hist_lines to avoid memory leak and state loss. */
hist_lines = old_hist_lines;
return grub_errno;
}
/* Copy the old lines into the new buffer. */
if (old_hist_lines)

View File

@@ -695,6 +695,9 @@ strip_trailing_digits (const char *p)
char *new, *end;
new = strdup (p);
if (new == NULL)
return NULL;
end = new + strlen(new) - 1;
while (end >= new)
{
@@ -709,13 +712,18 @@ strip_trailing_digits (const char *p)
char *
grub_util_devname_to_ofpath (const char *sys_devname)
{
char *name_buf, *device, *devnode, *devicenode, *ofpath;
char *name_buf, *device, *devnode, *devicenode, *ofpath = NULL;
name_buf = xrealpath (sys_devname);
device = get_basename (name_buf);
devnode = strip_trailing_digits (name_buf);
if (devnode == NULL)
goto devnode_fail;
devicenode = strip_trailing_digits (device);
if (devicenode == NULL)
goto devicenode_fail;
if (device[0] == 'h' && device[1] == 'd')
ofpath = of_path_of_ide(name_buf, device, devnode, devicenode);
@@ -741,8 +749,12 @@ grub_util_devname_to_ofpath (const char *sys_devname)
ofpath = NULL;
}
free (devnode);
free (devicenode);
devicenode_fail:
free (devnode);
devnode_fail:
free (name_buf);
return ofpath;

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.btrfs >/dev/null 2>&1; then
echo "mkfs.btrfs not installed; cannot test btrfs."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" btrfs

View File

@@ -4,7 +4,7 @@ set -ex
if ! which cpio >/dev/null 2>&1; then
echo "cpio not installed; cannot test cpio."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" cpio_bin

View File

@@ -4,7 +4,7 @@ set -ex
if ! which mkfs.erofs >/dev/null 2>&1; then
echo "mkfs.erofs not installed; cannot test erofs."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" erofs_compact

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.exfat >/dev/null 2>&1; then
echo "mkfs.exfat not installed; cannot test exFAT."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" exfat

View File

@@ -12,17 +12,17 @@ fi
if ! which mkfs.ext2 >/dev/null 2>&1; then
echo "mkfs.ext2 not installed; cannot test ext2."
exit 77
exit 99
fi
if ! which mkfs.ext3 >/dev/null 2>&1; then
echo "mkfs.ext3 not installed; cannot test ext3."
exit 77
exit 99
fi
if ! which mkfs.ext4 >/dev/null 2>&1; then
echo "mkfs.ext4 not installed; cannot test ext4."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" ext2_old

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.f2fs >/dev/null 2>&1; then
echo "mkfs.f2fs not installed; cannot test f2fs."
exit 77
exit 99
fi

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.vfat >/dev/null 2>&1; then
echo "mkfs.vfat not installed; cannot test FAT."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" vfat16a

View File

@@ -27,12 +27,12 @@ fi
if ! which cryptsetup >/dev/null 2>&1; then
echo "cryptsetup not installed; cannot test cryptomount."
exit 77
exit 99
fi
if ! which mkfs.vfat >/dev/null 2>&1; then
echo "mkfs.vfat not installed; cannot test cryptomount."
exit 77
exit 99
fi
COMMON_OPTS='${V:+--debug=$V} --cs-opts="--pbkdf-force-iterations 1000"'

View File

@@ -21,7 +21,7 @@ grubshell=@builddir@/grub-shell
if ! which gzip >/dev/null 2>&1; then
echo "gzip not installed; cannot test gzip compression."
exit 77
exit 99
fi
v=$(echo hello | "${grubshell}" --mkrescue-arg=--compress=gz)

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.hfs >/dev/null 2>&1; then
echo "mkfs.hfs not installed; cannot test HFS."
exit 77
exit 99
fi
if ! grep -q mac_roman /proc/modules && ! modprobe mac_roman; then

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.hfsplus >/dev/null 2>&1; then
echo "mkfs.hfsplus not installed; cannot test hfsplus."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" hfsplus

View File

@@ -4,7 +4,7 @@ set -ex
if ! which xorriso >/dev/null 2>&1; then
echo "xorriso not installed; cannot test iso9660."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" joliet

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.jfs >/dev/null 2>&1; then
echo "mkfs.jfs not installed; cannot test JFS."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" jfs

View File

@@ -12,12 +12,12 @@ fi
if ! which mkfs.ext2 >/dev/null 2>&1; then
echo "mkfs.ext2 not installed; cannot test luks."
exit 77
exit 99
fi
if ! which cryptsetup >/dev/null 2>&1; then
echo "cryptsetup not installed; cannot test luks."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" luks1

View File

@@ -12,12 +12,12 @@ fi
if ! which mkfs.ext2 >/dev/null 2>&1; then
echo "mkfs.ext2 not installed; cannot test luks2."
exit 77
exit 99
fi
if ! which cryptsetup >/dev/null 2>&1; then
echo "cryptsetup not installed; cannot test luks2."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" luks2

View File

@@ -21,7 +21,7 @@ grubshell=@builddir@/grub-shell
if ! which lzop >/dev/null 2>&1; then
echo "lzop not installed; cannot test lzo compression."
exit 77
exit 99
fi
v=$(echo hello | "${grubshell}" --mkrescue-arg=--compress=lzo)

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.minix >/dev/null 2>&1; then
echo "mkfs.minix not installed; cannot test minixfs."
exit 77
exit 99
fi
if ! mkfs.minix -h | grep -- -v > /dev/null; then

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.nilfs2 >/dev/null 2>&1; then
echo "mkfs.nilfs2 not installed; cannot test nilfs2."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" nilfs2

View File

@@ -12,12 +12,12 @@ fi
if ! which mkfs.ntfs >/dev/null 2>&1; then
echo "mkfs.ntfs not installed; cannot test ntfs."
exit 77
exit 99
fi
if ! which setfattr >/dev/null 2>&1; then
echo "setfattr not installed; cannot test ntfs."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" ntfs

View File

@@ -100,7 +100,7 @@ esac
if ! which ${parted} >/dev/null 2>&1; then
echo "${parted} not installed; cannot test partmap"
exit 77
exit 99
fi
imgfile="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 99

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.reiserfs >/dev/null 2>&1; then
echo "mkfs.reiserfs not installed; cannot test reiserfs."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" reiserfs

View File

@@ -4,7 +4,7 @@ set -ex
if ! which genromfs >/dev/null 2>&1; then
echo "genromfs not installed; cannot test romfs."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" romfs

View File

@@ -4,7 +4,7 @@ set -ex
if ! which mksquashfs >/dev/null 2>&1; then
echo "mksquashfs not installed; cannot test squashfs."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" squash4_gzip

View File

@@ -4,7 +4,7 @@ set -ex
if ! which tar >/dev/null 2>&1; then
echo "tar not installed; cannot test tar."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" tarfs

View File

@@ -41,7 +41,7 @@ fi
if ! command -v cryptsetup >/dev/null 2>&1; then
echo "cryptsetup not installed; cannot test tpm2."
exit 77
exit 99
fi
if ! grep -q tpm_vtpm_proxy /proc/modules && ! modprobe tpm_vtpm_proxy; then
@@ -51,7 +51,7 @@ fi
if ! command -v swtpm >/dev/null 2>&1; then
echo "swtpm not installed; cannot test tpm2."
exit 77
exit 99
fi
if ! command -v tpm2_startup >/dev/null 2>&1; then

View File

@@ -12,7 +12,7 @@ fi
if ! which mkudffs >/dev/null 2>&1; then
echo "mkudffs not installed; cannot test UDF."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" udf

View File

@@ -735,7 +735,7 @@ for LOGSECSIZE in $(range "$MINLOGSECSIZE" "$MAXLOGSECSIZE" 1); do
"mkfs.hfsplus" -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x468)) conv=notrunc count=8 ;;
x"hfsplus_wrap")
"mkfs.hfsplus" -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
"mkfs.hfsplus" -w -b $BLKSIZE -v "$FSLABEL" "${MOUNTDEVICE}"
dd if=/dev/urandom of="${MOUNTDEVICE}" bs=1 seek=$((0x468)) conv=notrunc count=8
MOUNTFS="hfsplus";;
x"hfsplus_casesens")

View File

@@ -12,7 +12,7 @@ fi
if ! which mkfs.xfs >/dev/null 2>&1; then
echo "mkfs.xfs not installed; cannot test xfs."
exit 77
exit 99
fi

View File

@@ -21,7 +21,7 @@ grubshell=@builddir@/grub-shell
if ! which xz >/dev/null 2>&1; then
echo "xz not installed; cannot test xz compression."
exit 77
exit 99
fi
v=$(echo hello | "${grubshell}" --mkrescue-arg=--compress=xz)

View File

@@ -12,7 +12,7 @@ fi
if ! which zpool >/dev/null 2>&1; then
echo "zpool not installed; cannot test zfs."
exit 77
exit 99
fi
"@builddir@/grub-fs-tester" zfs

View File

@@ -469,7 +469,7 @@ main (int argc, char *argv[])
argp_argv[0] = argv[0];
argp_argc = 1;
/* argp doesn't allow us to catch unknwon arguments,
/* argp doesn't allow us to catch unknown arguments,
so catch them before passing to argp
*/
{