Compiled QEMU With Static Linking and Curses Enabled for 32-Bit Linux

by Mike Levin SEO & Datamaster, 10/24/2013

There is a conundrum in the realm of technology, tools, and achieving the sort of mastery that artists and craftsmen achieve with their tools. Certain things like hammers and violins are timeless, and the musician and carpenter automatically used the tools of their trade with hardly a thought. Because technology is a constantly fluid, evolving field, would-be artisans and craftsmen in the field of technology are perpetually set back in their pursuit of a sort of mastery achievable in other fields. It doesn’t have to be this way. This is a recurring theme in my writings, and it is my starting point in today’s thoughts as I think through my next steps professionally and with my own remix of Linux for education, called Levinux.

Yesterday, I met a mentor of mine named Gerard Bucas for lunch. My history with him goes back to a company called Great Valley Products (GVP), which was a company he founded in the Valley Forge area near Philadelphia, near where I grew up and near where Commodore Computers was headquartered. Meeting with him is always very thought-provoking and fueling my creative thoughts for the months, and sometimes years, between the meetings we have now and then over the years. He founded GVP as a Commodore peripheral company, doing the things that Commodore engineering itself lacked the self-will and determination to do, like high performance hard drive controllers and graphics cards. Chats with him always go down similar veins of: what’s just now possible in terms of technology, systems, and communication. We were in the digital signage industry together for a few years at Scala in Pennsylvania, before my path led me to New York. None-the-less, we have kept in touch over the years. He is one of the few people who not only gets what I’m talking about, but has “been there and done that”… sometimes more than once. Gerard is a wonderful sounding-wall, and asks most of the right questions as they relate to his own endeavors to illuminate aspects of my own endeavors that I have not yet thoroughly enough thought about. Talking with Gerard helps me navigate my “next steps” and plan my roadmap.

I actually have a roadmap / next steps page on my website, and it is time that I updated it. There are so many distractions, but sometimes within the distractions are the creative seeds and the nested projects that make all the difference in the more important work. It’s a lot like the unpredictability of life itself, and you just have to intuit your way through some of the first-pass stuff, until you have enough good information to make better and better next-step decisions. That’s the point I’m at right now. I need to intuit my way through my next steps. I need to refine my roadmap… probably even on the public website version, without that itself becoming an excessive distraction.

There is so much to be distracted by. But I need to choose my immediate work, and the way I tackle it, with a certain timelessness in mind. The things I do and learn on the way, should and can, be equally applicable and relevant 5 or 10 years down the line as they are today. Not everything is throw-away work. Some things can put you on the path to tool-mastery. It was becoming pretty clear to me that the Unix/Linux underlying guts of everything was the lowest level in the abstraction pyramid of modern (and timeless) tools that a developer (pursuer of dreams) should ever have to address. There are certain aspects of optimization that could bring you to lower levels, but those details vary dramatically from platform to platform (such as are you on a register or stack based processor), and most developers - even those who want to “plunge deep” through the abstraction stacks for optimization - would rarely have to go to that level. Everyone would rather gain the advantages of the APIs (application program interfaces) that are inserted between abstraction layers to keep coding simpler, more portable between execution environments (hardware), and therefore also longer-lived.

Yet, there are great optimization and application performance advantages and technological miracles that can be performed diving down deep through the abstraction layers. There is a sort of corollary rapid implementation miracles (do work fast / reap the benefits fast) that can be performed embracing the latest and greatest abstraction goodies, and just accept that your tools are completely going to be reinvented underneath of you every 2 to 10 years, and you’re going to continually have to go through a retraining to just stay as good as you are today. Forget ever achieving the spontaneous expertise with your tools of a master craftsmen or artist. And, so it is a spectrum, and much of success in technology and career comes down to where to live on that spectrum MOST OF THE TIME, and where to be able to where to make the occasional jaunts and excursions.

THAT is what this post is about. Clearly, I have made quite a commitment to what I call the “short stack” with Levinux, consisting of Linux, Python, vim and git as the four timeless and pragmatic pillars of 80/20 rule effectiveness. Be able to do 80% of the things you want to be able to do by focusing on only the first 20% of what you feel you need to know and should be doing. Within that 20% are certain aspects of the Linux/Unix command world, which in itself you could spend a lifetime. It is something I have long envisioned as inescapable, so you might as well learn it. My recent journey into the Google App Engine was my first cloud experience (maybe Heroku really was) that isolated you from the underlying Linux/Unix environment through an abstraction layer that dealt with. That was an awakening.

Okay, it’s been about a year since my last attempt to build QEMU from source. I failed on several fronts. I couldn’t do a static compile, embedding all the requirements right into the binary, which would have been a huge boon to the Levinux project. I was unable to make make it uses ncurses across all platforms: Mac, Windows and Linux. It’s time to try again, just to clarify things in my mind again, with a year’s accumulated wisdom now, having Levinux out there for nearly a year in beta, now up to revision 2.1. That means I’ve had 11 revisions so far! Wow. But it’s still a magic cocktail mix, and I’d like to start fixing that, taking deeper control of what I’ve done.

Okay, so my Linux platform this time will be Ubuntu 13.04 under VMWare Fusion on my Macbook Air. Step 1:

sudo apt-get install build-essential

Next, I’m going to download qemu-1.6.1 from qemu.org. There has been A LOT of work on QEMU since I started this whole undertaking AGES ago. I actually started out before version 1.0 and before QEMU was out of beta.

Uncompress it, and put the qemu-1.6.1 directory in my ~/ home folder.

Some URLs from my past… http://mikelev.in/2012/10/compiling-qemu-from-source-on-linux/ http://mikelev.in/2012/05/compiling-qemu-on-mac-or-any-platform-isnt-easy/

Some new URLs to help… https://bugs.launchpad.net/qemu/+bug/1094786 http://askubuntu.com/questions/335875/error-zlib-check-failed-while-compiling-qemu

It appears that a shortcut to get all the qemu dependencies is:

sudo apt-get build-dep qemu

Okay, then you can cd into the qemu directory and trigger off the minimal config command that doesn’t raise too many new issues:

./configure –target-list=i386-softmmu –enable-curses

Then…

make

sudo make install

And after that, you will have all the qemu files in /usr/local/bin/

The qemu-system-i386 file in there can actually be moved into location in Levinux, and the following line needs to be edited out of the start script:

LD_LIBRARY_PATH=./

…(when you’re on a 32 bit system) and Levinux will actually work with the newly compiled QEMU binary. In fact, if the -curses parameter is added, QEMU will run in text-only mode, and the pointer capturing problem goes away!

Okay, I just tried it with the –static configure parameter, and when I do that, I DON’T HAVE TO EDIT OUT the LD_LIBRARY_PATH=./ line from the launch script! But if I don’t add the -curses parameter on running QEMU, then it tries to run in VNC mode. Very interesting. But I’m on the right track.

Unfortunately, the QEMU binary alone is 6MB, and I can’t be sure that it’s not finding dynamic library dependencies outside the qemu directory. And so, I’m going to drop this work-in-progress Levinux folder into Dropbox, and use VMWare fusion to roll back to a snapshot prior to installing the qemu dependencies.

It’s just a wee bit crazy, but what I’m doing here is rolling back the state of my system to before I did the “sudo apt-get build-dep qemu” command and the building of qemu from source, but shuttling the end product (the updated Levinux folder) “back in time” such as it were, to see if it’s truly self-contained (or at least not dependent on anything outside a default Ubuntu install).

If this works, then I will have my first truly text-only (no VGA SDL driver that causes pointer capture) version of Levinux. It will be on Linux only, and I wouldn’t want to roll it out without making the same thing work on Windows and Mac (not to mention all the other versions of Linux I’d need to test against). Also, I would be very interested in getting the size of the qemu binary down, and that MAY be possible by using configure with all the –disable-xen and this-and-that to make a super-minimal yet still modern qemu binary.

IT WORKED!

Okay, the key learnings here are:

1. We can build the gnu gcc compiler toolchain easily in Ubuntu with apt-get install build-essentials.

2. We can collect the qemu dependencies easily in Ubuntu with apt-get build-dep qemu.

3. We can use the configure statement: ./configure –target-list=i386-softmmu –enable-curses …but when we do, we have DISABLED the ability to start qemu from the command-line WITHOUT the -curses parameter, or it will go into headless VNC mode.

4. The –static configure parameter does in fact have an effect, making the qemu binary about 1MB larger, and seemingly encapsulated a few dependencies INSIDE the binary, which would otherwise had to have been bundled in and relied on setting the LD_LIBRARY_PATH environment variable. This is promising, but don’t expect ALL libraries to be able to be baked in.

Wow, even though qemu-system-i386 became 6.6MB, the folder of external library dependencies without a static compile totals 8.2MB! So, there is a net savings, and Levinux may become cleaner, more modern, AND shrink in size, even without recompile without on the –disable options. Very promising… at least on the Linux host platform, which is the best case scenario, since it’s the native home of the gnu toolchain. The files that become no longer required are:

libaio.so.1 libcaca.so.0 libcurl-gnutls.so.4 libgnutls.so.26 librados.so.2 librbd.so.1 librtmp.so.0 libSDL-1.2.so.0 libslang.so.2

I am optimistic that I will have similar success compiling the 64 bit x86_64 binary in static mode with curses support. I could actually create a transitional hybrid state of Levinux with the Linux versions coming up in curses mode while the Mac and Windows versions are still using the old widely distributed but old QEMU binaries from the Q and Takeda Toshiya version.

By the way, Takeda Toshiya’s precompiled QEMU binary for Windows that I’m using was his most recently distributed one from 2010, version 0.13.0 located at: http://homepage3.nifty.com/takeda-toshiya/

I’m going to try to start to abide by the GPL licenses now, and to that end I know that the source code I need to round up for qemu is 0.13.0 until I replace the Windows binary with my own compiled one, at which case I’ll distribute the source I actually compiled from. This is a first step.

This is an interesting and nuanced next step with Levinux. It is my first step away from my magic cocktail of binaries that miraculously work together. I had this vision of updating Levinux through-and-through, but there are so many parts to this, that would be folly. This is a chisel-strike by chisel-strike approach, where I can bank and thoroughly document my little accomplishments. It is perfectly tied to how this whole journal entry opened up today because this is the precise level of abstraction I need to VERY OCCASIONALLY dive down to, so that I know that I have command of the much higher level abstractions that exist in Levinux. This is the layer of abstraction that I’M providing to the world, and I can let that piece be magic to myself!

Okay, increment to version 2.2. And in your remaining time today, look at your social media update procedure when you do Levinux updates. Build tribe, man!