Home > Linux, Programming, Testing > Getting Started with 64-bit ARM Development: Hello World and Linux on ARMv8 Fast Models

Getting Started with 64-bit ARM Development: Hello World and Linux on ARMv8 Fast Models

At the end of last year, ARM announced ARMv8, the first ARM 64-bit ARM archtecture, and last week at ARM Techcon 2012, ARM announced the first ARMv8 cores: Cortex A53 and A57. But since there’s no silicon at the moment, what if you wanted to develop code running on ARMv8 before the hardware is available? The answer is: Fast Models, a Virtual Platform (VP) to accelerate software development. This is especially important for ARMv8 since hardware is not expected to be available for another year. In this post, I’ll first show how to run “Hello World!” in ARMv8 fast models, then we’ll run ARM Linux 64-Bit (Aarch64) in the virtual platform.

ARMv8 Foundation Model

In order allow the developer’s community to program for ARMv8 (Cortex A53/A57 cores), ARM has made ARMv8 Foundation Model, a virtual platform, available free of charge.

This v8 Foundation model provides a basic ARMv8 platform environment suitable for running bare metal semi-hosted applications, and Linux OS booting. The platform provides:

  • An ARMv8 processor cluster with 1-4 CPUs
  • Up to 8GB of RAM
  • An optional 128MB of secure RAM
  • 4 PL011 UARTs exposed as host TCP sockets
  •  A network device model connected to host network resources
  • A block storage device implemented as a file on the host
  •  A small system register block

The V8 processor model implements:

  • AArch64 at all exception levels
  • AArch32 support at EL0/EL1
  • Little and big endian at all exception levels
  • Generic timers
  • Self-hosted debug
  • GIC v2 memory mapped CPU interfaces and distributor
  • No support for Thumb2EE
  • No support for Crypto extensions

The models require an x86 64-bit Linux machine running Red Hat Enterprise Linux version 5.x for 64-bit architectures, Red Hat Enterprise Linux version 6.x for 64-bit architectures, Ubuntu 10.04 (64-bit) or later. However, any x86 64-bit Linux distributions with glibc v2.3.2 (or greater) and libstdc++ 6.0.0 (or greater), should be able to run the models. I used a machine running Ubuntu Desktop 12.04 LTS 64-bit with the instructions below.

Hello Word! for ARMv8

To get started, visit the page linked above, and click on “Download Now” at the bottom of the page. You’ll need to login or register (It’s free), and then on the top right of the screen click on “Download Now” again to start downloading the V8 Foundation Model.  You’ll a get a 8 MB file called FM000-KT-00035-r0p8-44rel23.tgz.

Let’s work in a terminal window, uncompress the file and run the “Hello World!” application.

tar xzvf FM000-KT-00035-r0p8-44rel23.tgz
cd ~/Foundation_v8pkg
./Foundation_v8 --image examples/hello.axf
 terminal_0: Listening for serial connection on port 5000
 terminal_1: Listening for serial connection on port 5001
 terminal_2: Listening for serial connection on port 5002
 terminal_3: Listening for serial connection on port 5003
 Simulation is started
 Hello, 64-bit world!

That’s it! Details are in in the document: DUI0677A_foundation_fast_model_ug.pdf, including instructions to access a web interface to monitor the machine, access to UART and more. hello.axf is a file based on “ARM Executable Format” that contains executable binary code generated with armlink linker part of the Keil ARM Compilation Tools. You can check the Makefile in the examples directory to see how armcc and armlink are used for the ARMv8 architecture.

Run ARMv8 Linux in the Virtual Platform

Now let’s do something a bit more interesting by running Linux (OpenEmbedded) in the v8 foundation model. The instructions I followed are available at http://www.linaro.org/engineering/armv8.

Prepare a working directory:

mkdir ~/linaro-armv8
cd ~/linaro-armv8

Download boot image:

wget http://releases.linaro.org/12.10/openembedded/aarch64/rc3/img-foundation.axf

Download and extract disk image:

wget http://releases.linaro.org/12.10/openembedded/aarch64/rc3/vexpress64-openembedded_sdk-armv8_20121019-22.img.gz
gunzip vexpress64-openembedded_sdk-armv8_20121019-22.img.gz

Run OpenEmbedded in the virtual platform:

~/Foundation_v8pkg/Foundation_v8 --image ~/linaro-armv8/img-foundation.axf --block-device ~/linaro-armv8/vexpress64-openembedded_sdk-armv8_20121019-22.img --network=nat

After a few seconds, a terminal window (Telnet attached to UART) with the kernel output should pop-up:

Linux boot on Cortex A57 virtual platformBe patient, and after several minutes (12 minutes on a PC based on Intel Core 2 processor @ 1.8 GHz), you should see the command prompt.
Let’s see if we really run on ARMv8:

uname -a
Linux genericarmv8 3.6.0-1-linaro-vexpress64 #1~ci+121019044339 SMP Fri Oct 19 05:03:44 UTC 2012 aarch64 GNU/Linux

cat /proc/cpuinfo
Processor       : AArch64 Processor rev 0 (aarch64)
processor       : 0
BogoMIPS        : 200.00

Features        : fp asimd
CPU implementer : 0x41
CPU architecture: AArch64
CPU variant     : 0x0
CPU part        : 0xd00
CPU revision    : 0

Hardware        : V2P-AARCH64

All good!

Building for ARMv8

Running Linux in ARMv8 is nice, but what you really want to do is write and build programs for the platform. Natively build programs inside the foundation models is probably not a good idea for most programs, since it would be quite slow, so you’ll have to cross-compile for Aarch64. I’ll build the “Hello World!” application as explained in https://wiki.linaro.org/HowTo/HelloAarch64.

First download and install aarch64-toolchain:

mkdir ~/aarch64-toolchain
cd ~/aarch64-toolchain
wget http://releases.linaro.org/12.10/components/toolchain/gcc-linaro/aarch64/rc1/gcc-linaro-aarch64-linux-gnu-4.7+svn191987-20120925+bzr2498_linux.tar.xz
tar xf gcc-linaro-aarch64-linux-gnu-4.7+svn191987-20120925+bzr2498_linux.tar.xz
export PATH=$PATH:$PWD/gcc-linaro-aarch64-linux-gnu-4.7+svn191987-20120925+bzr2498_linux/bin

Install some dependencies:

apt-get install build-essential ia32-libs

Then write an  “Hello World!” program, and cross-compile it:

aarch64-linux-gnu-gcc -o hello hello.c

Let’s check the file is really a 64-bit binary:

file hello
hello: ELF 64-bit LSB executable, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.39, BuildID[sha1]=0xf99cedfc98f57956a6de9c1c04beba2acf32dfee, not stripped

Now copy it to the virtual platform, either by updating the rootfs, or via NFS or http, and run the program:

./hello
Hello World! cnxsoft is in the 64-bit ARM house!

Success!

For more, there are other very useful ARM Linux 64-bit tutorials on Linaro website, such as:

And you could also try the minimal, LAMP or SDK Aarch64 images.

It’s also possible to run Android (32-bit) in the V8 models as shown in the video below (mainly an interview), but instructions do not appear available, and it’s not something I would want to try in my (slow) machine…

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter

  1. Nikolay Nikolaev
    November 6th, 2012 at 11:16 | #1

    Hello,

    there’s an alternative – the buildroot guys recently added their AArch64 buidl support too.
    A quick step-through:

    git clone git://git.buildroot.net/buildroot
    cd buildroot
    make arm_foundationv8_defconfig && make

    It takes some time now. Then run the resulting images like this:

    ${LOCATION_OF_FOUNDATIONV8_SIMULATOR}/Foundation_v8 \
    –image output/images/linux-system.axf \
    –block-device output/images/rootfs.ext2 \
    –network=nat

    Voilà. Now you have you own compiled distro. You don’t have to worry about downloading compilers and setting PATH, it’s all done for you. As a bonus you get the (almost) “latest” kernel:

    Welcome to Buildroot
    buildroot login: root
    # uname -a
    Linux buildroot 3.7.0-rc2 #1 SMP Tue Nov 6 06:06:00 EET 2012 aarch64 GNU/Linux
    #

    Just my $0.02

  2. Nikolay Nikolaev
    November 6th, 2012 at 11:20 | #2

    @Nikolay Nikolaev
    On my i7-3820 the simulator loads/runs pretty fast!
    You definitely need a fast machine here.

  3. November 6th, 2012 at 11:29 | #3

    @Nikolay Nikolaev
    Thanks. Always useful to know alternative methods.

  4. Sander
    November 6th, 2012 at 13:58 | #4

    Funny: the ‘file’ command does not yet know the ARM64 / AARCH64 structure:

    $ file examples/hello.axf
    examples/hello.axf: ELF 64-bit LSB executable, version 1 (SYSV), statically linked, not stripped

    So: no mentioning of ARM (let alone ARM64) at all. :-(

    FWIW:

    On my Raspi (with old-skool 32-bit ARM):

    $ file hello
    hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0xae83e4aa4bcb54db085cc4501ebac0dde2b265e9, not stripped

    And my x86-64:

    $ file hello
    hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x037c38ade17339c41ea6f028a6dee9c302326e86, not stripped

  5. Sander
    November 7th, 2012 at 02:37 | #5

    My emulator is running, but without network.

    After “udhcpc”, I have a network via ifconfig. Alas, I can’t get outside the emulator: traceroute only shows stars.

    So … How do I get network running? Or, easier, how do I get files in and out of the emlulator?

  6. Sander
    November 7th, 2012 at 04:56 | #6

    @Nikolay Nikolaev

    The buildroot is running now, but it’s download more that 1GB (“Cloning into bare repository ‘linux-7181edd0539e195f78adedbb6c3878f9f1e0c4bb’…”). Is that correct?

  7. Nikolay Nikolaev
    November 7th, 2012 at 05:29 | #7

    @Sander
    Well – yes, that’s a git ‘feature’ :)
    Just leave it and see what happens in the end.

    BTW I run “make menuconfig” and selected ‘links’ (it’s a popular textbased web browser).
    When I run the image – udhcpc eth0. Then you can do: links google.com. See – it works.
    I also had network problems with Linaro’s OpenEmbedded image – don’t know what is the issue there.

  8. Sander
    November 7th, 2012 at 05:34 | #8

    @Nikolay Nikolaev

    the make eventually succeeded, and I’m running the 3.7.0 Linux image. Problems
    – still no network
    – this image has no gcc :-(

  9. Sander
    November 7th, 2012 at 05:37 | #9

    FWIW: this is my ifconfig after the udhcpc

    Tips how to get the network running?

    # ifconfig
    eth0 Link encap:Ethernet HWaddr 00:02:F7:EF:CE:D4
    inet addr:172.20.51.1 Bcast:172.20.51.255 Mask:255.255.255.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:9 errors:0 dropped:0 overruns:0 frame:0
    TX packets:65 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:940 (940.0 B) TX bytes:4310 (4.2 KiB)
    Interrupt:47 Base address:0xa000 DMA chan:ff

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    UP LOOPBACK RUNNING MTU:65536 Metric:1
    RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

    #

    # traceroute -n 8.8.8.8
    traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 46 byte packets
    1 * * *
    2 * * *
    3 * * *

  10. November 7th, 2012 at 09:18 | #10

    @Sander
    Since it’s using NAT, you may have troubles accessing private IP addresses, but public addresses (i.e. The Internet) should be accessible (I haven’t tried).

    If you want to use a local server, you can run to start the image with –network=bridged instead of –network=nat.

    I did not use the network to copy hello binary to the rootfs, but instead mounted the rootfs and copied the file. The instructions are similar to what I wrote for the Raspberry Pi a while back:

    First find the offset:
    fdisk -l vexpress64-openembedded_sdk-armv8_20121019-22.img

    then mount the image:
    mount -t ext4 -o loop,offset=$((512*offset)) vexpress64-openembedded_sdk-armv8_20121019-22.img mnt

  11. Sander
    November 13th, 2012 at 04:49 | #11

    @cnxsoft

    Could you try your network connectivity within the ARM64 / aarch64 emulator?

    I tried a physical ethernet cable (with Wifi turned off), but “ping 8.8.8.8″ results in a 100% loss … :-(

    FWIW: Running on Ubuntu 12.10 64-bit.

  12. Sander
    November 13th, 2012 at 04:52 | #12

    PS: I can ping the VM’s own IP address, and it’s default gateway. But that’s it.

    root@genericarmv8:~# ip route show
    default via 172.20.51.254 dev eth0
    172.20.51.0/24 dev eth0 src 172.20.51.1

    root@genericarmv8:~# ping 172.20.51.254
    PING 172.20.51.254 (172.20.51.254): 56 data bytes
    64 bytes from 172.20.51.254: seq=0 ttl=64 time=0.699 ms
    64 bytes from 172.20.51.254: seq=1 ttl=64 time=0.414 ms
    64 bytes from 172.20.51.254: seq=2 ttl=64 time=0.401 ms
    ^C
    — 172.20.51.254 ping statistics —
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 0.401/0.504/0.699 ms
    root@genericarmv8:~#

    root@genericarmv8:~# ping 8.8.8.8
    PING 8.8.8.8 (8.8.8.8): 56 data bytes
    ^C
    — 8.8.8.8 ping statistics —
    9 packets transmitted, 0 packets received, 100% packet loss
    root@genericarmv8:~#

  13. November 13th, 2012 at 09:15 | #13

    @Sander
    The VP is very slow on my machine, and I have to reboot to Ubuntu. It may take a while, before I try it again.

    But are you using bridged mode? If so, the VP should not have its own gateway, but use one of the IP provided by your router.

  14. Sander
    November 15th, 2012 at 00:58 | #14

    @cnxsoft

    Yes, I had already tried “network=bridged”, but that way udhcpc does not get an IP address at all … :-(

    root@genericarmv8:~# ifconfig
    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    UP LOOPBACK RUNNING MTU:16436 Metric:1
    RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

    root@genericarmv8:~# udhcpc
    udhcpc (v1.20.2) started
    [ 55.816859] smc91x 1a000000.ethernet: eth0: link up, 10Mbps, half-duplex, lpa 0x0000
    Sending discover…
    Sending discover…
    Sending discover…
    Sending discover…
    Sending discover…

    root@genericarmv8:~# udhcpc –retries 4 -n -q -i eth0
    udhcpc (v1.20.2) started
    Sending discover…
    Sending discover…
    Sending discover…
    Sending discover…
    No lease, failing
    root@genericarmv8:~#

    root@genericarmv8:~# dmesg | grep -i eth
    [ 14.026993] eth0: SMC91C11xFD (rev 1) at ffffff800001a000 IRQ 47 [nowait]
    [ 14.027093] eth0: Ethernet addr: 00:02:f7:ef:ce:d4
    [ 14.027154] eth0: PHY LAN83C183 (LAN91C111 Internal)
    [ 55.816859] smc91x 1a000000.ethernet: eth0: link up, 10Mbps, half-duplex, lpa 0x0000
    root@genericarmv8:~#

    On the commandline of the host machine:

    sander@R540:~/linaro-armv8$ ~/Downloads/Foundation_v8pkg/Foundation_v8 –image ~/linaro-armv8/img-foundation.axf –block-device ~/linaro-armv8/vexpress64-openembedded_sdk-armv8_20121019-22.img –network=bridged
    terminal_0: Listening for serial connection on port 5000
    terminal_1: Listening for serial connection on port 5001
    terminal_2: Listening for serial connection on port 5002
    terminal_3: Listening for serial connection on port 5003

  15. November 15th, 2012 at 12:43 | #15

    @Sander
    OK, maybe bridged mode does not work yet. Anyway, using NAT should be fine since 8.8.8.8 is a public IP address.
    If you type “route” does it seem configured correctly?

    There are many product news at the moment, so many things to read. I think I’ll try it this week-end.

  16. Sander
    November 16th, 2012 at 01:03 | #16

    @cnxsoft

    Yes, ip route looks good; see my older post of November 13th, 2012 at 04:52

  17. November 18th, 2012 at 10:00 | #17

    @Sander
    It took a little whiile to figure out i had to use the middle button of the mouse to copy/paste text from an xterm terminal.., But network (i.e. wget) does work, just ICMP does not.

    root@genericarmv8:~# udhcpc -n
    udhcpc (v1.20.2) started
    [ 326.916846] smc91x 1a000000.ethernet: eth0: link up, 10Mbps, half-duplex, lpa 0x0000
    Sending discover…
    Sending select for 172.20.51.1…
    Lease of 172.20.51.1 obtained, lease time 86400
    /etc/udhcpc.d/50default: Adding DNS 172.20.51.254

    root@genericarmv8:~# ifconfig
    eth0 Link encap:Ethernet HWaddr 00:02:F7:EF:4F:57
    inet addr:172.20.51.1 Bcast:172.20.51.255 Mask:255.255.255.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:2 errors:0 dropped:0 overruns:0 frame:0
    TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:646 (646.0 B) TX bytes:3663 (3.5 KiB)
    Interrupt:47 Base address:0xa000 DMA chan:ff

    root@genericarmv8:~# route
    Kernel IP routing table
    Destination Gateway Genmask Flags Metric Ref Use Iface
    default 172.20.51.254 0.0.0.0 UG 0 0 0 eth0
    172.20.51.0 * 255.255.255.0 U 0 0 0 eth0
    root@genericarmv8:~

    root@genericarmv8:~# ping 172.20.51.254
    PING 172.20.51.254 (172.20.51.254): 56 data bytes
    64 bytes from 172.20.51.254: seq=0 ttl=64 time=0.957 ms
    64 bytes from 172.20.51.254: seq=1 ttl=64 time=0.455 ms
    64 bytes from 172.20.51.254: seq=2 ttl=64 time=0.400 ms
    ^C
    — 172.20.51.254 ping statistics —
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max = 0.400/0.604/0.957 ms

    root@genericarmv8:~# ping google.com
    PING google.com (74.125.135.102): 56 data bytes
    ^C
    — google.com ping statistics —
    14 packets transmitted, 0 packets received, 100% packet loss

    root@genericarmv8:~# wget http://www.google.com
    Connecting to http://www.google.com (74.125.135.105:80)
    Connecting to http://www.google.co.th (74.125.135.94:80)
    index.html 100% |*******************************| 700 0:00:00 ETA
    root@genericarmv8:~#

  18. Sander
    November 19th, 2012 at 13:52 | #18

    @cnxsoft

    Wow, indeed! Thank you!

    Note to myself: ping/traceroute is NOT a good test. :-(

  1. January 16th, 2013 at 21:55 | #1
  2. February 27th, 2014 at 20:25 | #2
  3. March 3rd, 2014 at 13:20 | #3
  4. April 9th, 2014 at 21:01 | #4
  5. May 8th, 2014 at 18:20 | #5