Welcome to Part 4 of the "Exploring the Virtual Platform" series. For readers just joining please refer to Part 1, Part 2, and Part 3 of the series to get up to speed (hopefully soon before it becomes too difficult for me to provide links to every previous topic and too difficult for you to catch up).
We will continue to look at the embedded software aspects of the ARM Integrator Virtual Platform. So far we looked at how to configure, build, and debug the kernel, but this is only one of the key parts of software needed for an embedded system. Today, we will look at the other key ingredient, the filesystem, or the file system (both are used interchangeably). A kernel is not much use unless there is a way to run application programs that utilize the services provided by the kernel to perform some tasks. The most common way to do this is by running programs that are stored on a filesystem.
A filesystem details the method by which files are logically organized on some kind of medium for storage and retrieval. For Linux this means a tree of files that can be hierarchically navigated. The file system also defines attributes such as how long file names can be and rules about file extensions.
In the previous parts of this series we have been running QEMU for the ARM Integrator Virtual Platform like this:
jasona@hamlake:[arm-test]% qemu-system-arm -kernel ~/kernel/linux-188.8.131.52/arch/arm/boot/zImage -initrd arm_root.img
Todays topic for today covers the last part of the command line: -initrd arm_root.img
The -initrd argument specifies that the file arm_root.img is a ramdisk that should be mounted by the kernel during the boot. This file contains all of the directory structure that you see after you boot and login as root. To get a better feel for it, run QEMU without the -initrd and see what happens:
jasona@hamlake:[arm-test]% qemu-system-arm -kernel ~/kernel/linux-184.108.40.206/arch/arm/boot/zImage
You will see that during the boot the kernel panics because there is no filesystem to mount. For a definition of panic look at the Wikipedia page, there is even a screen shot of a Linux panic with QEMU that is similar to what you will get with our ARM Integrator platform. For computer historians it's also fun to look at all the screen shots of various kinds of failures.
Now for the format of the filesystem. There are many kinds of Linux filesystems that have developed over the years as people try to improve the way data is stored and retrieved, most of the time from disks. A common filesystem type for a Linux hard disk is ext3, this is what I have on my machine. The ARM Integrator platform does not have a hard disk so the filesystem used is ramdisk, the directory structure is stored in RAM. One aspect you will notice about a ram disk is that new files created while running are not there when you stop and restart the machine.
Now lets add a new program to the filesystem, create a new file system image file containing the new program, and start the Virtual Platform with the new filesystem so we can run the program. Remember, the filesystem is a ramdisk so this is the only way to permanently put anything in the filesystem. It's OK because the target system doesn't really have any tools to create a new program anyway.
The secret is to find out that the format of the file arm_root.img is a gzipped cpio file.
To unzip the file and see what is in the filesystem create new directory under your currently place you are running from and extract the filesystem image:
jasona@hamlake:[fs]% mkdir fs ; cd fs
jasona@hamlake:[fs]% gunzip < ../arm_root.img | cpio -ivd
Now if you do ls you will see the contents of the filesystem.
./ bin/ etc/ lib/ root/ sbin/ tmp/ usr/ init@ ../
Now let's create a new program on the filesystem in the home directory for root. In the original filesystem after login as root the directory was empty.
Go into the root directory and create a simple C program like this one using your favorite editor.
printf("hello from my new ARM Integrator program\n");
Now cross-compile the program for the ARM:
jasona@hamlake:[root]% arm-none-linux-gnueabi-gcc -o hello hello.c
Now we have 2 files on our filesystem, hello and hello.c
To run hello on the Virtual Platform create a new filesystem image and start QEMU.
Go back up to the top of the filesystem (fs directory) and write the new image, again using cpio and gzip:
jasona@hamlake:[fs]% find . | cpio -ov --format=newc | gzip > ../arm_root2.img
To run the program start QEMU with the new filesystem image and give it a try, notice the -initrd file is now arm_root2.img
jasona@hamlake:[arm-test]% qemu-system-arm -kernel ~/kernel/linux-220.127.116.11/arch/arm/boot/zImage -initrd arm_root2.img
Here's the screen shot after running the new program.
Today's post demonstrates how the kernel and the filesystem work in combination to create the software for a Virtual Platform.
Many readers may be wondering why I cover all these embedded software topics about the Virtual Platform, after all this is cadence.com, not Wind River or Monta Vista or even Microsoft. The answer is easy, the best RTL and chip-level verification engineers are those that understand how an entire chip works, including the software. In the RTL world this means that to be a top performer it's necessary to understand the software compilation flow using the cross-compiler, the memory map of the chip, how to compile a software program, generate a file that be loaded into a memory model, maybe by $readmemh and how the processor executes. As projects spend more time at higher abstraction levels to verify more software and interaction with hardware all those skills and more are needed. The Virtual Platform pulls in embedded operating systems, new ways to debug software, filesystems, and more.
Stay tuned as the series continues to learn more about the hardware portion of the Virtual Platform.
Thanks for reading.