Skip to content
/ PLL Public

Partition Linux Loader - boot a linux kernel directly from a disk partition

License

Notifications You must be signed in to change notification settings

smjcc/PLL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 

Repository files navigation

PLL

Partition Linux Loader -- a tiny linux kernel boot loader

This code presently fits in three 512B sectors. PLL's minimalist design makes it very robust, and easy to audit. PLL does not need nor use any filesystems, so it cannot be disabled through changes to, or corruption of filesystems. PLL boots by loading a kernel directly out of the selected dedicated partition.

This is my daily boot loader on my desktop, and all of my servers. It was written to address difficulties that emerged periodically with lilo and grub, which were difficult to diagnose, especially with regard to servers running on older hardware.

PLL does not need nor use UEFI; it presumes a GPT for simplicity. I chose GPT because it supports numerous partitions, as well as partition names and UUIDs.

PLL loads and boots a kernel directly from a partition. The partitioun contain only the kernel, no filesystem. (though the kernel can of course contain an initmpfs).

PLL supports a kernel command line in the boot sector, and the ability to boot from an alternative partition “one time only” (reverting to the previous kernel on the next boot), and the ability to select which partition to load the kernel from by holding shift keys down at boot time.

PLL does not load a separate initmpfs file. When one is needed, it must be compiled into the kernel.

PLL compiles to three sectors at present: The boot sector or Master Boot Record (MBR) (Logical Block Address Zero [LBA0]), with the remaining two sectors sitting between the GPT and the physically first partition. Most partition editors provide this space by default, though I prefer to micro-manage my partiton locations. The execline install script PLLinstall will compile PLL appropriately for your GPT, and write the PLL sectors to the disk if instructed to do so.

PLL=v.v.v-xx.n Selecting the kernel load partition

The kernel command line stored in LBA0, is preloaded with PLL=v.v.v-xx.n, where v are version numbers, and xx is replaced at boot time with the BIOS number of the boot device. This command line option must exist and must be first.

One of three possible boot scenarios is selected by which character follows the xx in the PLL= option (. by default)
The three possible cases are ., +, and any other character:

In the case of .

At boot time, the state of the keyboard shift keys determines which partition the kernel will be loaded from:

  • no shift keys are down: partition 1 is selected.
  • a 'shift' key is down: partition 2 is selected.
  • a 'ctrl' key is down: partition 3 is selected.
  • an 'alt' key is down: partition 4 is selected.

for each of these cases, the n in the PLL= option will be replaced with the partition number that the kernel was actually loaded from.

In the case of +

The kernel will be loaded from the partion number following the + (at the n position) in the PLL= command option.

In all other cases

The partition number following the character (which replaced the .) will be 'xor'ed with 0b00000011 (which is an ASCII 1 xored with an ASCII 2) so that a 1 will become a 2, and vice versa. The kernel will be loaded from the resulting partition number. Then, the character in the . position, will be overwritten with + on disk in LBA0. (the number following the + is unchanged on either the disk [LBA0], or the command line option) Note that this is the only condition where PLL will write to disk.

This is effectively a “one time boot”. If the command line is not subsequently changed, the next boot will revert to the previous partition number. Applications can look at the PLL option in the command line in /proc/cmdline to check this character and determine if we have booted in a “one time boot” condition.

Dependencies

To Use

  • install execline via your package manager
  • install nasm via your package manager
  • clone PLL from codeberg/github/gitflic into /usr/src/PLL
    or if gentoo, use the ebuild in my overlay
  • use a partition editor (fdisk, parted, etc) to install a GPT (GUID partiton table) to your target disk (e.g. /dev/sdb):
    $ fdisk /dev/sdb
    create at least one partition large enough to contain your kernel. (e.g. /dev/sdb1 )
  • run the PLLinstall script to write the boot sectors:
    $ cd /usr/src/PLL
    $ ./PLLinstall /dev/sdb
    this will read the GPT, compile PLL to fit, and (if invoked with --write) write the sectors to the disk
  • compile a suitable kernel for your hardware
    if an initmpfs is needed, compile it into the kernel
  • write your kernel into the partiton:
    $ dd if=/boot/vmlinuz of=/dev/sdb1
  • The disk should now be bootable by a legacy boot BIOS

enhanced BIOS” calls.

If your BIOS supports enhanced BIOS calls, PLL will detect this and use Logical Block Addresses LBA reading from disk. If not, PLL will use the older “Cylinder/Head/Sector” (CHS) addressing. This later code is currently using only a 16 bit LBA, so only the top 33.5MB of the disk are accessible to load a kernel from. Linux kernels are not usually that big, so this has not been a problem on older hardware with limited RAM. On systems with gigabytes of RAM, loading a kernel with a very large embedded initmpfs could be desirable, but such systems usually support LBA addressing through enhanced BIOS calls. If this limitation becomes a problem, a larger LBA could be supported with more complex code, but it would never achieve the reach of LBA, which is 48bits.

other useful references

int-13
int-16