Page 1 of 3

Converting my kernel into plain binary dosn't work

Posted: Sun Jun 11, 2006 8:51 pm
by REV
Im using Watcom 11.0c and NASM 0.98 to make my kernel and I have a build batch file along with the makefiles for Watcom.

The NASM code is the 'bare bones' start up code. (Move to PMode and call function main).

Well the object files mix together perfectly and they both like each other. However I am also using Exe2Bin to covert it all to plain Binary and then write it to disk. This dosn't go so well. Exe2Bin whines about no starting address and the IP dosn't point to 0h or 100h. I know I can't use [org] in an *.Obj file. I read the NASM documentation and it didn't help.

So how can I make the coversion of my kernel from *.EXE into *.BIN and get loaded into a certain memory address?

My bootloader loads the kernel in 1000:0000 and then jumps to it. I know that this works because I tested it.

PS. I am making a Dos4g app because anyother application complains about the 32-bit object files.

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 2:24 am
by Ryu
I'm wondering if Watcom and NASM can produce OMFs, because I use jloc to link each object file and tell it exactly where the image is going to be loaded.

Although, jloc has a little hassle but I think its pretty unavoidable considering if you have multiple compilers to link a single binary. (You will realise this if you do function level linking like me) Give jloc a shot which I remember seeing a link on the OSFaq not sure, but google should also return some hits.

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 6:16 am
by REV
Nice. Watcom make OMF fils by default and NASM can be changed! Hmmmm JLOC. Is there an online tutorial?

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 9:04 am
by Ryu
Just the help file he provided with the linker: http://my.execpc.com/~geezer/johnfine/jloc.htm

This is basically what I only know the rest you will have to fiddle with. You create control files looking something like this for your kernel, lets just name this file kernel.cfg:

Code: Select all

ALL:
   kernel.obj
   file1.obj
   file2.obj
FINAL: 0 90000 0
   *
You'll probably only have to worry about the first two heximals in "FINAL: 0 90000 0". The first is your code segment base you are going to use, second is the image base is going to be executed. So for this example I would match this up by creating a zero based code selector, and load the image at 90000h.

Finally the command line to run the linker, just tell it which control file and name of the output file:

jloc .\kernel.cfg .\bin\kernel.sys

This should be enough to know so you can link the Watcom and NASM together in a flat binary. The linker is very flexible which you can do other things but its beyond me.

edit: Some corrections 8)

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 1:37 pm
by REV
Looks like I won't need EXE2BIN! :D

Hmmmm the documentation is poor for this linker but I'll figure it out. I always do. :)

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 6:28 pm
by REV
Nice. But how can I make Watcom make the object files without having to link them? Because as far as I know you have to link them. ???

I am also getting errors as well. All of the object files that were compiled by Watcom are complaining about __CHK. None of the NASM files appear to be affected.
Errors:
Undefined symbol __CHK in D:\CodyOS\hal\i386\system\system.c (system.obj)
Undefined symbol __CHK in D:\CodyOS\hal\i386\system\ports.c (ports.obj)
Undefined symbol __CHK in D:\CodyOS\hal\i386\floppy\floppy.c (floppy.obj)
Undefined symbol __CHK in D:\CodyOS\hal\i386\video\graphics.c (graphics.obj)
Undefined symbol __CHK in D:\CodyOS\hal\i386\video\video.c (video.obj)
Undefined symbol __CHK in D:\CodyOS\hal\i386\video\text.c (text.obj)
Undefined symbol __CHK in D:\CodyOS\init\kinit.c (kinit.obj)
Undefined symbol _cstart_ in D:\CodyOS\init\kinit.c (kinit.obj)
Undefined symbol __CHK in D:\CodyOS\core\out\print.c (print.obj)

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 8:03 pm
by Ryu
I think this is cause by the internal compiler setting.. which Watcom is automatically assuming a specific C runtime library will be used, therefore would have _start and stack checksum routines. I'm don't know Watcom at all, but is there a setting for Watcom to disable all default libraries? As far as not making Watcom linking theres probably a compiler switch as well.

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 8:07 pm
by REV
Also the starting address confuses me. Should I add:
[tt]MAIN: 1000 0000 0[/tt]
instead of BOOT?

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 8:12 pm
by Ryu
In a flat binary your starting address is always assumed to be offset 0 in the image. Using the name MAIN or BOOT doesn't matter I don't think, just what object file that is firstly added which I tried to show on my example.

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 8:19 pm
by REV
Hmmm. So my barebones (init.obj) should be added first? Then I need to add main() (kinit.obj)?

Re:Converting my kernel into plain binary dosn't work

Posted: Mon Jun 12, 2006 8:28 pm
by Ryu
Yep if it holds the starting entry. I shouldn't say it should be always at offset 0 because sometimes you may use ORG like a .com in DOS for example that starts at 100h. However you need some standard to know where the entry point is, which means you always need to link the object that holds the entry point first in a flat binary to make things simple. If you do function level linking there can be an exception to that, if you place _main.obj then _init.obj and _int.obj depends on _main.obj then the linker should have placed _init.obj in the top of the dependancy tree so then _init will be first in the image. But ofcourse this gets messy so its wise to keep the entry point as the first object. Hope that makes any sense :)

Re:Converting my kernel into plain binary dosn't work

Posted: Tue Jun 13, 2006 9:59 pm
by REV
I understand what your saying but mu code dosn't seem to seem to boot. My kernel sucks up 27 sectors on the disk. (I'm using a RAW file system for now, The bootloader loads it to the realmode address of 1000:0000) Could that be a proublem?

If not here is my code:
Init.Asm:
[tt]
[bits 16] ;Set us up in real mode.
[extern main_]
group DGROUP _TEXT _DATA _BSS _STACK

jmp start

segment _DATA class=DATA
(Varibles are declared here. Messages to be printed)

segment _TEXT class=CODE

start:
mov ah, 00h
mov al, 03h ;80x25x16 (Text mode)
int 10h

mov si, msgMadeit
call DisplayMessage

call main_

segment _BSS class=BSS
segment _STACK class=STACK
[/tt]

JLOC Linker:
[tt]

ALL:
init.obj
kinit.obj
system.obj
ports.obj
floppy.obj
graphics.obj
video.obj
text.obj
print.obj
MAIN: 1000 0000 0
*
[/tt]

Re:Converting my kernel into plain binary dosn't work

Posted: Tue Jun 13, 2006 10:46 pm
by Ryu
1000:0000 = 10000h linear, jloc uses the linear address sorry I should of mentioned that.

I don't see anything else wrong assuming that as segment registers were correctly setup, and you did a jmp to 1000:0000h with (MAIN: 10000 0000 0). If a problem persist maybe try a cli and hlt at the begining and post the register dump in Bochs.

Note: I'm not entirely sure if 16bit code is supported by jloc.

edit: Okay, it works for 16bit code, I forgot my boot.sys is 16bit. :D

Re:Converting my kernel into plain binary dosn't work

Posted: Wed Jun 14, 2006 1:00 pm
by REV
So I need to change the makefile in JLOC? ( I have a feeling that MAIN is the proublem)

On second thought it might be the bootloader slightly causing the proublem.

I'll send you my bootloader, init.asm and my linker script.

Re:Converting my kernel into plain binary dosn't work

Posted: Wed Jun 14, 2006 8:56 pm
by Ryu
Well if you ask me I wouldn't think MAIN is the problem, possibly if you name it the same as a segment such as _TEXT or _DATA etc. But Thats just assumptions without testing. At the moment I dont have access to any of my compilers/assemblers to varify this.

Have you changed that line in the control file? (MAIN: 10000 0 0). The linker does not change the segment registers however will compute offsets for an example:

mov eax, [immediate offset @some_data_in_image]

This is where jloc comes in and computes this offset at the specified base rather then relitive to image offset. And ofcourse at runtime the computed offset is to be relative to DS segment.

So I suggest you go through your code and make sure things like this is not confused. As I recommended, you should have a hex editor and disassembler at hand to do some debugging.