Skip navigation

Category Archives: Nerd Notes

I’ve been planning to get a new laptop for quite some time now, maybe at around December. However, certain miscalculations and one heartbreaking failure from the charger of my previous one means that I’m now typing this on a new machine, bought pretty way earlier than expected. And, like all good (or semi-good, depending on your loyalties) geeks do, I set-up the machine to dual-boot Windows 8 (pre-packaged with the hardware) and Linux the first time I had the opportunity (i.e., this long weekend).

It was hell.

Almost like this. Thankfully, only took me 1.5 days.

It seems that my hardships are all courtesy of UEFI/Secure Boot. Maybe there exists an easy way to achieve what I wanted but, judging by the volume of unresolved posts related to my problem scattered on the internet, it is not an obvious way. To anyone who might come across the same problems as me, here’s the complete narrative of how I managed to dual boot my machine.

0 Prologue

I dual-booted on an Acer Aspire-471G laptop. The OSes I want side-by-side is Windows 8 and Ubuntu 12.04 (Precise Pangolin). Since we’re dealing with the BIOS, I think it’s just proper that we get my machine on the record. If you run these steps on another machine, there might be some differences along the way.

Also, it seems that UEFI (and related dual-boot problems) has been around since Windows 7. However, I have never tried dual-booting a Windows 7 machine with Ubuntu—my experiences were all with XP and Vista, and it was all easy. And yes, I also encountered some 7-specific questions along the way.

1 Make sure that your LiveCD is 64-bit

There is no such thing as 32-bit UEFI. You will not be able to boot your machine in UEFI mode from your LiveCD if your LiveCD is  32-bit. While UEFI has support for legacy BIOS (and, from legacy BIOS, allow you to boot from a 32-bit LiveCD) this will result to a rather awkward and possibly-dangerous dual-boot set-up: you’d need to switch your BIOS mode from UEFI to legacy and back, depending on the OS you want to load.

(Blooper disclosure: I almost bricked my BIOS trying to boot from a 32-bit installer in UEFI mode: I ended up installing rEFInd through Windows and renaming stuff from my EFI System Partition, and got all sorts of weird and horrifying errors. The thing is, I just got the installer from one of our sysads at work and have used it previously to dual-boot an old 64-bit machine running XP. I’m glad I realized my mistake early.)

How do you determine then the bitness of your LiveCD installer?

At the root of your LiveCD, there is a file named README.diskdefines. Open that file (right-click->Open with->Notepad, or any other plain text editor). If you are looking at a 32-bit installer, that file will read like this (notice the ARCH variables):

#define DISKNAME  Ubuntu 12.04 LTS "Precise Pangolin" - Release i386
#define TYPE  binary
#define TYPEbinary  1
#define ARCH  i386
#define ARCHi386  1
#define DISKNUM  1
#define DISKNUM1  1
#define TOTALNUM  0
#define TOTALNUM0  1

On the other hand, if on a 64-bit installer, you’ll get:

#define DISKNAME  Ubuntu 12.04.1 LTS "Precise Pangolin" - Release amd64
#define TYPE  binary
#define TYPEbinary  1
#define ARCH  amd64
#define ARCHamd64  1
#define DISKNUM  1
#define DISKNUM1  1
#define TOTALNUM  0
#define TOTALNUM0  1

Also, the 64-bit version will have a directory named “efi” at the root. If you are seeing a 64-bit README.diskdefines and no “efi” directory, there is something wrong with your installer.

2 Get comfortable tweaking your BIOS

Warning: This can be dangerous! Proceed with a well-rested mind.

As you may have guessed earlier, there will be a lot of BIOS dealings involved here. To get to the BIOS set-up, press F2 while your machine boots.1

You need to be comfortable with two things: changing your boot order and adding .efis to the white list (“trusted”) of your machine. The first one is pretty basic but the second one has bit more technical details involved.

(For the first one, aside from being pretty basic, it is oftentimes unnecessary. You just need to make sure that your computer considers the HDD/Windows bootloader later than your optical drive and USB drive for bootable media. This is often the case. ACER ASPIRE-471G USERS, I must note that I was a bit surprised to find out that on this machine, this is not the case.)

White listing .efis involves setting a password and navigating your EFI System Partition (ESP) as well as other possibly-bootable media (like your LiveCD). Just remember two things here:

  • If you mess-up your system and suddenly can’t boot Windows, the .efis which Windows uses are at EFI/Microsoft/Boot and EFI/Boot, not case-sensitive, AFAIK. Might be worthwhile re-white listing the .efis inside these two.
  • If, after setting your boot order, you still can’t boot from your LiveCD installer, you need to white list the LiveCD efi, efi/boot/bootx64.efi

3 Installing Ubuntu

(I’ll be linking this part mostly.)

Now we get to the fun part. If your circumstances are anywhere like mine, you might need to partition your drive first. While you can partition your drive from the Ubuntu installer, in the interest of dual-booting, I recommend that you partition from Windows beforehand2. Here’s how.

Finally, you can proceed with installing Ubuntu. This tutorial pretty much says it all.

Note that the linked tutorial uses an older version of Ubuntu (11.10) which may or may not have caused the existence of the next section of this post which is…

4 PROBLEM!

After successfully installing Ubuntu, I rebooted. Sure the boot-up screen looked a bit different (there was a Unix-y underscore cursor present) but it still loaded directly to Windows 8!

I tried white listing the new EFI/ubuntu/grubx64.efi found in my ESP. However, that resulted to Ubuntu loading directly without even a shadow of GRUB showing up.

I then used the boot-repair utility and got these results. I had to re-white list EFI/ubuntu/grubx64.efi. Indeed, GRUB now shows up but without any option to boot Windows 8.

At this point, it’s been close to 1.5 days since I embarked on this task. I’m glad that xkcd got most of this stuff documented. And I’m also glad that, though I went beyond the 24-hour mark, nothing became a lost cause.

Besides, I’m not a very good swimmer!

In a moment of almost-frustrated defeat, I found zen from an earlier episode in this adventure. It dawned on me: just install rEFInd.

(Yep, my boot-up is now managed by rEFInd. Far from a perfect solution, in my opinion but it does what I wanted it to do. So long for now!)

  1. That’s on this Acer machine. If F2 does not work on yours, other candidates might be F10 and F8. []
  2. In my case, the Ubuntu installer didn’t detect another OS in my machine, didn’t detect Windows 8. I don’t know what would’ve happened if I made a wrong move while partitioning from the Ubuntu installer in this case. Hence, not recommended. []

Ok. Not really magic and I bet other people got this figured out and it’s just me because I’m not following standards. Anyway…

My portfolio website was the first time I ever did table-less layout. So, it was also the first time I discovered what a pain in the ass IE is when it comes to CSS handling. See for yourself.

This is how the home page looks with Chrome and, with some minor differences, in Firefox:

kode.skytreader.net in Google Chrome

My portfolio website rendered in Google Chrome.

Exactly how I intended it.

Now take a look at what happens when you give it to IE 9, which, as of this writing, is supposed to be the best stable build of IE.

kode.skytreader.net in IE9

My insides repulsively retch at this FrankenstIEn (sic) of a page.

I wasted spent countless hours experimenting with CSS so that IE may render it well. But, as you may have surmised looking at that screen shot, I ended up with my arms raised in frustrated surrender and just put up that message (which, yes, only appears for IE users) suggesting that they download either Chrome of Firefox.

It looked like that for a long time until I discovered−wait for it, drum roll please−doctypes and quirks mode.

Doctypes are, to oversimplify, comments at the beginning of HTML documents. It is like the hashbang line they always tell you to put at the beginning of your shell/Perl/Python scripts. They don’t really affect your code though they tell the executing environment (in this case, the browser) additional info about your code.

So, I put the following doctype declaration in my pages

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

And behold how IE renders my portfolio homepage (another drum roll please):

kode.skytreader.net in IE9, post DOCTYPE

TADAAA!!!!

Despite that it now renders as expected in IE, I chose to keep that little banner/taunt because really, world, we shouldn’t be using a browser that is as standards compliant as any 1990’s browser in the year 2012.

And I know that this isn’t the magic panacea of this wretched IllnEss. I’m sure it isn’t difficult to make IE break when your using CSS layers and positions even with quirks mode. But for sites with simple layouts, this one is definitely my life saver.

One of Java’s biggest advantage against C is its support for strings. The String class is so well-integrated into the language (it is part of the java.lang package) that newbies easily mistake it for a primitive type; in a typical Java introductory course, you’ll almost always find someone complaining why "Hello World" == "Hello World" returns false. One of it’s most useful features is how it allows concatenation using the + operator. Very intuitive.

However, this convenience comes with a price, as I will discuss in this post. Also, we’ll look at one way to mitigate this computational overhead.

Java’s Ruse
Tell me, what’s wrong/inefficient with the following lines of code?

1
2
3
4
5
6
7
8
String[] names = {"Homer", "Lenny", "Karl", "Barney"};
String greetEveryone = "Hello";
 
for(int i = 0, limit = names.length; i < limit; i++){
  greetEveryone += " " + names[i];
}
 
System.out.println(greetEveryone);

See nothing wrong? As I noted above, Java’s support of concatenation through the + operator is very intuitive. So intuitive it has led a lot of people (me guilty!) to overlook the String specification of the Java API. And I quote the JDK API 7 specification1:

Strings are constant; their values cannot be changed after they are created. …String objects are immutable…

Strings are immutable. Unlike incrementing the index variable i, which stores the incremented value to the same block of memory as the original value, concatenating a String actually creates a new object (which is quite a costly operation). The pointer of greetEveryone is just updated to the newly created object so that, come line 8, you get to greet the whole gang.

Stop Shooting Your Own Foot
Java actually sees line 5 as something like,

String space = " ";
String withName = space.concat(names[i]); 
String updatedGreeting = greetEveryone.concat(withName);
greetEveryone = updatedGreeting;

It creates three objects just so it can update one variable! And at every iteration of the loop, you create more Strings floating in memory. Putting the variable declarations outside the loop does not help either because, as I said, Strings are immutable and every assignment to an already-declared String variable creates a new String object.

Can’t we do better? Fortunately, Java already has a solution to this costly operation: StringBuilder and its thread-safe brother StringBuffer

And I quote from StringBuilder’s API 7 specification2

(StringBuilder is) [a] mutable sequence of characters.

The principal operations on a StringBuilder are the append and insert methods, which are overloaded so as to accept data of any type.

With StringBuilder, we can make Java read our code above as follows:

1
2
3
4
5
6
7
8
9
10
String[] names = {"Homer", "Lenny", "Karl", "Barney"};
StringBuilder greetEveryone = new StringBuilder("Hello");
 
for(int i = 0, limit = names.length; i < limit; i++){
  String space = " ";
  String withName = space.concat(names[i]); 
  greetEveryone.append(withName);
}
 
System.out.println(greetEveryone.toString());

But, that doesn’t seem to do that much…
For some of your typical uses of Strings—System.out.printing a debug trace or creating UI labels, for instance—using a StringBuilder might be overkill; debug traces may be disabled without affecting the program and UI labels are rarely concatenated with something else. But some Java operations rely heavily on Strings that a few extra lines declaring StringBuilders and calling their toString() later on is a worthy investment. IBM developerWorks3 note a throughput increase of 2.3x using StringBuffer over plain-old concatenation (which, again, does not seem much unless you read the rest of this post).

An instance where you’ll be very thankful for StringBuilder and StringBuffer is when you work with JDBC. While most of your queries will be pre-determined and so hardcoded, every now and then you will most likely have to generate a dynamic query (based on, say, user input). Querying a large database is already costly even without the expense of generating temporary objects for String concatenation. Suddenly, the meager 2.3x throughput increase seems a very generous deal. And heck it is.

Bonus Links
Looking for more ways to optimize Java code? Read Peter Sestoft’s paper on Java performance. For the numerical algorithms geek, he also has a paper on numeric performance in C, C#, and Java.

  1. http://docs.oracle.com/javase/7/docs/api/java/lang/String.html []
  2. http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html []
  3. http://www.ibm.com/developerworks/websphere/library/bestpractices/string_concatenation.html []

Whenever I code in C, one of my biggest annoyances is that there is no built-in function for determining an array’s size. So I either resort to hard-coding the maximum size the arrays my program will use (which is a waste of memory and is inflexible) or I allocate arrays dynamically (which is cumbersome).

When I mastered my bits a bit more, I realized that an array’s size can actually be determined by doing sizeof(array)/sizeof(array[0]). I then coded a function that will do just that for me. However, there are two problems with this:

  1. I’d have to define this function for every possible data type I’ll make an array of. AFAIK, C doesn’t have something like Java’s Object super-root class; and
  2. C is one hell of a liar. Among the things I (as a beginner and even as someone with moderate C experience) find very messy with C is that it is a pass-by-value language but it uses explicit pointers and so manages to act like a pass-by-reference language. Confusing, right?

Let’s a dwell a bit more on #2. Whenever you pass an array or a struct to some C function, say foo , that function can modify the contents of the array/struct for the whole program to see. It would seem to us that foo was given the whole array/struct upon function call. But no. C actually went behind your back1 and passed a pointer to the array/struct. That pointer is just an integer although C knows that it refers to some place in memory and uses that to modify the contents of your array/struct.

And boom. There goes the problem with doing

int size(int *array){
	return sizeof(array)/sizeof(array[1]);
}

as sizeof(array) will always return 4—the number of bytes in an integer (pointer).

I gave up my hopes on making C a bit more Java-ish for my taste. Until I (recently!) learned what macros are for.

Macros are the #define statements at the beginning of a C code listing, just after the #includes. I know that they can contain virtually almost every kind of C code but I’ve neglected that and up to now only used them to define constants. Assigning sizeof(array)/sizeof(array[0]) to a macro gives me just the thing I’m looking for.

So why would a lowly macro work where functions failed? It’s because of how macros are parsed. Whenever C encounters a macro, the bit of code assigned to that macro is, shall we say, copy-pasted directly into your code. So when we see

1
2
3
4
5
6
7
8
#include <stdio.h>
 
#define ARRAY_SIZE(array) ((sizeof(array) / sizeof(array[0])))
 
int main(){
	int foo[9] = {1,4,1,5,9,2,6,5,3};
	printf("%d\n", ARRAY_SIZE(foo));
}

C actually understands line 7 as

7
printf("%d\n", ((sizeof(foo) / sizeof(foo[0]))));

No parameter passing occurs, and hence no pointers. Everything is executed inline. While this may make parsing a bit longer, it surely is worth more than what it costs. And though it may not still be as nifty as Java (see what happens when you use that macro inside some function that requires an array as a parameter), it sure becomes less awkward with this.

Post Script. I orginally saw this trick here (CTRL+F to Chapter 17). Apparently, Linux has this macro pre-defined in linux/kernel.h . kernel.h includes fine in my machine but then it doesn’t seem to have the aforementioned macro. I opened my kernel.h and, indeed, it is not there. Weird.

  1. I just realized that C gurus will squirm at my choice of words. But hey, this is for non-gurus like me, alright? ;D []