ghaerr / elks

Embeddable Linux Kernel Subset - Linux for 8086
Other
1.02k stars 108 forks source link

Error building #1134

Closed toncho11 closed 2 years ago

toncho11 commented 2 years ago

I am using the latest compiler that was downloaded using the build script.

__KERNEL__ -o fmemory.tmp fmemory.S
ia16-elf-as -mtune=i8086  --32-segelf -o fmemory.o fmemory.tmp
rm fmemory.tmp
gcc -E -traditional -I/home/toncho/elks/include -I/home/toncho/elks/elks/include -I/home/toncho/elks/libc/include -DUTS_RELEASE=\"0.4.0\" -D__KERNEL__ -o peekpoke.tmp peekpoke.S
ia16-elf-as -mtune=i8086  --32-segelf -o peekpoke.o peekpoke.tmp
rm peekpoke.tmp
gcc -E -traditional -I/home/toncho/elks/include -I/home/toncho/elks/elks/include -I/home/toncho/elks/libc/include -DUTS_RELEASE=\"0.4.0\" -D__KERNEL__ -o string.tmp string.S
ia16-elf-as -mtune=i8086  --32-segelf -o string.o string.tmp
rm string.tmp
gcc -E -traditional -I/home/toncho/elks/include -I/home/toncho/elks/elks/include -I/home/toncho/elks/libc/include -DUTS_RELEASE=\"0.4.0\" -D__KERNEL__ -o bios15.tmp bios15.S
ia16-elf-as -mtune=i8086  --32-segelf -o bios15.o bios15.tmp
rm bios15.tmp
gcc -E -traditional -I/home/toncho/elks/include -I/home/toncho/elks/elks/include -I/home/toncho/elks/libc/include -DUTS_RELEASE=\"0.4.0\" -D__KERNEL__ -o unreal.tmp unreal.S
ia16-elf-as -mtune=i8086  --32-segelf -o unreal.o unreal.tmp
unreal.S: Assembler messages:
unreal.S:32: Error: no such architecture: `'
unreal.S:32: Error: junk at end of line, first unrecognized character is `1'
unreal.S:341: Warning: stand-alone `addr32' prefix
unreal.S:391: Warning: stand-alone `addr32' prefix
unreal.S:398: Warning: stand-alone `addr32' prefix
../../../Makefile-rules:235: recipe for target 'unreal.o' failed
make[3]: *** [unreal.o] Error 1
make[3]: Leaving directory '/home/toncho/elks/elks/arch/i86/lib'
Makefile:191: recipe for target 'lib/lib86.a' failed
make[2]: *** [lib/lib86.a] Error 2
make[2]: Leaving directory '/home/toncho/elks/elks/arch/i86'
Makefile:73: recipe for target 'Image' failed
make[1]: *** [Image] Error 2
make[1]: Leaving directory '/home/toncho/elks/elks'
Makefile:11: recipe for target 'all' failed
make: *** [all] Error 2
Build script has terminated with error 5
toncho11 commented 2 years ago

This is my config file. failed_config.txt

ghaerr commented 2 years ago

Hello @toncho11,

I haven't pulled down the latest compiler build, so I'm going to ask @tkchia what he thinks before doing so.

Hello @tkchia, in this case, ia16-elf-as is assembling elks/arch/i86/lib/unreal.S, which uses the following line which is causing this error:

        .arch i386,nojumps

The reason for this is that, unlike all other files in ELKS, this file is attempting to set unreal mode and requires the 0x66 or 0x67 (address32 or operand32) prefixes to be emitted for various instructions. Has this changed in the latest toolchain?

If so, what would be the recommended method for assembling this file, and would there be a way to keep this compatible with older source, or do all users need to update their toolchain with modified source? Note that -mtune=8086 is still being passed to ia16-elf-as for this assembly.

Thank you!

tkchia commented 2 years ago

Hello @toncho11, hello @ghaerr,

gcc -E -traditional -I/home/toncho/elks/include -I/home/toncho/elks/elks/include -I/home/toncho/elks/libc/include -DUTS_RELEASE=\"0.4.0\" -D__KERNEL__ -o unreal.tmp unreal.S
ia16-elf-as -mtune=i8086  --32-segelf -o unreal.o unreal.tmp
unreal.S: Assembler messages:
unreal.S:32: Error: no such architecture: `'
unreal.S:32: Error: junk at end of line, first unrecognized character is `1'

Hmm... OK... it turns out that this happens because we were (erroneously) using the host GCC to preprocess the unreal.S file, when we should be using ia16-elf-gcc. And it seems that @toncho11 was building ELKS on a 32-bit x86 system, so the macro i386 happened to be defined as 1 — along with macros __i386 and __i386__, which were also defined to be 1. So

    .arch   i386,nojumps

was preprocessed into (!)

    .arch   1,nojumps

(@ghaerr: If you pass -m32 to the host GCC you should be able to see this in the unreal.tmp output, and reproduce the problem.)

I am not sure why the makefile rules were using a separate preprocessing pass and were using -traditional — historical reasons? — but anyway, if we use ia16-elf-gcc rather than the host GCC, I think we should be able to remove this glitch. This is because ia16-elf-gcc does not define an i386 macro.

diff --git a/elks/Makefile-rules b/elks/Makefile-rules
index f69d0f1e..36b95408 100644
--- a/elks/Makefile-rules
+++ b/elks/Makefile-rules
@@ -232,7 +232,7 @@ endif
 .S.s: ;

 .S.o:
-   gcc -E -traditional $(INCLUDES) $(CCDEFS) -o $*.tmp $<
+   $(CC) -E -traditional $(INCLUDES) $(CCDEFS) -o $*.tmp $<
    $(AS) $(ASFLAGS) -o $*.o $*.tmp
    rm $*.tmp

diff --git a/elkscmd/Make.defs b/elkscmd/Make.defs
index 99a95518..72389522 100644
--- a/elkscmd/Make.defs
+++ b/elkscmd/Make.defs
@@ -98,7 +98,7 @@ CFLAGS=$(CFLBASE) $(WARNINGS) $(LOCALFLAGS) $(INCLUDES) -D__ELKS__ -DELKS_VERSIO
 # Standard compilation rules.

 .S.s:
-   gcc -E -traditional $(INCLUDES) $(CCDEFS) -o $*.s $<
+   $(CC) -E -traditional $(INCLUDES) $(CCDEFS) -o $*.s $<

 .s.o:
    $(AS) $(ASFLAGS) -o $*.o $<

Thank you!

tkchia commented 2 years ago

Hello @toncho11, hello @ghaerr,

About these:

unreal.S:341: Warning: stand-alone `addr32' prefix
unreal.S:391: Warning: stand-alone `addr32' prefix
unreal.S:398: Warning: stand-alone `addr32' prefix

These are because the addr32 's, by right, should appear on the same line as the instructions they modify — info gas specifically mentions this. These are warnings, not fatal errors, and ia16-elf-as will ultimately do the correct thing anyway.

To address the warnings, instead of saying

    addr32                // 32-bit address prefix
    rep
    movsw                 // word [ES:EDI++] <- [DS:ESI++], ECX times

just say

    addr32 rep movsw      // word [ES:EDI++] <- [DS:ESI++], ECX times

(Actually we can also use the same addr32 notation for the CPU bug workaround in the next lines. Instead of

    .byte  0x67           // 80386 B1 step chip bug on address size mixing
    nop

we can simply write

    addr32 nop            // 80386 B1 step chip bug on address size mixing

and ia16-elf-as will output the correct instruction.)

Thank you!

ghaerr commented 2 years ago

Hello @tkchia, hello @toncho11,

Thanks for your keen observation that this problem is actually the host's C preprocessor substituting '1' for 'i386'!! It makes you wonder what other symbols might be unknowingly changed in .S files. I had wondered what the "first unrecognized character '1'" was about. It might be a good idea to somehow turn off predefined symbols in the $(CC) -E pass if possible, to prevent this (although I suppose some .S might want those symbols for #if statements?)

I'll make all suggested changes and submit a PR. (I'm not able to easily test the '-m32' option since I'm developing solely on macOS.) It does seem somewhat amazing no one except @toncho11 until now has compiled ELKS on a 32-bit Linux system!

Thank you!

toncho11 commented 2 years ago

Yes, I confirm that it is a 32 bit system. Because it is an old Core2 Duo that I am using for ... ELKS compiling.

It also means that before it was building OK on a 32bit system.