3

I'm trying to compile an ASM program I wrote with NASM and the "ld" command from DJGPP. This is the code for the batch file I'm using to compiling it:

@echo off
set path=C:\NASM;%PATH%
nasm -f aout -o start.o start.asm
ld -T link.ld -o kernel.bin start.o

But when I run the file I get:

start.o: file not recognised: File format not recognized

What, in my build file, have I done wrong to cause this error message?

EDIT

This is my link.ld file:

OUTPUT_FORMAT("binary")
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 = .;
}

EDIT

Nothing else is working, so here is the code for my ASM file (I was creating kernel for an Operating System I've been working on):

[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_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

    dd MULTIBOOT_HEADER_MAGIC
    dd MULTIBOOT_HEADER_FLAGS
    dd MULTIBOOT_CHECKSUM

    dd mboot
    dd code
    dd bss
    dd end
    dd start

stublet:
    jmp $

SECTION .bss
    resb 8192
_sys_stack:
Greg Treleaven
  • 8,124
  • 7
  • 30
  • 30
  • Thanks Jerry, I didn't know how to use the code format properly. – Greg Treleaven Jun 21 '10 at 15:47
  • Are you sure you want `aout` and not `elf`? – Nikolai Fetissov Jun 21 '10 at 15:57
  • If I try to use `elf` instead, I get `ld: PE operations on a non PE file`. I have to admit, I have no idea what this means. Thanks for trying to help, though. – Greg Treleaven Jun 21 '10 at 17:48
  • Try this and let us know how far you get: `nasm start.asm \n ld -T link.ld -o kernel.bin start.obj`. `PE-COFF` is windows native binary format, `ELF` is usual on Unix. I'm guessing `nasm` knows how to produce either, but `ld` expects windows stuff. – Nikolai Fetissov Jun 21 '10 at 18:16
  • `aout` is older Unix format, btw. – Nikolai Fetissov Jun 21 '10 at 18:37
  • I'm gessing when you put \n you meant a new line. The output: `start.asm:31: error: binary output format does not support external references start.asm:32: error: binary output format does not support external references start.asm:33: error: binary output format does not support external references ld: start.obj: No such file: No such file or directory` Thanks for trying to help, can you explain these errors? – Greg Treleaven Jun 21 '10 at 18:37
  • Yes, `\n=new line`, just a limitation of comment formatting. These are specific to what you are doing in the assembler. Different binary formats have to be coded to specifically. My last suggestion would be to try `-f bin` option for `nasm` since it looks like you are building some raw stuff. If that fails we'll need to see what's in the .asm file. – Nikolai Fetissov Jun 21 '10 at 19:07

3 Answers3

2

You are missing text section in the code file:

[BITS 32]
SECTION .text
global start
...

For the object format try -f coff since that seems to be the right format for DJCPP (thanks @ninjalj):

valid output formats for -f are (`*' denotes default):
  * bin       flat-form binary files (e.g. DOS .COM, .SYS)
    ith       Intel hex
    srec      Motorola S-records
    aout      Linux a.out object files
    aoutb     NetBSD/FreeBSD a.out object files
    coff      COFF (i386) object files (e.g. DJGPP for DOS)
    elf32     ELF32 (i386) object files (e.g. Linux)
    elf       ELF (short name for ELF32) 
    elf64     ELF64 (x86_64) object files (e.g. Linux)
    as86      Linux as86 (bin86 version 0.3) object files
    obj       MS-DOS 16-bit/32-bit OMF object files
    win32     Microsoft Win32 (i386) object files
    win64     Microsoft Win64 (x86-64) object files
    rdf       Relocatable Dynamic Object File Format v2.0
    ieee      IEEE-695 (LADsoft variant) object file format
    macho32   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
    macho     MACHO (short name for MACHO32)
    macho64   NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
    dbg       Trace of all info passed to output stage

I have no solution for you for DJCPP, but I was able to compile and link this on my 64-bit Linux (with added .text section) as follows:

~$ nasm -f elf64 start.asm
~$ ld -T link.ld -o kernel.bin start.o
Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • Thanks for the advice, but when I tried with the `.test` section in it, it still said `ld: PE operations on a non PE file`. What is `PE`? Could I change my file to be compatible with it somehow? – Greg Treleaven Jun 22 '10 at 15:19
  • `PE` is "Portable Executable", see http://en.wikipedia.org/wiki/PE-COFF. Have you tried `-f coff`? – Nikolai Fetissov Jun 22 '10 at 15:26
  • I think you problem is that crooked cygwin environment. It's more pain then use. Can you try either native Microsoft linker (`link.exe`), or install Linux in a VM (VirtualBox is free: http://www.virtualbox.org/) – Nikolai Fetissov Jun 22 '10 at 15:39
  • I must second Nikolai N Fetissov; either try linux in a VM, or running natively on the bare hardware. Although I have read it is possible to do kernel development in MSVC++, see http://wiki.osdev.org/Visual_Studio – vyudh Nov 14 '12 at 18:48
  • I'm trying to figure out linking on Windows :S ...I run nasm, then ld? Do I then run gcc? Thanks! – IAbstract Apr 17 '15 at 16:15
  • Probably the native Windows `link.exe`, but I don't understand why you would go for that extra pain ... – Nikolai Fetissov Apr 17 '15 at 16:51
1

Have you tried nasm -f coff?

From nasm -hf output:

coff      COFF (i386) object files (e.g. DJGPP for DOS)
ninjalj
  • 42,493
  • 9
  • 106
  • 148
0

Judging by the multiboot header information, and the fact that this file is linked into a binary format output (as is specified in the linker script), tells me that this is an operating system kernel (or at least an academic example of one), and is therefore meant to be compiled and run in freestanding mode, and not a regular user space process (which requires a kernel to manage).

ld by default accepts the elf format (which very much replaces the old, obsolete aout format on unix platforms), you might have to specify aout as an input format in the linker script (or alternatively tell nasm to output elf format object files). multiboot works best with elf and does not require all that "aout_kludge"

The way this code (or any kernel code) was meant to be executed is by being loaded by a boot loader. As this is a multiboot compliant kernel, it was meant to be loaded by a multiboot compliant boot loader such as grub (see http://www.gnu.org/software/grub/).

I realize you are on windows, so you probably don't have the info documentation system properly installed at your site, but you can read read the GNU documentation at http://www.gnu.org/software/grub/manual/multiboot/multiboot.html . Also it looks like this code was meant to be compiled on a unix like platform, so at least you are right to use djgpp (gcc ported to windows).

As I am working on GNU/Linux, it is hard for me to debug whatever MS windows or djgpp issues need to be worked around, perhaps the GNU ld (part of binutils) info documentation would be helpful - http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_toc.html

vyudh
  • 91
  • 4