Booting the Linux Kernel Without an initrd/initramfs

来源:互联网 发布:京东数据开放平台 编辑:程序博客网 时间:2024/06/05 07:09

转自

http://www.dotslashlinux.com/2017/04/29/Booting-the-Linux-Kernel-Without-an-initrd-initramfs.html


DOTSLASHLINUX - DOTSLASHLINUX-logo

No, this is not a myth… It’s not a legend… It’s the truth and it’s doable! 

As you probably guessed from the title, in this article we’ll uncover the truth behind booting the linux kernel without using an initrd or an initramfs! 

Before we even start, booting without an initrd/initramfs might speed up your boot time by 100ms to 500ms. However, on some setups it may slow down your boot time by 800ms to 1sec! 

Prerequisites: 
You should compile your own kernel. 
You should compile your own kernel. 
You should compile your own kernel. 
You should compile your own kernel. 

I know this may sound like a nightmare for some of you, but that’s why DOTSLASHLINUX was created. Plus don’t worry the kernel configuration series is coming really soon, so look up to it! 

Here’s what we’re going to do: 
1- Remove initrd/initramfs support from the linux kernel. 
2- Remove UUIDs from kernel command line parameters and /etc/fstab. 
3- Build all modules into the linux kernel. 
4- Tell the bootloader where root is located and what filesystem it’s using. 
5- Reboot and get that rescue cd/usb since no one makes it in his 1st attempt :) 

It doesn’t really matter what distro you use (that is if you know that your distro isn’t going to break with the slightest change), but for those who want to tag along with me then I’ll be using my all time favorite distro Gentoo Linux. The version of the kernel’s source files that I’m using is 4.10.13. 


1- Removing initrd/initramfs Support from the Linux Kernel


If you’re using Gentoo Linux, simply navigate to:

cd /usr/src/linux
Copy


Now make sure you have ncurses installed and run:

make menuconfig
Copy


Now go to General Setup then search for CONFIG_BLK_DEV_INITRD and disable it:

  RCU Subsystem  --->  < > Kernel .config support  (12) Kernel log buffer size (16 => 64KB, 17 => 128KB)  (12) CPU kernel log buffer size contribution (13 => 8 KB, 17 => 128KB)  (12) Temporary per-CPU NMI log buffer size (12 => 4KB, 13 => 8KB)  [ ] Memory placement aware NUMA scheduler  -*- Control Group support  --->  [ ] Checkpoint/restore support  -*- Namespaces support  --->  [ ] Automatic process group scheduling  [ ] Enable deprecated sysfs features to support old userspace tools  -*- Kernel->user space relay support (formerly relayfs)  [ ] Initial RAM filesystem and RAM disk (initramfs/initrd) support  Compiler optimization level (Optimize for performance)  --->  [*] Configure standard kernel features (expert users)  --->  [*] Enable bpf() system call  -*- Use full shmem filesystem  [*] Enable AIO support  [*] Enable madvise/fadvise syscalls  [ ] Enable userfaultfd() system call  [*] Enable PCI quirk workarounds  [*] Enable membarrier() system call  [ ] Embedded system  Kernel Performance Events And Counters  --->  [*] Enable VM event counters for /proc/vmstat  [ ] Enable SLUB debugging support  [*] Disable heap randomization  Choose SLAB allocator (SLUB (Unqueued Allocator))  --->  [ ] SLAB freelist randomization  [ ] SLUB per cpu partial cache  [ ] Profiling support  [ ] Kprobes  [*] Optimize very unlikely/likely branches  [ ]   Static key selftest  [ ] GCC plugins  ----  Stack Protector buffer overflow detection (None)  --->  (28) Number of bits to use for ASLR of mmap base address  [*] Use a virtually-mapped stack  GCOV-based kernel profiling  --->
Copy



2- Remove these UUIDs!


Udev won’t start until root is mounted, so you can’t use UUIDs before that happens. Therefore, remove your UUID entries from your kernel command line parameters and from your /etc/fstab. Some may argue that these are filesystem UUIDs and are unrelated to udev and that what I mentioned previously is called PARTUUID, I won’t disagree as that is correct, but for the sake of simplicity just follow this tutorial. 

For example, if your root was on /dev/sda1 and you had: 

root=UUID="be9683c1-e42c-4a2b-18ad-97cc96b13ada 

as a kernel command line parameter or inside your /etc/fstab, then simply change it to: 

root=/dev/sda1 

For example, I’m using LILO as my bootloader and here’s my /etc/lilo.conf:

lba32boot=/dev/sdadefault=gentooimage=/boot/vmlinuz-4.10.13-gentoo-DOTSLASHLINUXlabel=gentooread-onlyroot=/dev/sda1append="rootfstype=ext4"
Copy


And here’s my /etc/fstab:

# (fs)(mountpoint)(type)(opts)(dump/pass)/dev/sda1/         ext4 noatime0 1
Copy



3- Build All Modules into the Linux Kernel


Things may get a little controversial here. I generally recommend building all modules into the linux kernel and disable loadable modules support since my setup doesn’t require many modules (I only have support for the basic stuff I use). You can do that by disabling CONFIG_MODULES: 

  Gentoo Linux  --->  [*] 64-bit kernel  General setup  --->  [ ] Enable loadable module support  ----  [*] Enable the block layer  --->  Processor type and features  --->  Power management and ACPI options  --->  Bus options (PCI etc.)  --->  Executable file formats / Emulations  --->  [*] Networking support  --->  Device Drivers  --->  Firmware Drivers  --->  File systems  --->  Kernel hacking  --->  Security options  --->  -*- Cryptographic API  --->  [ ] Virtualization  ----  Library routines  --->
Copy


However, if you were one of those guys who use tons of devices then you may leave the extra devices as loadable modules. 

There are still some necessary modules that need to be build into the linux kernel to be able to boot without an initrd/initramfs. These include modules for filesystems and modules for block devices. 

If you’re using ext4, navigate to Filesystems and make sure that CONFIG_EXT4_FS is built-in:

  [ ] Second extended fs support  [ ] The Extended 3 (ext3) filesystem  [*] The Extended 4 (ext4) filesystem  [ ]   Use ext4 for ext2 file systems  [ ]   Ext4 POSIX Access Control Lists  [ ]   Ext4 Security Labels  [ ]   Ext4 Encryption  [ ]   EXT4 debugging support  [ ] JBD2 (ext4) debugging support  [ ] Reiserfs support  [ ] JFS filesystem support  [ ] XFS filesystem support  [ ] GFS2 file system support  [ ] OCFS2 file system support  [ ] Btrfs filesystem support  [ ] NILFS2 file system support  [ ] F2FS filesystem support  [ ] Direct Access (DAX) support  [ ] Enable filesystem export operations for block IO  [*] Enable POSIX file locking API  [ ]   Enable Mandatory file locking  [ ] FS Encryption (Per-file encryption)  [ ] Dnotify support  [*] Inotify support for userspace  [*] Filesystem wide access notification  [ ] Quota support  [ ] Kernel automounter version 4 support (also supports v3)  [*] FUSE (Filesystem in Userspace) support  [ ]   Character device in Userspace support  [ ] Overlay filesystem support  Caches  --->  CD-ROM/DVD Filesystems  --->  DOS/FAT/NT Filesystems  --->  Pseudo filesystems  --->  [ ] Miscellaneous filesystems  ----  [ ] Network File Systems  ----  -*- Native language support  ---  [ ] Distributed Lock Manager (DLM)  ----
Copy


Now you need to check what block devices are you using (to be more precise, the block device where your root resides on), find out its kernel module and mark it as built-in. This is simple, fire up a terminal emulator and type:

lspci -kk
Copy


In my case I’m using a Toshiba MQ01ABD100 which is a SATA HDD that uses the ahci kernel module:

00:1f.2 SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (rev 04)    Subsystem: Toshiba America Info Systems 8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode]    Kernel driver in use: ahci
Copy


I navigate to Device Drivers then to Serial ATA and Parallel ATA drivers (libata) and mark CONFIG_SATA_AHCI as built-in:

  --- Serial ATA and Parallel ATA drivers (libata)  [ ]   Verbose ATA error reporting  [*]   ATA ACPI Support  [*]     SATA Zero Power Optical Disc Drive (ZPODD) support  [ ]   SATA Port Multiplier support  *** Controllers with non-SFF native interface ***  [*]   AHCI SATA support  [ ]   Platform AHCI SATA support  [ ]   Initio 162x SATA support (Very Experimental)  [ ]   ACard AHCI variant (ATP 8620)  [ ]   Silicon Image 3124/3132 SATA support  [ ]   ATA SFF support (for legacy IDE and PATA)
Copy



4- Notifying the Bootloader of the changes

Now we need to tell our bootloader the info that the initrd/initramfs would tell to the kernel. That is the location of root and the filesystem of root. 

If you’re using grub, fire up your favorite editor and edit /etc/default/grub:

nano /etc/default/grub
Copy
# Copyright 1999-2015 Gentoo Foundation# Distributed under the terms of the GNU General Public License v2## To populate all changes in this file you need to regenerate your# grub configuration file afterwards:#     'grub2-mkconfig -o /boot/grub/grub.cfg'## See the grub info page for documentation on possible variables and# their associated values.GRUB_DISTRIBUTOR="Gentoo"# Default menu entryGRUB_DEFAULT=0# Boot the default entry this many seconds after the menu is displayedGRUB_TIMEOUT=0#GRUB_TIMEOUT_STYLE=menu# Append parameters to the linux kernel command lineGRUB_CMDLINE_LINUX="root=/dev/sda1 rootfstype=ext4"## Examples:## Boot with network interface renaming disabled# GRUB_CMDLINE_LINUX="net.ifnames=0"## Boot with systemd instead of sysvinit (openrc)# GRUB_CMDLINE_LINUX="init=/usr/lib/systemd/systemd"# Append parameters to the linux kernel command line for non-recovery entries#GRUB_CMDLINE_LINUX_DEFAULT=""# Uncomment to disable graphical terminal (grub-pc only)#GRUB_TERMINAL=console# The resolution used on graphical terminal.# Note that you can use only modes which your graphic card supports via VBE.# You can see them in real GRUB with the command `vbeinfo'.#GRUB_GFXMODE=640x480# Set to 'text' to force the Linux kernel to boot in normal text# mode, 'keep' to preserve the graphics mode set using# 'GRUB_GFXMODE', 'WIDTHxHEIGHT'['xDEPTH'] to set a particular# graphics mode, or a sequence of these separated by commas or# semicolons to try several modes in sequence.#GRUB_GFXPAYLOAD_LINUX=# Path to theme spec txt file.# The starfield is by default provided with use truetype.# NOTE: when enabling custom theme, ensure you have required font/etc.#GRUB_THEME="/boot/grub/themes/starfield/theme.txt"# Background image used on graphical terminal.# Can be in various bitmap formats.#GRUB_BACKGROUND="/boot/grub/mybackground.png"# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to kernel#GRUB_DISABLE_LINUX_UUID=true# Uncomment to disable generation of recovery mode menu entries#GRUB_DISABLE_RECOVERY=true# Uncomment to disable generation of the submenu and put all choices on# the top-level menu.# Besides the visual affect of no sub menu, this makes navigation of the# menu easier for a user who can't see the screen.#GRUB_DISABLE_SUBMENU=y# Uncomment to play a tone when the main menu is displayed.# This is useful, for example, to allow users who can't see the screen# to know when they can make a choice on the menu.#GRUB_INIT_TUNE="60 800 1"
Copy


However, if you’re lucky enough to use LILO (like me xD), then the following configuration file will do:

lba32boot=/dev/sdadefault=gentooimage=/boot/vmlinuz-4.10.13-gentoo-DOTSLASHLINUXlabel=gentooread-onlyroot=/dev/sda1append="rootfstype=ext4"
Copy


This’ll also work as well:

lba32boot=/dev/sdadefault=gentooimage=/boot/vmlinuz-4.10.13-gentoo-DOTSLASHLINUXlabel=gentooread-onlyappend="root=/dev/sda1 rootfstype=ext4"
Copy


You may have to delete your initd/initramfs from your /boot and the initrd/initramfs entries in your bootloader’s configuration files. Don’t forget to recompile your kernel and to update your bootloader (if you’re using GRUB2 or LILO) before rebooting. 


Conclusion

Booting without an initrd/initramfs is 100% doable so don’t think it’s impossible. You may fail on your 1st attempt but don’t give up, just keep on trying different combinations every time you compile your kernel and you should be good to go. 

I’m using Gentoo Linux and can confirm that you can achieve a bootable kernel without initrd/initramfs. If your kernel is panicking then debug the problem and keep trying until it works. If you have a question as well then lemme know in the comments section below. 


阅读全文
0 0