Converting my kernel into plain binary dosn't work

Programming, for all ages and all languages.
Ryu

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

Post by Ryu »

Sure.. just make sure that its linked at the beginning of the image. Its makes it much more simpler to keep assembler code in a single segment (usually .code or can be .text) and let the linker handle the multiple segments within C compiled objects (.text, .data, .bss). Unless you plan to create a 16bit kernel that will grow larger then a 64KB segment, then it would be better to use segments or sections as NASM calls them.
Ryu

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

Post by Ryu »

Okay I promised to figure this out, it wasn't so hard to figure out.. (10mins at most) this control file assumes that you only have defined two segments the .text and .data segments.

The code in MASM used:

Code: Select all

.686P
.MODEL SMALL
OPTION PROLOGUE:none
OPTION EPILOGUE:none
OPTION CASEMAP: none
OPTION SCOPED

assume cs:nothing, ds:nothing, es:nothing, gs:nothing, fs:nothing

TEXT SEGMENT USE32
   db   1Ah, 2Ah, 3Ah, 4Ah
TEXT ENDS

DATA SEGMENT USE32
   db   1Dh, 2Dh, 3Dh, 4Dh
DATA ENDS

;.CODE  

END
The jloc script (note: jloc scripts don't read tabs, and they require each object be added on differnt lines):

ALL:
n:\output\ktest.obj

data: 0 FINAL.after FINAL.i_after
,,,DATA

text: 0 FINAL.start FINAL.start+text.length

FINAL: 0 90000 0
*


Heximal output of ktest.bin:

1A 2A 3A 4A 1D 2D 3D 4D

All the bytes is correct. The name given in jloc for individual segments does not matter, the special note on this script is the ",,,DATA" which will take the DATA segment in objects only. Don't ask me why the commas, I don't know, and this does not conflict if I capitalize the name data to DATA either. So names within jloc control files does not matter at all.


Its probably worth noting that in MASM, how ever you place the segments in code will end up data being first and text being last, with that original script I gave you. And to further experiment a little I tried:

ALL:
n:\output\ktest.obj

data: 0 FINAL.after FINAL.i_after
,,,DATA

text: 0 FINAL.start FINAL.start+text.length
,,,TEXT

FINAL: 0 90000 0
*


This ended up to be data first and padded in a 64KB segment before text appeared in the image which is reversed anyway. Finally I uncommented .CODE segment in my code and used the working jloc control file (first one mentioned in this post), and added this:

Code: Select all


TEXT SEGMENT USE32
   db   1Ah, 2Ah, 3Ah, 4Ah
TEXT ENDS

DATA SEGMENT USE32
   db   1Dh, 2Dh, 3Dh, 4Dh
DATA ENDS

.CODE  
   db   5Ah, 6Ah, 7Ah, 8Ah
END
The output is:
1A 2A 3A 4A 00 00 00 00 00 00 00 00 00 00 00 00 5A 6A 7A 8A 1D 2D 3D 4D

As you can see theres some padding bytes but this is okay, as long as the .text segment is in the beginning. Happy flat-binary coding, and remember to replace my "FINAL: 0 90000 0
" with "FINAL: 10000 10000 0" for your kernel.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

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

Post by Candy »

Is that implicit padding because of alignment or something else? It aligns your data to 16 byte, but is also equal in size to all bytes together...
Ryu

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

Post by Ryu »

Hmmm, that led me to do some other test and found out my control file isn't quite right. Although the padding bytes is for alignment, its pretty typical depending on the code model which should align itself in a single cache line, I suspect to prevent invalidating the instruction prefetch cache so data segement groups dont straddle in the code segment groups.

But this is the fix up to the control file that won't go all weird when more then 2 segments are defined (this explains the weird 64KB padding I had):

ALL:
n:\output\ktest.obj

data: 0 code.after data.length
,,,DATA

code: 0 text.after code.length
,,,CODE

text: 0 FINAL.start text.length

FINAL: 0 90000 0
*


The code:

Code: Select all

.686P
.MODEL SMALL
OPTION PROLOGUE:none
OPTION EPILOGUE:none
OPTION CASEMAP: none
OPTION SCOPED

assume cs:nothing, ds:nothing, es:nothing, gs:nothing, fs:nothing

TEXT SEGMENT USE32
???db???1Ah, 2Ah, 3Ah, 4Ah, 5Ah
TEXT ENDS

DATA SEGMENT USE32
???db???1Dh, 2Dh, 3Dh, 4Dh, 5Dh, 6Dh
DATA ENDS

.CODE  
???db???5Bh, 6Bh, 7Bh, 8Bh, 9Bh
END
And the output:
1A 2A 3A 4A 5A 00 1D 2D 3D 4D 5D 6D 00 00 00 00 5B 6B 7B 8B 9B

It seems jloc doesn't care about what is to be the next segment, even as I specified in the control file. But I really do not see it would be necessary. I did try a few other ways and nothing seem to change .code and .data in the direction I wanted.

edit: I guess the alignment has nothing to do with entire cache lines but only by aligning them in words *shrugs*, If someone can clarify this it would be nice.
.. Unless I'm mistaken to classify .text segments to be in a code group.
Ryu

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

Post by Ryu »

Ah okay its now working, with the same script in the above post with the code:

Code: Select all

TEXT SEGMENT USE32
???db???1Ah, 2Ah, 3Ah, 4Ah, 5Ah
TEXT ENDS

.CODE  
???db???5Bh, 6Bh, 7Bh, 8Bh, 9Bh
.DATA
???db???1Dh, 2Dh, 3Dh, 4Dh, 5Dh, 6Dh
output:
1A 2A 3A 4A 5A 00 00 00 00 00 00 00 00 00 00 00 5B 6B 7B 8B 9B 00 00 00 00 00 00 00 00 00 00 00 1D 2D 3D 4D 5D 6D

Everything is in the right order, and aligned properly. The problem was my ",,,DATA" didn't match up with my DATA segment in my code.

Also, because MASM doesn't natively use .text segements the name TEXT is found by jloc.
Ryu

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

Post by Ryu »

Okay I was also wrong with that script. I came around some other problems as I was supporting multiple segments in my kernel. The issue was the padding was incorrect and computed my offsets in runtime all wrong.

Some points:

* To define a "jloc section" is <section name>: <base> <base_start> <image_start> <selector>
- section name is just a namespace.
- base is linear base in linear memory the image to be loaded which calculates your relative offsets from this base (basically your segment register you will use).
- base_start is where the image will be loaded in memory, which will compute relatively with base. It allows you to to load an image on a nonzero offset of the segment. Ex use base=0, base_start=90000h and in runtime set DS=0 then a jmp far 0:90000h.
- image_start is the offset within the image does the jloc section begins.

* To add a segment into a "jloc section" is <namespace>, <group>, <class>, <segment>, <filename>
- '*' wild card can be used.
- adding multiple segments will be arranged in alphabetically ordered (not tested).
- omitt with ',' (commas).
- segment is the name of segments to add in object file(s)
- filename is the object file to look in.

Heres my control file:

ALL:
n:\output\ktest.obj

text: 0 data.after data.image+data.length
    ,,,TEXT,*

data: 0 code.after code.image+code.length
    ,,,DATA,*

code: 0 FINAL.after FINAL.image+FINAL.length
    ,,,_TEXT,*

FINAL: 0 90000 0
*


Notes on expressions:

The line ",,,TEXT,*" adds all segments named TEXT within all object file added. Be sure to tell it the exact name of the segment which can differnt when things get assembled. You can use a hex editor to peek in the object file to make sure.

"text: 0 data.after data.image+data.length" results the same with "text: 0 data.after data.i_after" however I think its best to think that an i_after is solely for image cacluations. I used data.image+data.length to ensure that the image is identical with how jloc is going to compute the location of that segment. Which was there solely to test if the padding bytes I had before was correct, which I think sometimes the actual segment size in image can be smaller then on runtime which is mostly dealing in virtual enviroments donno.


FINAL: 0 90000 0
*
This line will take all segments in the objects that was nevered added to any "jloc sections" and disgard it.


I think that wraps it up, but theres lots of fine details I didn't bother to add because its all in the jloc.html I just attempted to clearify some things. If anything goes wrong let me know .. :-X
REV

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

Post by REV »

Whoa this kinda blows me off here. :P Man am I confused with what to modify in my control file. (I'll try yours with the FINAL thing changed)

If this dosn't work can I use another linker that is similair to JLOC that dosn't have crappy documentation?

I'm gunna try this new script ou and post my results back here.
Ryu

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

Post by Ryu »

Okay good, I think we are on the verge of cracking it.

Just to be sure your script should look along the lines like this:

ALL:
n:\output\ktest.obj

data: 10000 text.after text.image+text.length
,,,_DATA,*

text: 10000 FINAL.after FINAL.image+FINAL.length
,,,_TEXT,*

FINAL: 10000 10000 0


I've excluded the star at the end because this will output an error when your linking and shows you all the segments in the objects that are not assigned to any "jloc section". Can you please post the error output.
REV wrote: If this dosn't work can I use another linker that is similair to JLOC that dosn't have crappy documentation?
I'll leave this for someone else to answer.
REV

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

Post by REV »

http://www.geocities.com/mike35989/Dump.txt

This forum software won't let me post so long so Im using my old geocities account to hold it.

For the record the "SECTION .text" and "SECTION .data" are still in the init.asm right?

During the orginal watcom linking I was getting warnings about "redefinitons" but I igorned that since the compiler said it ignored it.
Ryu

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

Post by Ryu »

Hmm, I don't know why you got overlap errors. Unless you have changed the script around. Now, I think your script should be looking like this: (It only concerns the segment that is suppose to be entry point)

ALL:
init.obj
file1.obj
file2.obj

code: 10000 10000 0
    ,,,text,*

other: 10000 code.after code.image+code.length
    ,,,*,*


All you need to added the init.obj first add the rest of the objects under ALL.

Also I noticed __CHK as unresolved symbol in all your objects, I think this is a stack checksum routine called at the end of each C function added by Watcom internally. You will need to somehow disable that in Watcom, but my guess you can get away with this by doing a release build.
REV

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

Post by REV »

Yes! It puts the code first. Now it dosn't want to execute on my 486. But give me some time I should fix it and figure out what is wrong.
REV

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

Post by REV »

Hmm I changed the script around and got rid of the "jmp Start" in init.asm and it works 5% of the time. What I mean is that when I compiler and link it into a binary it will work when control is passed. When I compile and link it a second time nothing happens. I tried this 10 times. It only works 1 out of the 10 times.

ALL:
init.obj

code: 10000 10000 0
,,,text,*

data: 10000 code.after code.image+code.length
,,,*,*
Ryu

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

Post by Ryu »

When I compile and link it a second time nothing happens. I tried this 10 times. It only works 1 out of the 10 times.
This is probably because your build procedure is not sequenced correctly. All your object files should be updated before jloc links them. Clean all object files before making another build if you have too.

The script is okay (actually looks the same to me), I have an identical script for my kernel with about 6 differnt segment names, and it never makes a differnt binary no matter how many times I rebuild it. Ofcourse if I change the code it creates a differnt binary. It would also be nice if you give me specific errors, perhaps the linker if any or from an emulation (like Bochs or Qemu) error outputs. You should really think about setting yourself up in a emulator like Bochs if you haven't already.
REV

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

Post by REV »

You mean like "If Exist *.Obj Del *.Obj" right at the beginning of my batch file. I tryed that it dosnt work.
Post Reply