Wednesday, March 4, 2009

Install Debian testing/lenny into Qemu MIPS Malta board

Install Debian testing/lenny into Qemu MIPS Malta board

1. Install debian (testing/lenny) with qemu-system-mipsel/malta.

qemu-img create -f qcow2 debian-mipsel.img 1G
lftp -c mirror ftp://ftp.fi.debian.org/debian/dists/testing/main/installer-mipsel/current/images/malta/netboot/
cd netboot
sudo qemu-system-mipsel -kernel vmlinux-2.6.26-1-4kc-malta -initrd initrd.gz -append 'console=ttyS0' -nographic -serial stdio -net nic -net tap -hda /path/to/debian-mipsel.img

Fellow the standard debian installation process and finish install debian (standard system) to debian-mipsel.img.
Note: Qemu emulation for architecture different from the host side is very slow, be patient during the installation. this maybe take more than 1 hrs depending on the host's hardware configuration.

2. Reboot to the debian-mipsel system we installed right now, rsyncing the entire file system if neccessary (in case of nfsroot). Before that, we'd better to build our own kernel. the qemu simulates MIPS MALTA board with the following hardware:

The Malta emulation supports the following devices:

* - Core board with MIPS 24Kf CPU and Galileo system controller
* - PIIX4 PCI/USB/SMbus controller
* - The Multi-I/O chip's serial device
* - PCnet32 PCI network card
* - Malta FPGA serial device
* - Cirrus VGA graphics card

compile kernel for mips malta board:

cd linux-2.6
make ARCH=mips malta_defconfig

Tune the defconfig if needed:

make ARCH=mips menuconfig
make ARCH=mips CROSS_COMPILE=mipsel-unknown-linux-gnu- -j3

After we have own own kernel, we could use this kernel to boot with our filesystem we installed right now:

sudo qemu-system-mipsel -kernel vmlinux -append 'root=/dev/hda1 ro console=ttyS0' -nographic -serial stdio -net nic -net tap -hda /path/to/debian-mipsel.img -boot c

Login into the new system, prepare to exports our filesystem using rsync:

aptitude update
aptitude install rsync

Since the `/' filesystem contains some virtual filesystem like /dev, /proc, /sys, we must avoid syncing these directory, and the simplest way I know is:

Mount the root filesystem to other directory:

mount /dev/hda1 /mnt

Mount other directory like /boot to the new mounted root (/mnt) if neccessary.

On a other machine, assume it's IP address is 192.168.2.104:

sudo mkdir -p /exports/nfs/diskless/debian-mipsel # on 192.168.2.104, choose a directory you prefer.

On our Qemu target:

cd /mnt
rsync -av * root@192.168.2.104:/exports/nfs/diskless/debian-mipsel/ # sync the entire filesystem to the remote machine.

Note 1: We use qemu to `cheat' for a filesystem installed with debian, in a simular way we could also have a rootfs for other architecture.
Note 2: Other than Debian, gentoo stage3 is also a good choice, and you don't have to install (with qemu-system-xxx), but surely you don't want to `emerge' in a qemu simluated target system ;-)
Note 3: If you have a debian host environment, the simplest way to install a rootfs might be use debootstrap, you can also debootstrap a filesystem for other architecture, please refer to `man debootstrap' for details.

3. Using Qemu/MALTA with nfsroot. Before that we have to modify the something in the nfsroot filesystem, ie:

cd /exports/nfs/diskless/debian-mipsel

vim etc/fstab # comment stuff like /dev/hda1 etc..
vim etc/inittab # comment tty* since we don't use any tty and uncomment ttyS0 and use a proper bitrate because our terminal is on ttyS0

cd /path/to/linux-2.6
sudo qemu-system-mipsel -kernel vmlinux -append 'root=/dev/nfs rw nfsroot=192.168.2.104:/exports/nfs/diskless/debian-mipsel ip=dhcp console=ttyS0' -nographic -serial stdio -net nic -net tap

Note: to use this, make sure DHCP and NFS server is configured properly, please refer to this document: http://wangbj.blogspot.com/2009/03/using-qemu-to-simulate-armintegratorcp.html or /usr/src/linux/Documentation/filesystem/nfsroot.txt (the best).

Monday, March 2, 2009

Using Qemu to simulate ARM/IntegratorCP board

Using Qemu to simulate ARM/IntegratorCP board

1. Qemu/u-boot setup.

Get a recent copy of u-boot sources, build for integrator board.

cd u-boot-2009.01
make integratorcp_config
make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi-

Now we could use qemu to run u-boot binary. ie:

qemu-system-arm -kernel u-boot -net nic -net tap -nographic -serial stdio

Note: we should have -net nic -net tap support, otherwise u-boot will not able to do network traffic.

2. Compile a kernel for IntegratorCP board.

cd linux-2.6
make ARCH=arm integrator_defconfig

tune settings to fit the IntergratorCP board, Qemu simulates this board with (from /usr/share/doc/qemu-xxx):

Use the executable 'qemu-system-arm' to simulate a ARM machine. The ARM Integrator/CP board is emulated with the following devices:

* - ARM926E, ARM1026E, ARM946E, ARM1136 or Cortex-A8 CPU
* - Two PL011 UARTs
* - SMC 91c111 Ethernet adapter
* - PL110 LCD controller
* - PL050 KMI with PS/2 keyboard and mouse.
* - PL181 MultiMedia Card Interface with SD card.

Note: ARM926E is an ARMv5te architecture.

make ARCH=arm menuconfig
make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- -j3
make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnueabi- uImage

3. Qemu, u-boot, and kernel together.

copy our uImage to tftp server, configure an tftp server first if you don't have one.

cp arch/arm/boot/uImage /tftpboot/uImage
/etc/init.d/in.tftpd start

run qemu with u-boot

qemu-system-arm -kernel ~/build/u-boot/u-boot-2009.01/u-boot -net nic -net tap -nographic -serial stdio

and then under u-boot prompt:

Integrator-CP # setenv ipaddr 10.0.0.21 # board ip address
Integrator-CP # setenv server 10.0.0.207 # tftp server ipaddress
Integrator-CP # setenv bootargs 'root=/dev/nfs rw nfsroot=10.0.0.207:/exports/nfs/diskless/gentoo-arm ip=dhcp console=ttyAMA0'
Integrator-CP # tftp 400000 uImage
Integrator-CP # bootm 400000

Note 1: I'm using nfs-root/diskless system, to use this, you have to configure a nfs server first, the corresponding /etc/exports file should be something like:

# /etc/exports: NFS file systems being exported. See exports(5).

/exports/nfs/diskless 10.0.0.0/255.255.255.0(rw,no_root_squash,no_subtree_check)

Note 2: /exports/nfs/diskless/gentoo-arm is a filesystem from gentoo/arm stage3 tarball, since we're using IP kernel level autoconfigration, so we have to tell the userspace program do not to configure ip anymore, under gentoo system, this could be done by (/etc/conf.d/net):

config_eth0=( "null" );

Change /etc/inittab so that init could start from ttyAMA0 with proper bitrate. you can also uncomment tty0-tty6 since we don't use them.

By default the init program is also trying to mount /etc/fstab entries, we could also uncomment unneccessary entries to avoid mount errors/warnings.

Note 3: The cross-toolchain is built by gentoo's crossdev by:

crossdev -S --ex-gdb -t arm-unknown-linux-gnueabi