<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>my tech blog &#187; Microblaze</title>
	<atom:link href="http://billauer.se/blog/category/microblaze/feed/" rel="self" type="application/rss+xml" />
	<link>https://billauer.se/blog</link>
	<description>Anything I found worthy to write down.</description>
	<lastBuildDate>Thu, 12 Mar 2026 11:36:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Capture data at 250 MBytes/sec with Linux on Microblaze</title>
		<link>https://billauer.se/blog/2011/09/dma-capture-frame-grabbing-xilinx-fpga-linux-microblaze/</link>
		<comments>https://billauer.se/blog/2011/09/dma-capture-frame-grabbing-xilinx-fpga-linux-microblaze/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 23:38:53 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1898</guid>
		<description><![CDATA[The problem The Xilinx Microblaze soft processor, which is implemented on the FPGA&#8217;s logic fabric, is indeed a stable and fully capable processor, but its rather low clock frequency &#8212; 70-100 MHz on a Spartan-6 &#8212; makes it a problematic candidate for data capture and frame grabbing. When running Linux on Microblaze, the current kernel [...]]]></description>
			<content:encoded><![CDATA[<h3>The problem</h3>
<p>The Xilinx Microblaze soft processor, which is implemented on the FPGA&#8217;s logic fabric, is indeed a stable and fully capable processor, but its rather low clock frequency &#8212; 70-100 MHz on a Spartan-6 &#8212; makes it a problematic candidate for data capture and frame grabbing.</p>
<p>When running <a href="http://xillybus.com/microblaze" target="_blank">Linux on Microblaze</a>, the current kernel allows for a data rate of approximately 1 MByte/sec due to internal overhead. It appears like there&#8217;s a lack of optimization of the parts in the kernel copying data.</p>
<p>So while Linux on Microblaze is a great solution for making the FPGA talk with storage and network in a high-level manner, it suffers from a very slow I/O, rendering it useless for data capture to a network shared disk, for example.</p>
<h3>How it&#8217;s tackled</h3>
<p>Technically speaking, the solution is to capture data directly into the processor&#8217;s DDR memory using DMA. Since the 32-bit bus&#8217; frequency is the same as the processor&#8217;s, even the lower end of 70 MHz allows for a theoretic throughput of 280 MBytes/sec. In practice, the <a href="http://xillybus.com/" target="_blank">Xillybus IP core</a> has the proven capability of capturing data arriving at a continuous rate of 250 MBytes/sec, on bursts of 8 MBytes each.</p>
<h3>Keep it simple</h3>
<p>Another bonus with using <a href="http://xillybus.com/" target="_blank">Xillybus</a>, is that the data is fed into a standard asynchronous FIFO on the FPGA. There is no need to interface with Microblaze&#8217;s buses, just connect data and read enable to a FIFO. The IP core supplies additional signals for synchronizing events with the processor, but their use is optional.</p>
<p>On the Linux side, it all boils down to opening a device file, reading data normally, and closing the file. The FPGA can signal EOF (end-of-file), so making a high speed data capture can be done from the shell prompt with the &#8220;cat&#8221; or &#8220;dd&#8221; commands. There&#8217;s no need to write complicated software nor a driver. Just a single standard UNIX command, and the data is stored in a regular disk file.</p>
<p>One thing to take into account, is that even though an 8 MBytes chunk of data is captured into the processor&#8217;s RAM in a split second, the I/O operation of copying it into some other media will typically take around 8 seconds. The memory access is fast, but the processor isn&#8217;t all that so.</p>
<h3>A few technicalities</h3>
<p>A working Linux distribution for Microblaze is <a href="http://xillybus.com/microblaze-download" target="_blank">available for download</a> at Xillybus&#8217; site. While this distribution has the Xillybus IP core and kernel driver included, that version captures data at the processor&#8217;s slow rates. For an evaluation kit supporting fast data capture, please contact Xillybus directly.</p>
<p>Another thing to mention is the reason for the 8 MBytes limit: The DDR memories come in larger sizes, but DMA memory is inherently within Linux kernel space. Allocating large physically continuous segments of RAM is difficult, and doing too well on that can make the entire system unstable.</p>
<p>There is a well-known workaround for this, though: It&#8217;s possible to give the kernel a boot parameter limiting the RAM it&#8217;s allowed to access. Using this simple trick, it&#8217;s possible to use the untouched chunk as a huge buffer. This requires a simple modification on the Xillybus driver. So it&#8217;s not so difficult to allow a capture segment of any size, as long as there&#8217;s enough RAM for both the buffer and the kernel itself.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/09/dma-capture-frame-grabbing-xilinx-fpga-linux-microblaze/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Download a Linux distribution for Xilinx&#8217; Microblaze</title>
		<link>https://billauer.se/blog/2011/09/linux-fpga-distro-microblaze-spartan-xilinx/</link>
		<comments>https://billauer.se/blog/2011/09/linux-fpga-distro-microblaze-spartan-xilinx/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 21:22:42 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1871</guid>
		<description><![CDATA[If you want to get to it, just go to the Xillybus mini-distro for Microblaze&#8217;s page. This distribution is a software kit, which allows you to run a functional Linux system on the SP605 or ML605 hardware evaluation kit (for Spartan-6 and Virtex-6, respectively). All components necessary to build it will be available for download [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to get to it, just go to the <a href="http://xillybus.com/microblaze">Xillybus mini-distro for Microblaze&#8217;s page</a>.</p>
<p>This distribution is a software kit, which allows you to run a  functional Linux system on the SP605 or ML605 hardware evaluation kit (for Spartan-6 and Virtex-6, respectively). All  components necessary to build it will be available for download at no cost (partly from Xilinx’ site). The distribution is not a demo kit; it&#8217;s a kickstart for a real-life application.</p>
<p>The steps to reaching a functional system include installing pieces  of software, and perform specific and rather trivial operations as described in detail. No  prior knowledge on either FPGA nor Linux is necessary. Your computer may  run either Windows or Linux for running this through.</p>
<p>This distribution will allow you to</p>
<ul>
<li>Run a Linux system which is ready for working with, including a DHCP  client, telnet, ftp, a small web server, mounting of NFS as well as  Windows (SMB) shares. The CompactFlash card will also serve as the local  disk which can be written to.</li>
<li>Easily compile your own user-space applications in with &#8220;make&#8221; and gcc (a ready-to-go cross-compilation environment will be available for download as well). Compilation is possibly dynamic against libraries which are part of the distro.</li>
<li>Easily develop your own Linux-reachable peripherals on the FPGA  using the Xillybus IP core, and transport data between the FPGA and  Linux user space applications with minimal effort.</li>
</ul>
<h3>Required hardware</h3>
<ul>
<li>A Xilinx <a href="http://www.xilinx.com/products/boards-and-kits/EK-S6-SP605-G.htm" target="_blank">SP605 evaluation kit</a> or <a href="http://www.xilinx.com/products/boards-and-kits/EK-V6-ML605-G.htm" target="_blank">ML605 ditto</a>.</li>
<li>A  Sandisk CompactFlash card, with at least 512 MB. Let me emphasize  this:  Make it a Sandisk card, and not anything else. You may get away  with  using other cards for a one-off loading with data and multiple  reads,  but the Linux system is going to use this storage as its hard  disk.  Anything else than Sandisk, including the card which comes with  the  evaluation kit itself, is most likely to have reliability problems,   which will give you a very wrong impression regarding the Linux  system’s  stability. Believe me, I’ve tried quite a few. Also, try to  make the  card not bigger than 8 GB, as the SysACE chip’s support of  larger cards  is questionable.</li>
<li>A CompactFlash to USB adapter. There is no  special requirements  here, as long as your operating system recognizes  it, and it’s  reliable. Which holds true even for those cheap universal  card readers  available on Ebay.</li>
</ul>
<p>As mentioned above, this is in the <a href="http://xillybus.com/microblaze">Xillybus mini-distro for Microblaze&#8217;s page</a>.</p>
<div id="_mcePaste" class="mcePaste" style="position: absolute; left: -10000px; top: 229px; width: 1px; height: 1px; overflow: hidden;">
<h3>Required hardware</h3>
<p>Before starting, please make sure you have the following equipment:</p>
<ul>
<li>A Xilinx <a href="http://www.xilinx.com/products/boards-and-kits/EK-S6-SP605-G.htm" target="_blank">SP605 evaluation kit</a> (hardware).</li>
<li>A  Sandisk CompactFlash card, with at least 512 MB. Let me emphasize  this:  Make it a Sandisk card, and not anything else. You may get away  with  using other cards for a one-off loading with data and multiple  reads,  but the Linux system is going to use this storage as its hard  disk.  Anything else than Sandisk, including the card which comes with  the  evaluation kit itself, is most likely to have reliability problems,   which will give you a very wrong impression regarding the Linux  system’s  stability. Believe me, I’ve tried quite a few. Also, try to  make the  card not bigger than 8 GB, as the SysACE chip’s support of  larger cards  is questionable.</li>
<li>A CompactFlash to USB adapter. There is no  special requirements  here, as long as your operating system recognizes  it, and it’s  reliable. Which holds true even for those cheap universal  card readers  available on Ebay.</li>
</ul>
<h3>Files to download</h3>
<ul>
<li>The CompactFlash image</li>
<li>The FPGA bundle</li>
</ul>
<h3>Downloading and installing the Xilinx EDK</h3>
<p>Unless  you already have Xilinx’ ISE Design suite with version 13.2  or above,  you’ll need to download the installation image. If you don’t  have the  Embedded version, you’ll need to acquire a license.</p>
<p>The magnitude of the downloaded file is 4-5 GB, so kick this off as soon as possible. To do so:</p>
<ul>
<li>Navigate to Xilinx website at <a href="http://www.xilinx.com/" target="_blank">http://www.xilinx.com/</a>,   and register as a new user if you don’t have an account on the site.   You’ll need to provide a valid password, as well as other details about   yourself. Xilinx allows access to file downloads only to registered   users.</li>
<li>Once logged in, navigate yourself to the page for download the ISE design suite (possibly <a href="http://www.xilinx.com/support/download/index.htm" target="_blank">this page</a>).   It’s best to download version 13.2, since the Xillybus bundle was   successfully built with it. But it’s most likely OK to use newer   versions. There is no need to request the Embedded suite at this point,   since the same chunk is downloaded for all versions. The feature set is   determined by the license, which is acquired later on. The software is   available for Windows as well as Linux.</li>
<li>Once downloaded,  install the software, following the instructions.  This takes around an  hour, and eats up some 15 GB of your disk. On  Windows installations,  it’s possible and common to divert from the  default installation path in  favor of one which doesn’t contain white  spaces, and possibly on a  non-C: partition. Installing on a network  drive is not recommended, as  it will slow down operation significantly.</li>
<li>The installation  wizard will suggest acquiring a license. Choose a  30-day evaluation of  the Embedded Edition of the ISE Design Suite.  Follow the wizard’s  instructions, which may vary, depending on your  computer’s  configuration. Note that license issues can be handled after  the  software is completely installed. On Windows, go to Start &gt;  Programs  &gt; Xilinx ISE Design Suite 13.2 &gt; Accessories &gt; Manage  Xilinx  Licenses.</li>
</ul>
<p class="postmetadata">Posted in <a title="View all posts in To xillybus site" rel="category" href="http://10.1.1.2:82/localblog/?cat=3">To xillybus site</a> | <a class="post-edit-link" title="Edit post" href="http://10.1.1.2:82/localblog/wp-admin/post.php?action=edit&amp;post=52">Edit</a> |   <a title="Comment on Download the Linux for Microblaze mini-distro" href="http://10.1.1.2:82/localblog/?p=52#respond">No Comments »</a></p>
<div id="post-40" class="post hentry category-to-xillybus-site">
<h2><a title="Permanent Link to Compiling applications" rel="bookmark" href="http://10.1.1.2:82/localblog/?p=40">Compiling applications</a></h2>
<p><small>September 13th, 2011 </small></p>
<div class="entry">
<p>C and C++ programs can be compiled easily to run on the  Microblaze Linux platform. The binaries are dynamically linked against  libraries, which are part of the mini-distro. This includes the  well-known basic libraries such as glibc and libm, as well as libcrypt,  libpthread, libresolv and several others (just list the files in the  distro’s /lib for all of them).</p>
<p>To get started immediately, just download the application  cross-compilation tarball. Open it anywhere on a Linux computer’s file  hierarchy (no superuser access is necessary) and you’re ready to go  right away. There is no “installation” necessary.</p>
<p>This package runs on 32-bit Linux as well as 64-bit. A suitable cross compiler for Windows is currently not available.</p>
<p>The cross compilation package has three subdirectories: gnutools,  example1 and example2. The gnutools subdirectory contains the GNU cross  compiler, libraries and utilities. There is no need to look under the  hood here.</p>
<p>The two other subdirectories each consist of a Makefile and a sample  file to compile. Just change directory to either of them, and type  “make” at shell prompt to compile an executable which runs on the  platform under Linux.</p>
<p>These are templates for compiling real applications. We’ll look at the Makefile in the example1 subdirectory:</p>
<pre>GNUPREFIX=../gnutools/microblazeel-unknown-linux-gnu/bin/microblazeel-unknown-linux-gnu-

CC=$(GNUPREFIX)gcc
AR=$(GNUPREFIX)ar
AS=$(GNUPREFIX)as
CXX=$(GNUPREFIX)g++
LD=$(GNUPREFIX)ld
STRIP=$(GNUPREFIX)strip

CFLAGS=-Wall -I. -O3

APPLICATION=hello

OBJECTS=#somefile.o somefile2.o etc

all: $(APPLICATION)

$(APPLICATION): $(OBJECTS) $(APPLICATION).o
	$(CC) $(CFLAGS) $(OBJECTS) $(APPLICATION).o -o $(APPLICATION)

clean:
	rm -f *~ $(APPLICATION) *.o</pre>
<p>The first line sets the internal variable GNUPREFIX. It’s given as a  relative path to the gnutools directory. This is done to make the bundle  run out of the box, but it’s also possible to decide on a certain  absolute path for the gnutools, and then set GNUPREFIX accordingly.</p>
<p>The CC, AR, AS, CXX, LD and STRIP variables are set so that GNU Make calls the cross compiler rather than the native compiler.</p>
<p>CFLAGS are the flags given to gcc on compilation. In particular,  library dependencies go here. For example and as shown in the example2  subdirectory, if mathematical functions such as sin() are used, the  “-lm” flag should be added here.</p>
<p>APPLICATION is the name of the final executable. It’s set here to  “hello” so a C source file hello.c is expected to have the main()  function.</p>
<p>OBJECTS is a space-delimited list of object targets: If the  applications is divided into several source files, each should be listed  here with the “.c” suffix replaced by “.o”.</p>
<p>The rest of the Makefile sets the targets, so that “make” and “make clean” work properly.</p>
<p>So all in all, this Makefile can be used to compile a fullblown software application targeted for the platform.</p>
</div>
<p class="postmetadata">Posted in <a title="View all posts in To xillybus site" rel="category" href="http://10.1.1.2:82/localblog/?cat=3">To xillybus site</a> | <a class="post-edit-link" title="Edit post" href="http://10.1.1.2:82/localblog/wp-admin/post.php?action=edit&amp;post=40">Edit</a> |   <a title="Comment on Compiling applications" href="http://10.1.1.2:82/localblog/?p=40#respond">No Comments »</a></p>
</div>
<div id="post-32" class="post hentry category-to-xillybus-site">
<h2><a title="Permanent Link to File system" rel="bookmark" href="http://10.1.1.2:82/localblog/?p=32">File system</a></h2>
<p><small>September 10th, 2011 </small></p>
<div class="entry">
<h3>File system structure</h3>
<p>The file system should look familiar to anyone who is at home with  Linux/UNIX systems. Since embedded systems tend to get shut off  accidentally, an effort has been made to keep essential files in  filesystems mounted read-only. This goes for the root filesystem as well  as the small FAT16 from which the System ACE chip reads the initial  boot data. While these can be remounted for read-write, this should be  avoided. Instead, a special partition has been set up for allowing write  access. Files which are normally altered in the root filesystems have  been replaced by symbolic links, as detailed below.</p>
<p>Users who have chosen a non-Sandisk CompactFlash should be advised  that mounting a filesystem for write carries a significant chance of  making it unmountable in the future, as repeated writes to system blocks  may push a low-end flash device beyond its reliability.</p>
<p>The CompactFlash has been assigned three partitions:</p>
<ul>
<li>Primary partition 1 (/dev/xsa1, 47MB). Configured as FAT16, and is  intended to hold the xillybus.ace file, from which the System ACE chip  configures the FPGA. Mounted read-only by default as /mnt/fat16 (or  /rw/system/mnt/fat16, to be accurate).</li>
<li>Primary partition 2 (/dev/xsa2, 205MB). This ext2 partition is used as the root filesystem, and is mounted read-only by default.</li>
<li>Primary partition 3 (/dev/xsa3, 91MB). This ext2 partition is used  for anything that needs to be written into the CompactFlash under normal  operation. It’s mounted read-write by default at /rw.</li>
</ul>
<p>The following files in the root filesystem are symbolic links:</p>
<ul>
<li>/mnt to /rw/system/mnt — This allows creation of subdirectories on  /mnt, and mounting /mnt/something. Unmounting is somewhat trickier,  because the system knows the mount point by its full path, so for  unmounting the full name, e.g. /rw/system/mnt/something must be used. Or  the name of the device file, when applicable.</li>
<li>.ash_history to /rw/system/.ash_history</li>
<li>/etc/httpd.conf to /rw/system/httpd.conf</li>
<li>/etc/resolv.conf to /rw/system/resolv.conf — This allows the DHCP  client to set up the DNS server list, despite the root file system being  unmounted.</li>
</ul>
<p>When necessary to write to the root partition, it can be remounted for read-write as follows:</p>
<pre># mount -o remount,rw /</pre>
<p>And for the FAT16 partition:</p>
<pre># mount -o remount,rw /dev/xsa3</pre>
<p>It’s recommended to remount them back as read-only as soon as  possible after finishing whatever was needed to be done with them. For  example, to remount the root partition back to read-only, go</p>
<pre># mount -o remount,ro /</pre>
<p>And he FAT16 partition:</p>
<pre># mount -o remount,ro /dev/xsa3</pre>
<h3>Shutting down the system</h3>
<p>Before powering down the card, the Linux system should be shut down  properly, or problems may occur on the next reboot. The command for  doing this is “halt”:</p>
<pre># halt</pre>
<p>This runs a small script, which attempts to remount all partitions on  the CompactFlash as read-only before running shutting down. If some  process in the system has a file open for write, this will fail. In this  case, use “ps” to track down the process, and possibly kill it (or kill  -9) so that the filesystem can be released.</p>
<h3>Execution environment</h3>
<p>The Linux distribution has the basic set of libraries for dynamic  linking, so basic applications can run on the platform just like on any  Linux machine.</p>
<p>Even so, the lightweight busybox suite supplies all UNIX command-line utilities. Please consult busybox’ <a href="http://linux.die.net/man/1/busybox" target="_blank">command summary</a> to get a summary of the commands and their usage. Note that the  installed version of busybox is v1.17.1, so the web site may reflect  newer version (with possibly unsupported utilities). Type “busybox” at  command prompt on the platform to get a full list of commands.</p>
<h3>Custom rc file</h3>
<p>When booting up, the script checks for the existence of an executable  file at /rw/system/userrc. If such file exists, it’s run as the last  stage of the boot process. This file can be used to e.g. set up  networking automatically.</p>
<p>The file is run “as is”. If it’s a script, it must have a #!  (shebang) header. It can also be an executable binary. Either way, don’t  forget to set the executable flag for it, or it will be ignored.</p>
<p>For example, to make the platform available on the LAN with a constant address 10.12.14.16, /rw/system/userrc should read:</p>
<pre>#!/bin/sh  

ifconfig eth0 10.12.14.16 netmask 255.0.0.0</pre>
<p>and made executable:</p>
<pre>/ # chmod a+x /rw/system/userrc</pre>
<p>Note that the platform can also get an address with DHCP. See the section about networking.</p>
</div>
<p class="postmetadata">Posted in <a title="View all posts in To xillybus site" rel="category" href="http://10.1.1.2:82/localblog/?cat=3">To xillybus site</a> | <a class="post-edit-link" title="Edit post" href="http://10.1.1.2:82/localblog/wp-admin/post.php?action=edit&amp;post=32">Edit</a> |   <a title="Comment on File system" href="http://10.1.1.2:82/localblog/?p=32#respond">No Comments »</a></p>
</div>
<div id="post-22" class="post hentry category-to-xillybus-site">
<h2><a title="Permanent Link to Setting up network" rel="bookmark" href="http://10.1.1.2:82/localblog/?p=22">Setting up network</a></h2>
<p><small>September 8th, 2011 </small></p>
<div class="entry">
<h3>Networking</h3>
<p>Connecting the card to a LAN is recommended. The Linux machine boots  up with servers supporting telnet, ftp and CGI-enabled http (meaning  that the card can be accessed with a web browser). On top of this, it’s  possible to mount shared folders from both Linux and Windows machines.  This is very convenient when developing applications, as there’s no need  to copy the files back and forth from and to a fullblown computer to  the embedded platform.</p>
<p>Please note that by enabling networking on the card, you expose it to   complete control by anyone who can access it. Anyone with access to  its  network interface can gain superuser access to it without supplying  any  credentials whatsoever. This is usually not a concern when the  card is  run on an internal LAN, since the latter is usually behind a  firewall  preventing requests from the outer world. Nevertheless, it’s  important  to realize that the card comes with zero networking security  (even  though it’s possibly to take security measures on this platform).</p>
<h3>Setting up Ethernet with DHCP</h3>
<p>If there’s a DHCP server available, simply type “dhcp” at shell prompt. When successful, it typically looks like this:</p>
<pre>/ # dhcp
udhcpc (v1.17.1) started
Sending discover...
PHY: c0729a0c:07 - Link is Up - 100/Full
Sending discover...
Sending select for 10.12.14.16...
Lease of 10.12.14.16 obtained, lease time 21600
deleting routers
route: SIOCDELRT: No such process
adding dns 10.0.0.1
adding dns 10.0.0.2
/ # eth0: no IPv6 routers present</pre>
<p>If the DHCP server offers addresses to DNS servers, they will be used as well.</p>
<h3>Setting up Ethernet manually</h3>
<p>The network can be set up manually with an ifconfig command as well.  For example, to assign the card an IP address of 10.12.14.16 with net  mask 255.0.0.0:</p>
<pre>/ # ifconfig eth0 10.12.14.16 netmask 255.0.0.0</pre>
<p>To access computers beyond the LAN, a gateway must be specified. Note  that by adding this gateway, the card becomes accessible to attackers  from the whole internet, which it wouldn’t be otherwise (because it  couldn’t establish a connection beyond the LAN).</p>
<p>Having that said, if the gateway is at 10.11.12.13, it’s declared with</p>
<pre>/ # route add default gw 10.11.12.13</pre>
<p>The gateway address must be within the previously given net mask, of course.</p>
<p>To set up DNS servers, edit /etc/resolv.conf as appropriate.</p>
<h3>telnet, ftp and web server</h3>
<p>Once the network is set up as shown above, connect to the platform  with telnet and ftp as usual. No username or password are required for  the telnet connections, and neither are they necessary for ftp. The  connecting ftp application may prompt the user for these, but they are  ignored by the platform; just supply anything you like.</p>
<p>To access the platform as a web server, simply open your browser and  type e.g. http://10.11.12.13/ on the address bar. The IP should be  adjusted to the one assigned to the platform, of course.</p>
<p>The platform can also contact servers with wget (possibly download  web pages as well as data from ftp servers). ftpget and ftpput are  simple ftp clients. Anyhow, it’s usually easier let the platform be the  server as modern full-blown computers generally don’t have these  services, as they’re problematic in terms of security.</p>
<p>When more than a single occasional file transfer is necessary, it’s wiser to mount a share, as described next.</p>
<h3>Accessing shared folders over the network</h3>
<p>The Linux kernel is configured to support network filesystem shares.  Both UNIX/Linux NFS as well as Window’s SMB are supported, so files may  be read and written to both UNIX and Windows computers.</p>
<p>Connection to a windows computer at 10.11.12.13, with the share name  “mydisk”, Windows user name “theuser” and password “thepass” goes</p>
<pre># mount -o user=theuser,password=thepass //10.11.12.13/mydisk /mnt/try</pre>
<p>(assuming that /mnt/try exists).</p>
<p>To mount an NFS share:</p>
<pre># mount 10.11.12.13:/thedir -o nolock,proto=tcp /mnt/try</pre>
<p>The nolock option is crucial here. Without it, the mount simply   hangs. But without the proto=tcp part, there’s a good chance that the   NFS connection will hang sooner or later. In short use both.</p>
<h3>Accessing files on the CompactFlash</h3>
<p>Remounting / for read/write</p>
<pre>/ # mount -o remount,rw /</pre>
</div>
<p class="postmetadata">Posted in <a title="View all posts in To xillybus site" rel="category" href="http://10.1.1.2:82/localblog/?cat=3">To xillybus site</a> | <a class="post-edit-link" title="Edit post" href="http://10.1.1.2:82/localblog/wp-admin/post.php?action=edit&amp;post=22">Edit</a> |   <a title="Comment on Setting up network" href="http://10.1.1.2:82/localblog/?p=22#respond">No Comments »</a></p>
</div>
<div id="post-17" class="post hentry category-to-xillybus-site">
<h2><a title="Permanent Link to Flow outline of docs" rel="bookmark" href="http://10.1.1.2:82/localblog/?p=17">Flow outline of docs</a></h2>
<p><small>September 8th, 2011 </small></p>
<div class="entry">
<h3>General flow</h3>
<p>Make the documentation page list out the recommended flow for reading</p>
<h3>Microblaze docs</h3>
<p>As follows:</p>
<ul>
<li>Equipment: Sandisk CF, USB adapter</li>
<li>Using the Flash image to load the flash (Windows and Linux, Windows recommended)</li>
<li>Building the FPGA subsystem (downloading ISE, picking the project, creating bitfile and ACE)</li>
<li>Storing the ACE file in the Compact Flash</li>
<li>Booting: What to expect. Connecting Hyperterminal</li>
<li>The license: Use as is with no restriction, changes in FPGA using Xillybus for evaluation or licensed.</li>
<li>Setting up network (with DHCP and without)</li>
<li>Accessing files: NFS mount, SMB mount, files on CF (FAT and extra partition), remounting root as rw.</li>
<li>Compiling applications (hopefully with Xilinx’ compiler)</li>
<li>Trying out Xillybus, of course</li>
</ul>
<h3>General flow</h3>
<ul>
<li>The main page stays as is. Where applicable, Microblaze is added to where it says PCIe.</li>
<li>The docs are separated into two tabs in the main header (will be three): PCIe and Microblaze</li>
<li>The main image to be edited to represent the situation better. Maybe a penguin instead of computer.</li>
<li>An extra taxonomy term added for each page, which may be empty. It  signifies specific-to: If one of its values is assigned, related pages  must also have the same value. This will avoid mixing up pages for  different pages. Some indication on each page may also be added.</li>
<li>The download page is split into the main one (what to expect) and a separate download page for PC and Microblaze.</li>
</ul>
</div>
<p class="postmetadata">Posted in <a title="View all posts in To xillybus site" rel="category" href="http://10.1.1.2:82/localblog/?cat=3">To xillybus site</a> | <a class="post-edit-link" title="Edit post" href="http://10.1.1.2:82/localblog/wp-admin/post.php?action=edit&amp;post=17">Edit</a> |   <a title="Comment on Flow outline of docs" href="http://10.1.1.2:82/localblog/?p=17#respond">No Comments »</a></p>
</div>
<div id="post-3" class="post hentry category-uncategorized">
<h2><a title="Permanent Link to Making money online: Get real" rel="bookmark" href="http://10.1.1.2:82/localblog/?p=3">Making money online: Get real</a></h2>
<p><small>June 2nd, 2009 </small></p>
<div class="entry">
<h3>Money for nothing: Is it really possible?</h3>
<p>Been there, done that: Offers to work from home. Become a billionaire  in a minute. Or just making a whole lot of money without moving from  your chair. The obvious scams are easy to tell: Buy this book and get  rich! Join now, but you just need to pay this little fee (NOW! NOW!).  What are a few dollars compared with the millions waiting for you?</p>
<p>It doesn’t work, of course. Some of these offers are nothings but  scams, others make it sound so much easier than it is. Affiliate  marketing, for example. There are zillions of surfers out there. How  difficult could it be to make a million of them click on a banner?</p>
<p>And then we have these pyramids. They call it “referral marketing”  but the bottom line is that you get the money your friends wasted. Which  works pretty well, if you have a lot of people around you, who  mistakenly considers you their friend.</p>
<p>Money doesn’t grow on trees, we’ve all been told. And still some  people manage to get it easier than others. What’s their secret?</p>
<h3>The key word is opportunity</h3>
<p>Everyone who has tried to earn some extra money online will  eventually tell you, that there are no free meals out there. The simple  rule of supply and demand tells us, that if a deal is too attractive, it  will soon balance itself towards am lower equilibrium point. So if  someone paid more than the minimum to get the job done, the payment will  soon fall as a result of overwhelming demand. Pure business logic means  to give away as much as necessary, but not more.</p>
<p>When this logic breaks, we call it an opportunity. It’s when we are  offered a deal which may look problematic, but has a potential. It’s a  low price for something we’re not so sure about. The difference between a  successful businessman and an eternal loser is the whether he can tell  an opportunity from a waste of money and time. Some are better at it  than others. But we all enjoy those opportunities in our real lives from  time to time. It’s now time to do that online as well.</p>
<h3>Where you can get a free meal for real</h3>
<p>In our real lives, the opportunity to get something for free comes  when a new business wants to hit the market. If you know someone who has  just opened a restaurant or pub, you’re likely to be offered a free  meal literally, just so the place won’t look empty. If you just walk by a  new place, someone may approach you with a sincere and good deal.  Nobody is playing a trick here; it’s taking advantage of a temporary  situation.</p>
<p>The internet is no different. The opportunities are found where  things start off. Once a web business reach cruise level, all you can  hope for is to get a modest payment for your work. Or possibly use it as  a platform for tricking money out of other people. Unless you’re very  lucky in some lottery or sweepstakes.</p>
<h3>A real online opportunity</h3>
<p><a href="http://10.1.1.2:82/" target="_blank">Editaste </a>started  off on June 1st 2009 with a competition between editions. What an  edition is, and all the other details about the competition itself are  given at the site itself, so we’ll stick to the basic facts here: The  site will hand out prizes to three winners <strong>every month</strong>,  starting from August 1st. The top prize is a reasonable sum of $20 (via  Paypal), which may not sound so much, but the way competition works,  whoever wins once, has a good chance to keep that position. Starting off  early is  important.</p>
<p>In order to participate, you’ll start an edition of your own, which  is a bit like a blog, but you don’t have to be good at writing to have  one. Instead, you need a good eye for things you can find on the web:  Youtube clips, items from the news, or anything else one you watch with  your browser. The whole idea is to collect these things (more or less  clicking a button), and make this collection so good, that other people  will subscribe to your edition, and check it out on a regular basis. If  you’re on the web a lot anyhow, this is almost no extra effort.</p>
<p>The competition is about who manages to get the maximal number of  regular readers. Your readers will see a fast-loading and simple  interface with no hassle at all. Except for a few non-intrusive Google  ads, all they’ll see is what you’ve picked for them. If you pick nice  things for them, they’ll love it. And they’ll come back for more. In the  end of the month, you have more of them than others, and there comes a  nice sum through Paypal. It’s not like you did some real work for this. <a href="http://10.1.1.2:82/" target="_blank">Want to try</a>?</p>
<h3>It’s not a pyramide</h3>
<p>Most bring-your-friend offers involve a catch. Referral networks tend  to ask you for a small startup fee and also from those you invite. They  pay you with part of their money. In the end, there are some hard  feelings, usually directed upwards in the pyramide. With yourself  somewhere in the middle.</p>
<p>Not with Editaste. To begin with, there are no fees at all. And  second, nobody you invite is going to be asked to do anything, except  for to register. All they do is enjoy your picks. It doesn’t matter if  they click the ads or not. All that matters is if they click what <strong>you </strong>brought to them. They win, you win. There is really no catch here.</p>
<h3>The wagon is rolling</h3>
<p>As with any opportunity, it’s temporary. Right now, if you start your  edition, you’ll get an irreversible advantage: time and experience.  Exactly like you’re hesitating right now, so is everybody else. Being  first means making the move where others wait. No good opportunity  looked good when it was there to be taken. It’s only afterwards that  people realize that they had the chance, but missed it.</p>
<p>Besides, there is nothing to lose. You’re not asked to pay anything.  If the absolute worst case, you’ll find that you’ve spent an  unsignificant amount of time to collect nice things for others. That, in  itself, isn’t so bad even if it’s not your intention.</p>
<p><strong>Do you want to win? Don’t wait. <a href="http://10.1.1.2:82/">Start your edition now and get a head start</a>!</strong></p>
</div>
<p class="postmetadata">Posted in <a title="View all posts in Uncategorized" rel="category" href="http://10.1.1.2:82/localblog/?cat=1">Uncategorized</a> | <a class="post-edit-link" title="Edit post" href="http://10.1.1.2:82/localblog/wp-admin/post.php?action=edit&amp;post=3">Edit</a> |   <a title="Comment on Making money online: Get real" href="http://10.1.1.2:82/localblog/?p=3#respond">No Comments »</a></p>
</div>
<div id="post-1" class="post hentry category-uncategorized">
<h2><a title="Permanent Link to Hello world!" rel="bookmark" href="http://10.1.1.2:82/localblog/?p=1">Hello world!</a></h2>
<p><small>June 2nd, 2009 </small></p>
<div class="entry">
<p>Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!</p>
</div>
<p class="postmetadata">Posted in <a title="View all posts in Uncategorized" rel="category" href="http://10.1.1.2:82/localblog/?cat=1">Uncategorized</a> | <a class="post-edit-link" title="Edit post" href="http://10.1.1.2:82/localblog/wp-admin/post.php?action=edit&amp;post=1">Edit</a> |   <a title="Comment on Hello world!" href="http://10.1.1.2:82/localblog/?p=1#respond">No Comments »</a></p>
</div>
<div id="sidebar">
<ul>
<li>
<form id="searchform" action="http://10.1.1.2:82/localblog/" method="get">
<div>
<input id="s" name="s" type="text" /></div>
</form>
</li>
<li class="pagenav">
<h2>Pages</h2>
<ul>
<li class="page_item page-item-2"><a title="About" href="http://10.1.1.2:82/localblog/?page_id=2">About</a></li>
</ul>
</li>
<li>
<h2>Archives</h2>
<ul>
<li><a title="September 2011" href="http://10.1.1.2:82/localblog/?m=201109">September 2011</a></li>
<li><a title="June 2009" href="http://10.1.1.2:82/localblog/?m=200906">June 2009</a></li>
</ul>
</li>
<li class="categories">
<h2>Categories</h2>
<ul>
<li class="cat-item cat-item-3"><a title="View all posts filed under To xillybus site" href="http://10.1.1.2:82/localblog/?cat=3">To xillybus site</a> (7)</li>
<li class="cat-item cat-item-1"><a title="View all posts filed under Uncategorized" href="http://10.1.1.2:82/localblog/?cat=1">Uncategorized</a> (2)</li>
</ul>
</li>
<li id="linkcat-2" class="linkcat">
<h2>Blogroll</h2>
<ul class="xoxo blogroll">
<li><a href="http://wordpress.org/development/">Development Blog</a></li>
<li><a href="http://codex.wordpress.org/">Documentation</a></li>
<li><a href="http://wordpress.org/extend/plugins/">Plugins</a></li>
<li><a href="http://wordpress.org/extend/ideas/">Suggest Ideas</a></li>
<li><a href="http://wordpress.org/support/">Support Forum</a></li>
<li><a href="http://wordpress.org/extend/themes/">Themes</a></li>
<li><a href="http://planet.wordpress.org/">WordPress Planet</a></li>
</ul>
</li>
<li>
<h2>Meta</h2>
<ul>
<li><a href="http://10.1.1.2:82/localblog/wp-admin/">Site Admin</a></li>
<li><a href="http://10.1.1.2:82/localblog/wp-login.php?action=logout&amp;_wpnonce=dab9763809">Log out</a></li>
<li><a title="This page validates as XHTML 1.0 Transitional" href="http://validator.w3.org/check/referer">Valid <abbr title="eXtensible HyperText Markup Language">XHTML</abbr></a></li>
<li><a href="http://gmpg.org/xfn/"><abbr title="XHTML Friends Network">XFN</abbr></a></li>
<li><a title="Powered by WordPress, state-of-the-art semantic personal publishing platform." href="http://wordpress.org/">WordPress</a></li>
</ul>
</li>
</ul>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/09/linux-fpga-distro-microblaze-spartan-xilinx/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Microblaze + Linux: Sample design of a custom peripheral</title>
		<link>https://billauer.se/blog/2011/08/microblaze-custom-ip-peripheral-axi4-cip-ipwiz/</link>
		<comments>https://billauer.se/blog/2011/08/microblaze-custom-ip-peripheral-axi4-cip-ipwiz/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 16:07:22 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1755</guid>
		<description><![CDATA[Scope Even though Xilinx supplies a cute wizard for creating peripherals in its EDK (version 13.2 in my case), it&#8217;s just enough to work as a demo. For a real-life case there&#8217;s no escape from getting down to the system&#8217;s guts. As it turns out, things are pretty well organized under EDK&#8217;s hood, which makes [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xillybus.com" target="_blank"><img class="aligncenter size-full wp-image-1397" style="margin-bottom: 50px;" src="https://billauer.se/blog/wp-content/uploads/2011/08/image2.jpg" alt="" width="536" height="248" /></a></p>
<h3>Scope</h3>
<p>Even though Xilinx supplies a cute wizard for creating peripherals in its EDK (version 13.2 in my case), it&#8217;s just enough to work as a demo. For a real-life case there&#8217;s no escape from getting down to the system&#8217;s guts. As it turns out, things are pretty well organized under EDK&#8217;s hood, which makes the attempt to cover it all up with a wizard even more questionable.</p>
<p>This post is a jot-down of the technicalities behind designing a minimal bare-boned peripheral and its Linux driver. With &#8220;bare-boned&#8221; I mean that it has the absolutely simplest bus interface (AXI4 Lite without even decoding the addresses), and that it&#8217;s in pure Verilog. No external IP is used.</p>
<p>This peripheral connects to the SP605&#8242;s four LEDs. Any write to its address region updates the LED&#8217;s state according to the written value&#8217;s four LSBs. Reading back from any of its covered addresses gives the four LSBs back. That&#8217;s all.</p>
<h3>Sources of information</h3>
<p>This post assumes that you&#8217;re familiar with running Linux on Microblaze. I have a <a title="Linux on Microblaze HOWTO (part I)" href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/" target="_blank">pretty extensive tutorial</a> on the subject for reference.</p>
<p>These are worth to look at:</p>
<ul>
<li>The official cores&#8217; sources (in  VHDL) can be found at  ISE_DS\EDK\hw\XilinxProcessorIPLib\pcores (path  from where ISE is installed). It&#8217;s interesting in  particular to look at  axi_lite_ipif_v1_00_a.</li>
<li>The AMBA AXI protocol specification, downloaded free from <a href="https://silver.arm.com/download/download.tm?pv=1074011" target="_blank">ARM&#8217;s site</a>.</li>
<li>Platform  Specification Format Reference Manual (UG642, psf_rm.pdf): Describes  the file formats in detail. Necessary when editing the files.</li>
<li>EDK  Concepts, Tools, and Techniques (UG683, edk_ctt.pdf) : The chapter  about Creating Your Own Intellectual Property is somewhat helpful to try  out the Wizard.</li>
</ul>
<h3>Understanding the process</h3>
<p>It looks like the missing link in Xilinx&#8217; documentation is to explain how the whole machinery works with regard to adopting a custom made peripheral. I&#8217;ll try to fill in that gap now.</p>
<p>Generally speaking, the minimal core consists of the following files, which should be in a dedicated directory under the &#8220;pcores&#8221; directory, which is under the EDK project&#8217;s top directory:</p>
<ul>
<li>data/minimal_v2_1_0.mpd: This file is what EDK looks at when an IP is added to a project. It contains all the information used directly by the EDK. The peripheral&#8217;s GUI is set up according to this information, and it&#8217;s also used when the EDK generates wrappers and connections for it. Its format is well documented, but it looks like it&#8217;s easier to just copy snippets from existing core&#8217;s MPD files. It&#8217;s also possible to generate this file automatically with PsfUtility from the toplevel source file, but it&#8217;s not clear if it&#8217;s worth the effort to learn yet another tool.</li>
<li>data/minimal_v2_1_0.pao: This file supplies EDK with a list of HDL files which need to be synthesized to create the peripheral. It also sets the order of synthesis.</li>
<li>hdl/verilog/minimal.v: The Verilog file constituting the peripheral. Of course there may be several files, which need to be mentioned in the PAO file.</li>
<li>Note that &#8220;black box&#8221; modules (presynthesized netlists) are listed in BBD files, which are not necessary in this example. When used, the MPD file is set to reflect this.</li>
</ul>
<p>The file names above relate to a peripheral called &#8220;minimal&#8221;. They change according to the project&#8217;s setting and version numbers.</p>
<p>All in all, the flow is pretty simple: Only the MPD file is considered by EDK, and only at platform netlist generation are the HDL files synthesized according to the PAO file. The instantiation and connection depend on the settings within the EDK (actually, the MHS file).</p>
<p>It&#8217;s easiest to create just any peripheral with the wizard, see what they do, and then modify the files.</p>
<h3>Going from Wizard&#8217;s output to minimal peripheral</h3>
<p>This is a short outline of the stages. The result is given in the next section.</p>
<ul>
<li>Edit the data/*.pao file: Remove all files and insert the single Verilog file, changing the type to verilog.</li>
<li>In  the data/*.mpd file, change OPTION HDL = VHDL to VERILOG too. Also add,  under ##ports, PORT minimal_leds = &#8220;&#8221;, DIR = O, VEC = [3:0] (so that  the I/O port is known. Note the =&#8221;" part).</li>
<li>Remove data/*.prj file  so no unnecessary files are included (even though this file seems to be ignored).</li>
<li>Roughly translate the VHDL file to Verilog. Make it Verilog parameters instead of VHDL generics.</li>
<li>Rename/remove  the devl directory, since its information is not in sync with the new  situation, and Custom IP Wizard can&#8217;t do any good at this point.</li>
<li>And finally, in EDK, Project &gt; Rescan User Repositories</li>
<li>Remove  the LED_4bits core from the project, choosing &#8220;Delete instance and any  connections to internal nets&#8221;. This will keep the net names used for connecting to the LEDs, and  make them available for connection to the new peripheral. Otherwise, the  external net names need to be set, and the system.ucf given at the  &#8220;project&#8221; tab updated to reflect the new nets.</li>
<li>Add the minimal core to the project, and connect the just released LEDs_4Bits_TRI_O to its minimal_leds port.</li>
<li>Create bitfile</li>
</ul>
<p>The  synthesis of the peripheral&#8217;s HDL takes place during the &#8220;create netlist&#8221; flow (which is, of course, part of generating bitfile).  For example, the synthesis of an instance named minimal_0 will appear as follows in the console</p>
<pre>INSTANCE:minimal_0 - C:\tryperipheral\system.mhs line 424 - Running XST
synthesis
PMSPEC -- Overriding Xilinx file
&lt;C:/ise13_2/ISE_DS/EDK/spartan6/data/spartan6.acd&gt; with local file
&lt;C:/ise13_2/ISE_DS/ISE/spartan6/data/spartan6.acd&gt;</pre>
<p>And if there are errors in the HDL, they will show up at this point.</p>
<h3>Sample files</h3>
<p>These are the files used for the minimal peripheral. They are a sloppy adoption of the files generated by the Custom IP Wizard, so they&#8217;re very likely to contain unnecessary declarations.</p>
<p>First, the Verilog file:</p>
<pre>module minimal #(
 parameter C_S_AXI_DATA_WIDTH = 32,
 parameter C_S_AXI_ADDR_WIDTH = 32,
 parameter C_S_AXI_MIN_SIZE = 'h000001FF,
 parameter C_USE_WSTRB = 0,
 parameter C_DPHASE_TIMEOUT = 8,
 parameter C_BASEADDR = 'hFFFFFFFF,
 parameter C_HIGHADDR = 'h00000000,
 parameter C_FAMILY = "spartan6",
 parameter C_NUM_REG = 1,
 parameter C_NUM_MEM = 1,
 parameter C_SLV_AWIDTH = 32,
 parameter C_SLV_DWIDTH = 32
 )
 (
 input S_AXI_ACLK,
 input S_AXI_ARESETN,
 input [(C_S_AXI_ADDR_WIDTH-1):0] S_AXI_AWADDR,
 input S_AXI_AWVALID,
 input  [(C_S_AXI_DATA_WIDTH-1):0] S_AXI_WDATA,
 input  [((C_S_AXI_DATA_WIDTH/8)-1):0] S_AXI_WSTRB,
 input S_AXI_WVALID,
 input S_AXI_BREADY,
 input  [(C_S_AXI_ADDR_WIDTH-1):0] S_AXI_ARADDR,
 input S_AXI_ARVALID,
 input S_AXI_RREADY,
 output S_AXI_ARREADY,
 output  [(C_S_AXI_DATA_WIDTH-1):0] S_AXI_RDATA,
 output  [1:0] S_AXI_RRESP,
 output S_AXI_RVALID,
 output S_AXI_WREADY,
 output [1:0] S_AXI_BRESP,
 output reg S_AXI_BVALID,
 output S_AXI_AWREADY,

 output reg [3:0] minimal_leds
 );

 assign  S_AXI_RDATA = minimal_leds;
 assign  S_AXI_RRESP = 0; // OKAY on AXI4
 assign  S_AXI_ARREADY = 1; // Always ready for read address
 assign  S_AXI_AWREADY = 1; // Always ready for write address
 assign  S_AXI_RVALID = 1; // Read data always valid (ILLEGAL)
 assign  S_AXI_WREADY = 1; // Always ready to write
 assign  S_AXI_BRESP = 0; // OKAY on AXI4

 // This will not work OK if several "bursts" are sent with no BVALIDs
 // inbetween. Not an expected scenario.

 always @(posedge S_AXI_ACLK)
   if (S_AXI_WVALID)
     begin
        S_AXI_BVALID &lt;= 1;
        minimal_leds &lt;= S_AXI_WDATA;
     end
   else if (S_AXI_BREADY &amp;&amp; S_AXI_BVALID) // Active BRESP cycle
     S_AXI_BVALID &lt;= 0;

endmodule</pre>
<p>Most of the parameters at the top can be removed, I believe. It appears like they are necessary only when creating the MPD file with PsfUtility.</p>
<p>All ports, except minimal_leds are standard AXI4 lite ports. The implementation of the interface isn&#8217;t example for anything except a quick and dirty peripheral which responds to bus requests. The only thing it does actively is to update minimal_leds when necessary, and toggle the AXI_BVALID, so that only one burst response is sent for each write cycle (which is always one clock long in AXI4 lite). It&#8217;s OK not to decode the address, since it&#8217;s the interconnect&#8217;s job to make sure each peripheral gets only what it directed to it.</p>
<p>Holding S_AXI_RVALID high all the time violates the AXI4 spec, since it&#8217;s required to be asserted only after ARVALID and ARREADY. But the interconnect tolerated this anyhow.</p>
<p>Now to minimal_v2_1_0.mpd:</p>
<pre>BEGIN minimal

## Peripheral Options
OPTION IPTYPE = PERIPHERAL
OPTION IMP_NETLIST = TRUE
OPTION HDL = VERILOG
OPTION IP_GROUP = MICROBLAZE:USER
OPTION DESC = MINIMAL
OPTION LONG_DESC = A minimal peripheral to start off with
OPTION ARCH_SUPPORT_MAP = (others=DEVELOPMENT)

## Bus Interfaces
BUS_INTERFACE BUS = S_AXI, BUS_STD = AXI, BUS_TYPE = SLAVE

## Generics for VHDL or Parameters for Verilog
PARAMETER C_S_AXI_DATA_WIDTH = 32, DT = INTEGER, BUS = S_AXI, ASSIGNMENT = CONSTANT
PARAMETER C_S_AXI_ADDR_WIDTH = 32, DT = INTEGER, BUS = S_AXI, ASSIGNMENT = CONSTANT
PARAMETER C_S_AXI_MIN_SIZE = 0x000001ff, DT = std_logic_vector, BUS = S_AXI
PARAMETER C_USE_WSTRB = 0, DT = INTEGER
PARAMETER C_DPHASE_TIMEOUT = 8, DT = INTEGER
PARAMETER C_BASEADDR = 0xffffffff, DT = std_logic_vector, MIN_SIZE = 0x0, PAIR = C_HIGHADDR, ADDRESS = BASE, BUS = S_AXI
PARAMETER C_HIGHADDR = 0x00000000, DT = std_logic_vector, PAIR = C_BASEADDR, ADDRESS = HIGH, BUS = S_AXI
PARAMETER C_FAMILY = virtex6, DT = STRING
PARAMETER C_NUM_REG = 1, DT = INTEGER
PARAMETER C_NUM_MEM = 1, DT = INTEGER
PARAMETER C_SLV_AWIDTH = 32, DT = INTEGER
PARAMETER C_SLV_DWIDTH = 32, DT = INTEGER
PARAMETER C_S_AXI_PROTOCOL = AXI4LITE, TYPE = NON_HDL, ASSIGNMENT = CONSTANT, DT = STRING, BUS = S_AXI

## Ports
PORT S_AXI_ACLK = "", DIR = I, SIGIS = CLK, BUS = S_AXI
PORT S_AXI_ARESETN = ARESETN, DIR = I, SIGIS = RST, BUS = S_AXI
PORT S_AXI_AWADDR = AWADDR, DIR = I, VEC = [(C_S_AXI_ADDR_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
PORT S_AXI_AWVALID = AWVALID, DIR = I, BUS = S_AXI
PORT S_AXI_WDATA = WDATA, DIR = I, VEC = [(C_S_AXI_DATA_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
PORT S_AXI_WSTRB = WSTRB, DIR = I, VEC = [((C_S_AXI_DATA_WIDTH/8)-1):0], ENDIAN = LITTLE, BUS = S_AXI
PORT S_AXI_WVALID = WVALID, DIR = I, BUS = S_AXI
PORT S_AXI_BREADY = BREADY, DIR = I, BUS = S_AXI
PORT S_AXI_ARADDR = ARADDR, DIR = I, VEC = [(C_S_AXI_ADDR_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
PORT S_AXI_ARVALID = ARVALID, DIR = I, BUS = S_AXI
PORT S_AXI_RREADY = RREADY, DIR = I, BUS = S_AXI
PORT S_AXI_ARREADY = ARREADY, DIR = O, BUS = S_AXI
PORT S_AXI_RDATA = RDATA, DIR = O, VEC = [(C_S_AXI_DATA_WIDTH-1):0], ENDIAN = LITTLE, BUS = S_AXI
PORT S_AXI_RRESP = RRESP, DIR = O, VEC = [1:0], BUS = S_AXI
PORT S_AXI_RVALID = RVALID, DIR = O, BUS = S_AXI
PORT S_AXI_WREADY = WREADY, DIR = O, BUS = S_AXI
PORT S_AXI_BRESP = BRESP, DIR = O, VEC = [1:0], BUS = S_AXI
PORT S_AXI_BVALID = BVALID, DIR = O, BUS = S_AXI
PORT S_AXI_AWREADY = AWREADY, DIR = O, BUS = S_AXI
PORT minimal_leds = "", DIR = O, VEC = [3:0]

END</pre>
<p>This file is exactly as generated by the Wizard, except for the HDL option in the beginning changed to VERILOG, and the added port minimal_leds at the end. Note its assignment to &#8220;&#8221;. This file is best created by looking at examples of existing cores.</p>
<p>Now to minimal_v2_1_0.pao:</p>
<pre>lib minimal_v1_00_a minimal verilog</pre>
<p>which was rewritten to reflect that the peripheral consists of one single Verilog file.</p>
<h3>The device tree file</h3>
<p>The device tree file needs to be generated as described in <a title="Linux on Microblaze HOWTO (part I)" href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/" target="_blank">one of my posts</a>. The relevant section is given here, since it relates to kernel code presented next:</p>
<pre>minimal_0: minimal@7ae00000 {
 compatible = <span style="color: #ff0000;">"xlnx,minimal-1.00.a"</span>;
 reg = &lt; <span style="color: #ff0000;">0x7ae00000</span> 0x10000 &gt;;
 xlnx,dphase-timeout = &lt;0x8&gt;;
 xlnx,family = "spartan6";
 xlnx,num-mem = &lt;0x1&gt;;
 xlnx,num-reg = &lt;0x1&gt;;
 xlnx,s-axi-min-size = &lt;0x1ff&gt;;
 xlnx,slv-awidth = &lt;<span style="color: #ff0000;">0x20</span>&gt;;
 xlnx,slv-dwidth = &lt;0x20&gt;;
 xlnx,use-wstrb = &lt;0x0&gt;;
 }</pre>
<p>It&#8217;s pretty evident that some of these parameters have no use.</p>
<h3>The driver</h3>
<p>First, it&#8217;s convenient to create a makefile for cross compilation. Even though the correct way is to set the environment variables in the shell, and run the module compilation in the same way the kernel itself is compiled, it&#8217;s much more convenient to go just &#8220;make&#8221; or &#8220;make clean&#8221; with this makefile. It&#8217;s not good for distribution, as the paths to both the kernel tree and cross compiler are hardcoded.</p>
<p>So here&#8217;s a dirty, but yet convenient makefile:</p>
<pre>export CROSS_COMPILE=/path/to/microblazeel-unknown-linux-gnu/bin/microblazeel-unknown-linux-gnu-
export ARCH=microblaze

ifneq ($(KERNELRELEASE),)
obj-m    := minimal.o

else
KDIR := /path/to/linux-2.6.38.6

default:
 @echo $(TARGET) &gt; module.target
 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
 @rm -f *.ko *.o modules.order Module.symvers *.mod.? .minimal.* *~
 @rm -rf .tmp_versions module.target

minimal.ko:
 $(MAKE)
endif</pre>
<p>And now to the driver itself, minimal.c:</p>
<pre>#include &lt;linux/platform_device.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/of.h&gt;
#include &lt;linux/of_address.h&gt;
#include &lt;linux/of_device.h&gt;
#include &lt;linux/of_platform.h&gt;
#include &lt;asm/io.h&gt;

/* Match table for of_platform binding */
static struct of_device_id minimal_of_match[] __devinitdata = {
 { .compatible = "xlnx,minimal-1.00.a", },
 {}
};

MODULE_ALIAS("minimal");

static void __iomem *regs;
static struct resource res;

static int __devinit
minimal_of_probe(struct platform_device *op, const struct of_device_id *match)
{

 const int *width;
 int ret;
 int val;

 ret = of_address_to_resource(op-&gt;dev.of_node, 0, &amp;res);
 if (ret) {
 printk(KERN_WARNING "minimal: Failed to obtain device tree resource\n");
 return ret;
 }

 printk(KERN_WARNING "minimal: Physical address to resource is %x\n", (unsigned int) res.start);

 if (!request_mem_region(res.start, 32, "mimimal")) {
 printk(KERN_WARNING "minimal: Failed to request I/O memory\n");
 return -EBUSY;
 }

 regs = of_iomap(op-&gt;dev.of_node, 0); /* Verify it's non-null! */

 printk(KERN_WARNING "minimal: Access address to registers is %x\n", (unsigned int) regs);

 width = of_get_property(op-&gt;dev.of_node, "xlnx,slv-dwidth", NULL);

 printk(KERN_WARNING "minimal: Obtained width=%d\n", be32_to_cpu(*width));

 val = ioread32(regs);
 printk(KERN_WARNING "minimal: Read %d, writing %d\n", val, val+1);

 iowrite32(++val, regs);

 return 0; /* Success */
}

static int __devexit minimal_of_remove(struct platform_device *op)
{
 iounmap(regs);
 release_mem_region(res.start, 32);
 return 0; /* Success */
}

static struct of_platform_driver minimal_of_driver = {
 .probe = minimal_of_probe,
 .remove = __devexit_p(minimal_of_remove),
 .driver = {
 .name = "minimal",
 .owner = THIS_MODULE,
 .of_match_table = minimal_of_match,
 },
};

int __init minimal_init(void)
{
 int ret;
 ret = of_register_platform_driver(&amp;minimal_of_driver);
 return ret;
}

void __exit minimal_exit(void)
{
 of_unregister_platform_driver(&amp;minimal_of_driver);
}

module_init(minimal_init);
module_exit(minimal_exit);

MODULE_AUTHOR("Eli Billauer");
MODULE_DESCRIPTION("Microblaze minimal module");
MODULE_LICENSE("GPL")</pre>
<p>It doesn&#8217;t do anything special, except for change the state of the LEDs every time it&#8217;s loaded. The drivers also reads one of the parameters from the device tree structure. Not fascinating, but keeps the code, well, minimal.</p>
<p>This code should be pretty straightforward to programmers who are familiar with PCI device drivers, with probing and removal working in more or less the same way. I&#8217;ve chosen a hardcoded segment of 32 bytes as the requested region. This depends on the peripheral, of course.</p>
<h3>A test run</h3>
<p>This is the transcript of the session on the UART console, as run on a freshly booted system. LEDs did indeed go on and off as reflected by the numbers.</p>
<pre>/ # insmod minimal.ko
minimal: Physical address to resource is 7ae00000
minimal: Access address to registers is c87e0000
minimal: Obtained width=32
minimal: Read 0, writing 1
/ # lsmod
minimal 1978 0 - Live 0xc8056000
ipv6 305961 10 - Live 0xc8763000
/ # cat /proc/iomem
40600000-4060000f : uartlite
40a00000-40a0ffff : xilinx_spi
40e00000-40e0ffff : xilinx_emaclite
7ae00000-7ae0001f : mimimal
/ # rmmod minimal
rmmod: module 'minimal' not found
/ # cat /proc/iomem
40600000-4060000f : uartlite
40a00000-40a0ffff : xilinx_spi
40e00000-40e0ffff : xilinx_emaclite
/ # lsmod
ipv6 305961 10 - Live 0xc8763000
/ # insmod minimal.ko
minimal: Physical address to resource is 7ae00000
minimal: Access address to registers is c8820000
minimal: Obtained width=32
minimal: Read 1, writing 2</pre>
<p>Note that rmmod produces an error message, which makes it look as if it failed to remove the module, when in fact all went well.</p>
<p>The physical address was indeed detected correctly (see device tree), and mapped to another kernel virtual address each time.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/08/microblaze-custom-ip-peripheral-axi4-cip-ipwiz/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Linux on Microblaze HOWTO (part IV)</title>
		<link>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-4/</link>
		<comments>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-4/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 16:23:12 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1726</guid>
		<description><![CDATA[This is part IV of my HOWTO on running Linux on Microblaze. The outline is as follows: Part I: Introduction and setting up the Microblaze processor Part II: Compiling the kernel Part III: Preparing for boot and booting Part IV: Compiling user space applications (this page) Compiling user space applications We shall now look at [...]]]></description>
			<content:encoded><![CDATA[<p>This is part IV of my HOWTO on running Linux on Microblaze. The outline is as follows:</p>
<ul>
<li><a href="../2011/08/linux-microblaze-howto-tutorial-primer-1/" target="_blank">Part I: Introduction and setting up the Microblaze processor</a></li>
<li><a href="../2011/08/linux-microblaze-howto-tutorial-primer-2/" target="_blank">Part II: Compiling the kernel</a></li>
<li><a href="../2011/08/linux-microblaze-howto-tutorial-primer-3/" target="_blank">Part III: Preparing for boot and booting</a></li>
<li>Part IV: Compiling user space applications (this page)</li>
</ul>
<p><a href="http://xillybus.com/media/microblaze.html" target="_blank"><img class="aligncenter size-full wp-image-1880" title="xillybus-distro-banner" src="https://billauer.se/blog/wp-content/uploads/2011/07/xillybus-distro-banner.jpg" alt="" width="536" height="134" /></a></p>
<h3>Compiling user space applications</h3>
<p>We shall now look at how to compile applications for execution under the Microblaze Linux machine. This is pretty straightforward for programs written for the specific environment. The problems may occur when compiling sources which were originally written for fullblown computers, as the build system may not have taken cross compilation into account. And as software projects tend to be hacked to death, with new features added all the time, the code may depend on libraries which are installed on every desktop, but not necessarily on an embedded system. These dependencies are at times a result of a completely offbeat feature, but it&#8217;s often simpler to compile the necessary library than to remove the feature. Since there is no single recipe for solving that kind of problems, we&#8217;ll stick to the basics of compiling for user space.</p>
<h3>Background</h3>
<p>Cross compilation of user space applications is actually more difficult than compiling the kernel, mainly because the kernel itself is, after all, a standalone application. There are a few things to take care of:</p>
<ul>
<li>Make sure libraries for dynamic linking are in place in the target runtime filesystem, as well as the dynamic linker itself.</li>
<li>The compilation should be done against the header files corresponding to the libraries present in the target.</li>
<li>The linked libraries used during compilation should correspond to those in the target.</li>
<li>The C Runtime stubs (crt1.o, crti.o, crtbegin.o, crtend.o and crtn.o) should fit the Linux user space environment (different files with similar names are used for Microblaze standalones).</li>
</ul>
<p>This may sound complicated, but most of the job has already been done. So it all boils down to a few simple things to bare in mind, as shown next.</p>
<h3>Preparing the target&#8217;s file system</h3>
<p>In <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/" target="_blank">part II</a> it was shown how to download and extract the cross compiler for Microblaze. The same tarball also has the entire package for the target&#8217;s root under microblazeel-unknown-linux-gnu/microblazeel-unknown-linux-gnu/sys-root. This directory should be copied into the target&#8217;s root as is.</p>
<p>But the target&#8217;s root directory is already populated with files as necessary to boot Linux, and run command line utilities with busybox. Some of the files in sys-root, dynamic libraries in particular, already exist in target root, and they&#8217;re not identical. But since busybox is statically linked, overwriting the dynamic libraries seems harmless. Overwriting the previous files where applicable is therefore the way to resolve these conflicts, since dynamically linked applications will be compiled against the newer libraries.</p>
<p>All in all, the sys-root directory is ~164 MB, which isn&#8217;t too bad when stored on a flash memory. ~129 of these are /lib. The library files include libm, libpthread, libresolv and several other important libraries.</p>
<p>/usr/include takes up ~14 MB, which is probably not necessary on the target system.</p>
<h3>Compilation</h3>
<p>For cross compilation we use the same compiler used for the kernel. To compile an application:</p>
<pre>/path/to/microblazeel-unknown-linux-gnu-gcc --sysroot=/path/to/nfsroot/ -o hello hello.c -lm</pre>
<p>where /path/to/nfsroot is the directory which will be the root directory when the executable runs, or a copy of it. The truth is I&#8217;m not really sure &#8211;sysroot is really necessary, but given the pretty wild search the GNU tools do to find include files and libraries, it looks like a good measure to point directly at where these should be found.</p>
<p>Note that if we omit &#8211;sysroot, compiling for Microblaze Linux user space is done simply by using the cross compiler normally, and that works too. This happens because the compiler was configured to look for libraries and includes from its own sys-root. The C runtime stubs are always taken from the compiler&#8217;s own.</p>
<p>This is a good time to repeat something said in part II: There is no need to &#8220;install&#8221; the Microblaze compiler, and neither do the files need to be owned by root. A simple untar anywhere is fine. The compiler uses relative paths to find its resources.</p>
<h3>Static linking</h3>
<p>To be somewhat safer, static compilation may be preferred, in particular when the whole system&#8217;s functionality consists of a single application. The executable file is considerably larger, but doesn&#8217;t depend on libraries, so it works even without the sys-root copy mentioned above. Just add the &#8211;static flag to gcc. e.g.</p>
<pre>/path/to/microblazeel-unknown-linux-gnu-gcc <span style="color: #ff0000;">--static</span> --sysroot=/path/to/nfsroot/ -o hello hello.c -lm</pre>
<p>The -lm flag is here to demonstrate that libraries should be at the end of the command line. This has no significance when the executable is compiled to be dynamic, but for static linking, failing to put the -lm (and other loadables) at the end will cause misleading errors such as:</p>
<pre>/tmp/cckqzZqo.o: In function `main':
: undefined reference to `sin'
collect2: ld returned 1 exit statu</pre>
<p>So put the -lm at the end, OK?</p>
<h3><del>Compiling from SDK</del></h3>
<p><strong><span style="text-decoration: underline;">Note</span>: I don&#8217;t present a working solution in this subject.</strong></p>
<p>Since the BSP, which is generated by the SDK along with the compilation directories, are just include files and libraries, it was appealing to try compiling Linux user space applications from the SDK. The method suggested is to overwrite the BSP created by SDK with include files and libraries for the Linux environment.</p>
<p>The problem I didn&#8217;t bother to solve in the end, was that the C runtime libraries used by the linker remained those for a standalone application, so the executable couldn&#8217;t run on Linux. Most likely, this can be solved easily, but since I don&#8217;t like IDEs myself, I left this issue as is.</p>
<p>Another problem with this method is that the BSP is erased every time the <strong>project</strong> is rebuilt (but it survives recompilation, of course). So it&#8217;s best to keep a copy of the entire BSP directory structure.</p>
<p>In short, this is the procedure, minus the part that makes the linker work with the Linux-related CRTs.</p>
<ul>
<li>Create a BSP by creating a C project</li>
<li>Copy all .a files from sys-root&#8217;s  /usr/lib and replace the lib directory in the BSP with a directory containing these (only)</li>
<li>Replace the BSP&#8217;s include directory with sys-root&#8217;s /usr/include as is</li>
<li>In SDK (Eclipse, actually), right-click the C project on the Project Explorer and pick Properties. Under C/C++ Build &gt; Settings &gt; Microblaze gcc linker &gt; Linker script,  remove the linker script given (edit the text, and remove the part saying ../src/lscript.ld)</li>
</ul>
<p>And again, this <strong>almost</strong> works. If someone takes this to the finish line, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Linux on Microblaze HOWTO (part III)</title>
		<link>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/</link>
		<comments>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 19:11:35 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1639</guid>
		<description><![CDATA[This is part III of my HOWTO on running Linux on Microblaze. The outline is as follows: Part I: Introduction and setting up the Microblaze processor Part II: Compiling the kernel Part III: Preparing for boot and booting (this page) Part IV: Compiling user space applications Generating the ACE file The ACE file is what [...]]]></description>
			<content:encoded><![CDATA[<p>This is part III of my HOWTO on running Linux on Microblaze. The outline is as follows:</p>
<ul>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/" target="_blank">Part I: Introduction and setting up the Microblaze processor</a></li>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/" target="_blank">Part II: Compiling the kernel</a></li>
<li>Part III: Preparing for boot and booting (this page)</li>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-4/" target="_blank">Part IV: Compiling user space applications</a></li>
</ul>
<p><a href="http://xillybus.com/media/microblaze.html" target="_blank"><img class="aligncenter size-full wp-image-1880" title="xillybus-distro-banner" src="https://billauer.se/blog/wp-content/uploads/2011/07/xillybus-distro-banner.jpg" alt="" width="536" height="134" /></a></p>
<h3>Generating the ACE file</h3>
<p>The ACE file is what the System ACE chip reads from, and programs the FPGA accordingly. It consists of a sequence of JTAG operations for each necessary task: Configure the FPGA itself, load the software into memory, set the software execution entry point, and kick the software off. All is done with JTAG commands, which the System ACE generates as it scans through its ACE file.</p>
<p>So let&#8217;s get down to business.</p>
<p>Create a directory to gather the relevant files, and copy the following into it:</p>
<ul>
<li>The Tcl script for generating ACE file: Found at ISE_DS/EDK/data/xmd/genace.tcl (relative to the path where Xilinx ISE is installed)</li>
<li>The bitstream (system.bit) file created by the EDK (explained in part I). Found in the &#8216;hw&#8217; subdirectory in the export bundle from EDK to SDK. Or just under &#8216;implementation&#8217; in the processor&#8217;s working directory. It&#8217;s the same file.</li>
<li>The kernel ELF file (simpleImage.xilinx, or the unstripped simpleImage.xilinx.unstrip) created by the kernel build system (explained in part II), found in arch/microblaze/boot/ in the kernel source tree.</li>
</ul>
<p>Open a command shell (Project &gt; Launch Xilinx Shell if you like), change to this directory and go:</p>
<pre>xmd -tcl genace.tcl -hw system.bit -elf simpleImage.xilinx -ace linuxmb.ace -board sp605 -target mdm</pre>
<p>which generates a lot of junk files (.svf most notably, which contain JTAG commands in a portable format), and eventually the linuxmb.ace is created (any file name is OK).</p>
<p>In the example above, I assumed that the target is the SP605 board. Looking at the genace.tcl script reveals easily which boards are supported. If it isn&#8217;t, it&#8217;s not such a big deal. The only reason the board matters is because the System ACE needs to know which device in the JTAG chain to talk with plus some programming parameters. The -board flags to this scrips allows setting the options in a “genace option file” (whatever that means). I would hack the script, though. It looks easier. See <a href="http://www.xilinx.com/itp/xilinx8/help/platform_studio/html/ps_p_dld_using_genace_script.htm" target="_blank">here</a> for more information.</p>
<h3>Writing to the Compact Flash</h3>
<p>First and foremost: If you have a compact flash which boots anything to the FPGA, don&#8217;t format it unless you really have to. The System ACE chip (by Xilinx) which reads from the flash directly is a bit picky about the file system format. Preferably use the card which came with the development kit.</p>
<p>And this too: If you just bought a 2 GB flash or so in a general electronics store, odds are that you&#8217;ll need to format it.</p>
<p>I explain how to format the flash in <a title="Booting a Microblaze processor + software using Compact Flash" href="https://billauer.se/blog/2011/07/system-ace-bitstream-microblaze-processor-compact-flash/" target="_blank">another post of mine</a>.</p>
<p>Assuming that the flash is formatted OK, copy the ACE file to the Compact Flash&#8217; root directory. Make sure that</p>
<ul>
<li>there is no other *.ace file in the root directory</li>
<li>there is no xilinx.sys in the root directory</li>
</ul>
<p>It is perfectly OK to have unrelated directories on the flash, so if there are some files on the flash already, I&#8217;d suggest creating a directory with just any name (say, &#8220;prevroot&#8221;) and move everything in the root directory into that one. And then copy the desired ACE file (linuxmb.ace in the example above) into the root directory.</p>
<p>That&#8217;s it. The Linux kernel should now boot, but it will complain (the kernel will panic, actually) that it doesn&#8217;t have any root filesystem. So&#8230;</p>
<h3>Setting up the root filesystem</h3>
<p>Once the kernel is up, it needs something to mount as a root filesystem, in which it expects to find its init executable and quite a few other files. Xilinx supplies an image of this bundle which were downloaded along with the cross compilers (see <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/" target="_blank">part II</a>), in the same directory.</p>
<p>You may recall that I chose to mount root over the network, using NFS. So to create a useful root directory to work with, just change directory to whatever is going to be root (in my case, the one exposed via NFS) and go</p>
<pre>zcat /path/to/microblaze_v1.0_le/initramfs_minimal_le.cpio.gz | cpio -i -d -H newc --no-absolute-filenames</pre>
<p>This bundle includes a practical set of executables (well, it&#8217;s actually a lot of symbolic links to busybox) including vi, watch, dd, grep, gzip, tar, rpm, nc and even httpd (a web server&#8230;!). There&#8217;s also a rootfs.cpio.gz in the kernel sources when downloaded from Xilinx&#8217; git (linux-2.6-xlnx.git in <a href="../2011/08/linux-microblaze-howto-tutorial-primer-2/" target="_blank">part II</a>) which I haven&#8217;t tried out. But it&#8217;s opened in the same way.</p>
<p>You may, of course, compile your own programs, which is discussed in <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-4/" target="_blank">part IV</a>.</p>
<p>There&#8217;s no &#8220;shutdown&#8221; executable, though. There&#8217;s &#8220;halt&#8221; instead.</p>
<h3>A test run</h3>
<p>Well, plug in the Compact Flash card, turn the power on, and hope to see a green LED blinking, which turns to steady green after a few seconds. When the LED is steady, expect some output on the UART. A typical log for SP605 is given at the end of this post.</p>
<p>At times, the SP605 board’s green LED went on, but nothing runs until SYS_ACE_RESET is pressed (the middle button out of three close to the Compact Flash jack). Looks like a powerup issue.</p>
<h3>Is it fast? Is it fast?</h3>
<p>This is maybe not such a fair comparison, and still the facts speak for themselves:</p>
<p>On Microblaze @ 75 MHz clock (37 BogoMIPS):</p>
<pre># dd if=/dev/zero of=/dev/null bs=1M count=10k
10240+0 records in
10240+0 records out
10737418240 bytes (10.0GB) copied, 1058.304486 seconds, 9.7MB/s
# dd if=/dev/zero of=/dev/null bs=512 count=100k
102400+0 records in
102400+0 records out
52428800 bytes (50.0MB) copied, 9.531130 seconds, 5.2MB/s</pre>
<p>The same thing on my own computer  @ 1.2 GHz (5600 BogoMIPS):</p>
<pre>$ dd if=/dev/zero of=/dev/null bs=1M count=10k
10240+0 records in
10240+0 records out
10737418240 bytes (11 GB) copied, 0.941238 s, 11.4 GB/s
$ dd if=/dev/zero of=/dev/null bs=512 count=100k
102400+0 records in
102400+0 records out
52428800 bytes (52 MB) copied, 0.0443318 s, 1.2 GB/s</pre>
<p>According to the BogoMIPSes, Microblaze should have been 150 times slower, not 1000 times slower!</p>
<h3>A typical boot log</h3>
<pre>early_printk_console is enabled at 0x40600000
Ramdisk addr 0x00000003, Compiled-in FDT at 0xc03c2348
Initializing cgroup subsys cpuset
Initializing cgroup subsys cpu
Linux version 2.6.38.6 (eli@localhost.localdomain) (gcc version 4.1.2) #19 Fri Aug 5 16:40:02 IDT 2011
setup_cpuinfo: initialising
setup_cpuinfo: Using full CPU PVR support
cache: wt_msr_noirq
setup_memory: max_mapnr: 0x8000
setup_memory: min_low_pfn: 0xc0000
setup_memory: max_low_pfn: 0xc8000
On node 0 totalpages: 32768
free_area_init_node: node 0, pgdat c04f515c, node_mem_map c05ca000
 Normal zone: 256 pages used for memmap
 Normal zone: 0 pages reserved
 Normal zone: 32512 pages, LIFO batch:7
pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
pcpu-alloc: [0] 0
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
Kernel command line: console=ttyUL0 ip=::::::dhcp rootfstype=nfs root=/dev/nfs rw nfsroot=10.11.12.13:/shared/nfsroot,tcp
PID hash table entries: 512 (order: -1, 2048 bytes)
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
allocated 655360 bytes of page_cgroup
please try 'cgroup_disable=memory' option if you don't want memory cgroups
Memory: 123204k/131072k available
SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:32
xlnx,xps-intc-1.00.a #0 at 0xc8000000, num_irq=8, edge=0x60
xlnx,xps-timer-1.00.a #0 at 0xc8004000, irq=7
Heartbeat GPIO at 0xc8008000
microblaze_timer_set_mode: shutdown
microblaze_timer_set_mode: periodic
Console: colour dummy device 80x25
Calibrating delay loop... 37.17 BogoMIPS (lpj=185856)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
Initializing cgroup subsys ns
ns_cgroup deprecated: consider using the 'clone_children' flag without the ns_cgroup.
Initializing cgroup subsys cpuacct
Initializing cgroup subsys memory
Initializing cgroup subsys devices
Initializing cgroup subsys freezer
Initializing cgroup subsys net_cls
devtmpfs: initialized
NET: Registered protocol family 16
PCI: Probing PCI hardware
bio: create slab &lt;bio-0&gt; at 0
XGpio: /axi@0/gpio@40040000: registered
XGpio: /axi@0/gpio@40020000: registered
XGpio: /axi@0/gpio@40000000: registered
vgaarb: loaded
Switching to clocksource microblaze_clocksource
microblaze_timer_set_mode: oneshot
Switched to NOHz mode on CPU #0
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 3, 32768 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
PCI: CLS 0 bytes, default 32
Skipping unavailable RESET gpio -2 (reset)
GPIO pin is already allocated
audit: initializing netlink socket (disabled)
type=2000 audit(0.429:1): initialized
VFS: Disk quotas dquot_6.5.2
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
squashfs: version 4.0 (2009/01/31) Phillip Lougher
fuse init (API version 7.16)
msgmni has been set to 240
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
40600000.serial: ttyUL0 at MMIO 0x40600000 (irq = 6) is a uartlite
console [ttyUL0] enabled
brd: module loaded
loop: module loaded
of:xsysace 41800000.sysace: Xilinx SystemACE revision 1.0.12
of:xsysace 41800000.sysace: capacity: 3980592 sectors
 xsa: xsa1
Xilinx SystemACE device driver, major=254
Generic platform RAM MTD, (c) 2004 Simtec Electronics
xilinx_spi 40a00000.spi: at 0x40A00000 mapped to 0xc8080000, irq=0
of:xilinx_emaclite 40e00000.ethernet: Device Tree Probing
Xilinx Emaclite MDIO: probed
of:xilinx_emaclite 40e00000.ethernet: MAC address is now 00:0a:35:49:b2:00
of:xilinx_emaclite 40e00000.ethernet: Xilinx EmacLite at 0x40E00000 mapped to 0xC80A0000, irq=5
device-mapper: uevent: version 1.0.3
device-mapper: ioctl: 4.19.1-ioctl (2011-01-07) initialised: dm-devel@redhat.com
nf_conntrack version 0.5.0 (1925 buckets, 7700 max)
ip_tables: (C) 2000-2006 Netfilter Core Team
TCP cubic registered
Initializing XFRM netlink socket
NET: Registered protocol family 17
Registering the dns_resolver key type
registered taskstats version 1
Sending DHCP requests .
PHY: c0020918:07 - Link is Up - 100/Full
., OK
IP-Config: Got DHCP answer from 10.11.12.13, my address is 10.11.12.155
IP-Config: Complete:
 device=eth0, addr=10.11.12.155, mask=255.255.255.0, gw=10.11.12.13,
 host=10.11.12.155, domain=, nis-domain=(none),
 bootserver=10.11.12.13, rootserver=10.11.12.13VFS: Mounted root (nfs filesystem) on device 0:13.
devtmpfs: mounted
Freeing unused kernel memory: 147k freed
Starting rcS...
++ Mounting filesystem
++ Starting telnet daemon
rcS Complete
/bin/sh: can't access tty; job control turned off
/ # NET: Registered protocol family 10
eth0: no IPv6 routers present</pre>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Linux on Microblaze HOWTO (part II)</title>
		<link>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/</link>
		<comments>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 21:45:55 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1616</guid>
		<description><![CDATA[This is part II of my HOWTO on running Linux on Microblaze. The outline is as follows: Part I: Introduction and setting up the Microblaze processor Part II: Compiling the kernel (this page) Part III: Preparing for boot and booting Part IV: Compiling user space applications Kernel compilation in general Compiling a Linux kernel traditionally [...]]]></description>
			<content:encoded><![CDATA[<p>This is part II of my HOWTO on running Linux on Microblaze. The outline is as follows:</p>
<ul>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/" target="_blank">Part I: Introduction and setting up the Microblaze processor</a></li>
<li>Part II: Compiling the kernel (this page)</li>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/" target="_blank">Part III: Preparing for boot and booting</a></li>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-4/" target="_blank">Part IV: Compiling user space applications</a></li>
</ul>
<p><a href="http://xillybus.com/media/microblaze.html" target="_blank"><img class="aligncenter size-full wp-image-1880" title="xillybus-distro-banner" src="https://billauer.se/blog/wp-content/uploads/2011/07/xillybus-distro-banner.jpg" alt="" width="536" height="134" /></a></p>
<h3>Kernel compilation in general</h3>
<p>Compiling a Linux kernel traditionally consists of the following steps (some of which are elaborated further below):</p>
<ul>
<li>Obtaining a kernel source tree.</li>
<li> Configure the kernel. Which all in all means to set up a file named &#8220;.config&#8221; in the kernel source&#8217;s root directory.</li>
<li>Compile actual kernel, ending up with an executable image.</li>
<li>Compile the post-boot loadable kernel modules.</li>
<li>Put everything in its place, set up the bootloader</li>
<li>Pray and boot</li>
</ul>
<p>When compiling for Microblaze, the process is somewhat different:</p>
<ul>
<li>Cross compilation: The compiled binaries run on a processor different from the one doing the compilation.</li>
<li>Kernel modules are most likely not used at all. They are a bit pointless when the hardware is known in advance, and also add some complexity in setting up the entire system for boot. Besides, modprobe on a Microblaze can take forever.</li>
<li>The hardware configuration is custom made, and the kernel needs to be informed about it (through the Device Tree Structure)</li>
</ul>
<h3>Downloading kernel sources</h3>
<p>Note that all kernels compile for all target architectures. If you download a kernel from Xilinx&#8217; repository, it may have the parts relevant to Xilinx slightly more updated. The emphasis is on &#8220;may&#8221;.<br />
The &#8220;vanilla&#8221; kernel (maintained by Linus Torvalds) can be downloaded from the <a href="https://www.kernel.org/" target="_blank">main kernel</a> archive or one of its mirrors. Several other flavors float around, including Xilinx own git</p>
<pre>git clone git://git.xilinx.com/linux-2.6-xlnx.git</pre>
<p>or Petalogix&#8217; git (after all, they do a lot of maintenance on the Xilinx devices):</p>
<pre>git clone git://developer.petalogix.com/linux-2.6-microblaze.git</pre>
<p>The question is always which kernel is best. The answer is that it&#8217;s a bit of a gamble. It&#8217;s usually almost exactly the same piece of software, with git version having the latest changes. That means the latest bug fixes, new drivers, but also the latest, undocumented and undiscovered bugs. Vanilla kernels tend to be more conservative, but the only rule is that there are no rules. So in short, toss a coin and pick one.</p>
<p>Personally, I compiled the kernel which happened to be on my hard disk for other purposes.</p>
<h3>Cross compilers</h3>
<p>The good news is that there&#8217;s no need to compile the GNU tools. As a matter of fact, this part turned out to be surprisingly painless. The cross compiler and binutils binaries + initramfs images can be downloaded with</p>
<pre>$ git clone git://git.xilinx.com/xldk/microblaze_v1.0_le.git
$ git clone git://git.xilinx.com/xldk/microblaze_v1.0.git</pre>
<p>Choose one, depending on whether you prefer little endian or big endian for your processor. I picked little endian, but there&#8217;s one initramfs in the big endian bundle which isn&#8217;t there for the little endian set (which only has the &#8220;minimal&#8221; image).</p>
<p>One of the files fetched by git is microblazeel-unknown-linux-gnu.tar.gz (<span style="color: #ff0000;">g</span>zipped tarball) for the little endian version and mb_gnu_tools_bin.tar.bz (<span style="color: #ff0000;">b</span>zipped tarball) for big endian. I&#8217;ll leave the latter, because I didn&#8217;t use it.</p>
<p>There&#8217;s no need to install anything, and no need to be root (actually, doing this as root is pretty unwise). Just untar the tarball of your choice in any directory. Tar generates several subdirectories, but we&#8217;re after the cross compilers. Or more precisely, to make the kernel build system use them. This boils down to this:</p>
<pre>export CROSS_COMPILE=/home/myhomedir/untarred-to/microblazeel-unknown-linux-gnu/bin/microblazeel-unknown-linux-gnu-</pre>
<p>First of all, note the dash at the end of the statement. The whole string is a prefix for all compilation commands made by the kernel build system. It is often recommended to set the path to where the compilers are, and then set CROSS_COMPILE to a shorter prefix. I don&#8217;t see the point in polluting the overall path. The build environment has no problem with the statement above.</p>
<p>It has also crossed my mind to use the mb-gcc and friends, which are part of the SDK. But that may require another paid-for license, in case different people do the FPGA and software (which usually is the case).</p>
<p>And to wrap this up: If I&#8217;ll ever need to build a cross compiler from scratch, I would start with looking at <a href="http://buildroot.net/" target="_blank">Buildroot</a> (and <a href="http://buildroot.uclibc.org/buildroot.html" target="_blank">another page</a> about it) or following <a href="http://frank.harvard.edu/~coldwell/toolchain/" target="_blank">this guide</a> (I haven&#8217;t tried either, though).</p>
<h3>Kernel configuration</h3>
<p>Setting this up correctly is a tedious process, and even the most seasoned kernel hackers may not get it right on the first go. If it&#8217;s your first time, prepare to spend quite a few hours on this. The less experienced you are with Linux in general, the more time will you need to spend to make an educated guess about your need for each feature offered.</p>
<p>You can try to use <a href="https://billauer.se/download/mblinux/config_sample" target="_blank">my configuration file</a>, or at least start off with it. It was made for against a 2.6.38 kernel, and booted well as shown in <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/" target="_blank">part III</a>. Copy the file as .config on the kernel source&#8217;s root, and start with oldconfig.</p>
<p>The commands involved are basically (all &#8220;make&#8221; commands issues at the kernel source&#8217;s top directory):</p>
<ul>
<li>Clean up everything, <strong>including the .config file</strong> if present. This is not necessary if you just uncompressed your kernel. It&#8217;s actually rarely necessary at all: &#8220;make ARCH=microblaze mrproper&#8221;. <strong>This will delete .config! </strong>(I know I just said it).</li>
<li>Adopt an existing .config file: &#8220;make ARCH=microblaze oldconfig&#8221;. This is useful in particular when switching to another kernel version or flavor. Only questions about new features are asked. If you downloaded my configuration file, I would suggest not to turn on options that are offered while running oldconfig, unless they are clearly Xilinx related.</li>
<li>Configure the kernel: &#8220;make ARCH=microblaze xconfig&#8221;, &#8220;make ARCH=microblaze gconfig&#8221; or &#8220;make ARCH=microblaze menuconfig&#8221; (pick one). These applications present the kernel options in a fairly user-friendly manner, and eventually save the result to .config. I recommend xconfig, because it&#8217;s graphic and has a search feature, which turns out very useful.</li>
</ul>
<p>When targeting an embedded platform, the strategy is to enable whatever is necessary in the kernel itself, and not count on kernel modules. A second issue is to eliminate anything unnecessary from the kernel. This is not just a matter of the kernel image&#8217;s size and speed, but enabling components which have nothing to do there can cause the kernel compilation to fail, and even worse, the kernel to crash at boot. Each architecture maintains a set of #include headers, and some kernel components may assume certain things that these architecture-dependent parts haven&#8217;t caught up with. So the rule that is whatever hasn&#8217;t been tested, won&#8217;t necessarily work. Enabling an esoteric keyboard driver on a Microblaze processor may very well fail the boot, simply because nobody cares.</p>
<p>In particular, you most likely want to follow these:</p>
<ul>
<li>Under Platform Options, set CONFIG_KERNEL_BASE_ADDR to where your DDR RAM begins (0xC0000000 on my processor), the targeted FPGA family as well as the other parameters (USE_*). The USE_* parameters&#8217; correct values can be found in the .dts file. Just copy the values of the processor elements with the same names.</li>
<li>Also set<br />
CONFIG_SERIAL_UARTLITE=y<br />
CONFIG_SERIAL_UARTLITE_CONSOLE=y<br />
CONFIG_SERIAL_CORE=y<br />
CONFIG_SERIAL_CORE_CONSOLE=y</li>
<li>Since we&#8217;re not going to use any boot loader, the kernel command line needs to be compiled into the kernel itself: Enable CMDLINE_BOOL (default bootloader kernel argument) and set it to something useful. As for the console, set it to console=ttyUL0, or nothing goes to console after the two first lines sent to console from early_printk_console (CONFIG_CMDLINE_FORCE may be necessary as well. It doesn’t hurt in the absence of a boot loader anyhow)</li>
<li>Enable CONFIG_MSDOS_FS and CONFIG_VFAT_FS in kernel (not module), so that the SystemACE can be read.</li>
<li>Enable CONFIG_XILINX_SYSACE</li>
<li>Enable CONFIG_XILINX_EMACLITE and CONFIG_FB_XILINX</li>
<li>Disable the FTRACE config option (under kernel hacking, compilation fails) instead of <a href="http://developer.petalogix.com/git/gitweb.cgi?p=linux-2.6-microblaze.git;a=commitdiff;h=8ca502a9a5ddf16cede949391d982119aed07140" target="_blank">using patch</a>.</li>
</ul>
<p>And for your own sake, make a copy of the .config file every now and then as you work on it. It&#8217;s very easy to delete it by mistake or to mess it up in general.</p>
<p>Setting the Linux boot parameters correctly is very important, because if they&#8217;re wrong, kernel recompilation is they only way to fix it in the absence of a boot loader. I&#8217;ve chosen to mount the root directory from the network, but note that /dev/sxa is the Compact flash itself (with /dev/sxa1 is the first partition, for example). So it&#8217;s fairly simple to add a partition to the flash device, and put a regular root filesystem there. Maybe I&#8217;ll do that myself and update this post.</p>
<p>Anyhow, my choice for the Linux boot parameters was</p>
<pre>console=ttyUL0 ip=::::::dhcp rootfstype=nfs root=/dev/nfs rw nfsroot=10.11.12.13:/shared/nfsroot,tcp</pre>
<p>where &#8220;/shared/nfsroot&#8221; is the shared NFS directory on the server with IP 10.11.12.13. This command is suitable for getting the root from the network, which is very convenient for development. This setting requires a DHCP server on the LAN. In case you don&#8217;t want to configure a DHCP server, use the ip=&lt;client-ip&gt;:&lt;server-ip&gt;:&lt;gw-ip&gt;:&lt;netmask&gt;:::off format instead. Documentation/filesystems/nfs/nfsroot.txt in the kernel sources has more about booting from NFS. I&#8217;ve also written a post about booting a <a title="Root over NFS: Diskless boot from network" href="https://billauer.se/blog/2011/01/diskless-boot-nfs-cobbler/" target="_blank">diskless PC from network</a>, but it&#8217;s a bit of an overkill.</p>
<p>In case you&#8217;re interested in how the whole configuration thing comes together, let&#8217;s take CONFIG_EARLY_PRINTK for example. In arch/microblaze/kernel/Makefile, one of the lines says:</p>
<pre>obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o</pre>
<p>On the other hand, in the config file it can say</p>
<pre>CONFIG_EARLY_PRINTK=y</pre>
<p>So when the Makefile is executed, the target early_prink.o is added to either obj-y, obj-m or obj-n. obj-y is the list of objects to be inserted into the kernel, obj-m is the list of modules, and obj- is the junk list. The configuration rules are given in the Kbuild files, next to the Makefiles.</p>
<h3>A small Makefile fix</h3>
<p>As of 2.6.38, there is a small error in the arch/microblaze/boot/Makefile, which makes the build system always attempt making an U-Boot image, which is not necessary in our case. This may result in an error message (saying &#8220;mkimage&#8221; wasn&#8217;t found), when everything is actually OK. So in the part saying</p>
<pre>$(obj)/simpleImage.%: vmlinux FORCE
 $(call if_changed,cp,.unstrip)
 $(call if_changed,objcopy)
 <span style="color: #ff0000;"><del>$(call if_changed,uimage)</del></span>
 $(call if_changed,strip)
 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'</pre>
<p>remove or comment out the line saying &#8220;$(call if_changed,uimage)&#8221;.</p>
<h3>Compiling the kernel</h3>
<p>Before starting: You didn&#8217;t forget to set CROSS_COMPILE and copy the updated xilinx.dts file to its place&#8230; right?</p>
<p>I prefer cleaning up before compiling:</p>
<pre>make ARCH=microblaze clean
rm arch/microblaze/boot/simpleImage.*</pre>
<p>This is a good time to ask why the image file isn&#8217;t cleaned by &#8220;make clean&#8221;. To be fixed, I suppose.</p>
<p>And then, the compilation is just</p>
<pre>make -j 8 ARCH=microblaze simpleImage.xilinx</pre>
<p>Note that the &#8220;.xilinx&#8221; suffix corresponds to the xilinx.dts file in the arch/microblaze/boot/dts/ directory. If another .dts file should be made effective, change the suffix.</p>
<p>The &#8220;-j 8&#8243; means that 8 compilation processes run in parallel, which is suitable for a quad processor with hyperthreading. Skip this option or use another number, depending on your computer, your spare time and your need to see the logic of the events.</p>
<p>The basic UNIX rule is that everything went fine unless an error message appeared. A more explicit confirmation is that it said</p>
<pre>OBJCOPY arch/microblaze/boot/simpleImage.xilinx</pre>
<p>somewhere close to the end, and that the arch/microblaze/boot/simpleImage.xilinx is indeed there, and has a date stamp that makes sense.</p>
<p>If and when you get errors, well, there&#8217;s no simple  recipe to solve that. The easiest way is to eliminate the need to compile that certain file by changing the kernel configuration, if the functionality is indeed unnecessary. Otherwise your best friends are Google and your brain, not necessarily in that order.</p>
<p>As for the Device Tree, it was compiled into a .dtb file (the Device Tree binary blob), which can be found in the same directory as the just generated kernel image. The Device Tree Compiler (dtc) comes with the kernel sources, and can be found in scripts/dtc.</p>
<p>And just to wrap this up: If you insist on seeing all the commands issued instead of the otherwise laconic output, there the KBUILD_VERBOSE flag. For example,</p>
<pre>make ARCH=microblaze KBUILD_VERBOSE=1 clean</pre>
<p>With a compiled kernel image at hand (which already has the Device Tree built-in), all that&#8217;s left is to set up the Compact Flash and boot. Go to <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/">part III</a> of this HOWTO.</p>
<h3>A few other make statements</h3>
<p>For completeness:</p>
<ul>
<li>Clean up any compiled binaries: Recommended after a change in .config: &#8220;make ARCH=microblaze clean&#8221;</li>
<li>Generate loadable modules: &#8220;make ARCH=microblaze modules&#8221;. Not necessary if everything needed is compiled into the kernel.</li>
<li>And then gather the modules in a neat directory (making sure you <strong>don&#8217;t</strong> have a /lib/modules directory with the same version number): &#8220;make ARCH=microblaze modules_install&#8221;. This will write to /lib/modules on the <strong>local</strong> machine, so if you happen to compile exactly the same kernel version for your own PC and the embedded target, the kernel modules the PC relies on will be overwritten.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Linux on Microblaze HOWTO (part I)</title>
		<link>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/</link>
		<comments>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 08:06:54 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1589</guid>
		<description><![CDATA[This is part I of my HOWTO on running Linux on Microblaze. The outline is as follows: Part I: Introduction and setting up the Microblaze processor (this page) Part II: Compiling the kernel Part III: Preparing for boot and booting Part IV: Compiling user space applications Introduction This HOWTO goes through the procedures for getting [...]]]></description>
			<content:encoded><![CDATA[<p>This is part I of my HOWTO on running Linux on Microblaze. The outline is as follows:</p>
<ul>
<li>Part I: Introduction and setting up the Microblaze processor (this page)</li>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/" target="_blank">Part II: Compiling the kernel</a></li>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/" target="_blank">Part III: Preparing for boot and booting</a></li>
<li><a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-4/" target="_blank">Part IV: Compiling user space applications</a></li>
</ul>
<p><a href="http://xillybus.com/media/microblaze.html" target="_blank"><img class="aligncenter size-full wp-image-1880" title="xillybus-distro-banner" src="https://billauer.se/blog/wp-content/uploads/2011/07/xillybus-distro-banner.jpg" alt="" width="536" height="134" /></a></p>
<h3>Introduction</h3>
<p>This HOWTO goes through the procedures for getting a simple Linux system running on a Xilinx Microblaze processor. The examples are given for an SP605 evaluation board, but almost everything here applies for other FPGAs and boards as well. The Xilinx software version used here is 13.2.</p>
<p>There are quite a few variants on how to get the bitstream and Linux kernel into their right places in the FPGA. The approach taken here is to boot up from the Compact Flash alone by writing a file to it. No bootloader is used in this howto; the SystemACE chip is responsible for loading both the FPGA bitstream and Linux kernel image, and it will do so reading one single (.ace) file. The main advantage of this approach is that there&#8217;s no need to set up a boot loader, which is yet another piece of software that can go wrong. The main disadvantage is that a bootloader allows some tweaking of the kernel configuration at boot time, which has to be done by recompiling the kernel otherwise.</p>
<p>The root filesystem is mounted from network (NFS) in this HOWTO.</p>
<p>I&#8217;m assuming the following prerequisites:</p>
<ul>
<li>You have the Xilinx tools set up properly, and have managed to compile and run a simple standalone &#8220;Hello, World&#8221; application with the EDK/SDK (having loaded the code to the FPGA in any way, we&#8217;ll get to that)</li>
<li>You&#8217;ve actually seen the RS-232 console data on a terminal, and feel confident about it (otherwise you may work hard to figure out why everything is stuck, when it&#8217;s actually your terminal window&#8217;s problem).</li>
<li>You&#8217;re running on one of the evaluation boards, or know how to set up the processor to work with your own (and have that tested already)</li>
<li>Your board has a systemACE flash chip (recent evaluation boards usually do)</li>
<li>You have access to a machine running Linux on a computer. Compiling the kernel will require this. The Xilinx tools can be run on whatever&#8217;s your cup of tea.</li>
<li>You have the ability to read and write files to a Compact Flash. This is most easily done with a simple adapter to a PC computer, which should be available in camera or computer accessories shops. Chances are you have one without necessarily being aware of it.</li>
</ul>
<h3>An outline of the steps</h3>
<p>So this is what we&#8217;ll do:</p>
<ul>
<li>Set up a Microblaze processor in the Xilinx EDK so it can run Linux.</li>
<li>Generate the processor, so an FPGA bitstream is at hand.</li>
<li>Export the processor to the Xilinx SDK and compile a dummy C application, so that  necessary metadata files are generated</li>
<li>Generate a Device Tree file (.dts) based upon files created by EDK/SDK, and copy it into the Linux kernel sources, so Linux is in sync with the EDK regarding what it&#8217;s running on.</li>
<li>Configure the kernel and compile it.</li>
<li>Create a .ace file from the FPGA bitstream and kernel image just compiled.</li>
<li>Set up the Compact Flash card.</li>
<li>Boot and hope for good</li>
</ul>
<p>And of course, certain software tools will need to be downloaded for this. We&#8217;ll come to this.</p>
<h3>Setting up the processor</h3>
<p>If you&#8217;re really lazy about this, you can use the <a href="https://billauer.se/download/mblinux/linuxblaze.zip" target="_blank">minimal processor I&#8217;ve generated</a> for the SP605 board. Unzip, double-click system.xmp, and skip to after the bullets below. It will work on that board only, of course.<span style="color: #ff0000;"><strong><br />
</strong></span></p>
<p>Otherwise: Start Platform Studio (EDK) and create a new platform, based upon the Wizard&#8217;s defaults.</p>
<p>Following a <a href="http://xilinx.wikidot.com/microblaze-linux" target="_blank">Microblaze on Linux</a> guide, in particular the part regarding minimal hardware requirements, there a need to make sure that the hardware has an MMU with two regions, a timer, an interrupt controller and a UART with an interrupt line. In the platform studio it goes like this:</p>
<p>Starting off with the Wizard’s defaults,</p>
<ul>
<li>Double click “microblaze_0″ on the Ports tab, and set the Linux with MMU preset on the Configuration wizard showing up. This will take care of most settings.</li>
<li>Still in the ports view, add an AXI Interrupt Controller (under Clock, Reset and Interrupt in the IP Catalog). Accept default settings. Make a new connection for its irq output, and connect it to the microblaze_0′s interrupt input pin.</li>
<li>Pick the RS232_Uart_1 and make a new connection for the interrupt line. Connect that signal to the interrupt controller.</li>
<li>Add an AXI Timer/Counter, and accept defaults. Make a new connection for the interrupt, and connect it to the interrupt controller.</li>
<li>Connect the interrupts of the Ethernet lite, SPI Flash, IIC SFP, IIC EEPROM, IIC_DVI, and SysACE cores to the interrupt controller as well.</li>
</ul>
<p>Then generate bitstream, export to SDK, and run the SDK, adopting this hardware platform. The goal of this is to generate a .mss file, which will be needed later. For this to happen, make a new C project (&#8220;Hello World&#8221; will do just fine) and compile it.</p>
<p>There is <strong>no need</strong> to <a href="https://billauer.se/blog/2011/07/microblaze-platform-studio-bitinit-data2mem/" target="_blank">&#8220;update the bitstream&#8221;</a> like with standalone applications: The Linux kernel can take care of itself, without having its entry address hardwired in the FPGA&#8217;s block RAM. We&#8217;ll use the system.bit, and not the download.bit (even though the latter works too).</p>
<h3>Creating a Device Tree file</h3>
<p>The purpose of this stage is to generate a .dts file, which is the format expected by the kernel build environment. It informs the kernel about the structure of the processor and its peripherals. The device tree structure is discusses further <a href="https://billauer.se/blog/2011/08/dts-of-open-firmware-microblaze/" target="_blank">here</a>.</p>
<p>If you chose to download and use my processor with no changes whatsoever, you can also <a href="https://billauer.se/download/mblinux/xilinx.dts" target="_blank">get my DTS file</a>. Just copy it to arch/microblaze/boot/dts/ in the to-be compiled kernel source tree.<span style="color: #ff0000;"><strong></strong></span></p>
<p>To make your own .dts file, first create a special directory, and make it the working directory of your shell.</p>
<p>The device tree file is generated automatically with the libgen utility with the help of a Tcl script. As of ISE 13.2, this script needs to be loaded separately with git:</p>
<pre><code>bash&gt; git clone git://git.xilinx.com/device-tree.git</code></pre>
<p>This generates a device-tree directory. Another <a href="http://xilinx.wikidot.com/device-tree-generator" target="_blank">web page</a> explains how to make SDK recognize the script, but I prefer command line for things like this. Another <a href="https://billauer.se/blog/2011/08/dts-of-open-firmware-microblaze/" target="_blank">post of mine</a> explains the device tree further.</p>
<p>Copy the system.xml file from the directory to which you exported to SDK (in the &#8220;hw&#8221; subdirectory), into the current one. Then copy system.mss from the project&#8217;s BSP directory. It will have a name like hello_world_bsp_0.</p>
<p>Edit the copy you made of system.mss, so that the BEGIN OS to END part reads</p>
<pre>BEGIN OS
 PARAMETER OS_NAME = device-tree
 PARAMETER OS_VER = 0.00.x
 PARAMETER PROC_INSTANCE = microblaze_0
END</pre>
<p>and not “standalone” for OS.</p>
<p>And then run libgen as follows (make sure it&#8217;s in the PATH. The easiest way is to launch a &#8220;Xilinx shell&#8221; from the EDK&#8217;s project menu):</p>
<pre>libgen -hw system.xml -lp device-tree -pe microblaze_0 -log libgen.log system.mss</pre>
<p>Which generates a xilinx.dts in microblaze_0/libsrc/device-tree_v0_00_x. Copy this file to arch/microblaze/boot/dts/ in the to-be compiled kernel source tree. If you can&#8217;t find the file there, and libgen didn&#8217;t complain about some error, you may have forgotten to edit system.mss as mentioned just above.</p>
<p>Now let&#8217;s go on to compiling the kernel, in <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-2/">part II</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>The Device Tree for embedded Linux and Xilinx FPGAs</title>
		<link>https://billauer.se/blog/2011/08/dts-of-open-firmware-microblaze/</link>
		<comments>https://billauer.se/blog/2011/08/dts-of-open-firmware-microblaze/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 10:14:46 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Linux kernel]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1557</guid>
		<description><![CDATA[Spoiler It&#8217;s very likely that you don&#8217;t need to read this. If all you want is to get a Linux kernel to detect a Microblaze processor on an Xilinx FPGA, the relevant information is in another post of mine. This post goes into the details which are necessary to understand, if you want to write [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xillybus.com/media/microblaze.html" target="_blank"><img class="aligncenter size-full wp-image-1880" title="xillybus-distro-banner" src="https://billauer.se/blog/wp-content/uploads/2011/07/xillybus-distro-banner.jpg" alt="" width="536" height="134" /></a></p>
<h3>Spoiler</h3>
<p>It&#8217;s very likely that you don&#8217;t need to read this. If all you want is to get a Linux kernel to detect a Microblaze processor on an Xilinx FPGA, the relevant information is in <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-1/" target="_blank">another post of mine</a>. This post goes into the details which are necessary to understand, if you want to write a kernel driver for a device tree mapped peripheral.</p>
<h3>Why a device tree is necessary</h3>
<p>The main issue with running Linux on an FPGA is that the Linux kernel needs to know what peripherals it has and where it can find them. On PC computers this problem was solved many years ago with the PCI bus: The BIOS detects the peripherals, allocates their addresses and interrupts and tells the operating system what it has and where it can be found. In the embedded world, this information was hardcoded into pieces of the kernel sources, which were written specifically for every board. With many boards out there, the kernel source grew way too fast. This far-from-optimal solution is not feasible with a soft processor, whose peripherals are configured per case. Hacking the kernel sources to match the FPGA is a recipe for bugs, crashes and being stuck with a certain kernel forever.</p>
<p>The elegant solution for this is the Flattened Device Tree. The idea is to create some binary data structure, which is either linked into the kernel image or given to it during boot. This binary blob contains the information about the processor itself and its peripherals, including the addresses, interrupts and several application-specific parameters. So the drivers for these peripherals are written very similar to PCI drivers: They declare what peripherals they support, and obtain their resources from a standard kernel API.</p>
<p>The code for Flattened Device Tree and Open Firmware resides in drivers/of in the kernel tree. The relevant include file is include/linux/of.h.</p>
<h3>Generation</h3>
<p>Note that at least for Xilinx FPGAs, there is no need to generate the device tree manually. Rather, get a copy of the <a href="http://xilinx.wikidot.com/device-tree-generator" target="_blank">device tree generator</a> with</p>
<pre><code>bash&gt; git clone git://git.xilinx.com/device-tree.git</code></pre>
<p>which basically consists of a TCL script run by libgen and a configuration file. The <a href="http://xilinx.wikidot.com/device-tree-generator" target="_blank">device tree generator&#8217;s page</a> explains how to make SDK recognize the script, but there&#8217;s no reason to play around with SDK for that.</p>
<p>Instead, go</p>
<pre>libgen -hw /path/to/system.xml -lp /path/to/device-tree -pe microblaze_0 -log libgen.log system.mss</pre>
<p>Which generates a system.dts in microblaze_0/libsrc/device-tree_v0_00_x</p>
<p>The system.mss file is generated as a byproduct when compiling just any a project  within SDK, and is found under the directory with the _bsp_n suffix. I  still need to find out how to create the file from the command line.</p>
<p>It needs to be modified, so that the BEGIN OS to END part reads</p>
<pre>BEGIN OS
 PARAMETER OS_NAME = device-tree
 PARAMETER OS_VER = 0.00.x
 PARAMETER PROC_INSTANCE = microblaze_0
END</pre>
<p>and not &#8220;standalone&#8221; for OS.</p>
<p>To get the system.xml file (which was necessary to create the system.mss), go Project &gt; Export Hardware to SDK  in the EDK platform studio. Or</p>
<pre>make -f system.make exporttosdk</pre>
<p>from the project&#8217;s home directory.</p>
<p>The correct setup of the device tree entry can be found in the Documentation/devicetree/bindings directory of the kernel sources. The xilinx.txt file describes the bindings for Xilinx peripherals, and explains how information in the system.mhs file is translated into a xilinx.dts.</p>
<p>As part of a full kernel compilation, the .dts is compiled into a .dtb file (the Device Tree binary blob), which can be found in the same directory as the generated kernel image. The Device Tree Compiler (dtc) comes with the kernel sources, and can be found in scripts/dtc.</p>
<h3>A sample entry</h3>
<p>The following example is given there for a Uartlite (which we&#8217;ll follow on below):</p>
<pre>opb_uartlite_0: serial@ec100000 {
 device_type = "serial";
 compatible = "xlnx,opb-uartlite-1.00.b";
 reg = &lt;ec100000 10000&gt;;
 interrupt-parent = &lt;&amp;opb_intc_0&gt;;
 interrupts = &lt;1 0&gt;; // got this from the opb_intc parameters
 current-speed = &lt;d#115200&gt;;     // standard serial device prop
 clock-frequency = &lt;d#50000000&gt;; // standard serial device prop
 xlnx,data-bits = &lt;8&gt;;
 xlnx,odd-parity = &lt;0&gt;;
 xlnx,use-parity = &lt;0&gt;;
 };</pre>
<p>It&#8217;s recommended to have a look at arch/microblaze/platform/generic/system.dts in the kernel sources for a fullblown file. Or one you&#8217;ve generated yourself, for that matter.</p>
<h3>Declarations in a kernel module driver</h3>
<p>Device tree mapped instances are treated by the kernel very much like PCI devices, only the source of information is the DTB (Device Tree Binary) rather than from the BIOS.</p>
<p>The parallel to PCI&#8217;s Vendor/Product IDs is an entry looking like this (taken from uartlite.c):</p>
<pre>static struct of_device_id ulite_of_match[] __devinitdata = {
 { .compatible = "xlnx,opb-uartlite-1.00.b", },
 { .compatible = "xlnx,xps-uartlite-1.00.a", },
 {}
};

MODULE_DEVICE_TABLE(of, ulite_of_match)</pre>
<p>Which is then bound to a driver with</p>
<pre>static struct of_platform_driver ulite_of_driver = {
 .probe = ulite_of_probe,
 .remove = __devexit_p(ulite_of_remove),
 .driver = {
 .name = "uartlite",
 .owner = THIS_MODULE,
 .of_match_table = ulite_of_match,
 },
}</pre>
<p>and then, finally, exposed to the kernel with</p>
<pre>static inline int __init ulite_of_register(void)
{
 pr_debug("uartlite: calling of_register_platform_driver()\n");
 return of_register_platform_driver(&amp;ulite_of_driver);
}</pre>
<p>somewhere at the end of the driver&#8217;s code. This format is very similar to the declaration of PCI devices, so if this is unclear, I&#8217;d suggest learning how to do it the PCI way, which is by far more documented.</p>
<p>And by the way, when the kernel is configured to support it, the device tree can be viewed in human-readable format in /proc/device-tree.</p>
<h3>The of_device_id structure</h3>
<p>The structure is defined in include/linux/mod_devicetable.h as</p>
<pre>struct of_device_id
{
 char    name[32];
 char    type[32];
 char    compatible[128];
#ifdef __KERNEL__
 void    *data;
#else
 kernel_ulong_t data;
#endif
};</pre>
<p>Surprisingly enough, the lengths of the entries are fixed and limited.The three strings, name, type and compatible are compared as strings (with strcmp(), see of/base.c) with the device tree&#8217;s node&#8217;s data. Everything declared (that is, non-NULL) in the structure must be equal with the node&#8217;s info for a match. In other words, NULLs are wildcards.</p>
<p>In the declaration example above, only the &#8220;compatible&#8221; part was declared, so any device matching the string exactly triggers off a probe on the driver.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/08/dts-of-open-firmware-microblaze/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Xilinx EDK &#8220;update bitstream&#8221; process: A closer look</title>
		<link>https://billauer.se/blog/2011/07/microblaze-platform-studio-bitinit-data2mem/</link>
		<comments>https://billauer.se/blog/2011/07/microblaze-platform-studio-bitinit-data2mem/#comments</comments>
		<pubDate>Sat, 30 Jul 2011 16:33:22 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1529</guid>
		<description><![CDATA[Introduction The Xilinx Platform Studio (EDK) has this &#8220;update bitstream&#8221; function, which I wasn&#8217;t so clear about, despite its documentation page. Its icon says &#8220;BRAM INIT&#8221; which turns out to be more accurate than expected. So what happens during this process? When is it necessary? If you&#8217;re into running a Linux kernel, you&#8217;re most likely [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xillybus.com/media/microblaze.html" target="_blank"><img class="aligncenter size-full wp-image-1880" title="xillybus-distro-banner" src="https://billauer.se/blog/wp-content/uploads/2011/07/xillybus-distro-banner.jpg" alt="" width="536" height="134" /></a></p>
<h3>Introduction</h3>
<p>The Xilinx Platform Studio (EDK) has this &#8220;update bitstream&#8221; function, which I wasn&#8217;t so clear about, despite <a href="http://www.xilinx.com/support/documentation/sw_manuals/xilinx11/pp_p_process_update_bitstream_processor_data_xps.htm" target="_blank">its documentation page</a>. Its icon says &#8220;BRAM INIT&#8221; which turns out to be more accurate than expected. So what happens during this process? When is it necessary?</p>
<p>If you&#8217;re into running a Linux kernel, you&#8217;re most likely wasting your time reading this, because the Linux kernel is kicked off directly from the external RAM, and hence this mangling isn&#8217;t necessary. To set up a Linux bitstream, see <a href="https://billauer.se/blog/2011/08/linux-microblaze-howto-tutorial-primer-3/" target="_blank">another post</a> of mine.</p>
<p>Having that said, let&#8217;s look at the problem this functions solves: A Microblaze processor starts executing at address 0 unless told otherwise. Its interrupt vectors are at near-zero addresses as well. These addresses are mapped to an FPGA block RAM.</p>
<p>What this block RAM should contain is a jump to the application&#8217;s entry point. On a SP605 board, this is most likely the beginning of the DDR memory, Oxc0000000. So when the processor kicks off, this block RAM&#8217;s address zero should contain:</p>
<pre>00000000 &lt;_start&gt;:
 0:    b000c000     imm    -16384
 4:    b8080000     brai    0
</pre>
<p>Which is Microblazish for &#8220;Jump to Oxc0000000&#8243; (note the lower 16 bits of both commands).</p>
<p>When a system is booted, there are two phases: First, the FPGA is loaded with its bitstream, and then the external memory, containing the bulk of execution code. And then the processor is unleashed.</p>
<p>So the block memory&#8217;s correct content needs to be included in the bitstream itself. But when the processor is implemented from its logic elements, it isn&#8217;t clear what should be written there. It&#8217;s only when the software is linked, that the addresses of the different segments are known.</p>
<p>But software compilation and linking requires the knowledge of the processor&#8217;s memory map, which is generated while the processor is implemented. So there&#8217;s a chicken-and-egg situation here.</p>
<h3>The egg was first</h3>
<p>The solution is that block RAM&#8217;s content is fixed after the software is compiled and linked. The reset and interrupt vectors are included in the ELF file generated by the software linker, and are mapped to the block RAM&#8217;s addresses. The &#8220;update bitstream&#8221; process reads the ELF file, finds the relevant region, and updates the bitstream file, producing the download.bit file. That&#8217;s why choosing the ELF file is necessary for this process.</p>
<h3>Necessity</h3>
<p>The original problem was that the execution starts from address zero. But if the ELF file points at the real starting point, and this is properly communicated to the processor at startup, there&#8217;s no need to set up the block RAM at all. Well, assuming that the executable takes care of interrupts and exception vectors soon enough. This is the case with Linux kernel images, for example, for which there is no need to update the bitstream.</p>
<h3>Some gory details</h3>
<p>The &#8220;update bitstream&#8221; process launches a command like</p>
<pre>bitinit -p xc6slx45tfgg484-3 system.mhs -pe microblaze_0 sdk/peripheral_tests_0/Debug/peripheral_tests_0.elf \
 -bt implementation/system.bit -o implementation/download.bit</pre>
<p>which takes place in two phases. In the first phase, the system.mhs file is read and parsed, so that the memory map is known and the block RAM is identified. This program then runs something like</p>
<pre>data2mem -bm "implementation/system_bd" -p xc6slx45tfgg484-3 -bt "implementation/system.bit" -bd "sdk/peripheral_tests_0/Debug/peripheral_tests_0.elf" tag microblaze_0 -o b implementation/download.bit</pre>
<p>Which is the action itself. Data2mem is a utility for mangling bitstreams so that their block RAMs contain desired data. The -bm flag tells data2mem to get the block RAM map from implementation/system_bd.bmm, which can be</p>
<pre>// BMM LOC annotation file.
//
// Release 13.2 - Data2MEM O.61xd, build 2.2 May 20, 2011
// Copyright (c) 1995-2011 Xilinx, Inc.  All rights reserved.

///////////////////////////////////////////////////////////////////////////////
//
// Processor 'microblaze_0', ID 100, memory map.
//
///////////////////////////////////////////////////////////////////////////////

ADDRESS_MAP microblaze_0 MICROBLAZE-LE 100

 ///////////////////////////////////////////////////////////////////////////////
 //
 // Processor 'microblaze_0' address space 'microblaze_0_bram_block_combined' 0x00000000:0x00001FFF (8 KBytes).
 //
 ///////////////////////////////////////////////////////////////////////////////

 ADDRESS_SPACE microblaze_0_bram_block_combined RAMB16 [0x00000000:0x00001FFF]
 BUS_BLOCK
 microblaze_0_bram_block/microblaze_0_bram_block/ramb16bwer_0 [31:24] INPUT = microblaze_0_bram_block_combined_0.mem PLACED = X3Y30;
 microblaze_0_bram_block/microblaze_0_bram_block/ramb16bwer_1 [23:16] INPUT = microblaze_0_bram_block_combined_1.mem PLACED = X2Y30;
 microblaze_0_bram_block/microblaze_0_bram_block/ramb16bwer_2 [15:8] INPUT = microblaze_0_bram_block_combined_2.mem PLACED = X2Y32;
 microblaze_0_bram_block/microblaze_0_bram_block/ramb16bwer_3 [7:0] INPUT = microblaze_0_bram_block_combined_3.mem PLACED = X2Y36;
 END_BUS_BLOCK;
 END_ADDRESS_SPACE;

END_ADDRESS_MAP;</pre>
<p>So this file defines the addresses covered as well as the physical positions of these block RAMs in the logic fabric.</p>
<p>The -bd flag points at the ELF file to get the data from, with the &#8220;tag microblaze_0&#8243; part saying that only the memories tagged microblaze_0 in the .bmm file should be handled, and the rest ignored.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/07/microblaze-platform-studio-bitinit-data2mem/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Microblaze ELF: A small look inside</title>
		<link>https://billauer.se/blog/2011/07/microblaze-elf-the-svf-and-ace/</link>
		<comments>https://billauer.se/blog/2011/07/microblaze-elf-the-svf-and-ace/#comments</comments>
		<pubDate>Sat, 30 Jul 2011 15:33:03 +0000</pubDate>
		<dc:creator>eli</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Microblaze]]></category>

		<guid isPermaLink="false">https://billauer.se/blog/?p=1519</guid>
		<description><![CDATA[This is a small reverse-engineering of the ELF file, as generated by Xilinx&#8217; SDK for a simple standalone application targeted for the SP605 board. ELF headers Looking into the ELF file, we have something like this: &#62; mb-objdump --headers sdk/peripheral_tests_1/Debug/peripheral_tests_1.elf sdk/peripheral_tests_1/Debug/peripheral_tests_1.elf:     file format elf32-microblazele Sections: Idx Name          Size      VMA       LMA       File off  Algn 0 .vectors.reset [...]]]></description>
			<content:encoded><![CDATA[<p>This is a small reverse-engineering of the ELF file, as generated by Xilinx&#8217; SDK for a simple standalone application targeted for the SP605 board.</p>
<h3>ELF headers</h3>
<p>Looking into the ELF file, we have something like this:</p>
<pre>&gt; mb-objdump --headers sdk/peripheral_tests_1/Debug/peripheral_tests_1.elf

sdk/peripheral_tests_1/Debug/peripheral_tests_1.elf:     file format elf32-microblazele

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
 0 .vectors.reset 00000008  00000000  00000000  000000b4  2**2
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 1 .vectors.sw_exception 00000008  00000008  00000008  000000bc  2**2
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 2 .vectors.interrupt 00000008  00000010  00000010  000000c4  2**2
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 3 .vectors.hw_exception 00000008  00000020  00000020  000000cc  2**2
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 4 .text         0000653c  c0000000  c0000000  000000d4  2**2
 CONTENTS, ALLOC, LOAD, CODE
 5 .init         0000003c  c000653c  c000653c  00006610  2**2
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 6 .fini         0000001c  c0006578  c0006578  0000664c  2**2
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 7 .ctors        00000008  c0006594  c0006594  00006668  2**2
 CONTENTS, ALLOC, LOAD, DATA
 8 .dtors        00000008  c000659c  c000659c  00006670  2**2
 CONTENTS, ALLOC, LOAD, DATA
 9 .rodata       00000986  c00065a4  c00065a4  00006678  2**2
 CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .sdata2       00000006  c0006f2a  c0006f2a  00006ffe  2**0
 ALLOC
 11 .sbss2        00000000  c0006f30  c0006f30  000071d8  2**0
 CONTENTS
 12 .data         000001d0  c0006f30  c0006f30  00007000  2**2
 CONTENTS, ALLOC, LOAD, DATA
 13 .eh_frame     00000004  c0007100  c0007100  000071d0  2**2
 CONTENTS, ALLOC, LOAD, DATA
 14 .jcr          00000004  c0007104  c0007104  000071d4  2**2
 CONTENTS, ALLOC, LOAD, DATA
 15 .sdata        00000000  c0007108  c0007108  000071d8  2**0
 CONTENTS
 16 .sbss         00000000  c0007108  c0007108  000071d8  2**0
 CONTENTS
 17 .tdata        00000000  c0007108  c0007108  000071d8  2**0
 CONTENTS
 18 .tbss         00000000  c0007108  c0007108  000071d8  2**0

 19 .bss          00000d78  c0007108  c0007108  000071d8  2**2
 ALLOC
 20 .heap         00000400  c0007e80  c0007e80  000071d8  2**0
 ALLOC
 21 .stack        00000400  c0008280  c0008280  000071d8  2**0
 ALLOC
 22 .debug_line   0000779f  00000000  00000000  000071d8  2**0
 CONTENTS, READONLY, DEBUGGING
 23 .debug_info   00008b11  00000000  00000000  0000e977  2**0
 CONTENTS, READONLY, DEBUGGING
 24 .debug_abbrev 000028e7  00000000  00000000  00017488  2**0
 CONTENTS, READONLY, DEBUGGING
 25 .debug_aranges 000006c0  00000000  00000000  00019d70  2**3
 CONTENTS, READONLY, DEBUGGING
 26 .debug_macinfo 0007f541  00000000  00000000  0001a430  2**0
 CONTENTS, READONLY, DEBUGGING
 27 .debug_frame  00000f10  00000000  00000000  00099974  2**2
 CONTENTS, READONLY, DEBUGGING
 28 .debug_loc    00003f80  00000000  00000000  0009a884  2**0
 CONTENTS, READONLY, DEBUGGING
 29 .debug_pubnames 00000fbe  00000000  00000000  0009e804  2**0
 CONTENTS, READONLY, DEBUGGING
 30 .debug_str    000018d5  00000000  00000000  0009f7c2  2**0
 CONTENTS, READONLY, DEBUGGING
 31 .debug_ranges 00000078  00000000  00000000  000a1097  2**0
 CONTENTS, READONLY, DEBUGGING</pre>
<p>Even though this is a lot of mumbo-jumbo, there are three main parts. The reset and interrupt vectors, around address zero, the main parts of the ELF (.text, .data and such) at Oxc0000000 and on, and the debug parts which have no memory allocation at all.</p>
<h3>The reset branch to application</h3>
<p>This is interesting to compare with the Microblaze&#8217;s memory map. It can be deduced from the .mhs file, but hey, the log file (with .log suffix) has this segment:</p>
<pre>Address Map for Processor microblaze_0
 (0000000000-0x00001fff) microblaze_0_d_bram_ctrl    microblaze_0_dlmb
 (0000000000-0x00001fff) microblaze_0_i_bram_ctrl    microblaze_0_ilmb
 (0x40000000-0x4000ffff) Push_Buttons_4Bits    axi4lite_0
 (0x40020000-0x4002ffff) LEDs_4Bits    axi4lite_0
 (0x40040000-0x4004ffff) DIP_Switches_4Bits    axi4lite_0
 (0x40600000-0x4060ffff) RS232_Uart_1    axi4lite_0
 (0x40800000-0x4080ffff) IIC_SFP    axi4lite_0
 (0x40820000-0x4082ffff) IIC_EEPROM    axi4lite_0
 (0x40840000-0x4084ffff) IIC_DVI    axi4lite_0
 (0x40a00000-0x40a0ffff) SPI_FLASH    axi4lite_0
 (0x40e00000-0x40e0ffff) Ethernet_Lite    axi4lite_0
 (0x41800000-0x4180ffff) SysACE_CompactFlash    axi4lite_0
 (0x74800000-0x7480ffff) debug_module    axi4lite_0
 (0xc0000000-0xc7ffffff) MCB_DDR3    axi4_0</pre>
<p>So obviously all the main ELF parts go directly to the DDR memory (that isn&#8217;t much of a surprise), and the reset/interrupt go to the internal block ram.</p>
<p>A quick disassembly reveals the gory details:</p>
<pre>&gt; mb-objdump --disassemble sdk/peripheral_tests_1/Debug/peripheral_tests_1.elf
sdk/peripheral_tests_1/Debug/peripheral_tests_1.elf:     file format elf32-microblazele

Disassembly of section .vectors.reset:

00000000 &lt;_start&gt;:
 0:    b000c000     imm    -16384
 4:    b8080000     brai    0
Disassembly of section .vectors.sw_exception:

00000008 &lt;_vector_sw_exception&gt;:
 8:    b000c000     imm    -16384
 c:    b8081858     brai    6232
Disassembly of section .vectors.interrupt:

00000010 &lt;_vector_interrupt&gt;:
 10:    b000c000     imm    -16384
 14:    b80818a4     brai    6308
Disassembly of section .vectors.hw_exception:

00000020 &lt;_vector_hw_exception&gt;:
 20:    b000c000     imm    -16384
 24:    b8081870     brai    6256
Disassembly of section .text:

c0000000 &lt;_start1&gt;:
c0000000:    b000c000     imm    -16384
c0000004:    31a07108     addik    r13, r0, 28936
c0000008:    b000c000     imm    -16384
c000000c:    30406f30     addik    r2, r0, 28464
<em>(... and it goes on and on ...</em>)</pre>
<p>So let&#8217;s look at the reset vector at address zero. The first IMM opcode loads C000 as the upper 16 bits for the command following, which is a branch immediate command. Together, they make a jump to Oxc000000. Likewise, the software exception jumps to Oxc0001858 and so on.</p>
<p>Since only the block RAM part can be included in the download.bit bitfile, only these jump vectors depend on the ELF file during the &#8220;Update bitfile&#8221; process. That&#8217;s why one gets away with not running this process, even when the ELF has been modified with a plain recompilation.</p>
<h3>And now to the bootloop ELF</h3>
<p>So what is the bootloop code doing? The headers are no more impressive than</p>
<pre>&gt; mb-objdump --headers bootloops/microblaze_0.elf

bootloops/microblaze_0.elf:     file format elf32-microblazele

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
 0 .boot         00000004  00000000  00000000  00000074  2**0
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 1 .text         00000000  00000000  00000000  00000074  2**0
 CONTENTS, ALLOC, LOAD, READONLY, CODE
 2 .data         00000000  00000000  00000000  00000074  2**0
 CONTENTS, ALLOC, LOAD, DATA
 3 .bss          00000000  00000000  00000000  00000078  2**0
 ALLOC</pre>
<p>Note the Size column: All entries are empty, except for the .boot section, which is four bytes small (one single instruction). That doesn&#8217;t leave room for sophisticated software, and the disassembly is indeed</p>
<pre>&gt; mb-objdump --disassemble bootloops/microblaze_0.elf

bootloops/microblaze_0.elf:     file format elf32-microblazele

Disassembly of section .boot:

00000000 &lt;_boot&gt;:
 0:    b8000000     bri    0        // 0</pre>
<p>Which is simply an endless loop. So they called it bootloop for a reason.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://billauer.se/blog/2011/07/microblaze-elf-the-svf-and-ace/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
