ARM RealView PB11MPCore reference design and the four-penguin (four CPUs) on this quadcore ARM11 machine.
Toolchain
The latest Linaro GCC toolchain is what I usually use to compile recent kernels. Also for the userspace, if it is a Cortex-A9 machine. For older RealViews like PB1176JZF-S or PB11MPCore you need to use a compiler built for ARMv6 or the stuff just won't work. You can use Rob Landleys precompiled ARMv6 binary if you like, it works for me.
Download the toolchain and install it such that it is always in your path. Sometimes the toolchain has been compiled for i686 and then you need to install a i686 multipath library to execute it on an x86_64 machine. A good way to get the cross compiler into your $PATH is to install it in /var/linus/gcc-linaro-arm-linux-gnueabihf-4.8-2013.08_linux/ and then add this to a file called /etc/profile.d/crosscompilers.sh
CS_BASE=/var/linus/gcc-linaro-arm-linux-gnueabihf-4.8-2013.08_linux/ export PATH=$PATH:${CS_BASE}/bin export MANPATH=$MANPATH:${CS_BASE}/share/doc/gcc-linaro-arm-linux-gnueabihf/man/
Building the upstream kernel
Here are some files that I use to configure and build RealView kernels out-of-the box. These use a minimal initramfs root filesystem placed in your home directory. (This is to get you to a prompt without a root filesystem installed in the flash, such as the ArchLinux method described below.) These root filesystems are created using this script. Prebuilt versions can be obtained here:
- realview.mak can be used for any RealView board/platform actually, you just have to edit it for the board you want.
- rootfs-pb1176.cpio CPIO archive with initramfs root filesystem for the PB1176JZF-S
- rootfs-pb11mp.cpio CPIO archive with initramfs root filesystem for the PB11MPCore
Copy the rootfs to you home directory and the *.mak file to your linux/ git tree or base dir and simply:
> make -f realview.mak config > make -f realview.mak build
Pre-built kernels
Here are a bunch of pre-built kernels with initramfs that can be used to test that the RealView machine is working. They should give prompt and graphics.
- RealView PB11MPCore: uImage-realview-pb11mp-v4.20+ - this is suitable to boot on the real PB11MP hardware from U-Boot
- RealView PB11MPCore: uImage-realview-pb11mp-v4.15-rc1 - this is suitable to boot on the real PB11MP hardware from U-Boot
- RealView PB11MPCore: uImage-realview-pb11mp-v4.13-rc6 - this is suitable to boot on the real PB11MP hardware from U-Boot
- RealView PB11MPCore: zImage-realview-pb11mp-v4.7-rc1 - this is suitable to boot in QEMU
- RealView PBX-A9: zImage-realview-pbxa9-v4.7-rc1
Running in QEMU
You can run a certain QEMU model of RealView like this (this assumes appended device tree, like my realview.mak will produce. All you need is the zImage binary.
#!/bin/bash # RealView PBX A9 qemu-system-arm -M realview-pbx-a9 -smp cpus=2 -no-reboot -kernel ${HOME}/zImage -append "console=ttyAMA0" -serial stdio
Install ArchLinux
I made an ArchLinux installtion based on the Rapberry Pi installation which is ARMv6 based.
Boot a rootfs from a USB stick
- Take a blank USB stick or hard disk or whatever USB storage you have.
- Plug the USB stick into your host computer.
- fdisk /dev/sdX
- Type o. This will clear out any partitions on the drive.
- Type p to list partitions. There should be no partitions left.
- Type n, then p for primary, 1 for the first partition on the drive, press ENTER to accept the default first sector, then enter again for the last sector so we use all the storage.
- Write the partition table and exit by typing w
- mkfs.ext4 /dev/sdX1
- cd /tmp
- wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz
- mkdir /mnt/rootfs && mount /dev/sdX1 /mnt/rootfs
- cd /mnt/rootfs
- tar xvfz /tmp/ArchLinuxARM-rpi-latest.tar.gz
- Edit the file etc/fstab edit out the /dev/mmcblk0p1 mount point (just put a # in front of the line) because we don't want to automount this on the RealView.
- cd
- umount /mnt/rootfs (this may take a while)
- Insert the USB stick into one of the RealView host ports
- Start U-Boot as usual
- Boot with the proper commandline, something like:
set bootargs mem=128M console=ttyAMA0,38400n8 root=/dev/sda1 rw rootwait rootfstype=ext4 init=/sbin/init set serverip 192.168.1.124 ; set ipaddr 192.168.1.35 ; tftpboot 0x00007fc0 192.168.1.124:uImage ; bootm
The mem=128M is there because the non-upstreamed hacked-up RealView bootloaders do not seem to detect memory properly at all.
Boot a rootfs from the SD card
- Take a blank 2GB SD card. Bigger will not work for compatibility reasons.
- fdisk /dev/mmcblk0
- Type o. This will clear out any partitions on the drive.
- Type p to list partitions. There should be no partitions left.
- Type n, then p for primary, 1 for the first partition on the drive, press ENTER to accept the default first sector, then type +100M for the last sector.
- Type t, then c to set the first partition to type W95 FAT32 (LBA).
- Type n, then p for primary, 2 for the second partition on the drive, and then press ENTER twice to accept the default first and last sector.
- Write the partition table and exit by typing w
- mkfs.vfat -n BOOT /dev/mmcblk0p1
- mkdir /mnt/boot && mount /dev/mmcblk0p1 /mnt/boot
- Copy the U-Boot AXF file to the BOOT partition.
- umount /mnt/boot
- mkfs.ext4 /dev/mmcblk0p2
- cd /tmp
- wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz
- mkdir /mnt/rootfs && mount /dev/mmcblk0p2 /mnt/rootfs
- cd /mnt/rootfs
- tar xvfz /tmp/ArchLinuxARM-rpi-latest.tar.gz
- cd
- umount /mnt/rootfs (this may take a while)
- Insert the card into the PB11MP and make sure the boot monitor finds the partition and can access the U-boot
- run u-boot.axf
- Boot with the proper commandline, something like:
set bootargs console=ttyAMA0,38400n8 root=/dev/mmcblk0p2 rw rootwait rootfstype=ext4 init=/sbin/init set serverip 192.168.1.124 ; set ipaddr 192.168.1.35 ; tftpboot 0x00007fc0 192.168.1.124:uImage ; bootm
After booting
- Login with alarm/alarm type su password root to get to the root account.
- If the network does not come up, type dhcpcd
- Upgrade the newly booted system with pacman -Syu
- The flash is formatted with UBIFS, you may want to access it? pacman -S mtd-utils
- You may want device mapper encryption: pacman -S cryptsetup
- Change root and alarm passwords
- hostnamectl set-hostname PogoPlug
- systemctl enable dhcpcd.service
- systemctl start dhcpcd.service
Running JTAG on the PB1176JZF-S
At one point I managed to wipe the flash on my PB1176JZF-S, even flushing the Boot Monitor. NOT GOOD. What to do? The manual says I should re-flash the boot monitor from the support CD. I found the right .axf file, but needed a JTAG to get this into the RAM and execute it.
ARM recommends using their own RealView debugger and a JTAG box from Kiel, and I actually had one of these around. However the support pages and the license registration page for this debugger is gone already, so it has bitrotted away, this isn't working anymore, atleast not for me.
The path of least resistance proved to be to set up OpenOCD to work with this board. I used a J-Link JTAG adapter instead of the Kiel thing, but I suspect any 20-pin JTAG adapter will work just as fine.
HOWTO reflash the Boot Monitor using JTAG and OpenOCD:
- Install OpenOCD
- Get a copy of the PB1176JZF-S boot monitor
- Put the boot monitor on the SD Card in the PB1176 as BOOTMON.AXF and also in the directory where you will run your JTAG session with OpenOCD
- Put all S6 switches in OFF mode, just normal operation.
- Set the CONFIG switch to OFF mode (orange LED not lit)
- Power on the system
- Open a terminal to ttyAMA0 as usual, wherever it is connected, like ttyS0.
- openocd -f tcl/interface/jlink.cfg -f tcl/board/arm_pb1176jzf-s.cfg
- In another terminal/window/tab, type: telnet localhost 4444 to access the target:
-
> reset halt JTAG tap: tc1176.cpu tap/device found: 0x07b76477 (mfg: 0x23b (ARM Ltd.), part: 0x7b76, ver: 0x0) found ARM1176 tc1176.cpu: ran after reset and before halt ... target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x000001d3 pc: 0x07c0b718 > load_image Boot_Monitor_PB1176.axf 144708 bytes written at address 0x07c00000 downloaded 144708 bytes in 0.724742s (194.989 KiB/s) > resume 0x07c00000
- Switch to the ordinary terminal: the boot monitor should be running!
- In the boot monitor erase all images and then put the boot monitor back in,
something like this (I also make a backup of SYSTEM.DAT):
ARM PB1176JZF-S Boot Monitor Version: V4.1.9 Build Date: Jun 3 2010 Tile Site : Tile Not Fitted Endian: Little M:\> flash Flash> list images (...) Flash> read binary SYSTEM.DAT SYSDAT Flash> erase image SYSTEM.DAT Flash> erase image Boot_Monitor Flash> write image BOOTMON.AXF Erasing Flash Writing Flash Progress 1% Progress 43% Progress 89% Progress 100% Flash> list images Flash Area Base 0x3C000000 Address Name ------- ---- 0x3C000000 BOOTMON
- Power off/on the target: the boot monitor should come up.
- You can now proceed to run U-Boot etc.
JTAG can be used for other things and real hardcore debugging too of course. I use it to restart U-Boot when the kernel crashes, just go to the OpenOCD prompt and:
> reset halt JTAG tap: tc1176.cpu tap/device found: 0x07b76477 (mfg: 0x23b, part: 0x7b76, ver: 0x0) found ARM1176 tc1176.cpu: ran after reset and before halt ... tc1176.cpu: target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x00000153 pc: 0x07c0b718 > resume 0x06000000