summaryrefslogtreecommitdiff
path: root/config/module/grub/default
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-09-18 21:04:00 +0100
committerLeah Rowe <leah@libreboot.org>2026-09-20 13:53:33 +0100
commit076c87ccf68f7fe5a3998e8cd8edd2033a2f2ef0 (patch)
tree9aaf04cfa16565227f733b917af3e3c485505544 /config/module/grub/default
parent387e6dd771588b7f8426c8d0934e610626730d51 (diff)
xbmk: make all projects multi-tree
we currently distinguish, by virtue of logic, multi- and single-tree projects. this introduces a lot of complexity, so the following patch has removed this distinction. all single-tree projects are now multi tree, but with only one tree. other design changes: config/git removed. rev/tree now handled with mkhelper and target configs. this allows per-tree remote handling, so we could (for example) add the mrchromebox coreboot fork easily, for specific chromebook models. config/project is now config/module/project. this cleans up the main config/ directory. cfgname variable: .config no longer hardcoded when doing configs in projects. it is configurable with this variable. if unset, the previous .cfg is used noconfig variable: set this in target/mkhelper configs, and config/module/project/tree/config/ is unused; instead, make is called without config copying. a "noconfig" placeholder is used. this enables cleaner usage of previously single-tree projects in the new multi-tree-only structure. cfgvars: variables reinitialised in project config are cleaned more reliably. in particular, several variables e.g. autogenargs were not being reset between projects, although the autogenargs variable is currently unused. general cleanup has been conducted across the build system, as part of this redesign. several parts of the build system more over-engineered as a result of the previous design, and the new design enabled a severe reduction in sloccount (75 lines reduced in lbmk). yes, this change *adds features* but there are fewer lines of code than before. this is the best kind of change. way better than the 3-line-diff. yes. rev= and tree= are set more centrally in configs. the mkhelper config can be used to set url/url_bkup, but individual trees can override them. configs have been cleaned up, with several variables now much more heavily centralised. config/git/ was used before to first download the bare repository, and then the real clone was made with patches. this allows git repositories to be cached for future re-builds. with config/git/ gone, the download logic for projects is more centrally implemented. a separate call to ./mk -f is no longer performed, and in fact ./mk -f never needs to be used anymore as a result. ./mk -f now is basically the same thing as -b, just without any action performed. this change will allow rapid expansion of the libreboot project. i want to add hundreds of chromebooks to the project, using mrchromebox, but the previous design did not permit this. this change means that i can easily have unlimited upstreams per project. coreboot will, in some follow-up changes, have the following upstreams: coreboot/default: coreboot.org coreboot/fam15h: 15h.org fork coreboot/chromebook: mrchromebox fork this can now be done freely without massive changes to the build system. under the previous design, i worked on a now-abandoned patch to do N remotes per project, reading repo links from a file. this meant that i'd have coreboot.org first (main and backup), then mrchromebox. this meant that lbmk would failover through to mrchromebox, wasting time for the user. this new design is much cleaner, and will enable the project to be maintained much more easily. Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'config/module/grub/default')
-rw-r--r--config/module/grub/default/config/payload305
-rw-r--r--config/module/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch90
-rw-r--r--config/module/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch25
-rw-r--r--config/module/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch107
-rw-r--r--config/module/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch38
-rw-r--r--config/module/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch102
-rw-r--r--config/module/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch34
-rw-r--r--config/module/grub/default/patches/0007-don-t-print-empty-error-messages.patch31
-rw-r--r--config/module/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch37
-rw-r--r--config/module/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch70
-rw-r--r--config/module/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch30
-rw-r--r--config/module/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch91
-rw-r--r--config/module/grub/default/target.cfg5
13 files changed, 965 insertions, 0 deletions
diff --git a/config/module/grub/default/config/payload b/config/module/grub/default/config/payload
new file mode 100644
index 00000000..3d84413e
--- /dev/null
+++ b/config/module/grub/default/config/payload
@@ -0,0 +1,305 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2014-2016,2020-2021,2023-2025 Leah Rowe <leah@libreboot.org>
+# Copyright (C) 2015 Klemens Nanni <contact@autoboot.org>
+
+set prefix=(memdisk)/boot/grub
+
+insmod at_keyboard
+insmod usb_keyboard
+insmod nativedisk
+insmod ehci
+insmod ohci
+insmod uhci
+insmod usb
+insmod usbms
+insmod regexp
+
+terminal_input --append at_keyboard
+terminal_input --append usb_keyboard
+terminal_output --append cbmemc
+
+# User interface overrides wherever "keystatus" is supported
+# Keep SHIFT key pressed before powering on to disable graphics
+if keystatus --shift; then
+ terminal_output --append vga_text
+else
+ gfxpayload=keep
+ terminal_output --append gfxterm
+
+ for dt in cbfsdisk memdisk; do
+ for it in png jpg; do
+ if [ -f (${dt})/background.${it} ]; then
+ insmod ${it}
+ background_image (${dt})/background.${it}
+ fi
+ done
+ done
+fi
+
+# Keep CTRL pressed to enable default serial terminal (COM1 or the like)
+if keystatus --ctrl; then
+ serial
+ terminal_input --append serial
+ terminal_output --append serial
+fi
+
+# Keep ALT pressed to enable spkmodem
+if keystatus --alt; then
+ terminal_output --append spkmodem
+fi
+
+
+set default="0"
+if [ -f (cbfsdisk)/timeout.cfg ]; then
+ source (cbfsdisk)/timeout.cfg
+else
+ set timeout=8
+fi
+set grub_scan_disk="ahci ata"
+if [ -f (cbfsdisk)/scan.cfg ]; then
+ source (cbfsdisk)/scan.cfg
+fi
+
+if [ -f (cbfsdisk)/keymap.gkb ]; then
+ keymap (cbfsdisk)/keymap.gkb
+fi
+
+function really_try_user_config {
+ set root="${1}"
+
+ if [ -f /"${2}"/grub.cfg ]; then
+ unset superusers
+ configfile /"${2}"/grub.cfg
+ fi
+}
+
+function try_user_config {
+ # The @/... entries are for cases where the BTRFS filesystem is being used
+ for dir in grub boot/grub @/grub @/boot/grub grub2 boot/grub2 @/grub2 @/boot/grub2 boot @/boot; do
+ really_try_user_config "${1}" "${dir}"
+ done
+ for dir in ubuntu debian redhat; do
+ really_try_user_config "${1}" "EFI/${dir}"
+ done
+}
+function search_grub {
+ echo -n "Attempting to load grub.cfg from '${1}' devices"
+ for i in 0 1 2 3 4 5 6 7 8; do
+ for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
+ if [ "${1}" != "nvme" ]; then
+ try_user_config "(${1}${i},${part})"
+ fi
+ done
+ if [ "${1}" != "nvme" ]; then
+ # raw devices e.g. (ahci0) instead of (ahci0,1)
+ try_user_config "(${1}${i})"
+ fi
+ done
+ echo # Insert newline
+}
+
+function try_isolinux_config {
+ set root="${1}"
+ for dir in '' /boot /EFI /@ /@/boot; do
+ if [ -f "${dir}"/isolinux/isolinux.cfg ]; then
+ syslinux_configfile -i "${dir}"/isolinux/isolinux.cfg
+ elif [ -f "${dir}"/syslinux/syslinux.cfg ]; then
+ syslinux_configfile -s "${dir}"/syslinux/syslinux.cfg
+ elif [ -f "${dir}"/syslinux/extlinux.conf ]; then
+ syslinux_configfile -s "${dir}"/syslinux/extlinux.conf
+ elif [ -f "${dir}"/extlinux/extlinux.conf ]; then
+ syslinux_configfile -s "${dir}"/extlinux/extlinux.conf
+ fi
+ done
+}
+function search_isolinux {
+ echo "\nAttempting to parse iso/sys/extlinux config from '${1}' devices"
+ for i in 0 1 2 3 4 5 6 7 8; do
+ for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
+ if [ "${1}" != "nvme" ]; then
+ try_isolinux_config "(${1}${i},${part})"
+ fi
+ done
+ if [ "${1}" != "nvme" ]; then
+ # raw devices e.g. (usb0) instead of (usb0,1)
+ try_isolinux_config "(${1}${i})"
+ fi
+ done
+ echo # Insert newline
+}
+function try_bootcfg {
+ try_user_config "${1}"
+ try_isolinux_config "${1}"
+}
+function search_bootcfg {
+ search_grub "${1}"
+ search_isolinux "${1}"
+}
+menuentry 'Load Operating System (incl. fully encrypted disks) [o]' --hotkey='o' {
+
+ for grub_disk in ${grub_scan_disk}; do
+ search_bootcfg ${grub_disk}
+ done
+
+ # grub device enumeration is very slow, so checks are hardcoded
+
+ raidvol="md/0 md/1 md/2 md/3 md/4 md/5 md/6 md/7 md/8 md/9"
+
+ # in practise, doing multiple redundant checks is perfectly fast
+ # TODO: optimize grub itself, and use */? here for everything
+
+ for vol in ${raidvol} ; do
+ try_bootcfg "${vol}"
+ done
+
+ unset bootdev
+ for grub_disk in ${grub_scan_disk}; do
+ for i in 0 1 2 3 4 5 6 7 8; do
+ for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
+ if [ "${grub_disk}" = "ahci" ]; then
+ bootdev="${bootdev} (ahci${i},${part})"
+ elif [ "${grub_disk}" = "ata" ]; then
+ bootdev="${bootdev} (ata${i},${part})"
+ elif [ "${grub_disk}" = "nvme" ]; then
+ # TODO: do we care about other namesapces
+ bootdev="${bootdev} (nvme${i}n1,${part})"
+ fi
+ done
+ done
+ done
+
+ set pager=0
+ echo -n "Attempting to unlock encrypted volumes"
+ for dev in ${bootdev} ${raidvol}; do
+ if cryptomount "${dev}" ; then break ; fi
+ done
+ set pager=1
+ echo
+
+ search_bootcfg crypto
+
+ lvmvol=""
+
+ # after cryptomount, lvm volumes might be available
+ # using * is slow on some machines, but we use it here,
+ # just once. in so doing, we find every lvm volume
+ for vol in (*); do
+ if regexp ^\\(lvm/ $vol; then
+ lvmvol="${lvmvol} ${vol}"
+ try_bootcfg "${vol}"
+ fi
+ done
+
+ # user might have put luks inside lvm
+ set pager=0
+ echo "Attempting to unlock encrypted LVMs"
+ for vol in ${lvmvol}; do
+ cryptomount "$vol"
+ done
+ set pager=1
+ echo
+
+ search_bootcfg crypto
+
+ true # Prevent pager requiring to accept each line instead of whole screen
+}
+
+menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on USB [s]' --hotkey='s' {
+ search_bootcfg usb
+}
+menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on AHCI [a]' --hotkey='a' {
+ search_bootcfg ahci
+}
+menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on ATA/IDE [d]' --hotkey='d' {
+ search_bootcfg ata
+}
+if [ -f (cbfsdisk)/grub.cfg ]; then
+menuentry 'Load configuration (grub.cfg) in CBFS [t]' --hotkey='t' {
+ set root='(cbfsdisk)'
+ if [ -f /grub.cfg ]; then
+ configfile /grub.cfg
+ fi
+}
+fi
+if [ -f (cbfsdisk)/grubtest.cfg ]; then
+menuentry 'Load test configuration (grubtest.cfg) inside of CBFS [t]' --hotkey='t' {
+ set root='(cbfsdisk)'
+ if [ -f /grubtest.cfg ]; then
+ configfile /grubtest.cfg
+ fi
+}
+fi
+if [ -f (cbfsdisk)/u-boot ]; then
+menuentry 'U-Boot i386 payload (experimental) [u]' --hotkey='u' {
+ set root='cbfsdisk'
+ chainloader /u-boot
+}
+fi
+if [ -f (cbfsdisk)/seabios.elf ]; then
+if [ -f (cbfsdisk)/img/u-boot ]; then
+menuentry 'Load SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
+ set root='cbfsdisk'
+ chainloader /seabios.elf
+}
+else
+menuentry 'Load SeaBIOS [b]' --hotkey='b' {
+ set root='cbfsdisk'
+ chainloader /seabios.elf
+}
+fi
+fi
+if [ -f (cbfsdisk)/img/grub2 ]; then
+if [ -f (cbfsdisk)/img/u-boot ]; then
+menuentry 'Return to SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
+ set root='cbfsdisk'
+ chainloader /fallback/payload
+}
+else
+menuentry 'Return to SeaBIOS [b]' --hotkey='b' {
+ set root='cbfsdisk'
+ chainloader /fallback/payload
+}
+fi
+fi
+menuentry 'Poweroff [p]' --hotkey='p' {
+ halt
+}
+menuentry 'Reboot [r]' --hotkey='r' {
+ reboot
+}
+if [ -f (cbfsdisk)/img/memtest ]; then
+menuentry 'Load MemTest86+ [m]' --hotkey='m' {
+ set root='cbfsdisk'
+ chainloader /img/memtest
+}
+fi
+
+submenu 'Other [z]' --hotkey='z' {
+ menuentry 'Enable default serial terminal [s]' --hotkey='s' {
+ serial
+ terminal_input --append serial
+ terminal_output --append serial
+ }
+
+ menuentry 'Disable default serial terminal' {
+ terminal_input --remove serial
+ terminal_output --remove serial
+ }
+
+ menuentry 'Enable gfxterm' {
+ terminal_output --append gfxterm
+ terminal_output --remove vga_text
+ }
+ menuentry 'Disable gfxterm [g]' --hotkey='g' {
+ terminal_output --remove gfxterm
+ terminal_output --append vga_text
+ }
+
+ menuentry 'Enable spkmodem [a]' --hotkey='a' {
+ terminal_output --append spkmodem
+ }
+
+ menuentry 'Disable spkmodem [z]' --hotkey='z' {
+ terminal_output --remove spkmodem
+ }
+}
diff --git a/config/module/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch b/config/module/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
new file mode 100644
index 00000000..7112b0aa
--- /dev/null
+++ b/config/module/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
@@ -0,0 +1,90 @@
+From 5a2c887181e7cdbd6b38d544e460d02623c902e6 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Sun, 31 Oct 2021 03:47:05 +0000
+Subject: [PATCH 01/10] mitigate grub's missing characters for borders/arrow
+ characters
+
+This cleans up the display on the main screen in GRUB.
+
+Just don't draw a border, at all.
+---
+ grub-core/normal/menu_text.c | 49 ++----------------------------------
+ 1 file changed, 2 insertions(+), 47 deletions(-)
+
+diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
+index 9c383e64a..8ec1dd1e8 100644
+--- a/grub-core/normal/menu_text.c
++++ b/grub-core/normal/menu_text.c
+@@ -108,47 +108,6 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right,
+ grub_print_message_indented_real (msg, margin_left, margin_right, term, 0);
+ }
+
+-static void
+-draw_border (struct grub_term_output *term, const struct grub_term_screen_geometry *geo)
+-{
+- int i;
+-
+- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+-
+- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
+- geo->first_entry_y - 1 });
+- grub_putcode (GRUB_UNICODE_CORNER_UL, term);
+- for (i = 0; i < geo->entry_width + 1; i++)
+- grub_putcode (GRUB_UNICODE_HLINE, term);
+- grub_putcode (GRUB_UNICODE_CORNER_UR, term);
+-
+- for (i = 0; i < geo->num_entries; i++)
+- {
+- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
+- geo->first_entry_y + i });
+- grub_putcode (GRUB_UNICODE_VLINE, term);
+- grub_term_gotoxy (term,
+- (struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1,
+- geo->first_entry_y + i });
+- grub_putcode (GRUB_UNICODE_VLINE, term);
+- }
+-
+- grub_term_gotoxy (term,
+- (struct grub_term_coordinate) { geo->first_entry_x - 1,
+- geo->first_entry_y - 1 + geo->num_entries + 1 });
+- grub_putcode (GRUB_UNICODE_CORNER_LL, term);
+- for (i = 0; i < geo->entry_width + 1; i++)
+- grub_putcode (GRUB_UNICODE_HLINE, term);
+- grub_putcode (GRUB_UNICODE_CORNER_LR, term);
+-
+- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+-
+- grub_term_gotoxy (term,
+- (struct grub_term_coordinate) { geo->first_entry_x - 1,
+- (geo->first_entry_y - 1 + geo->num_entries
+- + GRUB_TERM_MARGIN + 1) });
+-}
+-
+ static int
+ print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
+ {
+@@ -167,10 +126,8 @@ command-line or ESC to discard edits and return to the GRUB menu."),
+ {
+ char *msg_translated;
+
+- msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
+- "entry is highlighted."),
+- GRUB_UNICODE_UPARROW,
+- GRUB_UNICODE_DOWNARROW);
++ msg_translated = grub_xasprintf (_("Use the arrow keys to select which "
++ "entry is highlighted."));
+ if (!msg_translated)
+ return 0;
+ ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
+@@ -413,8 +370,6 @@ grub_menu_init_page (int nested, int edit,
+
+ grub_term_normal_color = grub_color_menu_normal;
+ grub_term_highlight_color = grub_color_menu_highlight;
+- if (geo->border)
+- draw_border (term, geo);
+ grub_term_normal_color = old_color_normal;
+ grub_term_highlight_color = old_color_highlight;
+ geo->timeout_y = geo->first_entry_y + geo->num_entries
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch b/config/module/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
new file mode 100644
index 00000000..af139ffc
--- /dev/null
+++ b/config/module/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
@@ -0,0 +1,25 @@
+From 25d7d35e0af74361a5510c3e6313b8ce5e00cd6a Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Sat, 19 Nov 2022 16:30:24 +0000
+Subject: [PATCH 02/10] say the name libreboot, in the grub menu
+
+---
+ grub-core/normal/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
+index de9a3f961..bed502cde 100644
+--- a/grub-core/normal/main.c
++++ b/grub-core/normal/main.c
+@@ -215,7 +215,7 @@ grub_normal_init_page (struct grub_term_output *term,
+
+ grub_term_cls (term);
+
+- msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION);
++ msg_formatted = grub_xasprintf (_("Libreboot 26.01 Magnanimous Max (GRUB menu): https://libreboot.org/"));
+ if (!msg_formatted)
+ return;
+
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/module/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
new file mode 100644
index 00000000..bb07abd6
--- /dev/null
+++ b/config/module/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
@@ -0,0 +1,107 @@
+From acff2df937bb4172f9bdb46d12e82edbbcad7996 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Mon, 30 Oct 2023 22:19:21 +0000
+Subject: [PATCH 03/10] at_keyboard coreboot: force scancodes2+translate
+
+Scan code set 2 with translation should be assumed in
+every case, as the default starting position.
+
+However, GRUB is trying to detect and use other modes
+such as set 2 without translation, or set 1 without
+translation from set 2; it also detects no-mode and
+assumes mode 1, on really old keyboards.
+
+The current behaviour has been retained, for everything
+except GRUB_MACHINE_COREBOOT; for the latter, scan code
+set 2 with translation is hardcoded, and forced in code.
+
+This is required to make keyboard initialisation work on
+the MEC5035 EC used by the Dell Latitude E6400, when
+running GRUB as a coreboot payload on that laptop. The
+EC reports scancode set 2 with translation when probed,
+but actually only outputs scancode set 1.
+
+Since GRUB is attempting to use it without translation,
+and since the machine reports set 2 with translation,
+but only ever outputs set 1 scancodes, this results in
+wrong keypresses for every key.
+
+This fix fixed that, by forcing set 2 with translation,
+treating it as set 1, but only on coreboot. This is the
+same behaviour used in GNU+Linux systems and SeaBIOS.
+With this change, GRUB keyboard initialisation now works
+just fine on those machines.
+
+This has *also* been tested on other coreboot machines
+running GRUB; several HP EliteBooks, ThinkPads and
+Dell Precision T1650. All seems to work just fine.
+
+Signed-off-by: Leah Rowe <leah@libreboot.org>
+---
+ grub-core/term/at_keyboard.c | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
+index f8a129eb7..8207225c2 100644
+--- a/grub-core/term/at_keyboard.c
++++ b/grub-core/term/at_keyboard.c
+@@ -138,6 +138,7 @@ write_mode (int mode)
+ return (i != GRUB_AT_TRIES);
+ }
+
++#if !defined (GRUB_MACHINE_COREBOOT)
+ static int
+ query_mode (void)
+ {
+@@ -161,10 +162,12 @@ query_mode (void)
+ return 3;
+ return 0;
+ }
++#endif
+
+ static void
+ set_scancodes (void)
+ {
++#if !defined (GRUB_MACHINE_COREBOOT)
+ /* You must have visited computer museum. Keyboard without scancode set
+ knowledge. Assume XT. */
+ if (!grub_keyboard_orig_set)
+@@ -173,20 +176,33 @@ set_scancodes (void)
+ ps2_state.current_set = 1;
+ return;
+ }
++#endif
+
+ #if !USE_SCANCODE_SET
+ ps2_state.current_set = 1;
+ return;
+-#else
++#endif
+
++#if defined (GRUB_MACHINE_COREBOOT)
++ /* enable translation */
++ grub_keyboard_controller_write (grub_keyboard_controller_orig
++ & ~KEYBOARD_AT_DISABLE);
++#else
++ /* if not coreboot, disable translation and try mode 2 first, before 1 */
+ grub_keyboard_controller_write (grub_keyboard_controller_orig
+ & ~KEYBOARD_AT_TRANSLATE
+ & ~KEYBOARD_AT_DISABLE);
++#endif
+
+ keyboard_controller_wait_until_ready ();
+ grub_outb (KEYBOARD_COMMAND_ENABLE, KEYBOARD_REG_DATA);
+-
+ write_mode (2);
++
++#if defined (GRUB_MACHINE_COREBOOT)
++ /* mode 2 with translation, so make grub treat as set 1 */
++ ps2_state.current_set = 1;
++#else
++ /* if not coreboot, translation isn't set; test 2 and fall back to 1 */
+ ps2_state.current_set = query_mode ();
+ grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set);
+ if (ps2_state.current_set == 2)
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch b/config/module/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
new file mode 100644
index 00000000..fbcbb2c3
--- /dev/null
+++ b/config/module/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
@@ -0,0 +1,38 @@
+From 247133e1f9820bcb81f7d27fc1395d64dc7b0a89 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Tue, 31 Oct 2023 10:33:28 +0000
+Subject: [PATCH 04/10] keylayouts: don't print "Unknown key" message
+
+on keyboards with stuck keys, this results in GRUB just
+spewing it repeatedly, preventing use of GRUB.
+
+in such cases, it's still possible to use the keyboard,
+and we should let the user at least boot.
+
+it often appears when people plug in faulty usb keyboards,
+but can appear for laptop keyboards too; one of my e6400
+has stuck keys.
+
+with this patch, grub should be a bit more reliable in
+terms of user experience, when the keyboard is faulty.
+
+Signed-off-by: Leah Rowe <leah@libreboot.org>
+---
+ grub-core/commands/keylayouts.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
+index aa3ba34f2..445fa0601 100644
+--- a/grub-core/commands/keylayouts.c
++++ b/grub-core/commands/keylayouts.c
+@@ -174,7 +174,6 @@ grub_term_map_key (grub_keyboard_key_t code, int status)
+ key = map_key_core (code, status, &alt_gr_consumed);
+
+ if (key == 0 || key == GRUB_TERM_SHIFT) {
+- grub_printf ("Unknown key 0x%x detected\n", code);
+ return GRUB_TERM_NO_KEY;
+ }
+
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch b/config/module/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
new file mode 100644
index 00000000..93b0c505
--- /dev/null
+++ b/config/module/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
@@ -0,0 +1,102 @@
+From c5ad46b7ba93136764fd1eae1bd0c0c32ce1c5b2 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Sun, 5 Nov 2023 16:14:58 +0000
+Subject: [PATCH 05/10] don't print missing prefix errors on the screen
+
+we do actually set the prefix. this patch modifies
+grub to still set grub_errno and return accordingly,
+so the behaviour is otherwise identical, but it will
+no longer print a warning message on the screen.
+
+Signed-off-by: Leah Rowe <leah@libreboot.org>
+---
+ grub-core/commands/keylayouts.c | 2 +-
+ grub-core/commands/loadenv.c | 2 +-
+ grub-core/commands/nativedisk.c | 2 +-
+ grub-core/efiemu/main.c | 3 +--
+ grub-core/font/font.c | 2 +-
+ grub-core/kern/dl.c | 2 +-
+ 6 files changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
+index 445fa0601..00bcf7025 100644
+--- a/grub-core/commands/keylayouts.c
++++ b/grub-core/commands/keylayouts.c
+@@ -211,7 +211,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
+ {
+ const char *prefix = grub_env_get ("prefix");
+ if (!prefix)
+- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable `%s' isn't set"), "prefix");
++ return (grub_errno = GRUB_ERR_BAD_ARGUMENT);
+ filename = grub_xasprintf ("%s/layouts/%s.gkb", prefix, argv[0]);
+ if (!filename)
+ return grub_errno;
+diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
+index 166445849..699b39bfa 100644
+--- a/grub-core/commands/loadenv.c
++++ b/grub-core/commands/loadenv.c
+@@ -58,7 +58,7 @@ open_envblk_file (char *filename,
+ prefix = grub_env_get ("prefix");
+ if (! prefix)
+ {
+- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
++ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
+ return 0;
+ }
+
+diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
+index 580c8d3b0..6806bff9c 100644
+--- a/grub-core/commands/nativedisk.c
++++ b/grub-core/commands/nativedisk.c
+@@ -186,7 +186,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
+ prefix = grub_env_get ("prefix");
+
+ if (! prefix)
+- return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
++ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
+
+ if (prefix)
+ path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL;
+diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c
+index e7037f4ed..e5d4dbff1 100644
+--- a/grub-core/efiemu/main.c
++++ b/grub-core/efiemu/main.c
+@@ -231,8 +231,7 @@ grub_efiemu_autocore (void)
+ prefix = grub_env_get ("prefix");
+
+ if (! prefix)
+- return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+- N_("variable `%s' isn't set"), "prefix");
++ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
+
+ suffix = grub_efiemu_get_default_core_name ();
+
+diff --git a/grub-core/font/font.c b/grub-core/font/font.c
+index 18de52562..2a0fea6c8 100644
+--- a/grub-core/font/font.c
++++ b/grub-core/font/font.c
+@@ -461,7 +461,7 @@ grub_font_load (const char *filename)
+
+ if (!prefix)
+ {
+- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
++ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
+ goto fail;
+ }
+ file = try_open_from_prefix (prefix, filename);
+diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
+index de8c3aa8d..eac3ea48d 100644
+--- a/grub-core/kern/dl.c
++++ b/grub-core/kern/dl.c
+@@ -880,7 +880,7 @@ grub_dl_load (const char *name)
+ return 0;
+
+ if (! grub_dl_dir) {
+- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
++ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
+ return 0;
+ }
+
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch b/config/module/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch
new file mode 100644
index 00000000..2dbf6d87
--- /dev/null
+++ b/config/module/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch
@@ -0,0 +1,34 @@
+From 6522ceca8949105b2e1575ada2f05b3061bfe8f3 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Sun, 5 Nov 2023 16:36:22 +0000
+Subject: [PATCH 06/10] don't print error if module not found
+
+still set grub_errno accordingly, and otherwise
+behave the same. in libreboot, we remove a lot of
+modules but then rely on loading a grub.cfg
+provided by a distro; in almost all cases that works,
+but also in almost all cases, that will try to load
+a module we don't actually need, but then it prints
+a message. this can annoy some users, so silence it.
+
+Signed-off-by: Leah Rowe <leah@libreboot.org>
+---
+ grub-core/kern/dl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
+index eac3ea48d..6d67ba54f 100644
+--- a/grub-core/kern/dl.c
++++ b/grub-core/kern/dl.c
+@@ -510,7 +510,7 @@ grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e)
+
+ s = grub_dl_find_section (e, ".modname");
+ if (!s)
+- return grub_error (GRUB_ERR_BAD_MODULE, "no module name found");
++ return (grub_errno = GRUB_ERR_BAD_MODULE);
+
+ mod->name = grub_strdup ((char *) e + s->sh_offset);
+ if (! mod->name)
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0007-don-t-print-empty-error-messages.patch b/config/module/grub/default/patches/0007-don-t-print-empty-error-messages.patch
new file mode 100644
index 00000000..67ae7d66
--- /dev/null
+++ b/config/module/grub/default/patches/0007-don-t-print-empty-error-messages.patch
@@ -0,0 +1,31 @@
+From 557d3e583e6aaa887d7b3876c6980ba0e0e671a3 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Sun, 5 Nov 2023 17:25:20 +0000
+Subject: [PATCH 07/10] don't print empty error messages
+
+this is part two of the quest to kill the prefix
+error message. after i disabled prefix-related
+messages, it still printed "error: ." on screen.
+
+Signed-off-by: Leah Rowe <leah@libreboot.org>
+---
+ grub-core/kern/err.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
+index ba04b57fb..dab62646d 100644
+--- a/grub-core/kern/err.c
++++ b/grub-core/kern/err.c
+@@ -116,7 +116,8 @@ grub_print_error (void)
+ {
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+- grub_err_printf (_("error: %s.\n"), grub_errmsg);
++ if (grub_strlen(grub_errmsg) > 0)
++ grub_err_printf (_("error: %s.\n"), grub_errmsg);
+ grub_err_printed_errors++;
+ }
+ }
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch b/config/module/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch
new file mode 100644
index 00000000..7ce1bf09
--- /dev/null
+++ b/config/module/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch
@@ -0,0 +1,37 @@
+From 101ea5afcfbe459e624df27c422f59b4ded07000 Mon Sep 17 00:00:00 2001
+From: Paul Menzel <pmenzel@molgen.mpg.de>
+Date: Mon, 17 May 2021 10:24:36 +0200
+Subject: [PATCH 08/10] kern/coreboot/mmap: Map to reserved
+
+https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6de9ee86bf9ae50967413e6a73b5dfd13e5ffb50
+
+Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
+---
+ grub-core/kern/coreboot/mmap.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/grub-core/kern/coreboot/mmap.c b/grub-core/kern/coreboot/mmap.c
+index caf8f7cef..2fc316e8d 100644
+--- a/grub-core/kern/coreboot/mmap.c
++++ b/grub-core/kern/coreboot/mmap.c
+@@ -59,7 +59,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
+ /* Multiboot mmaps match with the coreboot mmap
+ definition. Therefore, we can just pass type
+ through. */
+- mem_region->type,
++ (mem_region->type >= 13) ? 2 : mem_region->type,
+ ctx->hook_data))
+ return 1;
+ if (start < 0xa0000)
+@@ -81,7 +81,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
+ /* Multiboot mmaps match with the coreboot mmap
+ definition. Therefore, we can just pass type
+ through. */
+- mem_region->type,
++ (mem_region->type >= 13) ? 2 : mem_region->type,
+ ctx->hook_data))
+ return 1;
+ }
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch b/config/module/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch
new file mode 100644
index 00000000..9bb2563d
--- /dev/null
+++ b/config/module/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch
@@ -0,0 +1,70 @@
+From a56ceedd60bd6515ad3c84ec6aa4c3d66a8bac87 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Wed, 24 Dec 2025 01:42:17 +0100
+Subject: [PATCH 09/10] Revert "configure: Check linker for --image-base
+ support"
+
+This reverts commit 1a5417f39a0ccefcdd5440f2a67f84d2d2e26960.
+---
+ acinclude.m4 | 5 -----
+ configure.ac | 14 ++------------
+ 2 files changed, 2 insertions(+), 17 deletions(-)
+
+diff --git a/acinclude.m4 b/acinclude.m4
+index 70c1912f8..fa7840f09 100644
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -79,11 +79,6 @@ 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)
+diff --git a/configure.ac b/configure.ac
+index d8ca1b7c1..041cfbab4 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1461,6 +1461,7 @@ 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
+@@ -1468,6 +1469,7 @@ 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
+
+@@ -1798,18 +1800,6 @@ grub_PROG_TARGET_CC
+ m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
+
+ 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
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch b/config/module/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
new file mode 100644
index 00000000..0c968993
--- /dev/null
+++ b/config/module/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
@@ -0,0 +1,30 @@
+From 66028b6bc149a25894fe5ca395b22804f389a18e Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Mon, 19 Jan 2026 15:27:23 +0000
+Subject: [PATCH 10/10] Revert "configure: Print a more helpful error if
+ autoconf-archive is not installed"
+
+This reverts commit ac042f3f58d33ce9cd5ff61750f06da1a1d7b0eb.
+---
+ configure.ac | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 041cfbab4..209c0fb11 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1794,11 +1794,6 @@ LIBS=""
+ # Defined in acinclude.m4.
+ grub_ASM_USCORE
+ grub_PROG_TARGET_CC
+-
+-# The error message produced by autoconf if autoconf-archive is not installed is
+-# quite misleading and not very helpful. So, try point people in the right direction.
+-m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
+-
+ if test "x$TARGET_APPLE_LINKER" != x1 ; then
+ grub_PROG_OBJCOPY_ABSOLUTE
+ fi
+--
+2.47.3
+
diff --git a/config/module/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch b/config/module/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch
new file mode 100644
index 00000000..cfb66047
--- /dev/null
+++ b/config/module/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch
@@ -0,0 +1,91 @@
+From 5d18c96a22d98d137ea40bfc6aabadce933c2d45 Mon Sep 17 00:00:00 2001
+From: Leah Rowe <leah@libreboot.org>
+Date: Sun, 1 Feb 2026 20:30:55 +0100
+Subject: [PATCH 1/1] bootstrap: Don't download po files
+
+GRUB doesn't verify checksums at all, and it pulls from
+this URL recursively:
+
+https://translationproject.org/latest/grub/
+
+These files can change at any time, and GRUB is just
+downloading them trustingly. Even if the upstream is
+totally benevolent, what if they got hacked?
+
+I downloaded them, hashed them and decided to mirror
+them on my RSYNC mirror. In this way, Libreboot can now
+use them in a deterministic fashion.
+
+Simply adding them to the GRUB source code would mean
+patching GRUB, which would add 8MB to lbmk. I won't do
+it.
+
+Signed-off-by: Leah Rowe <leah@libreboot.org>
+---
+ bootstrap | 31 +++++++++++++------------------
+ 1 file changed, 13 insertions(+), 18 deletions(-)
+
+diff --git a/bootstrap b/bootstrap
+index dc9fb4383..9fc5a5c36 100755
+--- a/bootstrap
++++ b/bootstrap
+@@ -1,5 +1,16 @@
+ #! /bin/sh
+-# DO NOT EDIT! GENERATED AUTOMATICALLY!
++# THIS FILE WAS EDITED BY LIBREBOOT TO REMOVE
++# HACKY GRUB BEHAVIOUR; po files now downloaded
++# by lbmk, via config/submodule/grub/ - so that
++# versioned files are possible, with proper checksum
++# verification, and mirrors are used.
++
++# Yes. This file has been modified. I intend to
++# eventually remove this hacky script. Probably
++# replace the entire GRUB build system.
++
++# Please do fix/edit or (when possible) remove
++# this file. Thank you.
+
+ # Bootstrap this package from checked-out sources.
+
+@@ -145,13 +156,6 @@ bootstrap_post_import_hook() { :; }
+ # Override it via your own definition in bootstrap.conf.
+ bootstrap_epilogue() { :; }
+
+-# The command to download all .po files for a specified domain into a
+-# specified directory. Fill in the first %s with the destination
+-# directory and the second with the domain name.
+-po_download_command_format=\
+-"wget --mirror --level=1 -nd -nv -A.po -P '%s' \
+- https://translationproject.org/latest/%s/"
+-
+ # When extracting the package name from an AC_INIT invocation,
+ # prefer a non-empty tarname (4th argument of AC_INIT if given), else
+ # fall back to the package name (1st argument with munging).
+@@ -909,14 +913,6 @@ autopull()
+
+ # ----------------------------- Get translations. -----------------------------
+
+-download_po_files() {
+- subdir=$1
+- domain=$2
+- echo "$me: getting translations into $subdir for $domain..."
+- cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
+- eval "$cmd"
+-}
+-
+ # Mirror .po files to $po_dir/.reference and copy only the new
+ # or modified ones into $po_dir. Also update $po_dir/LINGUAS.
+ # Note po files that exist locally only are left in $po_dir but will
+@@ -932,8 +928,7 @@ update_po_files() {
+ ref_po_dir="$po_dir/.reference"
+
+ test -d $ref_po_dir || mkdir $ref_po_dir || return
+- download_po_files $ref_po_dir $domain \
+- && ls "$ref_po_dir"/*.po 2>/dev/null |
++ ls "$ref_po_dir"/*.po 2>/dev/null |
+ sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
+
+ for po in x $(ls $ref_po_dir | sed -n 's/\.po$//p'); do
+--
+2.47.3
+
diff --git a/config/module/grub/default/target.cfg b/config/module/grub/default/target.cfg
new file mode 100644
index 00000000..cfa2a287
--- /dev/null
+++ b/config/module/grub/default/target.cfg
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+rev="eaa3b8f0f90605a82c6bfda4c5c4b73c58eb81ac"
+
+tree="default"