{
    "mode": "info",
    "parameter": "grub-dev",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/info/grub-dev/json",
    "generated": "2026-11-12T13:45:22Z",
    "sections": {
        "File: grub-dev.info,  Node: Top,  Next: Getting the source code,  Up: (dir)": {
            "content": "",
            "subsections": []
        },
        "GNU GRUB developer manual": {
            "content": "",
            "subsections": []
        },
        "This is the developer documentation of GNU GRUB, the GRand Unified": {
            "content": "",
            "subsections": []
        },
        "Bootloader, a flexible and powerful boot loader program for a wide range": {
            "content": "of architectures.\n\nThis edition documents version 2.12.\n\nThis developer manual is for GNU GRUB (version 2.12, 31 August 2023).\n\nCopyright (C) 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011\nFree Software Foundation, Inc.\n\nPermission is granted to copy, distribute and/or modify this\ndocument under the terms of the GNU Free Documentation License,\nVersion 1.2 or any later version published by the Free Software\nFoundation; with no Invariant Sections.\n\n* Menu:\n\n* Getting the source code::\n* Coding style::\n* Finding your way around::\n* Contributing Changes::\n* Setting up and running test suite::\n* Updating External Code::\n* Debugging::\n* Porting::\n* Error Handling::\n* Stack and heap size::\n* BIOS port memory map::\n* Video Subsystem::\n* PFF2 Font File Format::\n* Graphical Menu Software Design::\n* Verifiers framework::\n* Lockdown framework::\n* Copying This Manual::         Copying This Manual\n* Index::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Getting the source code,  Next: Coding style,  Prev: Top,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "1 Getting the source code": {
            "content": "GRUB is maintained using the GIT revision control system\n(https://git-scm.com/book/en/v2).  To fetch:\n\ngit clone git://git.sv.gnu.org/grub.git\n\nWeb access is available under\nhttp://git.savannah.gnu.org/cgit/grub.git/\n\nThe branches available are:\n\n'master'\nMain development branch.\n'grub-legacy'\nGRUB 0.97 codebase.  Kept for reference and legal reasons\n'multiboot'\nMultiboot specfication\n'multiboot2'\nMultiboot2 specfication\n'developer branches'\nPrefixed with developer name.  Every developer of a team manages\nhis own branches.  Developer branches do not need changelog\nentries.\n\nOnce you have used 'git clone' to fetch an initial copy of a branch,\nyou can use 'git pull' to keep it up to date.  If you have modified your\nlocal version, you may need to resolve conflicts when pulling.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Coding style,  Next: Finding your way around,  Prev: Getting the source code,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "2 Coding style": {
            "content": "",
            "subsections": []
        },
        "Basically we follow the GNU Coding Standards": {
            "content": "(http://www.gnu.org/prep/standardstoc.html).  We define additional\nconventions for GRUB here.\n\n* Menu:\n\n* Naming Conventions::\n* Functions::\n* Variables::\n* Types::\n* Macros::\n* Comments::\n* Multi-Line Comments::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Naming Conventions,  Next: Functions,  Up: Coding style": {
            "content": "",
            "subsections": [
                {
                    "name": "2.1 Naming Conventions",
                    "content": ""
                }
            ]
        },
        "All global symbols (i.e.  functions, variables, types, and macros) must": {
            "content": "have the prefix grub or GRUB.  The all capital form is used only by\nmacros.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Functions,  Next: Variables,  Prev: Naming Conventions,  Up: Coding style": {
            "content": "",
            "subsections": [
                {
                    "name": "2.2 Functions",
                    "content": ""
                }
            ]
        },
        "If a function is global, its name must be prefixed with grub and must": {
            "content": "consist of only small letters.  If the function belongs to a specific\nfunction module, the name must also be prefixed with the module name.",
            "subsections": []
        },
        "For example, if a function is for file systems, its name is prefixed": {
            "content": "with grubfs.  If a function is for FAT file system but not for all\nfile systems, its name is prefixed with grubfsfat.  The hierarchy is\nnoted this way.\n\nAfter a prefix, a function name must start with a verb (such as get\nor is).  It must not be a noun.  Some kind of abbreviation is permitted,\nas long as it wouldn't make code less readable (e.g.  init).\n\nIf a function is local, its name may not start with any prefix.  It\nmust start with a verb.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Variables,  Next: Types,  Prev: Functions,  Up: Coding style": {
            "content": "",
            "subsections": [
                {
                    "name": "2.3 Variables",
                    "content": ""
                }
            ]
        },
        "The rule is mostly the same as functions, as noted above.  If a variable": {
            "content": "is global, its name must be prefixed with grub and must consist of only\nsmall letters.  If the variable belongs to a specific function module,\nthe name must also be prefixed with the module name.  For example, if a\nfunction is for dynamic loading, its name is prefixed with grubdl.  If\na variable is for ELF but not for all dynamic loading systems, its name\nis prefixed with grubdlelf.\n\nAfter a prefix, a variable name must start with a noun or an\nadjective (such as name or long) and it should end with a noun.  Some\nkind of abbreviation is permitted, as long as it wouldn't make code less\nreadable (e.g.  i18n).\n\nIf a variable is global in the scope of a single file (i.e.  it is\ndeclared with static), its name may not start with any prefix.  It must\nstart with a noun or an adjective.\n\nIf a variable is local, you may choose any shorter name, as long as\nit wouldn't make code less readable (e.g.  i).\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Types,  Next: Macros,  Prev: Variables,  Up: Coding style": {
            "content": "",
            "subsections": [
                {
                    "name": "2.4 Types",
                    "content": ""
                }
            ]
        },
        "The name of a type must be prefixed with grub and must consist of only": {
            "content": "small letters.  If the type belongs to a specific function module, the\nname must also be prefixed with the module name.  For example, if a type\nis for OS loaders, its name is prefixed with grubloader.  If a type is\nfor Multiboot but not for all OS loaders, its name is prefixed with\ngrubloaderlinux.\n\nThe name must be suffixed with t, to emphasize the fact that it is a\ntype but not a variable or a function.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Macros,  Next: Comments,  Prev: Types,  Up: Coding style": {
            "content": "",
            "subsections": [
                {
                    "name": "2.5 Macros",
                    "content": ""
                }
            ]
        },
        "If a macro is global, its name must be prefixed with GRUB and must": {
            "content": "consist of only large letters.  Other rules are the same as functions or\nvariables, depending on whether a macro is used like a function or a\nvariable.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Comments,  Next: Multi-Line Comments,  Prev: Macros,  Up: Coding style": {
            "content": "",
            "subsections": [
                {
                    "name": "2.6 Comments",
                    "content": "All comments shall be C-style comments, of the form '/* ... */'.  A\ncomment can be placed immediately preceding the entity it describes or\nit can be placed together with code, variable declarations, or other\nnon-comment entities.  However, it is recommended to not mix various\nforms especially in types/structs descriptions.\n\nAcceptable:\n/* The page # that is the front buffer. */\nint displayedpage;\n\nint renderpage; /* The page # that is the back buffer. */\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: Multi-Line Comments,  Prev: Comments,  Up: Coding style": {
            "content": "",
            "subsections": [
                {
                    "name": "2.7 Multi-Line Comments",
                    "content": ""
                }
            ]
        },
        "Comments spanning multiple lines shall be formatted with all lines after": {
            "content": "the first aligned with the first line.  Asterisk characters should be\nrepeated at the start of each subsequent line.\n\nAcceptable:\n/*\n* This is a comment\n* which spans multiple lines.\n* It is long.\n*/\n\nUnacceptable:\n/* This is a comment\nwhich spans multiple lines.\nIt is long. */\n\n/*\n* This is a comment\n* which spans multiple lines.\n* It is long. */\n\n/* This is a comment\n* which spans multiple lines.\n* It is long.\n*/\n\nIn particular first unacceptable form makes comment difficult to\ndistinguish from the code itself.  Especially if it contains the code\nsnippets and/or is long.  So, its usage is disallowed.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Finding your way around,  Next: Contributing Changes,  Prev: Coding style,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "3 Finding your way around": {
            "content": "Here is a brief map of the GRUB code base.\n\nGRUB uses Autoconf and Automake, with most of the Automake input\ngenerated by a Python script.  The top-level build rules are in\n'configure.ac', 'grub-core/Makefile.core.def', and 'Makefile.util.def'.\nEach block in a '*.def' file represents a build target, and specifies\nthe source files used to build it on various platforms.  The '*.def'\nfiles are processed into Automake input by 'gentpl.py' (which you only\nneed to look at if you are extending the build system).  If you are\nadding a new module which follows an existing pattern, such as a new\ncommand or a new filesystem implementation, it is usually easiest to\ngrep 'grub-core/Makefile.core.def' and 'Makefile.util.def' for an\nexisting example of that pattern to find out where it should be added.\n\nIn general, code that may be run at boot time is in a subdirectory of\n'grub-core', while code that is only run from within a full operating\nsystem is in a subdirectory of the top level.\n\nLow-level boot code, such as the MBR implementation on PC BIOS\nsystems, is in the 'grub-core/boot/' directory.\n\nThe GRUB kernel is in 'grub-core/kern/'.  This contains core\nfacilities such as the device, disk, and file frameworks, environment\nvariable handling, list processing, and so on.  The kernel should\ncontain enough to get up to a rescue prompt.  Header files for kernel\nfacilities, among others, are in 'include/'.\n\nTerminal implementations are in 'grub-core/term/'.\n\nDisk access code is spread across 'grub-core/disk/' (for accessing\nthe disk devices themselves), 'grub-core/partmap/' (for interpreting\npartition table data), and 'grub-core/fs/' (for accessing filesystems).",
            "subsections": []
        },
        "Note that, with the odd specialised exception, GRUB only contains code": {
            "content": "to read from filesystems and tries to avoid containing any code to\nwrite to filesystems; this lets us confidently assure users that GRUB\ncannot be responsible for filesystem corruption.\n\nPCI and USB bus handling is in 'grub-core/bus/'.\n\nVideo handling code is in 'grub-core/video/'.  The graphical menu\nsystem uses this heavily, but is in a separate directory,\n'grub-core/gfxmenu/'.\n\nMost commands are implemented by files in 'grub-core/commands/', with\nthe following exceptions:\n\n* A few core commands live in 'grub-core/kern/corecmd.c'.\n\n* Commands related to normal mode live under 'grub-core/normal/'.\n\n* Commands that load and boot kernels live under 'grub-core/loader/'.\n\n* The 'loopback' command is really a disk device, and so lives in\n'grub-core/disk/loopback.c'.\n\n* The 'gettext' command lives under 'grub-core/gettext/'.\n\n* The 'loadfont' and 'lsfonts' commands live under 'grub-core/font/'.\n\n* The 'serial', 'terminfo', and 'backgroundimage' commands live\nunder 'grub-core/term/'.\n\n* The 'efiemu*' commands live under 'grub-core/efiemu/'.\n\n* OS-dependent code should be under 'grub-core/osdep/'\n\n* Utility programs meant to be run from a full operating system\n(except OS-dependent code mentioned previously) are in 'util/'.\n\nThere are a few other special-purpose exceptions; grep for them if\nthey matter to you.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Contributing Changes,  Next: Setting up and running test suite,  Prev: Finding your way around,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "4 Contributing changes": {
            "content": "",
            "subsections": []
        },
        "Contributing changes to GRUB 2 is welcomed activity.  However we have a": {
            "content": "bit of control what kind of changes will be accepted to GRUB 2.",
            "subsections": []
        },
        "Therefore it is important to discuss your changes on grub-devel mailing": {
            "content": "list (see MailingLists).  On this page there are some basic details on\nthe development process and activities.\n\nFirst of all you should come up with the idea yourself what you want\nto contribute.  If you do not have that beforehand you are advised to\nstudy this manual and try GRUB 2 out to see what you think is missing\nfrom there.\n\nHere are additional pointers:\n* GRUB's Task Tracker (https://savannah.gnu.org/task/?group=grub)\n* GRUB's Bug Tracker (https://savannah.gnu.org/bugs/?group=grub)\n\nIf you intended to make changes to GRUB Legacy (<=0.97) those are not\naccepted anymore.\n\n* Menu:\n\n* Getting started::\n* Typical Developer Experience::\n* When you are approved for write access to project's files::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Getting started,  Next: Typical Developer Experience,  Up: Contributing Changes": {
            "content": "",
            "subsections": [
                {
                    "name": "4.1 Getting started",
                    "content": "* Always use latest GRUB 2 source code.  So get that first.\n\nFor developers it is recommended always to use the newest\ndevelopment version of GRUB 2.  If development takes a long period\nof time, please remember to keep in sync with newest developments\nregularly so it is much easier to integrate your change in the\nfuture.  GRUB 2 is being developed in a GIT repository.\n\nPlease check Savannah's GRUB project page for details how to get\nnewest git: GRUB 2 git Repository\n(https://savannah.gnu.org/git/?group=grub)\n\n* Compile it and try it out.\n\nIt is always good idea to first see that things work somehow and\nafter that to start to implement new features or develop fixes to\nbugs.\n\n* Study the code.\n\nThere are sometimes odd ways to do things in GRUB 2 code base.\nThis is mainly related to limited environment where GRUB 2 is being\nexecuted.  You usually do not need to understand it all so it is\nbetter to only try to look at places that relates to your work.\nPlease do not hesitate to ask for help if there is something that\nyou do not understand.\n\n* Develop a new feature.\n\nNow that you know what to do and how it should work in GRUB 2 code\nbase, please be free to develop it.  If you have not so far\nannounced your idea on grub-devel mailing list, please do it now.\nThis is to make sure you are not wasting your time working on the\nsolution that will not be integrated to GRUB 2 code base.\n\nYou might want to study our coding style before starting\ndevelopment so you do not need to change much of the code when your\npatch is being reviewed.  (see *note Coding style::)\n\nFor every accepted patch there has to exist a ChangeLog entry.  Our\nChangeLog consist of changes within source code and are not\ndescribing about what the change logically does.  Please see\nexamples from previous entries.\n\nAlso remember that GRUB 2 is licensed under GPLv3 license and that\nusually means that you are not allowed to copy pieces of code from\nother projects.  Even if the source project's license would be\ncompatible with GPLv3, please discuss it beforehand on grub-devel\nmailing list.\n\n* Test your change.\n\nTest that your change works properly.  Try it out a couple of\ntimes, preferably on different systems, and try to find problems\nwith it.\n\n* Publish your change.\n\nWhen you are happy with your change, first make sure it is\ncompilable with latest development version of GRUB 2.  After that\nplease send a patch to grub-devel for review.  Please describe in\nyour email why you made the change, what it changes and so on.\nPlease be prepared to receive even discouraging comments about your\npatch.  There is usually at least something that needs to be\nimproved in every patch.\n\nPlease use unified diff to make your patch (good match of arguments\nfor diff is '-pruN').\n\n* Respond to received feedback.\n\nIf you are asked to modify your patch, please do that and resubmit\nit for review.  If your change is large you are required to submit\na copyright agreement to FSF. Please keep in mind that if you are\nasked to submit for copyright agreement, process can take some time\nand is mandatory in order to get your changes integrated.\n\nIf you are not on grub-devel to respond to questions, most likely\nyour patch will not be accepted.  Also if problems arise from your\nchanges later on, it would be preferable that you also fix the\nproblem.  So stay around for a while.\n\n* Your patch is accepted.\n\nGood job!  Your patch will now be integrated into GRUB 2 mainline,\nand if it didn't break anything it will be publicly available in\nthe next release.\n\nNow you are welcome to do further improvements :)\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: Typical Developer Experience,  Next: When you are approved for write access to project's files,  Prev: Getting started,  Up: Contributing Changes": {
            "content": "",
            "subsections": [
                {
                    "name": "4.2 Typical Developer Experience",
                    "content": "The typical experience for a developer in this project is the following:\n\n1. You find yourself wanting to do something (e.g.  fixing a bug).\n2. You show some result in the mailing list or the IRC.\n3. You are getting to be known to other developers.\n4. You accumulate significant amount of contribution, so copyright\nassignment is processed.\n5. You are free to check in your changes on your own, legally\nspeaking.\n\nAt this point, it is rather annoying that you ought to ask somebody\nelse every change to be checked in.  For efficiency, it is far better,\nif you can commit it yourself.  Therefore, our policy is to give you the\nwrite permission to our official repository, once you have shown your\nskill and will, and the FSF clerks have dealt with your copyright\nassignment.\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: When you are approved for write access to project's files,  Prev: Typical Developer Experience,  Up: Contributing Changes": {
            "content": "",
            "subsections": [
                {
                    "name": "4.3 When you are approved for write access to project's files",
                    "content": ""
                }
            ]
        },
        "As you might know, GRUB is hosted on Savannah": {
            "content": "(https://savannah.gnu.org/projects/grub), thus the membership is managed\nby Savannah.  This means that, if you want to be a member of this\nproject:\n\n1. You need to create your own account on Savannah.\n2. You can submit \"Request for Inclusion\" from \"My Groups\" on\nSavannah.\n\nThen, one of the admins can approve your request, and you will be a\nmember.  If you don't want to use the Savannah interface to submit a\nrequest, you can simply notify the admins by email or something else,\nalternatively.  But you still need to create an account beforehand.\n\nNOTE: we sometimes receive a \"Request for Inclusion\" from an unknown\nperson.  In this case, the request would be just discarded, since it is\ntoo dangerous to allow a stranger to be a member, which automatically\ngives him a commit right to the repository, both for a legal reason and\nfor a technical reason.\n\nIf your intention is to just get started, please do not submit a\ninclusion request.  Instead, please subscribe to the mailing list, and\ncommunicate first (e.g.  sending a patch, asking a question, commenting\non another message...).\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Setting up and running test suite,  Next: Updating External Code,  Prev: Contributing Changes,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "5 Setting up and running test suite": {
            "content": "GRUB is basically a tiny operating system with read support for many\nfile systems and which has been ported to a variety of architectures.",
            "subsections": []
        },
        "As such, its test suite has quite a few dependencies required to fully": {
            "content": "run the suite.  These dependencies are currently documented in the\nINSTALL (https://git.savannah.gnu.org/cgit/grub.git/tree/INSTALL) file\nin the source repository.  Once installed, the test suite can be started\nby running the 'make check' command from the GRUB build directory.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Updating External Code,  Next: Debugging,  Prev: Setting up and running test suite,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "6 Updating external code": {
            "content": "GRUB includes some code from other projects, and it is sometimes\nnecessary to update it.\n\n* Menu:\n\n* Gnulib::\n* jsmn::\n* minilzo::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Gnulib,  Next: jsmn,  Up: Updating External Code": {
            "content": "",
            "subsections": [
                {
                    "name": "6.1 Gnulib",
                    "content": ""
                }
            ]
        },
        "Gnulib is a source code library that provides basic functionality to": {
            "content": "programs and libraries.  Many software packages make use of Gnulib to\navoid reinventing the portability wheel.\n\nGRUB imports Gnulib using its 'bootstrap' utility, identifying a\nparticular Git commit in 'bootstrap.conf'.  To upgrade to a new Gnulib\ncommit, set 'GNULIBREVISION' in 'bootstrap.conf' to the new commit ID,\nthen run './bootstrap' and whatever else you need to make sure it works.",
            "subsections": []
        },
        "Check for changes to Gnulib's 'NEWS' file between the old and new": {
            "content": "commits; in some cases it will be necessary to adjust GRUB to match.",
            "subsections": []
        },
        "You may also need to update the patches in": {
            "content": "'grub-core/lib/gnulib-patches/'.\n\nTo add a new Gnulib module or remove one that is no longer needed,\nchange 'gnulibmodules' in 'bootstrap.conf'.  Again, run './bootstrap'\nand whatever else you need to make sure it works.\n\nBootstrapping from an older distribution containing gettext version <\n0.18.3, will require a patch similar to this to be applied first before\nrunning the './bootstrap' utility:\n\ndiff --git a/bootstrap.conf b/bootstrap.conf\nindex 988dda0..a3193a9 100644\n--- a/bootstrap.conf\n+++ b/bootstrap.conf\n@ -67,7 +67,7 @ SKIPPO=t\nbuildreq=\"\\\nautoconf   2.63\nautomake   1.11\n-gettext    0.18.3\n+gettext    0.17\ngit        1.5.5\ntar        -\n\"\ndiff --git a/configure.ac b/configure.ac\nindex 08b518f..99f5b36 100644\n--- a/configure.ac\n+++ b/configure.ac\n@ -362,7 +362,7 @ ACCHECKPROG(HAVECXX, $CXX, yes, no)\n\nACGNUSOURCE\nAMGNUGETTEXT([external])\n-AMGNUGETTEXTVERSION([0.18.3])\n+AMGNUGETTEXTVERSION([0.17])\nACSYSLARGEFILE\n\n# Identify characteristics of the host architecture.\n\n\nIt will also be necessary to adjust the patches in\n'po/gettext-patches/' to apply to an older version of gettext.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: jsmn,  Next: minilzo,  Prev: Gnulib,  Up: Updating External Code": {
            "content": "",
            "subsections": [
                {
                    "name": "6.2 jsmn",
                    "content": "jsmn is a minimalistic JSON parser which is implemented in a single\nheader file 'jsmn.h'.  To import a different version of the jsmn parser,\nyou may simply download the 'jsmn.h' header from the desired tag or\ncommit to the target directory:\n\ncurl -L https://raw.githubusercontent.com/zserge/jsmn/v1.1.0/jsmn.h \\\n-o grub-core/lib/json/jsmn.h\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: minilzo,  Prev: jsmn,  Up: Updating External Code": {
            "content": "",
            "subsections": [
                {
                    "name": "6.3 minilzo",
                    "content": "miniLZO is a very lightweight subset of the LZO library intended for\neasy inclusion in other projects.  It is generated automatically from\nthe LZO source code and contains the most important LZO functions.\n\nTo upgrade to a new version of the miniLZO library, download the\nrelease tarball and copy the files into the target directory:\n\ncurl -L -O https://www.oberhumer.com/opensource/lzo/download/minilzo-2.10.tar.gz\ntar -zxf minilzo-2.10.tar.gz\nrm minilzo-2.10/testmini.c\nrm -r grub-core/lib/minilzo/*\ncp minilzo-2.10/*.[hc] grub-core/lib/minilzo\nrm -r minilzo-2.10*\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: Debugging,  Next: Porting,  Prev: Updating External Code,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "7 Debugging": {
            "content": "GRUB2 can be difficult to debug because it runs on the bare-metal and\nthus does not have the debugging facilities normally provided by an\noperating system.  This chapter aims to provide useful information on\nsome ways to debug GRUB2 for some architectures.  It by no means intends\nto be exhaustive.  The focus will be one x8664 and i386 architectures.",
            "subsections": []
        },
        "Luckily for some issues virtual machines have made the ability to debug": {
            "content": "GRUB2 much easier, and this chapter will focus debugging via the QEMU\nvirtual machine.  We will not be going over debugging of the userland\ntools (eg.  grub-install), there are many tutorials on debugging\nprograms in userland.\n\nYou will need GDB and the QEMU binaries for your system, on Debian\nthese can be installed with the 'gdb' and 'qemu-system-x86' packages.",
            "subsections": []
        },
        "Also it is assumed that you have already successfully compiled GRUB2": {
            "content": "from source for the target specified in the section below and have some\nfamiliarity with GDB. When GRUB2 is built it will create many different\nbinaries.  The ones of concern will be in the 'grub-core' directory of\nthe GRUB2 build dir.  To aide in debugging we will want the debugging\nsymbols generated during the build because these symbols are not kept in\nthe binaries which get installed to the boot location.  The build\nprocess outputs two sets of binaries, one without symbols which gets\nexecuted at boot, and another set of ELF images with debugging symbols.",
            "subsections": []
        },
        "The built images with debugging symbols will have a '.image' suffix, and": {
            "content": "the ones without a '.img' suffix.  Similarly, loadable modules with\ndebugging symbols will have a '.module' suffix, and ones without a\n'.mod' suffix.  In the case of the kernel the binary with symbols is\nnamed 'kernel.exec'.\n\nIn the following sections, information will be provided on debugging\non various targets using 'gdb' and the 'gdbgrub' GDB script.\n\n* Menu:\n\n* i386-pc::\n* x8664-efi::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: i386-pc,  Next: x8664-efi,  Up: Debugging": {
            "content": "",
            "subsections": [
                {
                    "name": "7.1 i386-pc",
                    "content": ""
                }
            ]
        },
        "The i386-pc target is a good place to start when first debugging GRUB2": {
            "content": "because in some respects it's easier than EFI platforms.  The reason\nbeing that the initial load address is always known in advance.  To\nstart debugging GRUB2 first QEMU must be started in GDB stub mode.  The\nfollowing command is a simple illustration:\n\nqemu-system-i386 -drive file=disk.img,format=raw \\\n-device virtio-scsi-pci,id=scsi0 -S -s\n\nThis will start a QEMU instance booting from 'disk.img'.  It will\npause at start waiting for a GDB instance to attach to it.  You should\nchange 'disk.img' to something more appropriate.  A block device can be\nused, but you may need to run QEMU as a privileged user.\n\nTo connect to this QEMU instance with GDB, the 'target remote' GDB\ncommand must be used.  We also need to load a binary image, preferably\nwith symbols.  This can be done using the GDB command 'file\nkernel.exec', if GDB is started from the 'grub-core' directory in the\nGRUB2 build directory.  GRUB2 developers have made this more simple by\nincluding a GDB script which does much of the setup.  This file is at\n'grub-core/gdbgrub' in the build directory and is also installed via\n'make install'.  When using a pre-built GRUB, the distribution may have\na package which installs this GDB script along with debug symbol\nbinaries, such as Debian's 'grub-pc-dbg' package.  The GDB script is\nintended to be used like so, assuming that '/path/to/script' is the path\nto the directory containing the gdbgrub script and debug symbol files:\n\ncd $(dirname /path/to/script/gdbgrub)\ngdb -x gdbgrub\n\nOnce GDB has been started with the 'gdbgrub' script it will\nautomatically connect to the QEMU instance.  You can then do things you\nnormally would in GDB like set a break point on GRUBMAIN.\n\nSetting breakpoints in modules is trickier since they haven't been\nloaded yet and are loaded at addresses determined at runtime.  The\nmodule could be loaded to different addresses in different QEMU\ninstances.  The debug symbols in the modules '.module' binary, thus are\nalways wrong, and GDB needs to be told where to load the symbols to.",
            "subsections": []
        },
        "But this must happen at runtime after GRUB2 has determined where the": {
            "content": "module will get loaded.  Luckily the 'gdbgrub' script takes care of\nthis with the 'runtimeloadmodule' command, which configures GDB to\nwatch for GRUB2 module loading and when it does add the module symbols\nwith the appropriate offset.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: x8664-efi,  Prev: i386-pc,  Up: Debugging": {
            "content": "",
            "subsections": [
                {
                    "name": "7.2 x8664-efi",
                    "content": ""
                }
            ]
        },
        "Using GDB to debug GRUB2 for the x8664-efi target has some similarities": {
            "content": "with the i386-pc target.  Please read and familiarize yourself with the\n*note i386-pc:: section when reading this one.  Extra care must be used\nto run QEMU such that it boots a UEFI firmware.  This usually involves\neither using the '-bios' option with a UEFI firmware blob (eg.\n'OVMF.fd') or loading the firmware via pflash.  This document will not\ngo further into how to do this as there are ample resource on the web.\n\nLike all EFI implementations, on x8664-efi the (U)EFI firmware that\nloads the GRUB2 EFI application determines at runtime where the\napplication will be loaded.  This means that we do not know where to\ntell GDB to load the symbols for the GRUB2 core until the (U)EFI\nfirmware determines it.  There are two good ways of figuring this out\nwhen running in QEMU: use a *note debug build of OVMF: OVMF debug log.\nand check the debug log, or have GRUB2 say where it is loaded.  Neither\nof these are ideal because they both generally give the information\nafter GRUB2 is already running, which makes debugging early boot\ninfeasible.  Technically, the first method does give the load address\nbefore GRUB2 is run, but without debugging the EFI firmware with\nsymbols, the author currently does not know how to cause the OVMF\nfirmware to pause at that point to use the load address before GRUB2 is\nrun.\n\nEven after getting the application load address, the loading of core\nsymbols is complicated by the fact that the debugging symbols for the\nkernel are in an ELF binary named 'kernel.exec' while what is in memory\nare sections for the PE32+ EFI binary.  When 'grub-mkimage' creates the\nPE32+ binary it condenses several segments from the ELF kernel binary\ninto one .data section in the PE32+ binary.  This must be taken into\naccount to properly load the other non-text sections.  Otherwise, GDB\nwill work as expected when breaking on functions, but, for instance,\nglobal variables will point to the wrong address in memory and thus give\nincorrect values (which can be difficult to debug).\n\nCalculating the correct offsets for sections is taken care of\nautomatically when loading the kernel symbols via the user-defined GDB\ncommand 'dynamicloadkernelexecsymbols', which takes one argument,\nthe address where the text section is loaded as determined by one of the\nmethods above.  Alternatively, the command 'dynamicloadsymbols' with\nthe text section address as an agrument can be called to load the kernel\nsymbols and set up loading the module symbols as they are loaded at\nruntime.\n\nIn the author's experience, when debugging with QEMU and OVMF, to\nhave debugging symbols loaded at the start of GRUB2 execution the GRUB2\nEFI application must be run via QEMU at least once prior in order to get\nthe load address.  Two methods for obtaining the load address are\ndescribed in two subsections below.  Generally speaking, the load\naddress does not change between QEMU runs.  There are exceptions to\nthis, namely that different GRUB2 EFI applications can be run at\ndifferent addresses.  Also, it has been observed that after running the\nEFI application for the first time, the second run will sometimes have a\ndifferent load address, but subsequent runs of the same EFI application\nwill have the same load address as the second run.  And it's a near\ncertainty that if the GRUB EFI binary has changed, eg.  been recompiled,\nthe load address will also be different.\n\nThis ability to predict what the load address will be allows one to\nassume the load address on subsequent runs and thus load the symbols\nbefore GRUB2 starts.  The following command illustrates this, assuming\nthat QEMU is running and waiting for a debugger connection and the\ncurrent working directory is where 'gdbgrub' resides:\n\ngdb -x gdbgrub -ex 'dynamicloadsymbols ADDRESS OF .TEXT SECTION'\n\nIf you load the symbols in this manner and, after continuing\nexecution, do not see output showing the module symbols loading, then it\nis very likely that the load address was incorrect.\n\nAnother thing to be aware of is how the loading of the GRUB image by\nthe firmware affects previously set software breakpoints.  On x86\nplatforms, software breakpoints are implemented by GDB by writing a\nspecial processor instruction at the location of the desired breakpoint.",
            "subsections": []
        },
        "This special instruction when executed will stop the program execution": {
            "content": "and hand control to the debugger, GDB. GDB will first save the\ninstruction bytes that are overwritten at the breakpoint and will put\nthem back when the breakpoint is hit.  If GRUB is being run for the\nfirst time in QEMU, the firmware will be loading the GRUB image into\nmemory where every byte is already set to 0.  This means that if a\nbreakpoint is set before GRUB is loaded, GDB will save the 0-byte(s)\nwhere the the special instruction will go.  Then when the firmware loads\nthe GRUB image and because it is unaware of the debugger, it will write\nthe GRUB image to memory, overwriting anything that was there previously\n-- notably in this case the instruction that implements the software\nbreakpoint.  This will be confusing for the person using GDB because GDB\nwill show the breakpoint as set, but the brekapoint will never be hit.",
            "subsections": []
        },
        "Furthermore, GDB then becomes confused, such that even deleting an": {
            "content": "recreating the breakpoint will not create usable breakpoints.  The\n'gdbgrub' script takes care of this by saving the breakpoints just\nbefore they are overwritten, and then restores them at the start of GRUB\nexecution.  So breakpoints for GRUB can be set before GRUB is loaded,\nbut be mindful of this effect if you are confused as to why breakpoints\nare not getting hit.\n\nAlso note, that hardware breakpoints do not suffer this problem.",
            "subsections": []
        },
        "They are implemented by having the breakpoint address in special debug": {
            "content": "registers on the CPU. So they can always be set freely without regard to\nwhether GRUB has been loaded or not.  The reason that hardware\nbreakpoints aren't always used is because there are a limited number of\nthem, usually around 4 on various CPUs, and specifically exactly 4 for\nx86 CPUs.  The 'gdbgrub' script goes out of its way to avoid using\nhardware breakpoints internally and uses them as briefly as possible\nwhen needed, thus allowing the user to have a maximal number at their\ndisposal.\n\n* Menu:\n\n* OVMF debug log::\n* Using the gdbinfo command::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: OVMF debug log,  Next: Using the gdbinfo command,  Up: x8664-efi": {
            "content": "",
            "subsections": []
        },
        "In order to get the GRUB2 load address from OVMF, first, a debug build": {
            "content": "of OVMF must be obtained (here is one\n(https://github.com/retrage/edk2-nightly/raw/master/bin/DEBUGX64OVMF.fd)\nwhich is not officially recommended).  OVMF will output debug messages\nto a special serial device, which we must add to QEMU. The following\nQEMU command will run the debug OVMF and write the debug messages to a\nfile named 'debug.log'.  It is assumed that 'disk.img' is a disk image\nor block device that is set up to boot GRUB2 EFI.\n\nqemu-system-x8664 -bios /path/to/debug/OVMF.fd \\\n-drive file=disk.img,format=raw \\\n-device virtio-scsi-pci,id=scsi0 \\\n-debugcon file:debug.log -global isa-debugcon.iobase=0x402\n\nIf GRUB2 was started by the (U)EFI firmware, then in the 'debug.log'\nfile one of the last lines should be a log message like: 'Loading driver\nat 0x00006AEE000 EntryPoint=0x00006AEE756'.  This means that the GRUB2\nEFI application was loaded at '0x00006AEE000' and its .text section is\nat '0x00006AEE756'.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Using the gdbinfo command,  Prev: OVMF debug log,  Up: x8664-efi": {
            "content": "",
            "subsections": []
        },
        "On EFI platforms the command 'gdbinfo' will output a string that is to": {
            "content": "be run in a GDB session running with the 'gdbgrub' GDB script.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Porting,  Next: Error Handling,  Prev: Debugging,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "8 Porting": {
            "content": "GRUB2 is designed to be easily portable accross platforms.  But because\nof the nature of bootloader every new port must be done separately.",
            "subsections": []
        },
        "Here is how I did MIPS (loongson and ARC) and Xen ports.  Note than this": {
            "content": "is more of suggestions, not absolute truth.\n\nFirst of all grab any architecture specifications you can find in\npublic (please avoid NDA).\n\nFirst stage is \"Hello world\".  I've done it outside of GRUB for\nsimplicity.  Your task is to have a small program which is loadable as\nbootloader and clearly shows its presence to you.  If you have easily\naccessible console you can just print a message.  If you have a mapped\nframebuffer you know address of, you can draw a square.  If you have a\ndebug facility, just hanging without crashing might be enough.  For the\nfirst stage you can choose to load the bootloader across the network\nsince format for network image is often easier than for local boot and\nit skips the need of small intermediary stages and nvram handling.",
            "subsections": []
        },
        "Additionally you can often have a good idea of the needed format by": {
            "content": "running \"file\" on any netbootable executable for given platform.\n\nThis program should probably have 2 parts: an assembler and C one.",
            "subsections": []
        },
        "Assembler one handles BSS cleaning and other needed setup (on some": {
            "content": "platforms you may need to switch modes or copy the executable to its\ndefinitive position).  So your code may look like (x86 assembly for\nillustration purposes)\n\n.globl start\nstart:\nmovl\t$bssstart, %edi\nmovl\t$end, %ecx\nsubl\t%edi, %ecx\nxorl\t%eax, %eax\ncld\nrep\nstosb\ncall main\n\n\nstatic const char msg[] = \"Hello, world\";\n\nvoid\nputchar (int c)\n{\n...\n}\n\nvoid\nmain (void)\n{\nconst char *ptr = msg;\nwhile (*ptr)\nputchar (*ptr++);\nwhile (1);\n}\n\nSometimes you need a third file: assembly stubs for\nABI-compatibility.\n\nOnce this file is functional it's time to move it into GRUB2.  The\nstartup assembly file goes to grub-core/kern/$cpu/$platform/startup.S.",
            "subsections": []
        },
        "You should also include grub/symbol.h and replace call to entry point": {
            "content": "with call to EXTC(grubmain).  The C file goes to\ngrub-core/kern/$cpu/$platform/init.c and its entry point is renamed to\nvoid grubmachineinit (void).  Keep final infinite loop for now.  Stubs\nfile if any goes to grub-core/kern/$cpu/$platform/callwrap.S. Sometimes\neither $cpu or $platform is dropped if file is used on several cpus\nrespectivelyplatforms.  Check those locations if they already have what\nyou're looking for.\n\nThen modify in configure.ac the following parts:\n\nCPU names:\n\ncase \"$targetcpu\" in\ni[[3456]]86)\ttargetcpu=i386 ;;\namd64)\ttargetcpu=x8664 ;;\nsparc)\ttargetcpu=sparc64 ;;\ns390x)\ttargetcpu=s390 ;;\n...\nesac\n\nSometimes CPU have additional architecture names which don't\ninfluence booting.  You might want to have some canonical name to avoid\nhaving bunch of identical platforms with different names.\n\nNOTE: it doesn't influence compile optimisations which depend solely\non chosen compiler and compile options.\n\nif test \"x$withplatform\" = x; then\ncase \"$targetcpu\"-\"$targetvendor\" in\ni386-apple) platform=efi ;;\ni386-*) platform=pc ;;\nx8664-apple) platform=efi ;;\nx8664-*) platform=pc ;;\npowerpc-*) platform=ieee1275 ;;\n...\nesac\nelse\n...\nfi\n\nThis part deals with guessing the platform from CPU and vendor.",
            "subsections": []
        },
        "Sometimes you need to use 32-bit mode for booting even if OS runs in": {
            "content": "64-bit one.  If so add your platform to:\n\ncase \"$targetcpu\"-\"$platform\" in\nx8664-efi) ;;\nx8664-emu) ;;\nx8664-*) targetcpu=i386 ;;\npowerpc64-ieee1275) targetcpu=powerpc ;;\nesac\n\nAdd your platform to the list of supported ones:\n\ncase \"$targetcpu\"-\"$platform\" in\ni386-efi) ;;\nx8664-efi) ;;\ni386-pc) ;;\ni386-multiboot) ;;\ni386-coreboot) ;;\n...\nesac\n\nIf explicit -m32 or -m64 is needed add it to:\n\ncase \"$targetcpu\" in\ni386 | powerpc) targetm32=1 ;;\nx8664 | sparc64) targetm64=1 ;;\nesac\n\nFinally you need to add a conditional to the following block:\n\nAMCONDITIONAL([CONDmipsarc], [test x$targetcpu = xmips -a x$platform = xarc])\nAMCONDITIONAL([CONDsparc64ieee1275], [test x$targetcpu = xsparc64 -a x$platform = xieee1275])\nAMCONDITIONAL([CONDpowerpcieee1275], [test x$targetcpu = xpowerpc -a x$platform = xieee1275])\n\nNext stop is gentpl.py.  You need to add your platform to the list of\nsupported ones (sorry that this list is duplicated):\n\nGRUBPLATFORMS = [ \"emu\", \"i386pc\", \"i386efi\", \"i386qemu\", \"i386coreboot\",\n\"i386multiboot\", \"i386ieee1275\", \"x8664efi\",\n\"mipsloongson\", \"sparc64ieee1275\",\n\"powerpcieee1275\", \"mipsarc\", \"ia64efi\",\n\"mipsqemumips\", \"s390mainframe\" ]\n\nYou may also want already to add new platform to one or several of\navailable groups.  In particular we always have a group for each CPU\neven when only one platform for given CPU is available.\n\nThen comes grub-core/Makefile.core.def.  In the block \"kernel\" you'll\nneed to define ldflags for your platform ($cpu$platformldflags).  You\nalso need to declare startup asm file ($cpu$platformstartup) as well\nas any other files (e.g.  init.c and callwrap.S) (e.g.  $cpu$platform =\nkern/$cpu/$platform/init.c).  At this stage you will also need to add\ndummy dl.c and cache.S with functions gruberrt\ngrubarchdlcheckheader (void *ehdr), gruberrt\ngrubarchdlrelocatesymbols (grubdlt mod, void *ehdr) (dl.c) and\nvoid grubarchsynccaches (void *address, grubsizet len) (cache.S).\nThey won't be used for now.\n\nYou will need to create directory include/$cpu/$platform and a file\ninclude/$cpu/types.h.  The latter following this template:\n\n#ifndef GRUBTYPESCPUHEADER\n#define GRUBTYPESCPUHEADER\t1\n\n/* The size of void *.  */\n#define GRUBTARGETSIZEOFVOIDP\t4\n\n/* The size of long.  */\n#define GRUBTARGETSIZEOFLONG\t\t4\n\n/* mycpu is big-endian.  */\n#define GRUBTARGETWORDSBIGENDIAN\t1\n/* Alternatively: mycpu is little-endian.  */\n#undef GRUBTARGETWORDSBIGENDIAN\n\n#endif /* ! GRUBTYPESCPUHEADER */\n\nYou will also need to add a dummy file to datetime and setjmp modules\nto avoid any of it having no files.  It can be just completely empty at\nthis stage.\n\nYou'll need to make grub-mkimage.c (util/grubmkimage.c) aware of the\nneeded format.  For most commonly used formats like ELF, PE, aout or raw\nthe support is already present and you'll need to make it follow the\nexistant code paths for your platform adding adjustments if necessary.\nWhen done compile:\n\n./bootstrap\n./configure --target=$cpu --with-platform=$platform TARGETCC=.. OBJCOPY=... STRIP=...\nmake > /dev/null\n\nAnd create image\n\n./grub-mkimage -d grub-core -O $formatid -o test.img\n\nAnd it's time to test your test.img.\n\nIf it works next stage is to have heap, console and timer.\n\nTo have the heap working you need to determine which regions are\nsuitable for heap usage, allocate them from firmware and map (if\napplicable).  Then call grubmminitregion (void *start, grubsizet s)\nfor every of this region.  As a shortcut for early port you can allocate\nright after end or have a big static array for heap.  If you do you'll\nprobably need to come back to this later.  As for output console you\nshould distinguish between an array of text, terminfo or graphics-based\nconsole.  Many of real-world examples don't fit perfectly into any of\nthese categories but one of the models is easier to be used as base.  In\nsecond and third case you should add your platform to terminfokernel\nrespectively videoinkernel group.  A good example of array of text is\ni386-pc (kern/i386/pc/init.c and term/i386/pc/console.c).  Of terminfo\nis ieee1275 (kern/ieee1275/init.c and term/ieee1275/console.c).  Of\nvideo is loongson (kern/mips/loongson/init.c).  Note that terminfo has\nto be inited in 2 stages: one before (to get at least rudimentary\nconsole as early as possible) and another after the heap (to get\nfull-featured console).  For the input there are string of keys,\nterminfo and direct hardware.  For string of keys look at i386-pc (same\nfiles), for terminfo ieee1275 (same files) and for hardware loongson\n(kern/mips/loongson/init.c and term/atkeyboard.c).\n\nFor the timer you'll need to call grubinstallgettimems (...)\nwith as sole argument a function returning a grubuint64t of a number\nof milliseconds elapsed since arbitrary point in the past.\n\nOnce these steps accomplished you can remove the inifinite loop and\nyou should be able to get to the minimal console.  Next step is to have\nmodule loading working.  For this you'll need to fill kern/$cpu/dl.c and\nkern/$cpu/cache.S with real handling of relocations and respectively the\nreal sync of I and D caches.  Also you'll need to decide where in the\nimage to store the modules.  Usual way is to have it concatenated at the\nend.  In this case you'll need to modify startup.S to copy modules out\nof bss to let's say ALIGNUP (end, 8) before cleaning out bss.  You'll\nprobably find useful to add totalmodulesize field to startup.S. In\ninit.c you need to set grubmodbase to the address where modules can be\nfound.  You may need grubmodulesgetend () to avoid declaring the\nspace occupied by modules as usable for heap.  You can test modules\nwith:\n\n./grub-mkimage -d grub-core -O $formatid -o test.img hello\n\nand then running \"hello\" in the shell.\n\nOnce this works, you should think of implementing disk access.  Look\naround disk/ for examples.\n\nThen, very importantly, you probably need to implement the actual\nloader (examples available in loader/)\n\nLast step to have minimally usable port is to add support to\ngrub-install to put GRUB in a place where firmware or platform will pick\nit up.\n\nNext steps are: filling datetime.c, setjmp.S, network (net/drivers),\nvideo (video/), halt (lib/), reboot (lib/).\n\nPlease add your platform to Platform limitations and Supported\nkernels chapter in user documentation and mention any steps you skipped\nwhich result in reduced features or performance.  Here is the quick\nchecklist of features.  Some of them are less important than others and\nskipping them is completely ok, just needs to be mentioned in user\ndocumentation.\n\nChecklist:\n* Is heap big enough?\n* Which charset is supported by console?\n* Does platform have disk driver?\n* Do you have network card support?\n* Are you able to retrieve datetime (with date)?\n* Are you able to set datetime (with date)?\n* Is serial supported?\n* Do you have direct disk support?\n* Do you have direct keyboard support?\n* Do you have USB support?\n* Do you support loading through network?\n* Do you support loading from disk?\n* Do you support chainloading?\n* Do you support network chainloading?\n* Does cpuid command supports checking all CPU features that the user\nmight want conditionalise on (64-bit mode, hypervisor,...)\n* Do you support hints?  How reliable are they?\n* Does platform have ACPI? If so do \"acpi\" and \"lsacpi\" modules work?\n* Do any of platform-specific operations mentioned in the relevant\nsection of user manual makes sense on your platform?\n* Does your platform support PCI? If so is there an appropriate\ndriver for GRUB?\n* Do you support badram?\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Error Handling,  Next: Stack and heap size,  Prev: Porting,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "9 Error Handling": {
            "content": "",
            "subsections": []
        },
        "Error handling in GRUB 2 is based on exception handling model.  As C": {
            "content": "language doesn't directly support exceptions, exception handling\nbehavior is emulated in software.\n\nWhen exception is raised, function must return to calling function.",
            "subsections": []
        },
        "If calling function does not provide handling of the exception it must": {
            "content": "return back to its calling function and so on, until exception is\nhandled.  If exception is not handled before prompt is displayed, error\nmessage will be shown to user.\n\nException information is stored on 'gruberrno' global variable.  If\n'gruberrno' variable contains value 'GRUBERRNONE', there is no active\nexception and application can continue normal processing.  When\n'gruberrno' has other value, it is required that application code\neither handles this error or returns instantly to caller.  If function\nis with return type 'gruberrt' is about to return 'GRUBERRNONE', it\nshould not set 'gruberrno' to that value.  Only set 'gruberrno' in\ncases where there is error situation.\n\nSimple exception forwarder.\ngruberrt\nforwardingexample (void)\n{\n/* Call function that might cause exception.  */\nfoobar ();\n\n/* No special exception handler, just forward possible exceptions.  */\nif (gruberrno != GRUBERRNONE)\n{\nreturn gruberrno;\n}\n\n/* All is OK, do more processing.  */\n\n/* Return OK signal, to caller.  */\nreturn GRUBERRNONE;\n}\n\nError reporting has two components, the actual error code (of type\n'gruberrt') and textual message that will be displayed to user.  List\nof valid error codes is listed in header file 'include/grub/err.h'.",
            "subsections": []
        },
        "Textual error message can contain any textual data.  At time of writing,": {
            "content": "error message can contain up to 256 characters (including terminating\nNUL). To ease error reporting there is a helper function 'gruberror'\nthat allows easier formatting of error messages and should be used\ninstead of writing directly to global variables.\n\nExample of error reporting.\ngruberrt\nfailingexample ()\n{\nreturn gruberror (GRUBERRFILENOTFOUND,\n\"Failed to read %s, tried %d times.\",\n\"test.txt\",\n10);\n}\n\nIf there is a special reason that error code does not need to be\ntaken account, 'gruberrno' can be zeroed back to 'GRUBERRNONE'.  In\ncases like this all previous error codes should have been handled\ncorrectly.  This makes sure that there are no unhandled exceptions.\n\nExample of zeroing 'gruberrno'.\ngruberrt\nprobeexample ()\n{\n/* Try to probe device type 1.  */\nprobefordevice ();\nif (gruberrno == GRUBERRNONE)\n{\n/* Device type 1 was found on system.  */\nregisterdevice ();\nreturn GRUBERRNONE;\n}\n/* Zero out error code.  */\ngruberrno = GRUBERRNONE;\n\n/* No device type 1 found, try to probe device type 2.  */\nprobefordevice2 ();\nif (gruberrno == GRUBERRNONE)\n{\n/* Device type 2 was found on system.  */\nregisterdevice2 ();\nreturn GRUBERRNONE;\n}\n/* Zero out error code.  */\ngruberrno = GRUBERRNONE;\n\n/* Return custom error message.  */\nreturn gruberror (GRUBERRUNKNOWNDEVICE, \"No device type 1 or 2 found.\");\n}\n\nSome times there is a need to continue processing even if there is a\nerror state in application.  In situations like this, there is a needed\nto save old error state and then call other functions that might fail.",
            "subsections": []
        },
        "To aid in this, there is a error stack implemented.  Error state can be": {
            "content": "pushed to error stack by calling function 'gruberrorpush ()'.  When\nprocessing has been completed, 'gruberrorpop ()' can be used to pop\nerror state from stack.  Error stack contains predefined amount of error\nstack items.  Error stack is protected for overflow and marks these\nsituations so overflow error does not get unseen.  If there is no space\navailable to store error message, it is simply discarded and overflow\nwill be marked as happened.  When overflow happens, it most likely will\ncorrupt error stack consistency as for pushed error there is no matching\npop, but overflow message will be shown to inform user about the\nsituation.  Overflow message will be shown at time when prompt is about\nto be drawn.\n\nExample usage of error stack.\n/* Save possible old error message.  */\ngruberrorpush ();\n\n/* Do your stuff here.  */\ncallpossiblyfailingfunction ();\n\nif (gruberrno != GRUBERRNONE)\n{\n/* Inform rest of the code that there is error (gruberrno\nis set). There is no pop here as we want both error states\nto be displayed.  */\nreturn;\n}\n\n/* Restore old error state by popping previous item from stack. */\ngruberrorpop ();\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Stack and heap size,  Next: BIOS port memory map,  Prev: Error Handling,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "10 Stack and heap size": {
            "content": "",
            "subsections": []
        },
        "On emu stack and heap are just normal host OS stack and heap.  Stack is": {
            "content": "typically 8 MiB although it's OS-dependent.\n\nOn i386-pc, i386-coreboot, i386-qemu and i386-multiboot the stack is\n60KiB. All available space between 1MiB and 4GiB marks is part of heap.\n\nOn *-xen stack is 4MiB. If compiled for x86-64 with GCC 4.4 or later\naddressable space is unlimited.  When compiled for x86-64 with older GCC\nversion addressable space is limited to 2GiB. When compiling for i386\naddressable space is limited to 4GiB. All addressable pages except the\nones for stack, GRUB binary, special pages and page table are in the\nheap.\n\nOn *-efi GRUB uses same stack as EFI. If compiled for x86-64 with GCC\n4.4 or later addressable space is unlimited.  When compiled for x86-64\nwith older GCC version addressable space is limited to 2GiB. For all\nother platforms addressable space is limited to 4GiB. GRUB allocates\npages from EFI for its heap, at most 1.6 GiB.\n\nOn i386-ieee1275 and powerpc-ieee1275 GRUB uses same stack as\nIEEE1275.\n\nOn i386-ieee1275 and powerpc-ieee1275, GRUB will allocate 32MiB for\nits heap on startup.  It may allocate more at runtime, as long as at\nleast 128MiB remain free in OpenFirmware.\n\nOn sparc64-ieee1275 stack is 256KiB and heap is 2MiB.\n\nOn mips(el)-qemumips and mipsel-loongson stack is 2MiB (everything\nbelow GRUB image) and everything above GRUB image (from 2MiB + kernel\nsize) until 256MiB is part of heap.\n\nOn mips-arc stack is 2MiB (everything below GRUB image) and\neverything above GRUB image(from 2MiB + kernel size) until 128MiB is\npart of heap.\n\nOn mipsel-arc stack is 2MiB (everything below GRUB image which is not\npart of ARC) and everything above GRUB image (from 7MiB + kernel size)\nuntil 256MiB is part of heap.\n\nOn arm-uboot stack is 256KiB and heap is 2MiB.\n\nIn short:\n\nemu         8 MiB              ?\ni386-pc     60 KiB             < 4 GiB\ni386-coreboot60 KiB            < 4 GiB\ni386-multiboot60 KiB           < 4 GiB\ni386-qemu   60 KiB             < 4 GiB\n*-efi       ?                  < 1.6 GiB\ni386-ieee1275?                 < 32 MiB\npowerpc-ieee1275?              available memory - 128MiB\nsparc64-ieee1275256KiB         2 MiB\narm-uboot   256KiB             2 MiB\nmips(el)-qemumips2MiB         253 MiB\nmipsel-loongson2MiB            253 MiB\nmips-arc    2MiB               125 MiB\nmipsel-arc  2MiB               248 MiB\nx8664-xen  4MiB               unlimited\n(GCC >=\n4.4)\nx8664-xen  4MiB               < 2GiB\n(GCC <\n4.4)\ni386-xen    4MiB               < 4GiB\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: BIOS port memory map,  Next: Video Subsystem,  Prev: Stack and heap size,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "11 BIOS port memory map": {
            "content": "0           0x1000 - 1         BIOS and real mode interrupts\n0x07BE      0x07FF             Partition table passed to another\nboot loader\n?           0x2000 - 1         Real mode stack\n0x7C00      0x7D00 - 1         Boot sector\n0x8000      ?                  GRUB kernel\n0x68000     0x71000 - 1        Disk buffer\n?           0x80000 - 1        Protected mode stack\n?           0xA0000 - 1        Extended BIOS Data Area\n0xA0000     0xC0000 - 1        Video RAM\n0xC0000     0x100000 - 1       BIOS\n0x100000    ?                  Heap and module code\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Video Subsystem,  Next: PFF2 Font File Format,  Prev: BIOS port memory map,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "12 Video Subsystem": {
            "content": "This document contains specification for Video Subsystem for GRUB2.\nCurrently only the usage interface is described in this document.",
            "subsections": []
        },
        "Internal structure of how video drivers are registering and how video": {
            "content": "driver manager works are not included here.\n\n* Menu:\n\n* Video API::\n* Example usage of Video API::\n* Bitmap API::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Video API,  Next: Example usage of Video API,  Up: Video Subsystem": {
            "content": "",
            "subsections": [
                {
                    "name": "12.1 Video API",
                    "content": "* Prototype:\ngruberrt\ngrubvideosetup (unsigned int width, unsigned int height, unsigned int modetype);\n* Description:\n\nDriver will use information provided to it to select best possible\nvideo mode and switch to it.  Supported values for 'modetype' are\n'GRUBVIDEOMODETYPEINDEXCOLOR' for index color modes,\n'GRUBVIDEOMODETYPERGB' for direct RGB color modes and\n'GRUBVIDEOMODETYPEDOUBLEBUFFERED' for double buffering.  When\nrequesting RGB mode, highest bits per pixel mode will be selected.\nWhen requesting Index color mode, mode with highest number of\ncolors will be selected.  If all parameters are specified as zero,\nvideo adapter will try to figure out best possible mode and\ninitialize it, platform specific differences are allowed here.  If\nthere is no mode matching request, error X will be returned.  If\nthere are no problems, function returns 'GRUBERRNONE'.\n\nThis function also performs following task upon succesful mode\nswitch.  Active rendering target is changed to screen and viewport\nis maximized to allow whole screen to be used when performing\ngraphics operations.  In RGB modes, emulated palette gets 16\nentries containing default values for VGA palette, other colors are\ndefined as black.  When switching to Indexed Color mode, driver may\nset default VGA palette to screen if the video card allows the\noperation.\n\n\n* Prototype:\n\ngruberrt\ngrubvideorestore (void);\n* Description:\n\nVideo subsystem will deinitialize activated video driver to restore\nold state of video device.  This can be used to switch back to text\nmode.\n\n\n* Prototype:\n\ngruberrt\ngrubvideogetinfo (struct grubvideomodeinfo *modeinfo);\nstruct grubvideomodeinfo\n{\n/* Width of the screen.  */\nunsigned int width;\n/* Height of the screen.  */\nunsigned int height;\n/* Mode type bitmask.  Contains information like is it Index color or\nRGB mode.  */\nunsigned int modetype;\n/* Bits per pixel.  */\nunsigned int bpp;\n/* Bytes per pixel.  */\nunsigned int bytesperpixel;\n/* Pitch of one scanline.  How many bytes there are for scanline.  */\nunsigned int pitch;\n/* In index color mode, number of colors.  In RGB mode this is 256.  */\nunsigned int numberofcolors;\n/* Optimization hint how binary data is coded.  */\nenum grubvideoblitformat blitformat;\n/* How many bits are reserved for red color.  */\nunsigned int redmasksize;\n/* What is location of red color bits.  In Index Color mode, this is 0.  */\nunsigned int redfieldpos;\n/* How many bits are reserved for green color.  */\nunsigned int greenmasksize;\n/* What is location of green color bits.  In Index Color mode, this is 0.  */\nunsigned int greenfieldpos;\n/* How many bits are reserved for blue color.  */\nunsigned int bluemasksize;\n/* What is location of blue color bits.  In Index Color mode, this is 0.  */\nunsigned int bluefieldpos;\n/* How many bits are reserved in color.  */\nunsigned int reservedmasksize;\n/* What is location of reserved color bits.  In Index Color mode,\nthis is 0.  */\nunsigned int reservedfieldpos;\n};\n* Description:\n\nSoftware developer can use this function to query properties of\nactive rendering taget.  Information provided here can be used by\nother parts of GRUB, like image loaders to convert loaded images to\ncorrect screen format to allow more optimized blitters to be used.\nIf there there is no configured video driver with active screen,\nerror 'GRUBERRBADDEVICE' is returned, otherwise 'modeinfo' is\nfilled with valid information and 'GRUBERRNONE' is returned.\n\n\n* Prototype:\n\nenum grubvideoblitformat\ngrubvideogetblitformat (struct grubvideomodeinfo *modeinfo);\nenum grubvideoblitformat\n{\n/* Follow exactly field & mask information.  */\nGRUBVIDEOBLITFORMATRGBA,\n/* Make optimization assumption.  */\nGRUBVIDEOBLITFORMATR8G8B8A8,\n/* Follow exactly field & mask information.  */\nGRUBVIDEOBLITFORMATRGB,\n/* Make optimization assumption.  */\nGRUBVIDEOBLITFORMATR8G8B8,\n/* When needed, decode color or just use value as is.  */\nGRUBVIDEOBLITFORMATINDEXCOLOR\n};\n* Description:\n\nUsed to query how data could be optimized to suit specified video\nmode.  Returns exact video format type, or a generic one if there\nis no definition for the type.  For generic formats, use\n'grubvideogetinfo' to query video color coding settings.\n\n\n* Prototype:\n\ngruberrt\ngrubvideosetpalette (unsigned int start, unsigned int count, struct grubvideopalettedata *palettedata);\nstruct grubvideopalettedata\n{\ngrubuint8t r; /* Red color value (0-255). */\ngrubuint8t g; /* Green color value (0-255). */\ngrubuint8t b; /* Blue color value (0-255). */\ngrubuint8t a; /* Reserved bits value (0-255). */\n};\n* Description:\n\nUsed to setup indexed color palettes.  If mode is RGB mode, colors\nwill be set to emulated palette data.  In Indexed Color modes,\npalettes will be set to hardware.  Color values will be converted\nto suit requirements of the video mode.  'start' will tell what\nhardware color index (or emulated color index) will be set to\naccording information in first indice of 'palettedata', after that\nboth hardware color index and 'palettedata' index will be\nincremented until 'count' number of colors have been set.\n\n\n* Prototype:\n\ngruberrt\ngrubvideogetpalette (unsigned int start, unsigned int count, struct grubvideopalettedata *palettedata);\nstruct grubvideopalettedata\n{\ngrubuint8t r; /* Red color value (0-255). */\ngrubuint8t g; /* Green color value (0-255). */\ngrubuint8t b; /* Blue color value (0-255). */\ngrubuint8t a; /* Reserved bits value (0-255). */\n};\n* Description:\n\nUsed to query indexed color palettes.  If mode is RGB mode, colors\nwill be copied from emulated palette data.  In Indexed Color modes,\npalettes will be read from hardware.  Color values will be\nconverted to suit structure format.  'start' will tell what\nhardware color index (or emulated color index) will be used as a\nsource for first indice of 'palettedata', after that both hardware\ncolor index and 'palettedata' index will be incremented until\n'count' number of colors have been read.\n\n\n* Prototype:\ngruberrt\ngrubvideosetareastatus (grubvideoareastatust areastatus);\nenum grubvideoareastatust\n{\nGRUBVIDEOAREADISABLED,\nGRUBVIDEOAREAENABLED\n};\n\n* Description:\n\nUsed to set area drawing mode for redrawing the specified region.\nDraw commands are performed in the intersection of the viewport and\nthe region called area.  Coordinates remain related to the\nviewport.  If draw commands try to draw over the area, they are\nclipped.  Set status to DISABLED if you need to draw everything.\nSet status to ENABLED and region to the desired rectangle to redraw\neverything inside the region leaving everything else intact.\nShould be used for redrawing of active elements.\n\n\n* Prototype:\ngruberrr\ngrubvideogetareastatus (grubvideoareastatust *areastatus);\n\n* Description: Used to query the area status.\n\n\n* Prototype:\n\ngruberrt\ngrubvideosetviewport (unsigned int x, unsigned int y, unsigned int width, unsigned int height);\n* Description:\n\nUsed to specify viewport where draw commands are performed.  When\nviewport is set, all draw commands coordinates relate to those\nspecified by 'x' and 'y'.  If draw commands try to draw over\nviewport, they are clipped.  If developer requests larger than\npossible viewport, width and height will be clamped to fit screen.\nIf 'x' and 'y' are out of bounds, all functions drawing to screen\nwill not be displayed.  In order to maximize viewport, use\n'grubvideogetinfo' to query actual screen dimensions and provide\nthat information to this function.\n\n\n* Prototype:\n\ngruberrt\ngrubvideogetviewport (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height);\n* Description:\n\nUsed to query current viewport dimensions.  Software developer can\nuse this to choose best way to render contents of the viewport.\n\n\n* Prototype:\n\ngruberrt\ngrubvideosetregion (unsigned int x, unsigned int y, unsigned int width, unsigned int height);\n* Description:\n\nUsed to specify the region of the screen which should be redrawn.\nUse absolute values.  When the region is set and area status is\nENABLE all draw commands will be performed inside the interseption\nof region and viewport named area.  If draw commands try to draw\nover viewport, they are clipped.  If developer requests larger than\npossible region, width and height will be clamped to fit screen.\nShould be used for redrawing of active elements.\n\n\n* Prototype:\n\ngruberrt\ngrubvideogetregion (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height);\n* Description:\n\nUsed to query current region dimensions.\n\n\n* Prototype:\n\ngrubvideocolort\ngrubvideomapcolor (grubuint32t colorname);\n* Description:\n\nMap color can be used to support color themes in GRUB. There will\nbe collection of color names that can be used to query actual\nscreen mapped color data.  Examples could be\n'GRUBCOLORCONSOLEBACKGROUND', 'GRUBCOLORCONSOLETEXT'.  The\nactual color defines are not specified at this point.\n\n\n* Prototype:\n\ngrubvideocolort\ngrubvideomaprgb (grubuint8t red, grubuint8t green, grubuint8t blue);\n* Description:\n\nMap RGB values to compatible screen color data.  Values are\nexpected to be in range 0-255 and in RGB modes they will be\nconverted to screen color data.  In index color modes, index color\npalette will be searched for specified color and then index is\nreturned.\n\n\n* Prototype:\n\ngrubvideocolort\ngrubvideomaprgba (grubuint8t red, grubuint8t green, grubuint8t blue, grubuint8t alpha);\n* Description:\n\nMap RGBA values to compatible screen color data.  Values are\nexpected to be in range 0-255.  In RGBA modes they will be\nconverted to screen color data.  In index color modes, index color\npalette will be searched for best matching color and its index is\nreturned.\n\n\n* Prototype:\n\ngruberrt\ngrubvideounmapcolor (grubvideocolort color, grubuint8t *red, grubuint8t *green, grubuint8t *blue, grubuint8t *alpha);\n* Description:\n\nUnmap color value from 'color' to color channels in 'red', 'green',\n'blue' and 'alpha'.  Values will be in range 0-255.  Active\nrendering target will be used for color domain.  In case alpha\ninformation is not available in rendering target, it is assumed to\nbe opaque (having value 255).\n\n\n* Prototype:\n\ngruberrt\ngrubvideofillrect (grubvideocolort color, int x, int y, unsigned int width, unsigned int height);\n* Description:\n\nFill specified area limited by given coordinates within specified\nviewport.  Negative coordinates are accepted in order to allow easy\nmoving of rectangle within viewport.  If coordinates are negative,\narea of the rectangle will be shrinken to follow size limits of the\nviewport.\n\nSoftware developer should use either 'grubvideomapcolor',\n'grubvideomaprgb' or 'grubvideomaprgba' to map requested\ncolor to 'color' parameter.\n\n\n* Prototype:\n\ngruberrt\ngrubvideoblitglyph (struct grubfontglyph *glyph, grubvideocolort color, int x, int y);\nstruct grubfontglyph {\n/* TBD. */\n};\n* Description:\n\nUsed to blit glyph to viewport in specified coodinates.  If glyph\nis at edge of viewport, pixels outside of viewport will be clipped\nout.  Software developer should use either 'grubvideomaprgb' or\n'grubvideomaprgba' to map requested color to 'color' parameter.\n\n\n* Prototype:\n\ngruberrt\ngrubvideoblitbitmap (struct grubvideobitmap *bitmap, enum grubvideoblitoperators oper, int x, int y, int offsetx, int offsety, unsigned int width, unsigned int height);\nstruct grubvideobitmap\n{\n/* TBD. */\n};\n\nenum grubvideoblitoperators\n{\nGRUBVIDEOBLITREPLACE,\nGRUBVIDEOBLITBLEND\n};\n* Description:\n\nUsed to blit bitmap to viewport in specified coordinates.  If part\nof bitmap is outside of viewport region, it will be clipped out.\nOffsets affect bitmap position where data will be copied from.\nNegative values for both viewport coordinates and bitmap offset\ncoordinates are allowed.  If data is looked out of bounds of\nbitmap, color value will be assumed to be transparent.  If viewport\ncoordinates are negative, area of the blitted rectangle will be\nshrinken to follow size limits of the viewport and bitmap.\nBlitting operator 'oper' specifies should source pixel replace data\nin screen or blend with pixel alpha value.\n\nSoftware developer should use 'grubvideobitmapcreate' or\n'grubvideobitmapload' to create or load bitmap data.\n\n\n* Prototype:\n\ngruberrt\ngrubvideoblitrendertarget (struct grubvideorendertarget *source, enum grubvideoblitoperators oper, int x, int y, int offsetx, int offsety, unsigned int width, unsigned int height);\nstruct grubvideorendertarget {\n/* This is private data for video driver. Should not be accessed from elsewhere directly.  */\n};\n\nenum grubvideoblitoperators\n{\nGRUBVIDEOBLITREPLACE,\nGRUBVIDEOBLITBLEND\n};\n* Description:\n\nUsed to blit source render target to viewport in specified\ncoordinates.  If part of source render target is outside of\nviewport region, it will be clipped out.  If blitting operator is\nspecified and source contains alpha values, resulting pixel color\ncomponents will be calculated using formula ((srccolor *\nsrcalpha) + (dstcolor * (255 - srcalpha)) / 255, if target\nbuffer has alpha, it will be set to srcalpha.  Offsets affect\nrender target position where data will be copied from.  If data is\nlooked out of bounds of render target, color value will be assumed\nto be transparent.  Blitting operator 'oper' specifies should\nsource pixel replace data in screen or blend with pixel alpha\nvalue.\n\n\n* Prototype:\n\ngruberrt\ngrubvideoscroll (grubvideocolort color, int dx, int dy);\n* Description:\n\nUsed to scroll viewport to specified direction.  New areas are\nfilled with specified color.  This function is used when screen is\nscroller up in video terminal.\n\n\n* Prototype:\n\ngruberrt\ngrubvideoswapbuffers (void);\n* Description:\n\nIf double buffering is enabled, this swaps frontbuffer and\nbackbuffer, in order to show values drawn to back buffer.  Video\ndriver is free to choose how this operation is techincally done.\n\n\n* Prototype:\n\ngruberrt\ngrubvideocreaterendertarget (struct grubvideorendertarget result, unsigned int width, unsigned int height, unsigned int modetype);\nstruct grubvideorendertarget {\n/* This is private data for video driver. Should not be accessed from elsewhere directly.  */\n};\n* Description:\n\nDriver will use information provided to it to create best fitting\nrender target.  'modetype' will be used to guide on selecting what\nfeatures are wanted for render target.  Supported values for\n'modetype' are 'GRUBVIDEOMODETYPEINDEXCOLOR' for index color\nmodes, 'GRUBVIDEOMODETYPERGB' for direct RGB color modes and\n'GRUBVIDEOMODETYPEALPHA' for alpha component.\n\n\n* Prototype:\n\ngruberrt\ngrubvideodeleterendertarget (struct grubvideorendertarget *target);\n* Description:\n\nUsed to delete previously created render target.  If 'target'\ncontains 'NULL' pointer, nothing will be done.  If render target is\ncorrectly destroyed, GRUBERRNONE is returned.\n\n\n* Prototype:\n\ngruberrt\ngrubvideosetactiverendertarget (struct grubvideorendertarget *target);\n* Description:\n\nSets active render target.  If this comand is successful all\ndrawing commands will be done to specified 'target'.  There is also\nspecial values for target, 'GRUBVIDEORENDERTARGETDISPLAY' used\nto reference screen's front buffer,\n'GRUBVIDEORENDERTARGETFRONTBUFFER' used to reference screen's\nfront buffer (alias for 'GRUBVIDEORENDERTARGETDISPLAY') and\n'GRUBVIDEORENDERTARGETBACKBUFFER' used to reference back\nbuffer (if double buffering is enabled).  If render target is\ncorreclty switched GRUBERRNONE is returned.  In no any event\nshall there be non drawable active render target.\n\n\n* Prototype:\n\ngruberrt\ngrubvideogetactiverendertarget (struct grubvideorendertarget target);\n* Description:\n\nReturns currently active render target.  It returns value in\n'target' that can be subsequently issued back to\n'grubvideosetactiverendertarget'.\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: Example usage of Video API,  Next: Bitmap API,  Prev: Video API,  Up: Video Subsystem": {
            "content": "",
            "subsections": [
                {
                    "name": "12.2 Example usage of Video API",
                    "content": "gruberrt rc;\n/* Try to initialize video mode 1024 x 768 with direct RGB.  */\nrc = grubvideosetup (1024, 768, GRUBVIDEOMODETYPERGB);\nif (rc != GRUBERRNONE)\n{\n/* Fall back to standard VGA Index Color mode.  */\nrc = grubvideosetup (640, 480, GRUBVIDEOMODETYPEINDEX);\nif (rc != GRUBERRNONE)\n{\n/* Handle error.  */\n}\n}\n\n\ngrubuint32t x, y, width, height;\ngrubvideocolort color;\nstruct grubfontglyph glyph;\ngruberrt rc;\n/* Query existing viewport.  */\ngrubvideogetviewport (&x, &y, &width, &height);\n/* Fill background.  */\ncolor = grubvideomapcolor (GRUBCOLORBACKGROUND);\ngrubvideofillrect (color, 0, 0, width, height);\n/* Setup console viewport.  */\ngrubvideosetviewport (x + 10, y + 10, width - 20, height - 20);\ngrubvideogetviewport (&x, &y, &width, &height);\ncolor = grubvideomapcolor (GRUBCOLORCONSOLEBACKGROUND);\ngrubvideofillrect (color, 0, 0, width, height);\n/* Draw text to viewport.  */\ncolor = grubvideomapcolor (GRUBCOLORCONSOLETEXT);\ngrubfontgetglyph ('X', &glyph);\ngrubvideoblitglyph (&glyph, color, 0, 0);\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: Bitmap API,  Prev: Example usage of Video API,  Up: Video Subsystem": {
            "content": "",
            "subsections": [
                {
                    "name": "12.3 Bitmap API",
                    "content": "* Prototype:\ngruberrt grubvideobitmapcreate (struct grubvideobitmap bitmap, unsigned int width, unsigned int height, enum grubvideoblitformat blitformat)\n\n* Description:\n\nCreates a new bitmap with given dimensions and blitting format.\nAllocated bitmap data can then be modified freely and finally\nblitted with 'grubvideoblitbitmap' to rendering target.\n\n\n* Prototype:\ngruberrt grubvideobitmapdestroy (struct grubvideobitmap *bitmap);\n\n* Description:\n\nWhen bitmap is no longer needed, it can be freed from memory using\nthis command.  'bitmap' is previously allocated bitmap with\n'grubvideobitmapcreate' or loaded with 'grubvideobitmapload'.\n\n\n* Prototype:\ngruberrt grubvideobitmapload (struct grubvideobitmap bitmap, const char *filename);\n\n* Description:\n\nTries to load given bitmap ('filename') using registered bitmap\nloaders.  In case bitmap format is not recognized or supported\nerror 'GRUBERRBADFILETYPE' is returned.\n\n\n* Prototype:\nunsigned int grubvideobitmapgetwidth (struct grubvideobitmap *bitmap);\n\n* Description:\n\nReturns bitmap width.\n\n\n* Prototype:\nunsigned int grubvideobitmapgetheight (struct grubvideobitmap *bitmap);\n\n* Description:\n\nReturn bitmap height.\n\n\n* Prototype:\nvoid grubvideobitmapgetmodeinfo (struct grubvideobitmap *bitmap, struct grubvideomodeinfo *modeinfo);\n\n* Description:\n\nReturns bitmap format details in form of 'grubvideomodeinfo'.\n\n\n* Prototype:\nvoid *grubvideobitmapgetdata (struct grubvideobitmap *bitmap);\n\n* Description:\n\nReturn pointer to bitmap data.  Contents of the pointed data can be\nfreely modified.  There is no extra protection against going off\nthe bounds so you have to be carefull how to access the data.\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: PFF2 Font File Format,  Next: Graphical Menu Software Design,  Prev: Video Subsystem,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "13 PFF2 Font File Format": {
            "content": "* Menu:\n\n* Introduction::\n* File Structure::\n* Font Metrics::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Introduction,  Next: File Structure,  Up: PFF2 Font File Format": {
            "content": "",
            "subsections": [
                {
                    "name": "13.1 Introduction",
                    "content": ""
                }
            ]
        },
        "The goal of this format is to provide a bitmap font format that is": {
            "content": "simple to use, compact, and cleanly supports Unicode.\n\n\n* Simple to read and use.  Since GRUB will only be reading the font\nfiles, we are more concerned with making the code to read the font\nsimple than we are with writing the font.\n\n* Compact storage.  The fonts will generally be stored in a small\nboot partition where GRUB is located, and this may be on a\nremovable storage device such as a CD or USB flash drive where\nspace is more limited than it is on most hard drives.\n\n* Unicode.  GRUB should not have to deal with multiple character\nencodings.  The font should always use Unicode character codes for\nsimple internationalization.\n\n\nThere are many existing bitmap font formats that GRUB could use.",
            "subsections": []
        },
        "However, there are aspects of these formats that may make them less than": {
            "content": "suitable for use in GRUB at this time:\n\n'BDF'\nInefficient storage; uses ASCII to describe properties and\nhexadecimal numbers in ASCII for the bitmap rows.\n'PCF'\nMany format variations such as byte order and bitmap padding (rows\npadded to byte, word, etc.)  would result in more complex code to\nhandle the font format.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: File Structure,  Next: Font Metrics,  Prev: Introduction,  Up: PFF2 Font File Format": {
            "content": "",
            "subsections": [
                {
                    "name": "13.2 File Structure",
                    "content": "A file *section* consists of a 4-byte name, a 32-bit big-endian length\n(not including the name or length), and then LENGTH more\nsection-type-specific bytes.\n\nThe standard file extension for PFF2 font files is '.pf2'.\n\n\n'FILE'\n*File type ID* (ASCII string).  This must be the first section in\nthe file.  It has length 4 and the contents are the four bytes of\nthe ASCII string 'PFF2'.\n\n'NAME'\n*Font name* (ASCII string).  This is the full font name including\nfamily, weight, style, and point size.  For instance, \"Helvetica\nBold Italic 14\".\n\n'FAMI'\n*Font family name* (ASCII string).  For instance, \"Helvetica\".\nThis should be included so that intelligent font substitution can\ntake place.\n\n'WEIG'\n*Font weight* (ASCII string).  Valid values are 'bold' and\n'normal'.  This should be included so that intelligent font\nsubstitution can take place.\n\n'SLAN'\n*Font slant* (ASCII string).  Valid values are 'italic' and\n'normal'.  This should be included so that intelligent font\nsubstitution can take place.\n\n'PTSZ'\n*Font point size* (uint16be).\n\n'MAXW'\n*Maximum character width in pixels* (uint16be).\n\n'MAXH'\n*Maximum character height in pixels* (uint16be).\n\n'ASCE'\n*Ascent in pixels* (uint16be).  *Note Font Metrics::, for details.\n\n'DESC'\n*Descent in pixels* (uint16be).  *Note Font Metrics::, for details.\n\n'CHIX'\n*Character index.*  The character index begins with a 32-bit\nbig-endian unsigned integer indicating the total size of the\nsection, not including this size value.  For each character, there\nis an instance of the following entry structure:\n\n* *Unicode code point.*  (32-bit big-endian integer.)\n\n* *Storage flags.*  (byte.)\n\n* Bits 2..0:\n\nIf equal to 000 binary, then the character data is stored\nuncompressed beginning at the offset indicated by the\ncharacter's *offset* value.\n\nIf equal to 001 binary, then the character data is stored\nwithin a compressed character definition block that\nbegins at the offset within the file indicated by the\ncharacter's *offset* value.\n\n* *Offset.*  (32-bit big-endian integer.)\n\nA marker that indicates the remainder of the file is data\naccessed via the character index (CHIX) section.  When reading\nthis font file, the rest of the file can be ignored when\nscanning the sections.  The length should be set to -1\n(0xFFFFFFFF).\n\nSupported data structures:\n\nCharacter definition Each character definition consists of:\n\n* *Width.*  Width of the bitmap in pixels.  The bitmap's\nextents represent the glyph's bounding box.  'uint16be'.\n\n* *Height.*  Height of the bitmap in pixels.  The bitmap's\nextents represent the glyph's bounding box.  'uint16be'.\n\n* *X offset.*  The number of pixels to shift the bitmap by\nhorizontally before drawing the character.  'int16be'.\n\n* *Y offset.*  The number of pixels to shift the bitmap by\nvertically before drawing the character.  'int16be'.\n\n* *Device width.*  The number of pixels to advance\nhorizontally from this character's origin to the origin\nof the next character.  'int16be'.\n\n* *Bitmap data.*  This is encoded as a string of bits.  It\nis organized as a row-major, top-down, left-to-right\nbitmap.  The most significant bit of each byte is taken\nto be the leftmost or uppermost bit in the byte.  For the\nsake of compact storage, rows are not padded to byte\nboundaries (i.e., a single byte may contain bits\nbelonging to multiple rows).  The last byte of the bitmap\n*is* padded with zero bits in the bits positions to the\nright of the last used bit if the bitmap data does not\nfill the last byte.\n\nThe length of the *bitmap data* field is (WIDTH * HEIGHT\n+ 7) / 8 using integer arithmetic, which is equivalent to\nceil(WIDTH * HEIGHT / 8) using real number arithmetic.\n\nIt remains to be determined whether bitmap fonts usually\nmake all glyph bitmaps the same height, or if smaller\nglyphs are stored with bitmaps having a lesser height.\nIn the latter case, the baseline would have to be used to\ncalculate the location the bitmap should be anchored at\non screen.\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: Font Metrics,  Prev: File Structure,  Up: PFF2 Font File Format": {
            "content": "",
            "subsections": [
                {
                    "name": "13.3 Font Metrics",
                    "content": "* Ascent.  The distance from the baseline to the top of most\ncharacters.  Note that in some cases characters may extend above\nthe ascent.\n\n* Descent.  The distance from the baseline to the bottom of most\ncharacters.  Note that in some cases characters may extend below\nthe descent.\n\n* Leading.  The amount of space, in pixels, to leave between the\ndescent of one line of text and the ascent of the next line.  This\nmetrics is not specified in the current file format; instead, the\nfont rendering engine calculates a reasonable leading value based\non the other font metrics.\n\n* Horizonal leading.  The amount of space, in pixels, to leave\nhorizontally between the left and right edges of two adjacent\nglyphs.  The *device width* field determines the effective leading\nvalue that is used to render the font.\n\nPlease fill this in.\n\n\nAn illustration of how the various font metrics apply to characters.\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: Graphical Menu Software Design,  Next: Verifiers framework,  Prev: PFF2 Font File Format,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "14 Graphical Menu Software Design": {
            "content": "* Menu:\n\n* Introduction2::\n* Startup Sequence::\n* GUI Components::\n* Command Line Window::\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Introduction2,  Next: Startup Sequence,  Up: Graphical Menu Software Design": {
            "content": "",
            "subsections": [
                {
                    "name": "14.1 Introduction",
                    "content": ""
                }
            ]
        },
        "The 'gfxmenu' module provides a graphical menu interface for GRUB 2.  It": {
            "content": "functions as an alternative to the menu interface provided by the\n'normal' module, which uses the grub terminal interface to display a\nmenu on a character-oriented terminal.\n\nThe graphical menu uses the GRUB video API, which is currently for\nthe VESA BIOS extensions (VBE) 2.0+.  This is supported on the i386-pc\nplatform.  However, the graphical menu itself does not depend on using\nVBE, so if another GRUB video driver were implemented, the 'gfxmenu'\ngraphical menu would work on the new video driver as well.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Startup Sequence,  Next: GUI Components,  Prev: Introduction2,  Up: Graphical Menu Software Design": {
            "content": "",
            "subsections": [
                {
                    "name": "14.2 Startup Sequence",
                    "content": "* grubenternormalmode [normal/main.c]\n* grubnormalexecute [normal/main.c]\n* readconfigfile [normal/main.c]\n* (When 'gfxmenu.mod' is loaded with 'insmod', it will call\n'grubmenuviewerregister()' to register itself.)\n* GRUBMODINIT (gfxmenu) [gfxmenu/gfxmenu.c]\n* grubmenuviewerregister [kern/menuviewer.c]\n* grubmenuviewershowmenu [kern/menuviewer.c]\n* getcurrentmenuviewer() [kern/menuviewer.c]\n* showmenu() [gfxmenu/gfxmenu.c]\n* grubgfxmenumodelnew [gfxmenu/model.c]\n* grubgfxmenuviewnew [gfxmenu/view.c]\n* setgraphicsmode [gfxmenu/view.c]\n* grubgfxmenuviewloadtheme [gfxmenu/themeloader.c]\n"
                }
            ]
        },
        "File: grub-dev.info,  Node: GUI Components,  Next: Command Line Window,  Prev: Startup Sequence,  Up: Graphical Menu Software Design": {
            "content": "",
            "subsections": [
                {
                    "name": "14.3 GUI Components",
                    "content": ""
                }
            ]
        },
        "The graphical menu implements a GUI component system that supports a": {
            "content": "container-based layout system.  Components can be added to containers,\nand containers (which are a type of component) can then be added to\nother containers, to form a tree of components.  Currently, the root\ncomponent of this tree is a 'canvas' component, which allows manual\nlayout of its child components.\n\nComponents (non-container):\n\n* label\n* image\n* progressbar\n* circularprogress\n* list (currently hard coded to be a boot menu list)\n\nContainers:\n\n* canvas\n* hbox\n* vbox\n\nThe GUI component instances are created by the theme loader in\n'gfxmenu/themeloader.c' when a theme is loaded.  Theme files specify\nstatements such as '+vbox{ +label { text=\"Hello\" } +label{ text=\"World\"\n} }' to add components to the component tree root.  By nesting the\ncomponent creation statements in the theme file, the instantiated\ncomponents are nested the same way.\n\nWhen a component is added to a container, that new child is\nconsidered *owned* by the container.  Great care should be taken if the\ncaller retains a reference to the child component, since it will be\ndestroyed if its parent container is destroyed.  A better choice instead\nof storing a pointer to the child component is to use the component ID\nto find the desired component.  Component IDs do not have to be unique\n(it is often useful to have multiple components with an ID of\n\"timeout\", for instance).\n\nIn order to access and use components in the component tree, there\nare two functions (defined in 'gfxmenu/guiutil.c') that are\nparticularly useful:\n\n* 'grubguifindbyid (root, id, callback, userdata)':\n\nThis function recursively traverses the component tree rooted at\nROOT, and for every component that has an ID equal to ID, calls the\nfunction pointed to by CALLBACK with the matching component and the\nvoid pointer USERDATA as arguments.  The callback function can do\nwhatever is desired to use the component passed in.\n\n* 'grubguiiteraterecursively (root, callback, userdata)':\n\nThis function calls the function pointed to by CALLBACK for every\ncomponent that is a descendant of ROOT in the component tree.  When\nthe callback function is called, the component and the void pointer\nUSERDATA as arguments.  The callback function can do whatever is\ndesired to use the component passed in.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Command Line Window,  Prev: GUI Components,  Up: Graphical Menu Software Design": {
            "content": "",
            "subsections": [
                {
                    "name": "14.4 Command Line Window",
                    "content": ""
                }
            ]
        },
        "The terminal window used to provide command line access within the": {
            "content": "graphical menu is managed by 'gfxmenu/view.c'.  The 'gfxterm' terminal\nis used, and it has been modified to allow rendering to an offscreen\nrender target to allow it to be composed into the double buffering\nsystem that the graphical menu view uses.  This is bad for performance,\nhowever, so it would probably be a good idea to make it possible to\ntemporarily disable double buffering as long as the terminal window is\nvisible.  There are still unresolved problems that occur when commands\nare executed from the terminal window that change the graphics mode.",
            "subsections": []
        },
        "It's possible that making 'grubvideorestore()' return to the graphics": {
            "content": "mode that was in use before 'grubvideosetup()' was called might fix\nsome of the problems.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Verifiers framework,  Next: Lockdown framework,  Prev: Graphical Menu Software Design,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "15 Verifiers framework": {
            "content": "",
            "subsections": []
        },
        "To register your own verifier call 'grubverifierregister' with a": {
            "content": "structure pointing to your functions.\n\nThe interface is inspired by the hash interface with\n'init'/'write'/'fini'.\n\nThere are essentially 2 ways of using it, hashing and whole-file\nverification.\n\nWith the hashing approach: During 'init' you decide whether you want\nto check the given file and init context.  In 'write' you update your\nhashing state.  In 'fini' you check that the hash matches the expected\nvalue/passes some check/...\n\nWith whole-file verification: During 'init' you decide whether you\nwant to check the given file and init context.  In 'write' you verify\nthe file and return an error if it fails.  You don't have 'fini'.\n\nAdditional 'verifystring' receives various strings like kernel\nparameters to verify.  Returning no error means successful verification\nand an error stops the current action.\n\nDetailed description of the API:\n\nEvery time a file is opened your 'init' function is called with file\ndescriptor and file type.  Your function can have the following\noutcomes:\n\n* returning no error and setting '*flags' to\n'GRUBVERIFYFLAGSDEFERAUTH'.  In this case verification is\ndeferred to other active verifiers.  Verification fails if nobody\ncares or selected verifier fails.\n\n* returning no error and setting '*flags' to\n'GRUBVERIFYFLAGSSKIPVERIFICATION'.  In this case your verifier\nwill not be called anymore and it is assumed to have skipped\nverification.\n\n* returning no error and not setting '*flags' to\n'GRUBVERIFYFLAGSSKIPVERIFICATION' In this case verification is\ndone as described in the following section.\n\n* returning an error.  Then opening of the file will fail due to\nfailed verification.\n\nIn the third case your 'write' will be called with chunks of the\nfile.  If you need the whole file in a single chunk then during 'init'\nset the bit 'GRUBVERIFYFLAGSSINGLECHUNK' in '*flags'.  During 'init'\nyou may set '*context' if you need additional context.  At every\niteration you may return an error and the file will be considered as\nhaving failed the verification.  If you return no error then\nverification continues.\n\nOptionally at the end of the file 'fini', if it exists, is called\nwith just the context.  If you return no error during any of 'init',\n'write' and 'fini' then the file is considered as having succeded\nverification.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Lockdown framework,  Next: Copying This Manual,  Prev: Verifiers framework,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "16 Lockdown framework": {
            "content": "",
            "subsections": []
        },
        "The GRUB can be locked down, which is a restricted mode where some": {
            "content": "operations are not allowed.  For instance, some commands cannot be used\nwhen the GRUB is locked down.\n\nThe function 'grublockdown()' is used to lockdown GRUB and the\nfunction 'grubislockdown()' function can be used to check whether\nlockdown is enabled or not.  When enabled, the function returns\n'GRUBLOCKDOWNENABLED' and 'GRUBLOCKDOWNDISABLED' when is not\nenabled.\n\nThe following functions can be used to register the commands that can\nonly be used when lockdown is disabled:\n\n* 'grubcmdlockdown()' registers command which should not run when\nthe GRUB is in lockdown mode.\n\n* 'grubcmdlockdown()' registers extended command which should not\nrun when the GRUB is in lockdown mode.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Copying This Manual,  Next: Index,  Prev: Lockdown framework,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "Appendix A Copying This Manual": {
            "content": "* Menu:\n\n* GNU Free Documentation License::  License for copying this manual.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: GNU Free Documentation License,  Up: Copying This Manual": {
            "content": "",
            "subsections": [
                {
                    "name": "A.1 GNU Free Documentation License",
                    "content": "Version 1.2, November 2002\n\nCopyright (C) 2000,2001,2002 Free Software Foundation, Inc.\n51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA\n\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n\n0. PREAMBLE\n\nThe purpose of this License is to make a manual, textbook, or other\nfunctional and useful document \"free\" in the sense of freedom: to\nassure everyone the effective freedom to copy and redistribute it,\nwith or without modifying it, either commercially or\nnoncommercially.  Secondarily, this License preserves for the\nauthor and publisher a way to get credit for their work, while not\nbeing considered responsible for modifications made by others.\n\nThis License is a kind of \"copyleft\", which means that derivative\nworks of the document must themselves be free in the same sense.\nIt complements the GNU General Public License, which is a copyleft\nlicense designed for free software.\n\nWe have designed this License in order to use it for manuals for\nfree software, because free software needs free documentation: a\nfree program should come with manuals providing the same freedoms\nthat the software does.  But this License is not limited to\nsoftware manuals; it can be used for any textual work, regardless\nof subject matter or whether it is published as a printed book.  We\nrecommend this License principally for works whose purpose is\ninstruction or reference.\n\n1. APPLICABILITY AND DEFINITIONS\n\nThis License applies to any manual or other work, in any medium,\nthat contains a notice placed by the copyright holder saying it can\nbe distributed under the terms of this License.  Such a notice\ngrants a world-wide, royalty-free license, unlimited in duration,\nto use that work under the conditions stated herein.  The\n\"Document\", below, refers to any such manual or work.  Any member\nof the public is a licensee, and is addressed as \"you\".  You accept\nthe license if you copy, modify or distribute the work in a way\nrequiring permission under copyright law.\n\nA \"Modified Version\" of the Document means any work containing the\nDocument or a portion of it, either copied verbatim, or with\nmodifications and/or translated into another language.\n\nA \"Secondary Section\" is a named appendix or a front-matter section\nof the Document that deals exclusively with the relationship of the\npublishers or authors of the Document to the Document's overall\nsubject (or to related matters) and contains nothing that could\nfall directly within that overall subject.  (Thus, if the Document\nis in part a textbook of mathematics, a Secondary Section may not\nexplain any mathematics.)  The relationship could be a matter of\nhistorical connection with the subject or with related matters, or\nof legal, commercial, philosophical, ethical or political position\nregarding them.\n\nThe \"Invariant Sections\" are certain Secondary Sections whose\ntitles are designated, as being those of Invariant Sections, in the\nnotice that says that the Document is released under this License.\nIf a section does not fit the above definition of Secondary then it\nis not allowed to be designated as Invariant.  The Document may\ncontain zero Invariant Sections.  If the Document does not identify\nany Invariant Sections then there are none.\n\nThe \"Cover Texts\" are certain short passages of text that are\nlisted, as Front-Cover Texts or Back-Cover Texts, in the notice\nthat says that the Document is released under this License.  A\nFront-Cover Text may be at most 5 words, and a Back-Cover Text may\nbe at most 25 words.\n\nA \"Transparent\" copy of the Document means a machine-readable copy,\nrepresented in a format whose specification is available to the\ngeneral public, that is suitable for revising the document\nstraightforwardly with generic text editors or (for images composed\nof pixels) generic paint programs or (for drawings) some widely\navailable drawing editor, and that is suitable for input to text\nformatters or for automatic translation to a variety of formats\nsuitable for input to text formatters.  A copy made in an otherwise\nTransparent file format whose markup, or absence of markup, has\nbeen arranged to thwart or discourage subsequent modification by\nreaders is not Transparent.  An image format is not Transparent if\nused for any substantial amount of text.  A copy that is not\n\"Transparent\" is called \"Opaque\".\n\nExamples of suitable formats for Transparent copies include plain\nASCII without markup, Texinfo input format, LaTeX input format,\nSGML or XML using a publicly available DTD, and standard-conforming\nsimple HTML, PostScript or PDF designed for human modification.\nExamples of transparent image formats include PNG, XCF and JPG.\nOpaque formats include proprietary formats that can be read and\nedited only by proprietary word processors, SGML or XML for which\nthe DTD and/or processing tools are not generally available, and\nthe machine-generated HTML, PostScript or PDF produced by some word\nprocessors for output purposes only.\n\nThe \"Title Page\" means, for a printed book, the title page itself,\nplus such following pages as are needed to hold, legibly, the\nmaterial this License requires to appear in the title page.  For\nworks in formats which do not have any title page as such, \"Title\nPage\" means the text near the most prominent appearance of the\nwork's title, preceding the beginning of the body of the text.\n\nA section \"Entitled XYZ\" means a named subunit of the Document\nwhose title either is precisely XYZ or contains XYZ in parentheses\nfollowing text that translates XYZ in another language.  (Here XYZ\nstands for a specific section name mentioned below, such as\n\"Acknowledgements\", \"Dedications\", \"Endorsements\", or \"History\".)\nTo \"Preserve the Title\" of such a section when you modify the\nDocument means that it remains a section \"Entitled XYZ\" according\nto this definition.\n\nThe Document may include Warranty Disclaimers next to the notice\nwhich states that this License applies to the Document.  These\nWarranty Disclaimers are considered to be included by reference in\nthis License, but only as regards disclaiming warranties: any other\nimplication that these Warranty Disclaimers may have is void and\nhas no effect on the meaning of this License.\n\n2. VERBATIM COPYING\n\nYou may copy and distribute the Document in any medium, either\ncommercially or noncommercially, provided that this License, the\ncopyright notices, and the license notice saying this License\napplies to the Document are reproduced in all copies, and that you\nadd no other conditions whatsoever to those of this License.  You\nmay not use technical measures to obstruct or control the reading\nor further copying of the copies you make or distribute.  However,\nyou may accept compensation in exchange for copies.  If you\ndistribute a large enough number of copies you must also follow the\nconditions in section 3.\n\nYou may also lend copies, under the same conditions stated above,\nand you may publicly display copies.\n\n3. COPYING IN QUANTITY\n\nIf you publish printed copies (or copies in media that commonly\nhave printed covers) of the Document, numbering more than 100, and\nthe Document's license notice requires Cover Texts, you must\nenclose the copies in covers that carry, clearly and legibly, all\nthese Cover Texts: Front-Cover Texts on the front cover, and\nBack-Cover Texts on the back cover.  Both covers must also clearly\nand legibly identify you as the publisher of these copies.  The\nfront cover must present the full title with all words of the title\nequally prominent and visible.  You may add other material on the\ncovers in addition.  Copying with changes limited to the covers, as\nlong as they preserve the title of the Document and satisfy these\nconditions, can be treated as verbatim copying in other respects.\n\nIf the required texts for either cover are too voluminous to fit\nlegibly, you should put the first ones listed (as many as fit\nreasonably) on the actual cover, and continue the rest onto\nadjacent pages.\n\nIf you publish or distribute Opaque copies of the Document\nnumbering more than 100, you must either include a machine-readable\nTransparent copy along with each Opaque copy, or state in or with\neach Opaque copy a computer-network location from which the general\nnetwork-using public has access to download using public-standard\nnetwork protocols a complete Transparent copy of the Document, free\nof added material.  If you use the latter option, you must take\nreasonably prudent steps, when you begin distribution of Opaque\ncopies in quantity, to ensure that this Transparent copy will\nremain thus accessible at the stated location until at least one\nyear after the last time you distribute an Opaque copy (directly or\nthrough your agents or retailers) of that edition to the public.\n\nIt is requested, but not required, that you contact the authors of\nthe Document well before redistributing any large number of copies,\nto give them a chance to provide you with an updated version of the\nDocument.\n\n4. MODIFICATIONS\n\nYou may copy and distribute a Modified Version of the Document\nunder the conditions of sections 2 and 3 above, provided that you\nrelease the Modified Version under precisely this License, with the\nModified Version filling the role of the Document, thus licensing\ndistribution and modification of the Modified Version to whoever\npossesses a copy of it.  In addition, you must do these things in\nthe Modified Version:\n\nA. Use in the Title Page (and on the covers, if any) a title\ndistinct from that of the Document, and from those of previous\nversions (which should, if there were any, be listed in the\nHistory section of the Document).  You may use the same title\nas a previous version if the original publisher of that\nversion gives permission.\n\nB. List on the Title Page, as authors, one or more persons or\nentities responsible for authorship of the modifications in\nthe Modified Version, together with at least five of the\nprincipal authors of the Document (all of its principal\nauthors, if it has fewer than five), unless they release you\nfrom this requirement.\n\nC. State on the Title page the name of the publisher of the\nModified Version, as the publisher.\n\nD. Preserve all the copyright notices of the Document.\n\nE. Add an appropriate copyright notice for your modifications\nadjacent to the other copyright notices.\n\nF. Include, immediately after the copyright notices, a license\nnotice giving the public permission to use the Modified\nVersion under the terms of this License, in the form shown in\nthe Addendum below.\n\nG. Preserve in that license notice the full lists of Invariant\nSections and required Cover Texts given in the Document's\nlicense notice.\n\nH. Include an unaltered copy of this License.\n\nI. Preserve the section Entitled \"History\", Preserve its Title,\nand add to it an item stating at least the title, year, new\nauthors, and publisher of the Modified Version as given on the\nTitle Page.  If there is no section Entitled \"History\" in the\nDocument, create one stating the title, year, authors, and\npublisher of the Document as given on its Title Page, then add\nan item describing the Modified Version as stated in the\nprevious sentence.\n\nJ. Preserve the network location, if any, given in the Document\nfor public access to a Transparent copy of the Document, and\nlikewise the network locations given in the Document for\nprevious versions it was based on.  These may be placed in the\n\"History\" section.  You may omit a network location for a work\nthat was published at least four years before the Document\nitself, or if the original publisher of the version it refers\nto gives permission.\n\nK. For any section Entitled \"Acknowledgements\" or \"Dedications\",\nPreserve the Title of the section, and preserve in the section\nall the substance and tone of each of the contributor\nacknowledgements and/or dedications given therein.\n\nL. Preserve all the Invariant Sections of the Document, unaltered\nin their text and in their titles.  Section numbers or the\nequivalent are not considered part of the section titles.\n\nM. Delete any section Entitled \"Endorsements\".  Such a section\nmay not be included in the Modified Version.\n\nN. Do not retitle any existing section to be Entitled\n\"Endorsements\" or to conflict in title with any Invariant\nSection.\n\nO. Preserve any Warranty Disclaimers.\n\nIf the Modified Version includes new front-matter sections or\nappendices that qualify as Secondary Sections and contain no\nmaterial copied from the Document, you may at your option designate\nsome or all of these sections as invariant.  To do this, add their\ntitles to the list of Invariant Sections in the Modified Version's\nlicense notice.  These titles must be distinct from any other\nsection titles.\n\nYou may add a section Entitled \"Endorsements\", provided it contains\nnothing but endorsements of your Modified Version by various\nparties--for example, statements of peer review or that the text\nhas been approved by an organization as the authoritative\ndefinition of a standard.\n\nYou may add a passage of up to five words as a Front-Cover Text,\nand a passage of up to 25 words as a Back-Cover Text, to the end of\nthe list of Cover Texts in the Modified Version.  Only one passage\nof Front-Cover Text and one of Back-Cover Text may be added by (or\nthrough arrangements made by) any one entity.  If the Document\nalready includes a cover text for the same cover, previously added\nby you or by arrangement made by the same entity you are acting on\nbehalf of, you may not add another; but you may replace the old\none, on explicit permission from the previous publisher that added\nthe old one.\n\nThe author(s) and publisher(s) of the Document do not by this\nLicense give permission to use their names for publicity for or to\nassert or imply endorsement of any Modified Version.\n\n5. COMBINING DOCUMENTS\n\nYou may combine the Document with other documents released under\nthis License, under the terms defined in section 4 above for\nmodified versions, provided that you include in the combination all\nof the Invariant Sections of all of the original documents,\nunmodified, and list them all as Invariant Sections of your\ncombined work in its license notice, and that you preserve all\ntheir Warranty Disclaimers.\n\nThe combined work need only contain one copy of this License, and\nmultiple identical Invariant Sections may be replaced with a single\ncopy.  If there are multiple Invariant Sections with the same name\nbut different contents, make the title of each such section unique\nby adding at the end of it, in parentheses, the name of the\noriginal author or publisher of that section if known, or else a\nunique number.  Make the same adjustment to the section titles in\nthe list of Invariant Sections in the license notice of the\ncombined work.\n\nIn the combination, you must combine any sections Entitled\n\"History\" in the various original documents, forming one section\nEntitled \"History\"; likewise combine any sections Entitled\n\"Acknowledgements\", and any sections Entitled \"Dedications\".  You\nmust delete all sections Entitled \"Endorsements.\"\n\n6. COLLECTIONS OF DOCUMENTS\n\nYou may make a collection consisting of the Document and other\ndocuments released under this License, and replace the individual\ncopies of this License in the various documents with a single copy\nthat is included in the collection, provided that you follow the\nrules of this License for verbatim copying of each of the documents\nin all other respects.\n\nYou may extract a single document from such a collection, and\ndistribute it individually under this License, provided you insert\na copy of this License into the extracted document, and follow this\nLicense in all other respects regarding verbatim copying of that\ndocument.\n\n7. AGGREGATION WITH INDEPENDENT WORKS\n\nA compilation of the Document or its derivatives with other\nseparate and independent documents or works, in or on a volume of a\nstorage or distribution medium, is called an \"aggregate\" if the\ncopyright resulting from the compilation is not used to limit the\nlegal rights of the compilation's users beyond what the individual\nworks permit.  When the Document is included in an aggregate, this\nLicense does not apply to the other works in the aggregate which\nare not themselves derivative works of the Document.\n\nIf the Cover Text requirement of section 3 is applicable to these\ncopies of the Document, then if the Document is less than one half\nof the entire aggregate, the Document's Cover Texts may be placed\non covers that bracket the Document within the aggregate, or the\nelectronic equivalent of covers if the Document is in electronic\nform.  Otherwise they must appear on printed covers that bracket\nthe whole aggregate.\n\n8. TRANSLATION\n\nTranslation is considered a kind of modification, so you may\ndistribute translations of the Document under the terms of section\n4.  Replacing Invariant Sections with translations requires special\npermission from their copyright holders, but you may include\ntranslations of some or all Invariant Sections in addition to the\noriginal versions of these Invariant Sections.  You may include a\ntranslation of this License, and all the license notices in the\nDocument, and any Warranty Disclaimers, provided that you also\ninclude the original English version of this License and the\noriginal versions of those notices and disclaimers.  In case of a\ndisagreement between the translation and the original version of\nthis License or a notice or disclaimer, the original version will\nprevail.\n\nIf a section in the Document is Entitled \"Acknowledgements\",\n\"Dedications\", or \"History\", the requirement (section 4) to\nPreserve its Title (section 1) will typically require changing the\nactual title.\n\n9. TERMINATION\n\nYou may not copy, modify, sublicense, or distribute the Document\nexcept as expressly provided for under this License.  Any other\nattempt to copy, modify, sublicense or distribute the Document is\nvoid, and will automatically terminate your rights under this\nLicense.  However, parties who have received copies, or rights,\nfrom you under this License will not have their licenses terminated\nso long as such parties remain in full compliance.\n\n10. FUTURE REVISIONS OF THIS LICENSE\n\nThe Free Software Foundation may publish new, revised versions of\nthe GNU Free Documentation License from time to time.  Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.  See\n<http://www.gnu.org/copyleft/>.\n\nEach version of the License is given a distinguishing version\nnumber.  If the Document specifies that a particular numbered\nversion of this License \"or any later version\" applies to it, you\nhave the option of following the terms and conditions either of\nthat specified version or of any later version that has been\npublished (not as a draft) by the Free Software Foundation.  If the\nDocument does not specify a version number of this License, you may\nchoose any version ever published (not as a draft) by the Free\nSoftware Foundation.\n\n"
                }
            ]
        },
        "To use this License in a document you have written, include a copy of": {
            "content": "the License in the document and put the following copyright and license\nnotices just after the title page:\n\nCopyright (C)  YEAR  YOUR NAME.\nPermission is granted to copy, distribute and/or modify this document\nunder the terms of the GNU Free Documentation License, Version 1.2\nor any later version published by the Free Software Foundation;\nwith no Invariant Sections, no Front-Cover Texts, and no Back-Cover\nTexts.  A copy of the license is included in the section entitled ``GNU\nFree Documentation License''.\n\nIf you have Invariant Sections, Front-Cover Texts and Back-Cover\nTexts, replace the \"with...Texts.\"  line with this:\n\nwith the Invariant Sections being LIST THEIR TITLES, with\nthe Front-Cover Texts being LIST, and with the Back-Cover Texts\nbeing LIST.\n\nIf you have Invariant Sections without Cover Texts, or some other\ncombination of the three, merge those two alternatives to suit the\nsituation.\n\nIf your document contains nontrivial examples of program code, we\nrecommend releasing these examples in parallel under your choice of free\nsoftware license, such as the GNU General Public License, to permit\ntheir use in free software.\n",
            "subsections": []
        },
        "File: grub-dev.info,  Node: Index,  Prev: Copying This Manual,  Up: Top": {
            "content": "",
            "subsections": []
        },
        "Index": {
            "content": "* Menu:\n\n* FDL, GNU Free Documentation License:   GNU Free Documentation License.\n(line 6)\n\n",
            "subsections": []
        }
    },
    "flags": [],
    "examples": [],
    "see_also": []
}