i've now decided that coding the whole os in assembler is not the solution, so i settle up for c++.
well, its quite difficult, since i need a compiler which can work with a different base (since i'm using paging, at some point the code's base is 0xF0000000, before it was 0x7C00 while booting and 0x00000000 while initializing). but the most important thing is, that the linker can output in a raw-binary format without any os-specific header-thingy.

things i've tried:
- the visual c++-compiler:
well, it's quite good, but the linker won't output without header - well, is it possible anyhow?. i could even generate the code with different bases.
i thought even of writing a program which just grabs that piece of code and puts it in a seperate file, when it is linked correctly.
- the gcc-compiler + the linker ld.exe
didn't try long with it, but i still don't get a raw output (if i give it the option --oformat binary it sould do, but the program generates an exception.... - i took a look at another os, where that option is used) and i think the compiler can't handle different base-adresses.

its just too much work coding in assembler... c++ would make things so much easier :)

thanks anyway
Posted on 2004-01-07 13:42:49 by hartyl
Try and use John Fine's JLOC ...
Posted on 2004-01-07 14:01:12 by BogdanOntanu
I'd recoment using fasm, you'll be able to get raw output directly, and you'll be able to specify any origin.

Just one side note (worth pointing out just incase someone missed it), you cannot use masm (and mostlikey not any other M$ product - I think VC++ follows the same EULA as masm) to make any kind of OS, since it's illegal. (search the board if you want more info).

But for writing mid-level OS code I'd say pure C is the best (no need to bring C++ objects into the picture). Besides what says doing things in C++ makes it easier, I often find myself doing things faster in asm than I C++ (I guess it's all damn typecasts that slows me down :/ )

Maybe you must make each 'address section' in it's own file (compile it to raw and then cat the files together).
Posted on 2004-01-08 10:09:53 by scientica
I would have also suggested FASM (or waiting for SOL_ASM) but he wanted a c/c++ solution.

I also thing anything else but ASM is an overkill and in most cases no way easyer ... just a mind ideea that is easyer ... but it is his choice and i respect it.

I course C++ typecasting every little day i work :D

Instead of helping me find mistakes it is mostly slowing me down and making me search for axes nearby

I do not see any use for C++ and clases other than fancy IDE and the fact that they want to hide that there are structures with function pointers inside...and that is not nice structured programming isnt it :rolleyes:

Somehow the humman race considers that hideing and lieing is a very nice and good thing...
Posted on 2004-01-08 10:25:09 by BogdanOntanu

you cannot use masm (and mostlikey not any other M$ product - I think VC++ follows the same EULA as masm) to make any kind of OS, since it's illegal.

You cannot use the most recent masm from DDKs to do anything but drivers, if you follow their EULA - if you *bought* masm, you should be able to use it for whatever you want. Same goes for VC++ I bet.

I often find myself doing things faster in asm than I C++ (I guess it's all damn typecasts that slows me down :/

That's because you're working with the WIN32 API that was designed for C...

hartyl, the GNU ld is pretty powerful once you start messing with linker scripts. You can do a lot of nice stuff, and binary output isn't a problem.

But why not go for a PE-based kernel? Keep basic initialization in assembly, then jump to your PE kernel once it's loaded and basic paging etc is set up. You can always add support for relocations later on if you want to, but of course choosing an arbitrary imagebase isn't a problem either.

I'd suggest you to keep the core kernel pretty small, and split off as much as you can into modules. Makes it easier to update components on-the-fly and can give better error isolation. Besides, it makes it easier to discard an entire unused module from memory, instead of just unused pages.
Posted on 2004-01-08 11:08:08 by f0dder

If you are looking for a free C/C++ compiler, you can try Pelle's C, Digital Mars, Blodshed and Open Watcom.
Posted on 2004-01-08 12:28:20 by Vortex
It sounds more like he's looking for a linker that can produce binary output than he's looking for a free C/C++ compiler ^_^

OpenWatcom, while not really that hot anymore, might be a choice though... from what I remember, watcom had a lot of output options.
Posted on 2004-01-08 12:33:06 by f0dder
good information you're giving me. i've tried to make it with the gcc compiler and the ld linker the easiest way (a minimal code to see it working).
i have 2 files and want to link the together while one file uses functions of the other. it looks like this:

extern "C"
{ void core();

int foo_bar(unsigned long foo);

void main()
{ int x=foo_bar(1);

int foo_bar(unsigned long foo)
{ return (int)(foo-1);


extern "C"
{ int foo_bar(unsigned long);

void core()
{ foo_bar(1);

i compile to object-files like this:

gcc boot.cpp -c
gcc core.cpp -c

but when linking i get the error:

>ld boot.o core.o -e _main

boot.o(.text+0x7):boot.cpp: undefined reference to `__main'
boot.o(.text+0x1e):boot.cpp: undefined reference to `core'
core.o(.text+0xc):core.cpp: undefined reference to `foo_bar'

why doesn't it work? why can't the linker find my references between the object-files?
(addition: i have never done self-linking before...)
(another addition: ld just crashes when i use "--oformat binary"... - another "why?!")
Posted on 2004-01-08 14:31:18 by hartyl
when specifying entrypoint, you should probably just use "main" and not "_main".

You're doing .cpp files - thus, you'll have name decoration on your stuff. You're trying to import symbols without name decoration ("extern C" block), but you're exporting them as decorated names - you need a "extern C" block with prototype for the symbols in the source file exporting them, too - I suggest doing this via header files, since you can use same header files for both the exporting and importing files. This helps making sure you have the same defitions everywhere, too!

Also, remember to put "static" (or unnamed namespaces, if you want to take advantage of new C++ features) on all symbols you do not wish to export, so you avoid name clashes and weird errors.

ld crashes on binary output? Weird. Yay for wonderful bugfree open software ;)

Hm, either I accidentally wiped out my old toy kernel :(, or I have RARed it up and moved it to a backup CD... I'll have to look around a bit :-s - I was going to attach the ld linker script I used for my kernel. Damn.
Posted on 2004-01-08 14:50:33 by f0dder
omg! deleting a kernel? :D

you're brilliant; didn't know that the exported functions have to appear also in the "extern C"-block - learnt something :D

it works even more than before; i got dev-cpp, the newest version with the "ld"-linker. that version doesnt crash when i use the "--oformat binary", but it doesnt work either giving me this error:
"PE operations on non PE file."
cruel, isn't it?
Posted on 2004-01-08 15:20:47 by hartyl
it does seem like I have a backup from 20020711 - phew. Probably haven't messed with it since then. Wonder why it's gone from my harddrive and I don't have other backups of it :-s. The linker script looks like this:

.text 0x100000 :
__TEXT_START = . ;
__TEXT_END = . ;

.data ALIGN(32) : /* we don't need 4k alignment for data */
__DATA_START = . ;
__DATA_END = . ;

.bss ALIGN(4096) :
__BSS_START = . ;
. = ALIGN(4096);
__BSS_END = . ;
__KERNEL_END = . ;

.init ALIGN(4096):

- it's clear that ld is more powerful than the MS linker, I sometimes miss being able to define symbols and control section order... too bad it's such a big piece of dirty GNU code, it would be nice adding ms-coff support (only difference from gnu-coff should be relative relocations) and ms library support...
Posted on 2004-01-08 15:29:28 by f0dder
you might already know my answer:
i have no idea how the script works, what the syntax is like, where the obj-files are specified.
the code looks nice, but where is the __KERNEL_ENTRY__ defined? is it a symbol? if you output in binary, where do the section-names appear (actually the aren't used, are they?)? maybe a complete reference of the script and its syntax?

how does the ld-linker react on ms-coff obj-files?

i'll play around with this script, maybe i get a good result.

thanks at all; i'll tell you what i got then :)
Posted on 2004-01-09 02:48:10 by hartyl
You can find examples here: kernel1 kernel2 kernel3

Also you know that a procedure, function, method is only a entry point for the whole file, eg:

mov eax, eax
rol ax,1

You can mark in any place the start, including point to ret, what I whant to say is that the functions of C are address, then you can do some like #define entry funct, and that will give you the correct, or more, code void __KERNEL_ENTRY__(void), also I am thinking in some fun... you know that you can make a prototype for pointer functions, I dont remember the correct sintaxis, but search for function pointers, and you can have diferent entry points, only mark what you whant.... (I not think I explain this ok.. :S)

Also If i am not wrong, dev-cpp use http://mingw.org/ then you can search for http://sources.redhat.com/binutils/docs-2.12/ld.info/Scripts.html#Scripts ok... is a source from red had, but is from the docs of mingw (http://mingw.org/docs.shtml)

it's clear that ld is more powerful than the MS linker
What about the assembler? :D

Have a nice dy or night.
Posted on 2004-01-09 04:26:22 by rea
The input files aren't specified in the linker script (they can be, though) - I use the linker script to control the order of sections, plus add some symbols. Specify .obj and .lib on commandline.

__KERNEL_ENTRY__ is defined in one of my .c files (or perhaps a .asm one, can't remember). It may seem a bit pointless including it, but iirc ld bitches if you don't have an entrypoint - even for binary output.

The section-names appear nowhere, but it's nice being able to control the order they appear in the binary output.

For a reference of the script, your best bet is probably unix "info ld" or go to http://www.delorie.com/djgpp/ and get the 32bit dos extended djgpp, as it has the texinfo program + docs on ld.

how does the ld-linker react on ms-coff obj-files?

Good question. DJGPP uses the gnu-coff or dj-coff or whatever... dunno if perhaps mingw32 supports ms-coff? The only difference I encountered between the two formats were with regards to relocations. In the MS format, the code has a dword 0 and the linker does the entire relocation, in the other format it has a value where the relocation delta will be applied.

I'd still advise you to use PE or ELF for your kernel, but getting binary kernel loading to work first is probably a good idea :)


What about the assembler? :D

I'd much rather use masm than gas - or well, perhaps gas is okay after they added intel syntax. I don't do "high-level" coding in assembly anyway, so I tend to prefer nasm or fasm, since they do what I want them to.
Posted on 2004-01-09 06:12:57 by f0dder
Addendum: there isn't really any way to distinguish ms-coff from the other coff format - apart from runtime crashes if you use an incompatible linker and object format (have a look at generated code with a disassembler).
Posted on 2004-01-09 06:13:49 by f0dder
Hi f0dder,

Do you know if there is any specification/reference for the MS COFF obj file and lib format?
Posted on 2004-01-09 12:23:19 by Vortex
look in MSDN, it's there along with the PE format. mscoff is identical to the gnu coff anyway, except for those relocs and prolly extended debug info.
Posted on 2004-01-09 13:46:25 by f0dder
man, i start hating it; so much good information, and i still keep failing.
i went to level 0, i got kernel1.zip (posted by hgb) and used exactly the tools used for that example. the gcc-compiler and ld-linker are from the dev-cpp-binaries (newest i think) and i got the newest nasmw as well. then i exectued the kernelbuild.bat, where the compiler does its work, the assembler as well, but the linker just outputs a message complaining about the object file from nasmw:


C:\Dev-Cpp\bin>nasmw -f aout kernel.asm -o kernel.o

C:\Dev-Cpp\bin>ld -T kernel.ld kernel.o
kernel.o: file not recognized: File format not recognized

if i use another file-format (coff,obj,win32) i get "PE operation on non PE file."

this can't be true?! or am i predicted to failing using windows for developing my system (do the linux-assembler/compiler/linker-versions behave differently?)
Posted on 2004-01-10 05:29:56 by hartyl
The only 'error' that I obtain when I compile (by hand or in the command line.. naa use the bat ;) ) is:

$ nasm -faout kernel.asm
$ ld -T kernel.ld kernel.o
ld: warning: cannot find entry symbol start; defaulting to ff800000
$ ls
a.out* kernel.asm kernelbuild.bat kernel.ld kernel.o

That is because the linker dont know where is the entry point in the files that you pass to it (specially the .o or other object files, the reference is not specified where is it), the simbol start, this is because in the nasm source is not specified that start is 'exported', you can do that with: global start then let all the codes there like there are..., the asm file is:
 [bits 32]

global start
jmp $

And the output now is:

$ nasm -faout kernel.asm
$ ld -T kernel.ld kernel.o
$ ls
a.out* kernel.asm kernelbuild.bat kernel.ld kernel.o

At less no errors

the ld that I use is: $ ld --version
GNU ld version 20020717

I not hink that there exist a problem in the port of ld to win, try first with the correction to the asm file.

Also other option that some persons like a lot is bin nasm -fbin

Have a nice day or night.
Posted on 2004-01-10 10:33:31 by rea
Originally posted by hgb
I not hink that there exist a problem in the port of ld to win, try first with the correction to the asm file.

hmm, somehow i don't thrust the output of nasm

Originally posted by hgb
Also other option that some persons like a lot is bin nasm -fbin

nah, that's the reason why i want to do it the obj-file-way; i can't make any references to the c-files when i just make a binary assembler-code.

the linker gives the same error if i try the obj-files from fasm (MS COFF, COFF or ELF)...

either i give the whole thing up, or i have the do it a dirty way, i think
Posted on 2004-01-10 13:39:22 by hartyl