2

I have a problem with my 32-bit protected mode OS project Sinatra. I can compile sources to object files, but I don't know how to link these together. I use NASM and TDM-GCC on Windows. I have fixed problems with my code so it compiles. I have removed the comments for brevity.

My file boot.asm:

[BITS 32]
[global start]
[extern _JlMain]
start: 
    cli
    call _JlMain
    hlt

My file JSinatra.h:

#ifndef __SINATRA_H__
#define __SINATRA_H__

#define JWhiteText 0x07
void JlMain();
void JlClearScreen();
unsigned int JlPrintF(char * message, unsigned int line);

#endif

My file JSinatra.c:

#include "JSinatra.h"

void JlClearScreen() // clear entire screen
{
    char * vidmem = (char * ) 0xb8000;
    unsigned int i = 0;
    while (i < (80 * 25 * 2)) {
        vidmem[i] = ' ';
        i += 1;
        vidmem[i] = JWhiteText;
        i += 1;
    }
}
unsigned int JlPrintF(char * message, unsigned int line) {
    char * vidmem = (char * ) 0xb8000;
    unsigned int i = 0;
    i = line * 80 * 2;
    while ( * message != 0) {
        if ( * message == '\n') {
            line += 1;
            i = (line * 80 * 2); * message += 1;
        } else {
            vidmem[i] = * message; * message += 1;
            i += 1;
            vidmem[i] = JWhiteText;
            i += 1;
        }
    }
    return (1);
}
void JlMain() {
    JlClearScreen();
    JlPrintF("Sinatra v0 Virgin/Kernel Mode\n", 0);
}

I need to load my OS starting at absolute address 0x100000. How can I properly compile and link my code to create a binary image?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • What compiler and linker toolchain are you using? With GCC and GNU binutils, this is trivial. Both C and assembly files result in ELF files that `ld` knows how to link. I'm sorry, but your question is incredibly vague, and I think you need to learn some fundamentals before you ask us how to help with your OS project. – Jonathon Reinhart Aug 28 '15 at 20:55
  • I am using GCC/G++ (in my opinions, they're same) and Netw. Assembler in Windows. I have source files as I said, but I don't understand ld and I don't know how linker script should I use. – AraneaSerket6848 Aug 28 '15 at 20:58
  • What "Assembler in Windows"? It sounds bad. – Eugene Sh. Aug 28 '15 at 21:00
  • 2
    I'm sorry, but this is far too broad for Stack Overflow. We can't possibly teach you everything you need to know about compilers, assemblers, linkers, linker scripts, etc. in one question. I strongly suggest you do your own research, by finding tutorials and sample code, from which you can learn. – Jonathon Reinhart Aug 28 '15 at 21:04
  • Sorry for the broadness. As I said, I don't know linker-script and I'm adding one of the ld scripts online. – AraneaSerket6848 Aug 28 '15 at 21:06
  • @AraneaSerket6848 I looked quickly at your code and one thing is missing (and one needs to know for linking) - how does your kernel boot? Your code clearly isn't designed to be booted straight from the BIOS. Are you using a multiboot boot loader of some kind (`grub` for example)? And what location is your boot loader starting execution from (I can take a wild guess that it might be 0x100000) ? – Michael Petch Aug 28 '15 at 21:33
  • @MichaelPetch I'm trying to loading it at 0x100000 without grub. – AraneaSerket6848 Aug 28 '15 at 21:41
  • If you aren't using `grub` are you using any bootloader at all? If not that is going to be a big problem. I thought you might have been using something like grub that starts at boot up and then loads your kernel. I thought there was some other loader in there mainly because your source code doesn't go into protected mode by itself which means something has to have done it for you already. – Michael Petch Aug 28 '15 at 21:44
  • @MichaelPetch No, I am not using any. I'm using [BITS 32] statement. – AraneaSerket6848 Aug 28 '15 at 21:45
  • [BITS 32] doesn't put you in protected mode. It just says what instruction set will be used when generating the code. – Michael Petch Aug 28 '15 at 21:53
  • Maybe I have to ask this way. How do you test your kernel? What environment? an emulator like bochs? or something else? – Michael Petch Aug 28 '15 at 21:54
  • just make sure that the asm functions are using/expecting the same linkage format as C is using and then include all the object files (result of compiling and assembling) in the link statement. – user3629249 Aug 29 '15 at 00:06
  • @AraneaSerket6848 : I have reworded your question and put your code inside the question in the hopes that this question will be reopened.I have used information you have provided in the comments to help make the question more specific. – Michael Petch Sep 06 '15 at 01:13
  • @AraneaSerket6848 : You may be interested in this zip file http://www.capp-sysware.com/misc/sinatra.zip . It is an update to your project, a floppy disk image (with grub setup to load your kernel), a sample batch file, and a **README.TXT** file that I recommend going through first. My answer to your question still applies. This answers your followup question about how to load _SINATRA.IMG_ kernel file into a disk image that can be used in BOCHS. The disk image in the archive does boot in BOCHS and loads clears the screen and prints your kernel info on the top line. – Michael Petch Sep 07 '15 at 05:22

2 Answers2

3

First of all, if you're compiling to ELF, then you mustn't add an initial underscore before functions in assembly.

Now, in order to link different source files together, you obviously have to get them to common ground, which is in this case, object code.

So, what you'll do is:

  1. Assemble the assembly source files to object code.
  2. Compile but not link C source files to object code. In gcc: gcc -c file.c -o file.o
  3. Link those together. In gcc: gcc cfile.o asfile.o -o app
Amr Ayman
  • 1,129
  • 1
  • 8
  • 24
1

Using GCC-TDM and NASM on Windows

Because you are targeting an OS being loaded at an absolute address without C-runtimes you'll need to make sure you compile as freestanding code; that your asm and C files target the same type of object (win32/PECOFF); and the last step will be converting the PECOFF file to a binary image.

To compile C files you would use something like:

gcc -m32 -ffreestanding -c JSinatra.c -o JSinatra.o

To assemble the asm files you would use something like:

nasm -f win32 boot.asm -o boot.o

To link them together you have to do it in two steps:

ld -m i386pe -T NUL -o sinatra.tmp -Ttext 0x100000 boot.o JSinatra.o

The ld command above will create a temporary file sinatra.tmp that is a 32-bit PECOFF executable. You then need to convert sinatra.tmp to a binary image with a command like:

objcopy -O binary sinatra.tmp sinatra.img

You should then have a binary image in the file sinatra.img

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • ld: unrecognised emulation mode: elf_i386, Supported emulations: i386pe @MichaelPetch – AraneaSerket6848 Sep 05 '15 at 18:35
  • ld: cannot perform PE operations on non PE output file 'sinatra'. @MichaelPetch – AraneaSerket6848 Sep 05 '15 at 18:53
  • It says the same! (and I'm using TDM-GCC, Cygwin or MinGW taking centuries to install...) @MichaelPetch – AraneaSerket6848 Sep 05 '15 at 19:05
  • Please notify me when you came. @MichaelPetch – AraneaSerket6848 Sep 05 '15 at 19:31
  • @AraneaSerket6848 : I just updated the answer. My original `ld` command was in error as I inadvertently removed the `.text` section which meant your string that was to be displayed wasn't present in the final image – Michael Petch Sep 05 '15 at 23:45
  • It compiled! But how I can boot this image? @MichaelPetch – AraneaSerket6848 Sep 06 '15 at 14:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/88931/discussion-between-araneaserket6848-and-michael-petch). – AraneaSerket6848 Sep 06 '15 at 14:35
  • @AraneaSerket6848 : You may be interested in this zip file http://www.capp-sysware.com/misc/sinatra.zip . It is an update to your project, a floppy disk image (with grub setup to load your kernel), a sample batch file, and a **README.TXT** file that I recommend going through first. My answer to your question still applies. This answers your followup question about how to load _SINATRA.IMG_ kernel file into a disk image that can be used in BOCHS. The disk image in the archive does boot in BOCHS and loads clears the screen and prints your kernel info on the top line. – Michael Petch Sep 07 '15 at 05:23