So I've compiled my kernel and initrd. How can I then create an image and install grub to actually load this image from a disk? My goal isn't to create a livecd out of it that is bootable from USB, as there are plenty of articles on that. My goal is to create an image (I know dd if=/dev/zero of=linux.img ... is what I need to create an overall image) and simply write that image to the first sector of the disk using dd and have it just boot from there. However, where does my kernel and initrd go in that img? Right behind each other? This disk isn't going to have any partitions. It's a custom kernel and minimal busybox setup that is stripped down. I therefore do not need a /boot partition and all the "files" aren't going to live on another partition because there isn't going to be one or much of any files.

I know the MBR is 512 bytes and I assume grub is also just going to overwrite 512 bytes to the first sector. But how do I even get grub installed on the image? Would grub-install linux.img even work? I know that grub knows where to load the kernel and initrd from a normal setup because those live in /boot but this "image" doesn't have partitions on it to look in /boot . Do I just set root to itself?

Any help would be appreciated

Initrd creation procedure: https://pastebin.com/ti9LXakx

Current init script within initrd:

mount -t sysfs sysfs /sys 
mount -t proc proc /proc 
mount -t devtmpfs udev /dev 
exec /bin/sh

1 Answer 1


512 bytes is far too little for GRUB: on a classic BIOS-booting MBR-partitioned disk, GRUB also places parts of itself in the normally-unused blocks #1..#2047, as modern OSs place the start of the first partition exactly 1 MiB from the beginning of the disk, at block #2048. Typically it might use about 100 of those blocks, depending on which features are selected to be built into the GRUB core image and which are left to be loaded as GRUB modules (from some filesystem).

And you don't even get all of the 512 bytes in the MBR block (block #0): at minimum, two bytes at the end of the MBR block are occupied by the signature that tells the BIOS that this disk is bootable.

GRUB has a built-in expectation that the disk/partition/logical volume/encrypted volume it finds its configuration file, kernel and initrd on contains a filesystem of some sort. If you want to read the kernel and initramfs by just reading consecutive blocks off the disk, that sounds more like what the ancient LILO bootloader did... I wonder if it's still usable with the modern kernels?

In short, leaving out the partition table is not the advantage you think it is. With a custom configuration, you could make GRUB read blocks #A .. #B as the kernel, and #(B+1).. #C as the initramfs file, but that would be just making your own life more difficult for no good reason.

And since you mentioned a Live CD, if you want your image to also work when burned to a CD-ROM/DVD or used as a virtual CD in a virtual machine, you must create a hybrid image that works both as a HDD image with a bootloader in MBR, and as a valid ISO9660 CD/DVD image with El Torito boot extensions - which requires a separate bootloader in a different location on the image.

And if you want UEFI compatibility... "You must unlearn what you have learned."

With UEFI, the system firmware will expect to find a FAT filesystem (preferably FAT32, but other forms of FAT will also be acceptable for newer versions of UEFI), and the bootloader as a file with a particular name in that filesystem. Since the filesystem is already there to satisfy the firmware requirements for UEFI bootability, you might as well use it to have the kernel, initramfs and the configuration of your bootloader in there as regular files.

To create your image, you could use losetup to bind it to a /dev/loop<device_number> device, after which you can use the device just like a real disk. If the image contains a partition table, you can use losetup -P to automatically create partition devices of the form /dev/loop<device_number>p<partition_number> to allow easy access to any partitions within the image file.

  • I find kpartx simpler to manage the loop device with partitioned media. Mar 11 at 16:10
  • i was able to figure this all out by reading about loop devices so i ended up setting that up, mounting it, then grub-installing onto the mounted boot. but you are correct about using losetup because that is exactly how it is done. the only question i have is, if my kernel is 1.9M and my initrd is only 5M, why then do I need 16M to create my image file from /dev/zero? I tried with less and there isn't enough space. Does LILO take up that much space as well? I had assumed I would end up with just whatever my kernel and initrd is, not so much extra.
    – unixpipe
    Mar 11 at 23:03
  • Some filesystem types have minimum size requirements (for example, you cannot make a FAT32 partition smaller than 32M), and the filesystem metadata (i.e. directories, inodes and some way to keep track which blocks are allocated and which are not) take some space too. But in modern terms, 16M is tiny: unless you work with embedded systems or retrocomputing, I would see no need to try fit things tighter than that.
    – telcoM
    Mar 12 at 2:57
  • yes I am considering working with embedded systems. Are they using other tools to get this done? I've stripped down my busybox as much as possible as well but disappointed that its still just about 9-10M but I am forced to make my image 16M because of the loop device.
    – unixpipe
    Mar 12 at 5:49
  • The limit is not caused by the loop device. Are you partitioning the image? Modern partitioning tools will normally place the start of the 1st partition at exactly 1 MiB from the start of the device for data alignment reasons. Which filesystem type are you using, and what parameters are you using for the mkfs tool? If using a journaling filesystem like ext4, it will allocate space for the filesystem journal... but if the media is read-only during expected use, you won't need a journaling filesystem.
    – telcoM
    Mar 12 at 12:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .