Error ld: cannot represent machine `elf32-i386'

Programming, for all ages and all languages.
Post Reply
zman97211
Posts: 22
Joined: Sun Aug 23, 2009 7:35 am

Error ld: cannot represent machine `elf32-i386'

Post by zman97211 »

I have been playing around with entering protected mode from a simple custom kernel. I'm trying to create a 32-bit binary elf file as output which will be loaded and started by GRUB. The machine I'm running on is an Ubuntu installation on an AMD 64-bit processor. I have succesfully build this and booted it using NASM and DJGPP on Windows, before deciding to use Linux as by build environment. I have searched but can't find any help on this error message.

My source is a very short assembly file, compiled with NASM into "kernel.o".

"objdump -i" lists "elf32-i386" as one of the supported formats.

"objdump -x kernel.o" tells me that kernel.o's format is indeed elf32-i386.

I am invoking "ld -T link.ld".

It outputs

Code: Select all

ld: cannot represent machine `elf32-i386'
Here is the linker script I am using (I've played around with the format and arch lines with no success):

Code: Select all

OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(elf32-i386)
TARGET(elf32-i386)
INPUT(kernel.o)
OUTPUT(kernel.bin)
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
I have successfully build other packages from source so I believe my build environment, binutils, etc should be functional.

Thanks in advance for the help! Below is the source for kernel.o in case it's important (I don't think it is).

Code: Select all

[BITS 32]
global	start

start:
	mov	esp,_sys_stack
	jmp	stublet

ALIGN 4
mboot:
	MULTIBOOT_PAGE_ALIGN	equ 1<<0
	MULTIBOOT_MEMORY_INFO	equ 1<<1
	MULTIBOOT_HEADER_MAGIC	equ 0x1BADB002
	MULTIBOOT_HEADER_FLAGS	equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
	MULTIBOOT_CHECKSUM	equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

stublet:
	mov	ebx,0xb8002
	mov	[ebx],byte 0x0f
	mov	[ebx+1],byte '*'
	jmp	$

SECTION .bss
	resb 8192               ; This reserves 8KBytes of memory here

_sys_stack:
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: Error ld: cannot represent machine `elf32-i386'

Post by NickJohnson »

In my linker script, I have the line "OUTPUT_FORMAT(elf32-i386)" instead of "OUTPUT_ARCH(elf32-i386)". Maybe that's your issue?

Either way, you should really build a cross compiler (which includes the linker) if you're going to be writing for a different architecture than the one you're using. Take a look here.
zman97211
Posts: 22
Joined: Sun Aug 23, 2009 7:35 am

Re: Error ld: cannot represent machine `elf32-i386'

Post by zman97211 »

I removed the OUTPUT_ARCH line and left in the OUTPUT_FORMAT line with no improvement.

I'm currently building the cross-compiler using the link you provided and I'll post the results when I have them.

Thanks!
User avatar
dc740
Member
Member
Posts: 40
Joined: Sat Jul 04, 2009 12:43 am
Location: Argentina

Re: Error ld: cannot represent machine `elf32-i386'

Post by dc740 »

Try this:

OUTPUT_ARCH(i386)



I tested it with the James's tutorial and seems to be working... I didn't do it in C. I followed the tutorial doing everything in asm... but it should work anyway

good luck! :)
zman97211
Posts: 22
Joined: Sun Aug 23, 2009 7:35 am

Re: Error ld: cannot represent machine `elf32-i386'

Post by zman97211 »

Ok. I made the cross-compiling binutils and gcc, but still no luck, same error.

I then changed the OUTPUT_ARCH(i386) as mentioned in the latest post, and got a successful link using my host system's linker! However, I received a warning from ld:

Code: Select all

ld: warning: cannot find entry symbol start; defaulting to 0000000000100000
The start symbol is global in my source and listed in my linker script as the entry point ENTRY(start), and listed with objdump -x kernel.o:

Code: Select all

kernel.o:     file format elf32-i386
kernel.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .bss          00002000  00000000  00000000  00000160  2**2
                  ALLOC
  1 .text         0000001d  00000000  00000000  00000160  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
SYMBOL TABLE:
00000000 l    df *ABS*	00000000 kernel.asm
00000000 l    d  .bss	00000000 .bss
00000000 l    d  .text	00000000 .text
00000000 l       *UND*	00000000 mboot
00000001 l       *ABS*	00000000 MULTIBOOT_PAGE_ALIGN
00000002 l       *ABS*	00000000 MULTIBOOT_MEMORY_INFO
1badb002 l       *ABS*	00000000 MULTIBOOT_HEADER_MAGIC
00000003 l       *ABS*	00000000 MULTIBOOT_HEADER_FLAGS
e4524ffb l       *ABS*	00000000 MULTIBOOT_CHECKSUM
00000000 l       *UND*	00000000 stublet
00002000 l       .bss	00000000 _sys_stack
00000000         *UND*	00000000 code
00000000         *UND*	00000000 bss
00000000         *UND*	00000000 end
00000000         *UND*	00000000 start


RELOCATION RECORDS FOR [.text]:
OFFSET   TYPE              VALUE 
00000001 R_386_32          .bss
Also, my multiboot header does not work without the aout kludge, I just figured that out. I thought that by using an elf binary, which Grub should understand, the kludge wasn't required. I put it back in and was able to run my code with Bochs.

Back to the ld documentation....
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: Error ld: cannot represent machine `elf32-i386'

Post by NickJohnson »

zman97211 wrote:Also, my multiboot header does not work without the aout kludge, I just figured that out. I thought that by using an elf binary, which Grub should understand, the kludge wasn't required. I put it back in and was able to run my code with Bochs.
I believe the header still has to be at the beginning of the binary, after the ELF header. In your layout, .bss is before .text, and therefore the header is in the middle of the binary. Try switching .text's and .bss's order in the linker script.
User avatar
dc740
Member
Member
Posts: 40
Joined: Sat Jul 04, 2009 12:43 am
Location: Argentina

Re: Error ld: cannot represent machine `elf32-i386'

Post by dc740 »

I think Nick is right. Here is a piece of my start.asm file

Code: Select all

; This is the kernel's entry point. We could either call main here,
; or we can use this to setup the stack or other nice stuff, like
; perhaps setting up the GDT and segments. Please note that interrupts
; are disabled at this point: More on interrupts later!
[BITS 32]

SECTION .data
; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4'
ALIGN 4
mboot:
    ; Multiboot macros to make a few lines later more readable
    MULTIBOOT_PAGE_ALIGN        equ 1<<0
    MULTIBOOT_MEMORY_INFO       equ 1<<1
    MULTIBOOT_AOUT_KLUDGE       equ 1<<16
    MULTIBOOT_HEADER_MAGIC      equ 0x1BADB002
    MULTIBOOT_HEADER_FLAGS      equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
    MULTIBOOT_CHECKSUM  equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
    EXTERN code, bss, end

    ; This is the GRUB Multiboot header. A boot signature
    dd MULTIBOOT_HEADER_MAGIC
    dd MULTIBOOT_HEADER_FLAGS
    dd MULTIBOOT_CHECKSUM

    ; AOUT kludge - must be physical addresses. Make a note of these:
    ; The linker script fills in the data for these ones!
    dd mboot
    dd code
    dd bss
    dd end
    dd start

section .text
global start
start:
;put your code here!!!   :)
PS:I'm sure it looks familiar. I guess most of us start learning from tutorials before reading 98234798 articles and books about this beautiful art :)
zman97211
Posts: 22
Joined: Sun Aug 23, 2009 7:35 am

Re: Error ld: cannot represent machine `elf32-i386'

Post by zman97211 »

I appreciate all the help you guys have given me. I've now been able to set up a GDT using a segmented model and done a few basic tasks, but it has uncovered another issue I'm having now, which I'll describe in a new thread.

Steve
Post Reply