Help with linker on bare-bones

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Anubis208
Posts: 8
Joined: Wed Jul 02, 2008 9:23 am

Help with linker on bare-bones

Post by Anubis208 »

I am following the first bare bones tutorial on the wiki. I am using DJGPP on Windows (I like linux, but it doesn't have drivers for my ethernet card (can't get ndiswrapper to work either)).

The source files and linker files are identical to those in the tutorial. I had to remove the -Werror flag to get the C to compile, but otherwise am using the exact commands described in the tutorial. Everything compiles fine, but when I link I get this error:

>ld -T linker.ld -o kernel.bin loader.o kernel.o
loader.o: file not recognized: File format not recognized

How can I get this to link?
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: Help with linker on bare-bones

Post by AJ »

Anubis208 wrote:I had to remove the -Werror flag to get the C to compile
Bad Sign. Do not allow your code to compile with any warnings - they are there for a reason.
loader.o: file not recognized: File format not recognized
You need a GCC Cross-Compiler :)

Cheers,
Adam
Anubis208
Posts: 8
Joined: Wed Jul 02, 2008 9:23 am

Re: Help with linker on bare-bones

Post by Anubis208 »

Here are the warnings I get

>gcc -o kernel.o -c kernel.c -Wall -Wextra -Werror -nostdlib -nostartfiles -nodefaultlibs
cc1.exe: warnings being treated as errors
kernel.c:1: warning: unused parameter 'mbd'
kernel.c:1: warning: unused parameter 'magic'

Code: Select all

void kmain( void* mbd, unsigned int magic)
{
  unsigned char *videoram = (unsigned char *)0xB80000;
  videoram[0] = 76;
  videoram[1] = 0x07;
}

I think its because I don't use the arguments to kmain?


Also I'm kind of new to the whole command line copiling thing.
Your saying its the linker that's the problem and it doesn't recognize the ELF from the assembler?
If so, could I just get a cross-platform linker instead of building the whole GCC?
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: Help with linker on bare-bones

Post by AJ »

Hi,

AFAIK, you can just build cross-binutils, which will provide you with the compatible ld, but my personal recommendation would be that if you are installing Cygwin and building binutils anyway, you may as well go the whole way and build yourself a cross-compiled version of GCC. It's what many people are using on the forums and if you hit problems later people are more likely to be able to help on this forum.

If you remove the parameter names from main a la:

Code: Select all

void kmain( void*, unsigned int)
{
...
}
You can keep -Werror turned on and just add the param names later when you need them. This way, GCC will continue to treat other warnings as errors.

Cheers,
Adam
midir
Member
Member
Posts: 46
Joined: Fri Jun 13, 2008 4:09 pm

Re: Help with linker on bare-bones

Post by midir »

Your saying its the linker that's the problem and it doesn't recognize the ELF from the assembler?
If so, could I just get a cross-platform linker instead of building the whole GCC?
I use MinGW for compiling on Windows. It's not the easiest compiler in the world to get set up but it does work very well. Its LD will accept ELF object files from the assembler.

It only seems to build Windows PE format executables unfortunately, but this does not matter since GRUB will look for the Multiboot header and use that for loading it. You could also write a script to strip the PE header off the output executable file, possibly rearranging the sections into a new executable format, if you don't want it (which is what I did).
Anubis208
Posts: 8
Joined: Wed Jul 02, 2008 9:23 am

Re: Help with linker on bare-bones

Post by Anubis208 »

I have Dev-Cpp installed on my computer. Is there any way I could use Mingw from that?
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Re: Help with linker on bare-bones

Post by suthers »

Yup that's what I do, there is a gcc mingw compiler in the \bin\ of your dev-c++ directory, it works exactly like any other gcc compiler and you can use it in your command line to build you C/C++ files for your OS...
Jules

edit: the only problem with that is the gcc compiler that comes with even the newest version of dev-c++ is antiquated, but it still works, I've got the newest version and it comes with gcc 3.4.2...
eax
Member
Member
Posts: 57
Joined: Mon Jun 23, 2008 6:45 am

Re: Help with linker on bare-bones

Post by eax »

Just a comment on that cross compiler guide aj linked, well I hadnt ever built a cross compiler before and I went through that guide and managed to get one built.It is a good guide and helped my understanding a fair bit.
Anubis208
Posts: 8
Joined: Wed Jul 02, 2008 9:23 am

Re: Help with linker on bare-bones

Post by Anubis208 »

I downloaded the MinGW linker and replaced the DJGPP linker with it. Now I can link my kernel.

Now I have found another problem. I made the pad file using this assembly

Code: Select all

times 750 db '.'
and when assembled it made the file 750 bytes. Then I used the copy command to put the files together

copy /B stage1+stage2+pad+kernel.bin floppy.img

and got my img file. I then booted it using Qemu. It booted fine, but when I typed
kernel 200+8 at the GRUB prompt, it froze.

I got it to work with Bochs, but when I type kernel 200+8 it says

grub> kernel 200+8
Error 13: Invalid or unsupported executable format
grub>
midir
Member
Member
Posts: 46
Joined: Fri Jun 13, 2008 4:09 pm

Re: Help with linker on bare-bones

Post by midir »

"Error 13: Invalid or unsupported executable format" means GRUB couldn't either find or understand the Multiboot header, or the exe format. I got that message a lot until I read the Multiboot docs properly. In your case, the issue is that MinGW generates PE files, and GRUB can only boot ELF or Multiboot "a.out kludge" files. (The tutorial is aimed primarily at those compiling on Linux).

If you read the Multiboot docs, it explains that for other kernel formats you need to include the address fields flag (value 0x00010000) in the flags field, and specify the header_addr, load_addr, load_end_addr, bss_end_addr, and entry_addr fields in the header. (Notice that currently, you've not told GRUB where to actually put your kernel in memory.)

Don't worry it's not as hard as it sounds. Here's the header and entry code I use, (originally based on the bare bones tutorial in the wiki):

Code: Select all

global _multiboot_header
global _multiboot_entry
extern _kmain

; setting up the Multiboot header - see GRUB docs for details
align 4
_multiboot_header:
	MAGIC equ 0x1BADB002
	FLAGS equ 0x00010002 ; MMAP + AOUT KLUDGE

	magic dd MAGIC
	flags dd FLAGS
	checksum dd 0 - (FLAGS + MAGIC)
	header_addr dd _multiboot_header
	load_addr dd _multiboot_header
	load_end_addr dd 0
	bss_end_addr dd 0
	entry_addr dd _multiboot_entry

_multiboot_entry:
	mov esp, 0x00020000 ; set up the stack somewhere in low memory
	push eax ; pass Multiboot magic number
	push ebx ; pass Multiboot info structure
	
	mov edx, 0x3f2 ; turn off the floppy drive before we enter the kernel
	mov al, 0x0c
	out dx, al
	
	call _kmain ; call kernel proper
On a semi-related note, I'm not sure I agree with how the bare bones tutorial loads the kernel into the floppy image. Seems a bit error prone, and reliant on exact file sizes of a certain version of GRUB. From what I've read, the easiest way on Windows is to use something like Filedisk or Virtual Floppy Disk to mount the floppy image to a drive letter, copy the kernel file onto it the usual way, and unmount it back to a disk image so the emulator can read it. Beautifully, this can be done in a command line *.bat file to automate it as part of the compilation process. This makes it possible to include other OS files later, and to *automate* the GRUB command to load the kernel with a menu.cfg file. (Actually, I didn't know about these disk programs when I started, so I wrote a PHP script to open the floppy image file and interpret a FAT filesystem within it, to manipulate the files in it directly. Works but it's very complicated!)
Anubis208
Posts: 8
Joined: Wed Jul 02, 2008 9:23 am

Re: Help with linker on bare-bones

Post by Anubis208 »

That method didn't work.
I get this when I link:
ld: warning: cannot find entry symbol _loader; defaulting to 00100000
is that normal?

All I want to do is boot a kernel and have A20 and PMode enabled by the loader. If anyone could direct me to another bootloader that could do that, that would work too.

edit: I did the math and the pad puts my kernel at sector 200.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Help with linker on bare-bones

Post by Combuster »

Well the common way to use grub is to install it to a FAT-formatted floppy, then copy over the kernel to the disk like any other file.

There are several images containing FAT+GRUB around - if you have linux with grub installed you can make your own. Go have a look as it makes those things a lot easier.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Anubis208
Posts: 8
Joined: Wed Jul 02, 2008 9:23 am

Re: Help with linker on bare-bones

Post by Anubis208 »

Does anyone know of another bootloader that enables A20 and PMode?
GRUB just doesn't seem to be made for me.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Help with linker on bare-bones

Post by Combuster »

Write your own.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Anubis208
Posts: 8
Joined: Wed Jul 02, 2008 9:23 am

Re: Help with linker on bare-bones

Post by Anubis208 »

Can you direct me to a tutorial that describes how to do it (I have already attempted several times without success)?
Post Reply