UPDATE: A more streamlined version of this process is available: From 0 to Raspberry Pi Linux in 45 Minutes
In previous posts I’ve described building the Linux kernel using ELLCC, building Linux for a Raspberry Pi B+, building Linux for the Pi 2, and building Linux on a Mac. In this post we’ll build enough userland and create an SD card that will boot on the Raspberry Pi 2. I just got it to boot this evening and it only gets to the login prompt where I can log in as root, but I think it is pretty cool nonetheless.
I mentioned the ellcc/libecc/ecclinux directory that is in the ELLCC source tree and is included in the ELLCC binary distributions. In this directory, there is a little script that will get sources for the Linux kernel from kernel.org, and a bunch of userland programs from suckless.org and other places. The script will then patch the sources if necessary and build them.
These are the steps I took to create a boot-able SD card. I happened to have a 32 Gig SD card lying around, so I decided to use it. On my Linux box, an SD card shows up as /dev/sdc* so the following commands reflect that. Your system may assign different name. You should verify the name by using df, or something similar, to determine what a newly inserted SD card is.
I’m going to go into a bit of detail here because it is the first time I did this for Linux and I want to keep a detailed record.
UPDATE: I made a little script that populates the SD card. It is in the source repository. The script replaces/enhances the rest of this post.
The first thing I did was to remove the old partitions on the card.
sudo parted /dev/sdc print Model: Generic- SD/MMC (scsi) Disk /dev/sdc: 32.1GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 512B 62.9MB 62.9MB primary 2 62.9MB 67.1MB 4209kB primary
My card had 2 partitions that I got rid of:
sudo parted /dev/sdc rm 1 Information: You may need to update /etc/fstab. sudo parted /dev/sdc rm 2 Information: You may need to update /etc/fstab. sudo parted /dev/sdc print Model: Generic- SD/MMC (scsi) Disk /dev/sdc: 32.1GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags
Now that the old partitions are gone, we can make new partitions for the Pi. The Pi boots using two partitions, one is in MS-DOS or FAT format, the other is in Linux ext4 format. The Pi has an interesting boot sequence, which is nicely described on this page, but basically the GPU starts up first and executes a first and second stage boot loader, which is really the GPU’s OS, before the ARM is brought up and the Linux kernel is booted. The FAT partition is used by the GPU and contains all the files it needs. The ext4 partition contains the rest of the Linux userland. The FAT partition os mounted as /boot after the ext4 partition is mounted as /.So the next step is to create these two partitions. First the FAT partition:
sudo parted -a optimal /dev/sdc unit chs mkpart primary 0,130,2 8,40,31 sudo parted /dev/sdc set 1 lba on
Now we can fill the rest of the disk with the ext4 partition:
sudo parted -a optimal /dev/sdc mkpart primary 67.1MB 100%
Now we’ll format the file systems:
sudo mkfs -t fat /dev/sdc1 mkfs.fat 3.0.27 (2014-11-12)
Then the ext4 partition:
sudo mkfs -t ext4 /dev/sdc2 mke2fs 1.42.12 (29-Aug-2014) Creating filesystem with 7820288 4k blocks and 1957888 inodes Filesystem UUID: 3823b7f5-66b6-4e9f-a10e-4a6658d6469f Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done
We have to mark the first partition as the boot partition:
sudo parted /dev/sdc set 1 lba on Information: You may need to update /etc/fstab. sudo parted /dev/sdc print Model: Generic- SD/MMC (scsi) Disk /dev/sdc: 32.1GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 4194kB 67.1MB 62.9MB primary fat16 lba 2 67.1MB 32.1GB 32.0GB primary ext4
Now we can populate the card. First, build everything using the script. If you run the script with no arguments, it will give you a hint about how to run it:
[~] dev% cd ellcc/libecc/ecclinux [~/ellcc/libecc/ecclinux] dev% ./build usage: ./build [options] target options: -packages 'packag1 package2 ...' Specific packages to build -exclude 'packag1 package2 ...' Specific packages to exclude -clean Clean up a previous build targets: help This message bcmrpi Raspberry Pi (ARMv6) bcm2709 Raspberry Pi 2 (ARMv7) available packages: uboot kernel sinit sbase ubase smdev nldev nlmon svc sdhcp loksh ntfs3g iproute2 e2fsprogs vim ellcc packages not buildable on the Mac: uboot iproute2 e2fsprogs vim
In this case I’ll build for the Raspberry Pi 2:
[~/ellcc/libecc/ecclinux] dev% ./build bcm2709 CHK include/config/kernel.release GEN ./Makefile CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h Using /home/rich/ellcc/libecc/ecclinux/linux-4.1.15 as source for kernel ...
The SD card can be populated after the build completes:
mkdir boot root sudo mount /dev/sdc1 boot sudo mount /dev/sdc2 root cp -r image/arm-linux-engeabihf/bcm2709/* boot sudo cp boot/vmlinuz-4.1.15-v7 boot/kernel7.img cd image/arm-linux-engeabihf/ tar cvfp - bin etc lib sbin usr var | (cd ../../root; sudo tar xfp -) cd cm2709/ rm -fr *.old tar cvfp - * | ( cd ../../../boot ; sudo tar xfp - ) cd ../../.. cd etc chmod oug+x rc.* cp * ../root/etc/ cd ../sbin tar cvfp - * | ( cd ../root/sbin/ ; sudo tar xf - ) cd ../bin chmod oug+x * tar cvfp - * | ( cd ../root/bin/ ; sudo tar xf - ) sudo cp boot.rpi/* boot/ cd root sudo mkdir root proc sys var/run sudo mknod dev/tty0 c 4 0 cd .. sudo umount boot root
I popped the SD card into my Pi 2 and finally got the login: prompt. The initial root password is empty.
This has been a busy weekend. I got a boot, the Packers won, and it is late Sunday night and I have to work early tomorrow. I will be making the SD create steps into a script soon, but for now I’ll put up a new binary release of ELLCC, version 0.1.26, that has all the changes if you want to try this out.