Wednesday, August 19, 2015

Compiling a Linux Kernel for gem5

It took me a while to find a combination of versions of the Linux kernel and gcc that would boot on gem5 simulation x86, so I wanted to take some notes on the version I finally got to work.

First, you need the full system files for x86 for gem5, as explained in step 8 of this post. I'll go ahead and repost those instructions here.



  • To run in full system mode, you will need to download some more files from the gem5 website.
  • First, you'll need to download the full system files and config files for X86. They are available here: http://www.m5sim.org/Download. Extract both of these to a directory where they will live (for our example, we'll assume this directory is /home/user123/gem5-util/). They need to be in a place where gem5 can see them while they are running. When you extract these files, you will get two directories, "binaries" and "disks".
  • In the "disks" directory, there is a file called "linux-x86.img". This needs to be renamed to "x86root.img".
  • gem5 also needs a file called "linux2-bigswap.img" to be in the disks directory. The only place I've found this is in the full system files for the Alpha architecture posted on the gem5 website, here:http://www.m5sim.org/Download. Download the Alpha system files, extract them, and move the file "linux2-bigswap.img" from this package to the "disks" directory containing the file "x86root.img".
  • Now, set the environment variable M5_PATH to point to /home/user123/gem5-util (or wherever you put the "disks" and "config" directories).

Next, clone the Linux kernel repo using git.

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

The version of the kernel I've gotten to work with gem5 is 2.6.27.6, so checkout that one out.

$ git checkout v2.6.27.6.

Now, get the config files provided by gem5.

wget http://www.m5sim.org/dist/current/x86/config-x86.tar.bz2
$ tar -xjvf config-x86.tar.bz2

The only configuration I've gotten to work is "linux-2.6.22.9".

$ cp configs/linux-2.6.22.9 .config

I had to roll back to gcc-3.4.6 to get it to compile. You can get gcc-3.4.6 from here: link. I forced the kernel build system to use this version by doing:

$ ln -s <path to gcc-3.4.6> ./gcc
$ ln -s <path to gcc-3.4.6> ./g++
$ export PATH=:$PATH

Adding the colon to the beginning tells bash to look in the pwd first for programs. Now, build it.

$ make vmlinux -j

And you should be able to boot with this using gem5. It asks a bunch of questions regarding kernel configuration. I answer the default for all of them, and this works fine.

$ ./build/X86/gem5.opt ./configs/example/fs.py --cpu-type=timing \
--disk-image=<path to x86root.img> \
--kernel=<path to built vmlinux>

For a little more information on this topic, see this discussion on the gem5 mailing list: link.

Tuesday, July 7, 2015

Building a Toolchain for OR1K

I recently have started looking more into the site OpenCores.org, and came across its page on building a toolchain for OR1K.

I ran into a couple of problems when following the instructions for building the Newlib toolchain. One was this error when building stage 1 of gcc:

        "configure: error: cannot compute suffix of object files: cannot compile"

Instructions for resolving this error are given on the gcc website here. However, the tips there along with most help I found given on other sites suggest that the problem is that the locations of the MPC, MPFR, and GMP libraries are not in LD_LIBRARY_PATH. I am running Ubuntu, made sure that these libraries were installed and were in the LD_LIBRARY_PATH, and was still getting the error. I noticed that my versions of these libraries were newer than those listed in the or1k-gcc/contrib/download_prerequesites script, so I tried running it to get those versions. Unfortunately, it seems the download locations listed in that script don't exist anymore. So I downloaded the listed versions of these libraries from the projects' websites (MPC 0.8.1, MPFR 2.4.2, and GMP 4.3.2), commented out the commands from the script that downloaded the tarballs, and reran the script. After this, the building of stage 1 of gcc worked. I'll post updates here with further information that might be useful.

Saturday, June 13, 2015

Notes on Cross-compiling

A quick post with some useful links and commands:
  • Building binutils, gcc, and gdb: link.
    • See the section "Roll-your-own".
  • Page with a nice table of available targets: link.
  • Comments on examining gcc's IR with the "-fdump-tree-all" and '-fdump-rtl-all" options: link.
  • Useful clang commands.
    • Generate assembly:
      • clang -S ./helloworld.c -target x86
    • Emit LLVM intermediate code:
      • clang -S -emit-llvm ./helloworld.c -o ./helloworld.s
    • Compile LLVM intermediate code into assembly code:
      • llc -march x86 ./helloworld.s
    • Use binutils to generate object file:
      • as ./helloworld.s -o helloworld.o
    • Or gcc to generate executable:
      • gcc ./helloworld.s -o helloworld
  • Command for disassembling object file:
    • objdump -d helloworld.o
  • Command to extract text from object file:
    • objcopy -O binary --only-section=.text /path/firmware.ko /content.bin

Update 9 Aug. 2016.

I realized it could be useful to explain here how to generate a MIPS binary.

The MIPS assembly can be generated using the clang command above:
  • clang -S ./helloworld.c -target mips -o helloworld.s
To generate a MIPS binary, we can build binutils for MIPS.
  • Download latest binutils from here: link.
  • Then (assuming you are on version 2.27 of binutils):
    • tar xzvf binutils-2.27
    • mkdir build-binutils
    • cd build-binutils
    • ../binutils-2.27/configure --TARGET=mips-el-unknown-linux-gnu --prefix=<installpath>
    • make
    • make install
  • helloworld.s can be assembled like this:
    • <installpath>/mipsel-unknown-linux-gnu-as helloworld.s -o helloworld
  • You can examine the contents of the output file using the built objdump, as described above:
    • <installpath>/mipsel-unknown-linux-gnu-objdump -d helloworld
  • And extract the text:
    • <installpath>/mipsel-unknown-linux-gnu-objcopy -O helloworld --only-section=.text ./helloworld helloworld.text
Much of the above was taken from here: link.

Monday, January 12, 2015

Building Octave 3.8.2 on CentOS 6.6

I recently ran into some trouble building Octave on CentOS.  After some searching of different message boards that offered steps towards resolution that didn't solve the problem for me, I came across this post which pointed me in the right direction.

I downloaded the BLAS source from here (click the "blas.tgz" link under the section "Reference BLAS Verstion 3.5.0"), and built it using the instructions given on the post linked above

gfortran -shared -O2 *.f -o libblas.so -fPIC

As suggested by that post, pointing the configure script to the lapack build at /usr/lib64/liblapack.so.3 didn't work. Instead, it required to download the "atlas" package from the yum repos, and point the configure script to the lapack library provided with it.

A couple of additional steps were required to resolve some problems with the configure script. Namely, I had to install the readline-devel package and the qt-devel package (to allow building of the gui). The command for configuration finally was

./configure --with-blas=/home/user123/BLAS/libblas.so --with-lapack=/usr/lib64/atlas/liblapack.so.3