As usually happens, I have some ideas of my own straight after posting. Without actually understanding any of this, I have done some experiments (randomly commenting out bits of assembler and seeing what happens) and have discovered: The "Warning: warning: missing prefix `*' in absolute indirect address, maybe misassembled!" probably doesn't matter, but I can make it go away by changing call (%eax) to: call *(%eax) The perhaps serious error "relocation truncated to fit" is caused by this line: ljmp $KERNEL_CS, $EXT(_SMP_TRAMP_32_ENTRY_) I can make it go away by moving the .code32 directive to the other side of it, i.e. replacing /* now go to 32-bit segment */ ljmp $KERNEL_CS, $EXT(_SMP_TRAMP_32_ENTRY_) .code32 by: .code32 /* now go to 32-bit segment */ ljmp $KERNEL_CS, $EXT(_SMP_TRAMP_32_ENTRY_) This change may be a good one, because the there's comment immediately following that says: * [_SMP_TRAMP_32_ENTRY_ - 6] is the 32 bit address of the ljmp destination. My empirical measurements indicate that the ljmp instruction takes only 5 bytes in 16-bit mode, but 7 bytes in 32-bit mode. All this in oskit/libsmp/x86/boot.S, so it may not be totally relevant to L4 hackers ... Edmund