My bootloader can't be compiled with gcc 4.6 and 4.7 ... only 4.5

By compiling a trivial C file with the flags you provided, between gcc-4.5 and gcc-4.6, and using objdump -h to examine the output, it seems that the .eh_frame section is introduced in gcc-4.6.

The ld script you provided does not take care of that section, and it probably should. You can use strip -R .eh_frame -R .eh_frame_hdr to remove that section and others from the object files prior to linking.

Anyway, since the linker is the same for both gcc versions, objdump -h on the object files will hint at the difference that causes this problem.


Is there any command line argument which will turn off a feature that may produce bigger sections

Yes: if you care about size, you should build with -Os. The -O3 explicitly enables optimizations which could lead to larger code size. Since the bootloader executes once, using -O3 for it is almost certainly wrong.

Edit:

"Optimization in assembly is meaningless ...
... and other objects here ..."

Is all of your code in assembly? If so, optimization level is indeed meaningless, but then you should be able to simply compare output from readelf -S vga_pm.S.o built with both compilers, and see exactly which sections are different.

But it appears more likely that some of your objects are not in assembly, in which case the difference between -O3 and -Os will be quite meaningful.


GCC adds some unwanted debug sections to its binary output (use objdump -h <file> to see them), I usually put those I don't want in a /DISCARD/ rule in my ld scripts to get rid of them :

/DISCARD/ : {
        *(.debug_*)
        *(.note*)
        *(.indent)
        *(.comment)
        *(.stab)
        *(.stabstr)
        *(.eh_frame)
}