Emulate piCore with QEMU

Compile the RPI Linux Kernel

Start by creating a working directory and getting the necessary sources and tools:

1
2
3
4
5
6
mkdir /tmp/picore-qemu
cd /tmp/picore-qemu
git clone https://github.com/raspberrypi/tools --depth 1
git clone https://github.com/raspberrypi/linux --depth 1
export CCPREFIX=/tmp/picore-qemu/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-
cd linux

Continue by patching and configuring the kernel as outlined in my previous post. When you get to the menuconfig, in addition to the other options (i.e. the ones described in the last post), also select these:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
File systems --->
[*] Miscellaneous filesystems --->
<*> SquashFS 4.0 - Squashed file system support
File decompression options (Decompress file data into an intermediate buffer) --->
Decompressor parallelisation options (Single threaded compression) --->
[*] Squashfs XATTR support
[*] Include support for ZLIB compressed file systems (NEW)
[*] Include support for LZ4 compressed file systems
[*] Include support for LZO compressed file systems
[*] Include support for XZ compressed file systems
[*] Use 4K device block size?
[*] Additional option for memory-constrained systems
(3) Number of fragments cached (NEW)
Device Drivers --->
[*] Block devices --->
<*> Loopback device support

Then continue compiling the kernel:

1
make ARCH=arm CROSS_COMPILE=${CCPREFIX} zImage modules -j4

Install the modules in a temporary directory:

1
make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=/tmp/picore-qemu/mod_install modules_install

Prepare the initramfs

Download and extract the latest piCore image, then mount the first partition and copy out the piCore initramfs 6.0.gz:

1
2
3
4
5
6
7
wget http://tinycorelinux.net/6.x/armv6/release/6.0/piCore-6.0.zip
unzip piCore-6.0.zip
mkdir fat32
fdisk -l piCore-6.0.img # find the unit size and start of the first partition
mount -ooffset=$((8192 * 512)) piCore-6.0.img fat32
cp fat32/6.0.gz .
umount fat32

Extract the piCore initramfs and copy in the new kernel modules we just compiled. These steps have to be done as root to preserve file permissions:

1
2
3
4
5
6
7
sudo su
mkdir initramfs
cd initramfs/
gzip -cd ../6.0.gz | cpio -vid
rm -r lib/modules/3.12.36-piCore+/ usr/local/lib/modules/3.12.36-piCore+/
cp -r /tmp/picore-qemu/mod_install/lib/modules/4.1.10+/ lib/modules/
ln -s /usr/local/lib/modules/4.1.10+/kernel lib/modules/4.1.10+/kernel.tclocal

Make some changes to make booting smoother, free some space and be able to run tce commands as root:

1
2
3
sed -i '/scaling_governor/ s/^/#/' opt/bootlocal.sh
sed -i '/checknotroot/ s/^/#/' usr/bin/tce*
rm -r lib/modules/4.1.10+/kernel/sound/ lib/modules/4.1.10+/kernel/drivers/mmc

Finish up by recompressing the initramfs:

1
2
find . -print0 | cpio --null -ov --format=newc | gzip > ../6.0.gz
cd ..

Boot to TinyCore

First, create a disk image that we will use for storing extensions and persistent configuration:

1
qemu-img create -f qcow2 sda.qcow2 1G

Boot with the kernel we just compiled, the initramfs and the disk image:

1
2
cp /tmp/picore-qemu/linux/arch/arm/boot/zImage .
qemu-system-arm -M versatilepb -cpu arm1176 -kernel zImage -initrd 6.0.gz -append "console=ttyAMA0 nortc nozswap" -hda sda.qcow2 -nographic

Login with username tc (just type tc and hit enter). Then, become root, format the disk image, and setup the tce directory on the disk image. By having the tce directory on the disk image, we can persist installed extensions across boots.

1
2
3
4
5
sudo su
mkfs.ext4 /dev/sda
mkdir /mnt/sda
mount /dev/sda /mnt/sda/
tce-setdrive -s /mnt/sda

Now, any extensions you install will be stored on the disk image, so they will be automatically loaded when you boot. To check that this works, lets try installing an openssh server and then rebooting:

1
2
3
4
5
tce-load -iw openssh
/usr/local/etc/init.d/openssh start
# Add this bootlocal.sh to have it start on boot:
echo /usr/local/etc/init.d/openssh start >> /opt/bootlocal.sh

Just check that ssh is working (change the tc user’s password first):

1
2
passwd tc
ssh tc@localhost

To persist the openssh configuration (and passwd file) across boots, we can back them up by adding their paths to /opt/.filetool.lst and calling filetool.sh -b:

1
2
3
4
5
6
cat <<'EOF' >> /opt/.filetool.lst
/usr/local/etc/ssh
/etc/passwd
/etc/shadow
EOF
filetool.sh -b

The files should now be backed up and stored in /mnt/sda/tce/mydata.tgz. Lets reboot and check that the ssh server is in fact started after booting:

1
reboot

You can also ssh in from your guest machine by forwarding a port with QEMU:

1
qemu-system-arm -net nic -net user,hostfwd=tcp::10022-:22 -M versatilepb -cpu arm1176 -kernel zImage -initrd 6.0.gz -append "console=ttyAMA0 nortc nozswap" -hda sda.qcow2 -nographic

References

http://forum.tinycorelinux.net/index.php?topic=14080.0
http://myblog-kenton.blogspot.com/2012/03/install-openssh-server-on-tiny-core.html