1. ABOUT
well, this project was started to make grub2 configuration more easy, understandable and flexible. i believe that not everyone is happy with all of this config files and scripts. if you need to change something in this mechanism, you face huge number of cross-linked scripts: /etc/grub.d/*, /usr/lib/something/else, /usr/share/whatever/else... just take a look at os-prober with its scripts and you'll understand what i'm talking about. what is more, all of this stuff is almost not self-documented. e.g., i saw a case, when an option wasn't even included in /etc/default/grub, but user knew about it from 'info grub' (who reads 'info' pages? most used and suitable way is 'man' at the moment).
so, i was sick of this huge and difficult machine and that's why i decided to make my own configuration mechanism. here are some advantages you can get:
- everything in one file. you don't need to care about these scripts spread across the whole filesystem. you'll just have single grub2.rc file, which itself is config and configuration script at the same time. everything you need you'll find here and only here. btw, it also makes this scheme more portable
- unlike GNU mechanism, this script is well-documented. my first aim was to make it human-readable, so other developers can understand, modify and impove it. as for users, every config option is followed with detailed description
- it works faster. really. i don't think anyone will really care if it takes 1 second instead of 2, but "get the facts"
- extra-features. yes, it provides some things you may found useful, which original realisation doesn't have. all of them are fully described below, in "configuration" section
of course, grub2rc has some restrictions too. currently it doesn't support MacOS or GNU/Hurd like GNU scheme does, but i believe most users won't need it at all. also "default=saved" is not currently supported, but it's in my nearest TODO, and i'm going to implement this as soon as i'll have enough time
2. DEPENDENCIES
nothing unusual here. grub2rc should work on any GNU/Linux system (and maybe on BSD, not tested) with following installed:
- bash. there are some bash built-in features used, so it may work incorrectly in other shells. anyhow, if you even use alternative shell, i don't think you haven't bash in your system
- coreutils. if it's not very small busybox-based system, you have it
- util-linux. again, any Lniux distro 99.9% has it
- straight hands :D
3. INSTALLATION
ok, you'll have it all downloaded, and you want to give it a try. firstly, you should place your grub2.rc at suitable place. i recommend "/etc/grub2.rc", but in case you use common /boot partition for several systems, it could be e.g. "/boot/grub/grub2.rc". so, do something like
sudo cp /your/path/to/grub2.rc /etc/grub2.rc
sudo chown root:root /etc/grub2.rc
sudo chmod 755 /etc/grub2.rc
now you may want to test it before daily usage. in such case, skip instructions below for now and go to "configuration" section to configure your settings and make first test run.
once you are with results, you can override your "update-grub" command with grub2.rc. firstly, backup original file
sudo mv /usr/sbin/update-grub{,.orig} -v
now you need to make /usr/sbin/update-grub a symlink to /etc/grub2.rc (or whereever it is placed). on Debian-based the best way is to use "alternatives" mechanism:
# firstly, add original executable
sudo update-alternatives --install /usr/sbin/update-grub update-grub /usr/sbin/update-grub.orig 40
# and then add grub2.rc
sudo update-alternatives --install /usr/sbin/update-grub update-grub /etc/grub2.rc 40
that's all! now "update-grub" alternative should point to grub2.rc. you make check this by running
update-alternatives --display update-grub
in case you don't have "update-alternatives" in your system, you can simply make a symlink:
sudo ln /etc/grub2.rc -isv /usr/sbin/update-grub
now when you run "update-grub" (or it's run by dpkg trigger or whatever), grub2.rc will be run instead
4. CONFIGURATION
this is the main section of this readme, here i will explain all configuration options you may find in grub2.rc. i will follow the order of appearance. let's go:
- output_file
this option sets where script should save the resulting config. value should be absolute path (well, you can use $HOME if you want, but make sure that sudo preserves your enviroment, otherwise consult 'man sudo' and 'man sudoers' or simply use '/home/username/...'). this option is needed when you make some tests and don't want to touch your /boot/grub/grub.cfg. since everything is fine, just replace value with "/boot/grub/grub.cfg"
GENERIC OPTIONS
- default
same as in /etc/default/grub. default entry to be selected when menu is shown, can be numeric value starting with 0 (0 is first row in your menu, 1 is the second and so on) or exact name: e.g. if you see smth like
menuentry "Debian testing @ 2.6.34.7 (on /dev/sda3)" { ... }
in resulting config, then you should use "Debian testing @ 2.6.34.7 (on /dev/sda3)" to make this entry default one. default: 0
- timeout
again, same as in /etc/default/grub. how long to display menu before booting default entry if no action is coming from user. value is a number of seconds. "-1" means infinite timeout - menu will be shown until you select entry to boot and hit enter. default: 10
- hidden_timeout
in some cases you may want not to see boot menu at all - e.g. when you have only one OS on this machine. here you can use several ways be setting value to:
- "on" - no menu will be displayed, grub will wait N seconds (set in "timeout" option) and boot default entry. during this timeout you can hit Esc to display menu if you need it
- "timer" - same as "on", but countdown timer will be displayed instead of blank screen. the same way, you can call menu by Esc
- "shift" - slightly different way: if you hold Shift during startup, boot menu will be shown. otherwise grub will immediately boot default entry without waiting
- "off" (or comment this option) - no hidden menu, usual menu with given timeout
default: off
- generic_color
- generic_highlight
color for text (non-graphic) mode. each value is /-separated pair of colors, where the first one is text color and the second one is background color.
"generic_color" is for usual (non-selected row), "generic_highlight" is for selected row. e.g. "white/black" means white text on black background
- graphic_default_text
same as above, but for graphic mode. this options sets colors for welcome/help messages in the top/bottom of screen and for grub console
- graphic_color
- graphic_highlight
same as "generic_color" and "generic_highlight", but for graphic mode. note that in grapthic mode "black" as bgcolor means transparent background.
here is a list of available colors:
black blue brown cyan dark-gray green light-cyan light-blue light-green
light-gray light-magenta light-red magenta red white yellow
names are self-explanatory, but you can also look at this color table: http://help.ubuntu.ru/_media/wiki/02da6dc42f98.png
- background
specify background image you'd like to use as menu wallpaper. value should be absolute path. and of course it shouldn't be on encrypted/lvm/raid partition, as grub won't be able to access your file in such case. supported formats are:
- png
- tga
- jpg (only 8-bit depth, use with caution!)
also it's recommended that your bg image fits grub resolution (see below) to avoid ugly stretching/croping/etc
default: off
- gfxmode
screen resolution to use in boot menu. value is "WxH[xColorDepth]" or comma-separated list of such modes. if you specify list of several modes, first working one will be used
e.g. "1280x1024x32,1280x1024x16,1024x768"
you can also run "vbeinfo" in grub2 console to see list of supported resolutions.
default: 640x480
- bg_hard_check
if enabled, perform paranoidal check on bg image. only if image resolution matches gfxmode, it will be accepted. value: true/false, default: false
- font
font file to use in graphic mode. in grub 1.97 there are two of them: unicode.pf2 and ascii.pf2. maybe you'll find other fonts for grub2, so set absolute path to font file here
- drives
it's the most interesting option. here you can specify list of devices where grub2rc should search for installed OS. there are two aims:
1) speed. we can really save some time spent to searching on devices where no OS is installed
2) flexibility. if you don't want to see some OS in boot menu, just don't include device it is installed on.
value is space separated list of devices. named with or without leading /dev at your option, you can even mix two ways like "sda1 /dev/sda4 sdb5 mapper/luks1 /dev/mapper/lvm-root".
also you can specify your devices by uuid, which is more flexible way, and thus recommended. if you specify devices by uuid, they will be found correctyl even when you connect/disconnect/replace other drives. to use this way, name devices by "UUID=xxxxxx-xxxx-xxxx-xxxxx", like in fstab. and you can also mix all ways like "UUID=c5b73142-239c-4a68-9df1-7c4104a83528 sda5 /dev/mapper/luks1"
if you device requires special actions to be mounted, you should perform then btfore running grub2rc. e.g. for luks partiotions you should firstly open luks-container (and optionally mount the device anywhere).
for GNU/Linux systems with separate /boot you should specify only root device, /boot will be founded automatically. for currently running GNU/Linux OS you don't need to include root device here.
leave blank or comment to use auto-detection and search through all available devices
- runv
this is a list of functions to run, order is also followed. e.g. if you don't have windows here or don't want to see it in boot menu - simply don't include "os_win" function here, which will also save some time spent on searching for nothing. available functions are:
- linux - GNU/Linux OS you are currently running
- os_win - windows OS on another devices
- os_linux - GNU/Linux on another devices
- custom_[0-9] - custom functions (see "custom functions" section below)
- removable - see "removable devices" section below
you can also prefix any function with "!" to temporary disable it, eg. "linux !os_win os_linux".
default: "linux os_linux os_win"
LINUX OPTIONS
- sort_type
how to sort your kernel files (/boot/vmlinuz* or smth like that). values:
- "date" - sort by date, most recent first
- "name" - sort by name, higher versions first
default: name
- kernel_params
parameters you want to pass to kernel. e.g, "quiet nomodeset text"
- console_mode
graphic mode to use in Linux console. same as $gfxmode (see above). comment or leave blank to leave default (KMS autodetection or whatever works for your system). default: nothing
- hidden_recovery_key
here is another extra-feature. using this, you can hide "recovery entries" for Linux kernels, but use recovery mode by holding specified key when selecting menuentry (press <key>+Enter to boot in recovery, Enter for usual boot). values: "alt", "ctrl", "shift". use "off" or comment this to still use normal+recovery entries separately
- allow_monolith
this option sets whether to allow using "monolith" kernels without initrd or not. when enabled, kernels with no initrd found can be used, otherwise they will be skipped and warning will be thrown. value: true/false, default: false
- last_kernel_only
use this you you want to see only latest (or currently running) kernel in boot menu. this may be useful when you don't want to litter your menu with older kernels you usually don't need, but also want to keep them for manual rescue boot. values:
- "latest" - sort kernels according to $sort_type (see above) and grab only the first one
- "running" - on local GNU/Linux system: include only currently running kernel (detected by 'uname -r'). on other OS: behave like "latest".
- "off" (or comment) - disable this, use all kernels.
default: off
- linux_title
specify custom title format for GNU/Linux menuentries. you can use (strictly speaking, you should use at least one of) following substitutions:
&O = OS name (e.g. Debian)
&V = OS version (e.g. 6.0)
&C = version codename (e.g. squeeze)
&K = kernel version (e.g. 2.6.38.1-i686)
&D = root device (e.g. /dev/sda5)
also you should \-escape special characters like brackets, quotes, $. #, etc.
value: string like "&O GNU\/Linux &C @ &K \(on &D\)"
default: "&O &V @ &K \(on &D\)"
- kernel_pattern
- inited_pattern
here you should set how your kernel and inittrd files are called. e.g. in Debian it will be smth like "vmlinuz-2.6.34 + initrd.img-2.6.34", thus you should use "vmlinuz*" and "initrd.img*". if in your system it's "kernel26_2.6.34 + initramfs_2.6.34", use "kernel26*" and "initramfs*".
if you use common /boot and store your kernels from different OS in extra folders (like /boot/debian and /boot/fedora, for example), you can include such location too. create custom functions (read "linux custom functions" below) and specify patterns like "debian/vmlinuz*" and "debian/initrd.img*"
default: "vmlinuz*", "initrd*"
WINDOWS OPTIONS
- win_checkfs
check if there is ntfs/vfat fs on partition before trying to find windows here. this helps to avoid useless searching on non-windows fs and thus save some time. don't know why you may want to disable it if not for fun :D. value: true/false
5. CUSTOM FUNCTIONS
you can also expand grub2rc functionality by using custom functions, this way is similar to /etc/grub.d/40_custom, but here is 10 functions reserved for your usage, they are named "custom_N", where N is 0 to 9. scroll "CONFIG SECTION" in your grub2.rc and you'll find "CUSTOM SECTION" with 2 example functions. well, you are free to do anything your bash skills allow here. simplest case is when you just want to add some additional menuentries. then you use something like that:
custom_0() {
log "adding custom entries from $func"
cat << EOF
menuentry "reboot" { reboot }
menuentry "shutdown" { halt }
EOF
}
if you are more advanced bash-developer, you can construct more complicated functions, of course. just remember that all output to stdout is redirected to resulting config file, and all stderr goes to console as traceback messages. you can simply use log(), warning() and error() functions for 3 types of messages. also feel free to use any other functions (e.g. fstab_find(), relative_path()) you'll find in grub2.rc for your needs. all of this functions are documented, describing actions they do and arguments they need (if any).
6. LINUX CUSTOM FUNCTIONS
you can locally change some variables from "Linux options" above for specific GNU/Linux OS without changing them globally. to do this, you should create function, which name should match root device for selected OS. for example, you're running on Debian and also have Fedora on /dev/sda3, and for Fedora you need "nomodeset" kernel param, but you don't want it in Debian. in that case, you create such function:
sda3() {
kernel_params="nomodeset"
}
thus, "nomodeset" will only be added when processing /dev/sda3 and Fedora on it. in the same way you can change title format, kernel/initrd patterns, whatever else you can set globally.
if your deivce is "/dev/mapper/luks1", you should use "luks1" as function name - you use basename only, not the whole path. also for names like "lvm-root" you should replace "-" with "_" ("lvm_root" for /dev/mapper/lvm-root).
and you can also name your functions by uuid, which is recommended way. here you should also replace "-" with "_", as bash function name can't contain dash character. back to example above, you run
sudo blkid -o value -s UUID /dev/sda3 | tr "-" "_"
and write smth like
c8e35f6b_9635_44a6_b165_ea7c7c8f0fe2() {
whatever you need here...
}
strictly speaking, you are not limited only to changing variables temporary. you can perform anything here, the only limit is your bash knowledge...
7. REMOVABLE DEVICES
well, here i want to offer you my new conception of using grub2 with OS on removable drives. my way works like that:
- you mark device as removable (described below)
- if it's present, it's scanned for installed OS
- menuentries for found OS saved to device-specific separate config file
- if device is not present, but config file for it exists, such file is included
- during boot time grub checks for every of such devices
- and if devices is present, menuentries from its file are displayed
thus it creates menuentries for removable devices, and when devices is plugged at boot time, you'll see these entries, but if device is not present, you won't get wrong entries pointing to non-existing fs. hope my explanation was clear))) now let's see how to use it:
firstly, you need to mark device as removable. to do that, you just prefix it with @ in your $drives. smth like:
drives="sda2 sda5 @sdb1"
this will work, but config files for this device will be mentioned in grub.cfg only if device was present during last update-grub. thus uuid way is highly recommended, go this way:
drives="sda2 UUID=daba3823-9adf-4f8a-960d-98b021cadf0f @UUID=959bfffa-aa26-4365-87bf-fcd7da4a8496"
which means that last one is removable device. now it will be scanned and menuentries for this device will be stored in file named "959bfffa-aa26-4365-87bf-fcd7da4a8496", which will be placed along with resulting grub.cfg. at next "update-grub" if device will be here, things will go the same way, otherwise grub2rc will found no device, but config file for it, and such file will be included, and grub2 will check for such device at startup. that's easy)))
8. GET INVOLVED!
if you are bash developer, you can help improving this projects by writing patches and making any useful stuff. feel free to modify anything and implement any ideas. if you have any ideas, fixes, improvements, or you want to become project member, contact me (see below)!
if you're simple user, you can help by providing your feedback. if something works not like you expected, and you think it's bug, please report it to bug tracker on SourceForge project page. if you don't understand something, visit project forum on SF or contact me directly. even if everything is fine, let me know let all works good for you. feel free to provide any feedback, as it really helps! also you can become a beta-tester and test grub2rc in different cases.
so, if you need help or have any questions / bugs / patches / improvments / ideas / feature requests / thanks / other feedback - feel free to write:
SourceFourge project page: http://sf.net/projects/grub2rc
email: dimas000<at>ya.ru
jabber/xmpp: dimas000<at>jabber.ru
you are always welcome!
9. LICENSE
see comments at the top of script. it's free software, and any non-commercial usage is allowed