Page 1 of 1

Calling 16-Bit kernel from 16-Bit assembly boot code?

Posted: Thu Nov 17, 2005 12:00 am
by Daedalus
Hi guys,

I'm restarting my OS project I was doing, intending to write most of it myself.

However, I'm having a bit of trouble. My bootloader works fine, I've tested it with other 16-Bit real mode booters. However, they are written entirely in assembly.

I wish to include a Turbo C 2.01 program I wrote, but this is proving difficult. Does anyone know if its possible to link a program written in Turbo C, and write the loaded kernel in assembly (TASM most likely.)

I'm having trouble explaining this. Basically, all I want to do is:

Bootloader loads file 'loader.bin', jumps to execution start.
Loader.bin contains 'start.asm' and 'loader.c' (compiled, of course). start.asm should only call _main located in loader.c

I can't however get the assembly to start the 'main' function in the C code. The C code by itself as an exe or com file works fine (uses the BIOS for IO) but when linked with my own version of the startup library (which just calls _main) nothing happens.
Which is exactly the same thing that happens if I strip the loader.exe file and put it on my disk as loader.bin to be loaded and booted by the bootloader :\

Sorry for the long description, having trouble expressing exactly whats wrong and what I need.

Thanks in advance!

Re: Calling 16-Bit kernel from 16-Bit assembly boot code?

Posted: Thu Nov 17, 2005 12:00 am
by carbonBased
This is certainly possible. I haven't used TC in over a decade, though, so I can't elaborate much :)

If I reall, tcc had a command line switch that would allow it to produce assembly language, as well. That *might* help as a first step... compile your C to assembly, and assemble them both together with tasm.

Combining asm and c is relatively simple for your purposes... you *should* be able to assemble your asm into an object file, and compile your c into an object file, and link them both together without issue. The only real trick is to ensure that your 'libc' runtime is being used, and not TCs. I'm not sure how you would ensure this... probably another command line param.

--Jeff

Re: Calling 16-Bit kernel from 16-Bit assembly boot code?

Posted: Tue Nov 22, 2005 12:00 am
by boot_rom
you surely setup the stack frame correctly for your _main? when executing the stand-alone application this is done for you by our os loader (aka DOS exec). there is no longer such a loader. so you have to do this in your loader.bin.

Re: Calling 16-Bit kernel from 16-Bit assembly boot code?

Posted: Wed Nov 23, 2005 12:00 am
by Daedalus
Forgive me, but could you possibly help me with that?

Something as simple as this would allow me to expand a lot:

Code: Select all

void putchar (char c)
{
        asm push ax
        asm mov  ah, 0x00e
        asm mov  al, c
        asm int  0x10
        asm pop  ax
}

void putstring (char *s)
{
  for(; *s; s++)
    putchar(*s);
}

int main (void)
{
  char msg[] = "Hello, world!\n\rYour operating system has booted ;) Enjoy!";
    putstring(s);
    /* Optionally, halt: */
    /* for( ; ; ) ; */
  return 0;
}
With the assembly code merely calling the C function main.

I have a (much larger) but working executable compiled in turbo c, which itself uses no libc, all the required functions are in the source.

Thanks for the help!

Re: Calling 16-Bit kernel from 16-Bit assembly boot code?

Posted: Wed Nov 23, 2005 12:00 am
by carbonBased
Is that cut-n-pasted from your code? 'cuz you've defined a string 'msg' but you're printing 's' which is undefined.

Given that you appear to be working in real mode, creating a stack frame is simple... just point ss:sp to valid memory (remembering that stacks expand down in real mode, unless you perform some trickery).

--Jeff

Re: Calling 16-Bit kernel from 16-Bit assembly boot code?

Posted: Wed Nov 23, 2005 12:00 am
by Daedalus
Ah yes sorry, the first 2 functions are from my code, and I wrote the main function quickly, forgetting I named the string msg; woops!

As for the stack pointers and such, I must admit I havent dealt much with assembly. I know enough to understand what's going on, but I'm not sure of how to do what you said.

Sorry to ask, but would you mind showing me how to do it ?

Re: Calling 16-Bit kernel from 16-Bit assembly boot code?

Posted: Sun Dec 04, 2005 12:00 am
by luke
You cannot access ss directly, use ax instead.
Here is the code to set ss and sp to valid memory(assuming that you aren't using the segment 0900h):

Code: Select all

mov ax, 0900h ; we are using ax to set ss
mov ss, ax ; set ss
mov sp, 0ffffh ; use entire segment(we can:) )