yast2-bootloader


Table of Contents
Main goals for 8.2
Bootloader module concept
Bootloader-specific function calling mechanism
Bootloader configuration reading/writitng/proposing
Diagrams
Initrd module
Bootloader module
BootCommon module
Bootloader-specific modules interface
User interface
GRUB bootloader
LILO bootloader

Main goals for 8.2


Bootloader module concept

Encapsulation

Every other module, which needs to access bootloader, shouldn't need to know that there are many different bootloaders. Because of this there is the Bootloader module, which encapsulates functions of other bootloaders, and calls appropriate function of appropriate module depending on currently used bootloader. This interface should stay stable as long as possible, the probablity that some internal interfaces will change in future, is much higher.


One-way import

Since cyclic importing of modules may bring a lot of problems because of cyclic calling inside constructors, in the whole bootloader module all importing is done only one way. The only exception is interaction with Storage module forced by needs to regard the disk situation when deciding what bootloader to use on one side, and the need to know what bootloader is used when proposing partitioning on the other side. There is no import cycle insude whole bootloader module, the bootloader module's modules are strictly layered, each module imports only modules from bellow layers.


Files included only once

Since included file is parsed on every place where it is included (often many times during one run of YaST2), it takes some time. Because of this include files from bootloader-related modules are included into just one module/client file. This brings the advantage of performance, and helps avoiding import-include cycles. Since the file is imported by one module only, it isn't needed to import this module nor use it's identifier when accessing it's variables and/or functions. Here are two exceptinos: One is the popups.ycp include file, which doesn't need any functions of any module from bootloader package, and the other one is ui.ycp, which is included by several clients.


Bootloader dependent/independent parts border

Since there are many different bootloaders supported (currently should be supported at least LILO, GRUB, ELILO, S390 bootloader and PPC bootloader), there was really needed to define clearly the border between code, which is bootloader dependent and conde which is bootloader independent.

There are three main layers. The top one is made by the Bootloader module and it's includes, partially the ui.ycp include. This is the point clients and other modules should use to use bootloader functions. This layer is bootloader independent, but there are some locations regarding different bootloaders. There are bootloader switching (configuration conversion) mechanisms, bootloader-dependent function choosing mecahnism, maybe some others.

Second, middle layer, is made of bootloader-dependent modules, and their includes. Every supported bootloader should have it's module. It should be the onlo point, where common part of bootloader module accesses the bootloader-dependent parts. This module must contain function describing what function specific to this bootloader are present. Should contain all bootloader-specific routines.

The last, bottom layer, contains routines, which may be used by more bootloaders, and generic versions of bootloader-specific functions, which get called if no specific function for currently used bootloader is present. Also contains many variables for storing general information and for some by more bootloader used variables.


Installation vs. configuration of installed system

There is only one module for both of these tasks. Only one UI, only one internals. There are proposing functions available during configuration of installed system, this way it is possible to recreate original configuration.


Installation

There is full control of the installation process - not only location and few additional parameters, but everything, including bootloader sections and manual editing of future configuration files. This brought some problems (because after user creates/modifies sections, many things including disk partitioning may change), but they seem to be solved and configuration (automatically set settings) are updated everytime disk configuration changes. Sections created/modified by user of course can't be changed.


UI

The concept of UI is described in separate chapter.


Bootloader-specific function calling mechanism

Each bootloader-specific module must provide function, which returns map describing the functions provided by the bootloader-specific module. Details about return value are available in Bootloader-specific module description section.

Since future versions of YCP interpreter may need to parse and check all (possibly) used module and include files, all files of all bootloaders must be present (which forbids architecture-dependent conditional presence of bootloader-related files in .spec file).

The getFunctions function is the only point, where all bootloader must be listed. It's task is to choose depending on parameter specifying bootloader which set of bootloader-specific functions should be used. In the body of this functions, there is stored map from bootloader identifiers to term, which after evaluation returns the set of bootloader-specific functions. From this map term to evaluate is choosen and evaluated, and this map is a return value of this function.

Each function, which should be able to be called without checking of bootloader, has s shortcut (usually called like eg. blRead for Read function). This function gets list of functions for currently used bootloader, chooses term appropriate to the concrete function, depending on concrete function and it's parameters adds some parameters if needed, and evaluates the term. If some value should be returned (depending on concrete function), returns result of the evaluation of the term. If there is no entry in map representing appropriate bootloader-specific function, then generic version of the function (locater in the BootCommon module) is called.

There is (at least currently) no automatical way to generate these functions, each of them must be written manually.


Bootloader configuration reading/writitng/proposing

Reading

Bootloader configuration reading process consists from two steps. First is to detect which bootloader is in use (reading appropriate sysconfig variable), and the second step is to read bootloader-dependent setetings. The only common part of bootloader reading process is to assign device to match the sysconfig variable (eg. if in sysconfig is as location written MBR, then /dev/hda2 as bootloader device must be changed to MBR of first disk). Additionally, Read function of Initrd module is called.


Writing

Writing configuration is much more complex process. It consists from three steps: save Initrd, save bootloader configuration files and call required binary (eg. /sbin/lilo).

Saving configuration files consists from two steps. First is to save common sysconfig variables (file /etc/sysconfig/bootloader, variables LOADER_TYPE and LOADER_LOCATION). Second step is call bootloader-specific function to write it's configuration files.

Running bootloader executable is bootloader-dependent operation. In some cases there is needed to call bootloader executable every time anything is changed (eg. LILO), in some cases only if bootloader location is to be changed (eg. GRUB), some bootloaders have no executable (eg. ELILO).

Before running bootloader's specific write, in some cases should be run functions that should modify the MBR of the first hard disk. There are currently functions for setting active partition and for replacing code in MBR with generic code (which loads bootsector of bootloader partition). It is upon bootloader-specific code whether it will run these functions.

Since many other modules can call the Write function just to reinstall bootloader (eg. after manual changing of initrd settings), it was needed to allow to customize the write process. Function to modify the write process and possibilities of modification are described in the Section called Bootloader module.


Proposing

Proposing configuration is very complex operation. The main problem is that it must be regarded that configuration of disks isn't final and can change in future, and reproposing must combine previous configuration, which could be changed by user, and new state of disks. Of course this doesn't affect reproposing of configuration when user wants to recreate original configuration, but there is one proposing mechanism. The proposing mechanism must be able to propose the configuration from scratch, but must be able to detect changes done inside disks configuration, and update the configuration according to these changes.

There are some rules how to handle each section when proposing function is called when there has been any configuration proposed. Section could be proposed, or manually added, can be modified, or left as it was proposed. The same as for sections must be done for global section.

  • If section was added by user manually, then never change it when partitioning changes.

  • If section was proposed, but not changed by user, then recreate it new.

  • If section was proposed and then modified by user, the situation is much harder. The big question is what has been changed by user. If there was no change in partitioning of the disk, then everything is OK and section can be left as is. But if disks have been repartitioned, and at least one partition affecting this section was changed, then the section may be incorrect and user must get warned. Currently warning the user is the only mechanism to solve these situations, because there is no easy way to fix the configuration of the section and not destroy any changes made by the user. In case any configuratino file was changed manually inside the editor, then no reproposing is done, and user gets only a warning.

The proposing mechanism mainly depends on bootloader, which is used, and is described in bootloader-specific chapters describing single bootloaders.


Diagrams

Figure 1. UI workflow

Figure 2. Bootloader installation call sequence

Figure 3. Bootloader configuration call sequence

Figure 4. Bootloader call graph


Initrd module

General information

Initrd module is used for handling list of Initrd modules. Inside stores list of modules, which shall be contained in initial ramdisk, allows to add/remove any module to/from this list. Also when adding module to initrd, it is possible to specify parameters of the module.

For storing of list of initrd modules variable INITRD_MODULES in /etc/sysconfig/kernel is used (contains list of modules separated by blank character). Parameters of modules are stored in /etc/modules.conf the same way like for modules which aren't to be a part of initrd.

When calling the Write function of this module, first checking whether saving is really needed is done (if some module was added, or if function was called during installation, then it is needed). Modules settings are saved to /etc/modules.conf, list of modules to /etc/sysconfig/kernel, and after it /sbin/mkinitrd is called to create ramdisk. Note that even though list of modules is empty, /sbin/mkinitrd must be called, because some modules are added to initrd by this script.


List of declarations

  • global define void AddModule (string modname, string modargs)

  • global define map Export ()

  • global define void Import (map settings)

  • global define list ListModules ()

  • global define boolean Read ()

  • global define void RemoveModule (string modname)

  • global define void Reset ()

  • global define void Update ()

  • global define void Write ()

  • global define void setSplash (string vga)

  • list modules

  • map modules_settings

  • global boolean changed

  • boolean was_read

  • string splash


Global functions

  • global define void AddModule (string modname, string modargs) inserts module to list of modules which shall be contained in initial ramdisk with it's parameters. When saving initial ramdisk will be recreated.

  • global define map Export () export settings of Initrd module to returning map.

  • global define void Import (map settings)imports map of settings to module's internal structures.

  • global define list ListModules () returns list of modules which are (or will be) present in initial ramdisk.

  • global define boolean Read () reads list of initrd modules from sysconfig file. Sets changed variable to false.

  • global define void RemoveModule (string modname) removes module from ramdisk when writing bootloader configuration to disk.

  • global define void Reset () resets modules list to empty and sets changed variable to false.

  • global define void Update () modifies internal structures according to changes which happened since previous versions (eg. modules split/merge, removing some modules,...). Is called only if Mode::update is set to true.

  • global define void Write () (if was changed) saves list of initrd modules to sysconfig files and rebuilds initrd. If updating the system, then after reading settings (if hasn't been read before) Update function is called to update list and settings of modules in initrd.

  • global define void setSplash (string vga) is used to add proper splash screen to initrd. As parameter takes the kernel vga parameter, internally translates to resolution.


Internal variables

  • list modules contains list of modules to be inserted to initrd. Is important, because map doesn't preserve order of module, which is imnportant.

  • map modules_settings is map from names of modules, which should be contained in initial ramdisk, to their parameters. For changing this variable should be appropriate functions used.

  • global boolean changed is true if initrd needs to be rebuilt when saving configuration. Shall be directly used only from Bootloader module.

  • boolean was_read is true if settings were already read from disk, otherwise false

  • string splash contains resolution of splash image


Bootloader module

List of declarations

  • global define map Export ()

  • global define void Import (map settings)

  • global define boolean Read ()

  • global define void Reset ()

  • global define void Propose ()

  • global define string Summary (list style)

  • global define boolean Write ()

  • global define void SetWriteMode (map settings)

  • global define string getDefaultSection ()

  • global define string getKernelParam (string section, string key)

  • global define list getSectionsList (symbol type)

  • global define boolean setKernelParam (string section, string key, string value)

  • global define string getLoaderType ()

  • global define void getLoaderType (string bootloader)

  • global define string getRootDevice ()

  • global define string getBootDevice ()

  • global define void setRootDevice (string device)

  • global define void setBootDevice (string device)

  • global define boolean LbaSupport()

  • global define void ReadOrProposeIfNeeded ()

  • global boolean repeating_write


Main functions

  • global define map Export () returns map containing all internal settings of bootloader, including bootloader-specific settings.

  • global define void Import (map settings) imports map of settings to bootloader module's internal memory. Shall contain bootloader-specific and initrd settings too.

  • global define boolean Read () reads all saved settings from disk to module's internal memory. Returns true on success, false on fail.

  • global define void Reset () resets all settings stored in bootloader's internal memory to initial values.

  • global define void Propose () generates proposed settings and stores them in module's internal memory.

  • global define string Summary (list style) generates bootloader summary and returns it in result string. Parameter is list of symbols specifying style of summary (see autogenerated documentation)

  • global define boolean Write () writes bootloader configuration to disk or eprom (platform-dependent).

  • global define void SetWriteMode (map settings) sets variables, which may change the bootloader writing process. As parameter takes a map, where keys are variable names (as strings), values will be set into appropriate variables. If some key is missing, variable stays unchanged. Available variables are:

    • "insert_initrd" : boolean forces (if true) or forbids (if false) inserting initrd to bootloader configuration files when saving bootloader configuration if exists. Doesn't remove it if present and set to false. Default is false.

    • "initrd_changed_externally" : boolean makes (if true) saving process saving cfg. files the same way like if initrd might be added or removed. Default is false. In case of LILO and other bootloaders which need to recreate lists of blocks calls the bootloader installed (eg. lilo).

    • "forbid_save_initrd" : boolean forbids (if true) or allows (if false) saving and creating initrd. Doesn't affect function Initrd::Write, only avoids calling this function from Bootloader::Write. Default is false.

    • "save_all" : boolean if true forces saving of all bootloader settings, including recreating initrd, saving bootloader configuration file(s) and calling required executable. The process is the same as during installation.


Linux sections handling functions

  • global define string getDefaultSection () returns string containing label (or title) of currently set default section.

  • global define string getKernelParam (string section, string key) parses kernel parameters in specified section, selects specified parameter, and returns it's value. Returns "false" if option or section is not present, "true" if present without value (eg. nosmp). Set section name to "DEFAULT" to use default section.

  • global define list getSectionsList (symbol type) returns list of strings representing section names. Argument type can be set to `all (list of all sections), `linux (list of linux sections only) and `other (list other sections only).

  • global define boolean setKernelParam (string section, string key, string value) adds or replaces kernel parameter in specified section. Returns true on success, false on fail. If value is set to "true", parameter without value is added, if "false", parameter is removed.

Note, that after changing of kernel parameters, you must call the Bootloader::Write () function.


Other functions

  • global define string getLoaderType () returns currently used or configured bootloader. There will be no global variable for detecting current bootloader.

  • global define void setLoaderType (string bootloader) sets the bootloader to use. If parameter is nil, then next time getLoaderType () will be called bootloader will be reread from disk or redetected.

  • global define string getRootDevice () returns device which contains the / (root) directory.

  • global define string getBootDevice () returns device containing the /boot directory. Returns the same as getRootDevice () if no extra /boot partition exists.

  • global define void setRootDevice (string device) sets device containing the / (root) directory. Should be set to real root partition of installed/configured machine. Normally this function isn't needed to be used, everything gets detected.

  • global define void setBootDevice (string device) sets device containing the /boot directory. Should be set to real /boot partition of installed/configured machine. Normally this function isn't needed to be used, everything gets detected.

  • global define boolean LbaSupport() returns true if current configuration supports LBA-32 mode (and in this case no extra /boot partition is required).

  • global define void ReadOrProposeIfNeeded () checks whether settings were read or proposed, and if not, reads or proposes new settings (according to current Mode::* variables). Should be used only from internal functions of bootloader module.


Variables

  • global boolean repeating_write is used just for internal moduel's needs (detects, whether repeated writing is running and in case of installation the installation progress bar shall not be moved).


BootCommon module

Note

This module contains all declarations as bootloader specific module, which are used as common versions of bootloader-specific functions, if special function is not needed, except the GetFunctions () function. Only additional declarations are listed


List of declarations

  • global define symbol getLoaderType (boolean recheck)

  • global define symbol setLoaderType (symbol bootloader)

  • string loader_type

  • global boolean was_proposed

  • global boolean was_read

  • global map dependent_settings

  • global boolean changed

  • global boolean location_changed


Bootloader type handling functions

  • global define symbol getLoaderType (boolean recheck) returns currently used bootloader. If parameter set to true, bootloader type is checked again, if false, then read previously detected or by user set settings.

  • global define symbol setLoaderType (symbol bootloader) sets current bootloader to use.


Variables for being used inside yast2-bootlaoder package only

  • global map dependent_settings for storing bootloader-dependent settings (because module is more usable for storing bootloader-dependent settings than include file which is used).

  • global boolean changed is true if bootloader configuration has changed and must be saved.

  • string loader_type stores type of currently used bootloader. Shouldn't be used directly because of initialization, function getLoaderType shall be used instead.

  • global boolean location_changed is true if bootloader location was changed and bootloader must be installed again (eg. grub doesn't have to be installed again if only menu was changed).

  • boolean was_proposed is true is Propose function was already called, otherwise false.

  • boolean was_read is true if settings were already read from disk, otherwise false.


Bootloader-specific modules interface

Motivation

Different bootloaders are installing different ways, require different informations, etc. The goal of new design is to allow different bootloaders to have their own dialogs, proposal, and functions for several tasks, but to provide generic dialogs and functions too. Common part of bootloader installer should not contain bootloader-specific code, everything bootloader-specific should be encapsulated in bootloader-specific module.


Bootloader-specific module description function

global define map GetFunctions () function shall return a map describing what functions contains bootloader-specific part installator. It is used for checking for what functions can be used generic functions and what functions need to be specific.

Returned map shall contains following keys (values are terms, they will be evaluated when function call is wanted):

  • "export" export function, should return map of bootloader specific settings.

  • "import" import function, must have one map parameter for settings to import.

  • "read" reads bootloader specific settings from disk to module's internal variables. Returns boolean true if success.

  • "reset" resets all module variables to their default values.

  • "propose" proposes bootloader configuration. May be called repeatedly during installation proposal, in this case shall only update settings according to changes of partitioning.

  • "save" saves all configuration files of bootloader to disk. Should backup old configuration files before rewriting them. Returns boolean true on success.

  • "summary" creates the summary text for installation proposal. Returns string with summary text in the "raw_proposal" format.

  • "update" updates read settings of bootloader to newer version if needed. Doesn't read or write anything.

  • "write" makes the real installation of bootloader when needed. On i386 this should call the lilo command, may do some additional actions (activating partition,...). Returns boolean true on success.

  • "widgets" returns map of bootloader specific widgets. Special key "tableentries" is used for map of single bootloader options. See more details in UI section.

  • "sequence" fixes the dialog aliases and workflow sequences according to specific bootloader needs. Has parameter containing map of sequences, shall modify it and return with changes and added aliases which differ from generic version. More details in UI section.

  • "getfiles" shall generate map from filenames to file contents. It shall be used to generate future bootloader cfg. files for manual editing. Returns the map.

  • "setfiles" stores map with the same format as result of "getfiles" to internal structures (after parsing them). Should change the BootCommon::files_edited variable if some file was changed. Has one map parameter.

  • "getoptions" returns map of options which can be present in bootloader. Map contains key `global for global options, and keys "image" and "other" (can differ for different bootloaders) for sections. Value of each key is list of options. If returns nil, the "Add" button for adding options will be disabled. To enable it if yuo don't want to create options list, just return empty map. Combobox for choosing option is always editable, lists don't have to be complete.

  • "updoptlst" updates list of options to be shown in table. As parameter has map of options and values, returns list of option keys. Must read from BootCommon::variables whether edits global section or single section.

Value of each key shall be term, which will be evaluated in moment specified function is needed (after adding parameters if needed). Return value will be returned to caller (if function has return value). If some key is missing in the map, gemeric function is used (which typically means function usable for LiLo, because most of bootloaders for Linux are similar to LiLo.


User interface

UI concept

The general user interface and workflow is the same for all supported bootloaders. But usually some widgets need to have a little different behaviour or look for different bootloaders. Because of this there is common workflow, which can be used for all bootloaders, and common set of widgets (or widget groups), which can be replaced by bootloader-specific widget (widget group). Each widget has defined it's look and behaviour. It has various functions for restoring settings when shown, handle changes, check whether currently set settings are OK,...). This makes possible to write whole dialog at once and not duplicate code between different bootloaders if it isn't needed.

The function for displaying dialog creates a look of the dialog from the widgets (some may be general, some bootloader-specific according to inidividual bootloader's set of widgets), creates help using helps of dialog member widgets, collects events which may result to replacing the dialog with other one, and call generic dialog function with parameters specifying wizard sequencer buttons, help, caption and everything else what is needed to display the dialog. (Not all dialogs do this, it is still possible to create and handle dialog completly inside specific dialog function). Generic dialog function calls appropriate function of all widgets which are part of the dialog.

Popup widgets related to single option behave mainly the same way as widgets in the wizard sequencer dialog. The map describing the widget only must have function for displaying one-line summary in the table (otherwise generic one is used), and optionaly help is in the format of label widget (no HTML).

Of course the concept allows to modify the base workflow for single bootloader, or completely replace it.


GetWidgets function

Function global define map GetWidgets () returns map describing all bootloader-specific widgets or whole dialogs. Resulting map should contain (may be empty) map from widget name (string) to term, which will after evaluation return widget description map. Don't use maps containing terms as functions directly, but better use functions returning the map, because terms ase evaluated into depth, including all map entries. This map is then used to display widget, initialize it, handle it's events and displaying appropriate help.


Widget description map

Widget description map contains following fields:

  • "widget" : term contains widget to be displayed in the dialog.

  • "restore" : term, will be evaluated after dialog gets shown. Appropriate contents of dialog (eg. texts from textentries) shoud be set during evaluating this term.

  • "handle" : term, which will be evaluated everytime some UI event is generated (at each UI::UserInput ()). Before evaluating, symbol parameter will be added, containing result value of UI::UserInput (), second parameter containing list of events leading to exit widget with saving will be added. Handler's return value must contain symbol, which may be the same, but can be changed. If nil is returned, it is handled the same wasy as if it wouldn't be changed.

  • "help" : string representing help, which should be displayed to the widget. The help will be included in dialog help at appropriate place (left bar for normal dialog - in HTML format, as a label for popups).

  • "validate" : term, will be evaluated when it will be needed (dialog will be exited other way than Back or Abort button). Shall return true if everything is OK, false if not. If there is any problem, should display appropriate popup and change focus to problematic widget.

  • "exits" : list contains list of symbols, which if are generated and dialog is correctly validated, dialog is left returning this symbol to wizard sequencer.


Option widget description map

Option widget description map contains all fields as widget description map, additionally following:

  • "label" : string label, which will be shown in the table of settings. Key not present means option name will be used.

  • "summary" : term will be evaluated to get the text to the settings table. Result of evaluation of this term will be used. If key not present, raw value will be used if it is part of configuration file, otherwise will be empty.


Widgets handling functions

These unctions may be usefull for complete dialog writers, and are used in generic versions of dialogs. They are used to apply all needed actions on list of widgets and create widget maps from widget names.

  • global define list getWidgets (list names) transforms list of widget names to list of widget maps (contents described above). If bootloader-specific version of widhet exists, then is returned, otherwise generic widget is returned in the list.

  • global define map getPopupWidget (any name) returns map of specified single-option widget. If bootloader-specific versin exists, it is returned, otherwise generic (if exists) is used or widget is generated according to option type

  • global define map getPopupWidgets () gets maps of all popup widgets. Specific/common version is choosen the same way as in getPopupWidget case.

  • global define void readWidgets (list widgets) evaluates the "restore" terms of all maps in list. This is used to read all widgets settings.

  • global define void handleChange (list widgets, any action) takes the list of widgets and evaluates the "handle" terms (after adding the action symbol and list of actions causing exiting including save). Before evaluating checks whether it is needed to validate widgets data and if yes, then if validation is OK (using validateWidgetsIfNeeded function). If validation fails, doesn't do anything. Validation must succeed for all widgets present in dialog/popup.

  • global define boolean validateWidgetsIfNeeded (list widgets, any action) checks whether generated event is reason to validate (leaving dialog other way than Back or Abort), and if yes, then checks all widget whether they have proper values set. Returns true if no validation is needed or everything is OK and action can be handled properly, false if validation of some widget failed. Widget validation function should display some warning or change focus if validation fails.

  • global define list getExitEvents (list widgets) returns merge of all "exits" lists of widgets in dialog, adds symbols `back, `abort and `next.

  • global define string mergeHelps (list widgets) merges helps of specified widgets to one string.


Workflow sequence changes

Universal UI allows to add new dialogs to sequence or modify the sequence any way. What bootloader-specific module must do, is to provide key "sequence" in bootloader description function result. As argument the function when calling receives map containing current sections (key is section name, value map of sequence). Function can modify them, add new sequences, remove existing. Additionally can add "aliases" entry (value map of aliases). which is needed for adding new dialogs to sequence. This map is mesged with common aliases map (in case of conflict bootloader-specific alias is used). Return value of this function must contain updated wizard sequencer data.


GRUB bootloader

GRUB is new bootloader currently being used on i386 and compatibles, and on AMD x86-64. It has following advantages:

  1. Possible to boot unconfigured section, or update boot p[arameters at boot time

  2. Understands common filesystem, in case of new kernel there is no need to reinstall anything

Of course there are some problems with GRUB:

  1. Can't read kernel/initrd images from volumes located on LVM or MD

  2. Needs explicitly set mapping between UNIX-like devices and BIOS IDs

First problem can be easily solved by adding blocklists instead of filenames into configuration files (which removes second advantage). If no device map is present, GRUB can detect it's own, but in case of multiple disk this detection is usually not correct.


Configuration files

There are three important files on the disk storing GRUB's configuration. First is device map located at /boot/grub/device.map. It stores only mapping between GRUB's device names and Linux device names (eg. (hd0) /dev/hda).

Second, /etc/grub.conf contains list of commands to be run for installing the GRUB bootloader. Contains location of GRUB's stages, file with bootloader menu, and others.

Third file contains the bootloader menu. It is located at /boot/grub/menu.lst. If using filesystem to read this file (and not reading as blocklist), it isn't needed to run any tool after this file is changed, changes file will be read next time system will boot.


Configuration reading and writing

/boot/grub/device.map and /etc/grub.conf are small text files, which are read and written as strings, and parsed by the YCP code inside the BootGRUB module (more percisely it's include). /boot/grub/menu.lst is larger, and to reading and writing. this file the lilo agent is used. Some updates of this agent were needed to make it usable for GRUB (because of other syntax and importance of the order of lines inside a section). Only if bootloader location has changed, during installation or upon extra request bootloader is reinstalled after writing it's configuration.


Proposing configuration

Proposing configuration of GRUB is much harder job than proposing configuration for LILO, because in case of lilo for kernel image normal path from root is written to configuration file, and it doesn't change when user chooses to repartition the disk, but in case of GRUB the path in configuration file contains device name and path from root of the filesystem. Eg. if user repartitiones the disk and adds extra partition for /boot filesystem, both path and device name must get changed.

The general proposing concept is nearly the same as in case of LILO (the Section called LILO bootloader). Additionally, there must be added for the gfxmenu entry the same handling as for sections and in them mentioned files.


LILO bootloader

The LILO bootloader was a long time the default bootloader on i386 architecture. Now is used on i386 and compatibles, and on new AMD's platform x86-64.


Configuration files

LILO bootloader uses only one configuration file located at /etc/lilo.conf. Everytime this file is changed, /sbin/lilo must be callot to make the changes effect.


Configuration reading and writing

Reading and writing of /etc/lilo.conf is made using the lilo agent. Everytime this file changes, /sbin/lilo is called to make the changes effect.


Proposing configuration

Initial proposing generates standard sections and implicit globals. Each section has additional internal attribute describing it's state (was proposed and not changed by user) and devices it uses (usually the device containing /boot and / (root) partitions, in case of loading bootsector of other partition the device of the partition). When checking the proposal, partitions of each sections get compared to partitions, which have been changed, and depending on the result section is recreated, left as is, or user gets warned.

Because when proposing configuration it does't have to be clear whether initrd will exist, memtest86 will be present or graphic menu available, there is additional checking done when writing configuration. If in configuration file mentioned file doesn't exist (eg. initrd not created), corresponding record is removed from configuration file before writing ut to the disk.