Page 1 of 1

Bloody Beginner 3: loading and executing programs

Posted: Mon Jul 14, 2008 8:08 am
by hpclutz
Back again ;)
however, this time I hope with a more interesting philosophical / design discussion - I think there is no straight-forward answer for this, unless I am just #-o

What I want to tackle next is load code into memory (don't even know how to read a disk yet ;) )and then execute it. However, I want to be able to call OS system methods from this code. This implies however that I know the entry addresses of the respective methods - as the OS is still subject to change and as I may potentially even load it to different locations, these addresses are not static though...

Implicitly I have to find a means of identifying the relevant addresses during load / execution. So far I can think of the following methods:
  • Translate all jump / call addresses from a "unique" identifier into the current method addresses during load. This requires an identifier of some sort (a string?) as well as a means to identify the current addresses of the methods (how?). It furthermore requires that the whole code needs to be searched for the according ids.
  • Use something like a translation table to which all method calls in the code jump and from where the actual procedure would be called (like a header). This makes it easier to "translate" the code, still requires IDs and identification of the method addresses though
  • Export the OS functions into a library and link the library into the code during compilation. This is obviously least desirable, as it duplicates all functions and it is difficult to maintain updates.
  • Execute the code in an interpreted fashion, i.e. load into memory but execute step by step and interpret the calls ("just in time compilation"). This is obviously the slowest version, but it would allow code management in the long run (see C#)
What are your opinions? How did you tackle code loading and execution? Or am I just stupid?

Cheers

Re: Bloody Beginner 3: loading and executing programs

Posted: Mon Jul 14, 2008 8:22 am
by jal
hpclutz wrote:Back again ;)
A few obeservations. First, on the Intel architecture, an OS usually uses ring 0 for kernel code and ring 3 for user code. From ring 3, one cannot call directly into any ring 0 code. The usual solution is to use software interrupts (or, more typical, a single one), but it would also be possible to use call gates. Using the first solution would not need the application to know any address, only the interrupt number. The kernel will fill the IDT, so the application doesn't need to know anything about the address. For a detailed explanation, read the Intel manuals. Secondly, Windows 95 used a method by which an interrupt was, the first time it was called, replaced by a far call. I believe that they did this for speed reasons, as a far call (even through a call gate) is faster than an interrupt (I'm not sure whether they used this method for kernel calls or DLL calls only, memory is fading). Thirdly, the solutions you give seem to imply you haven't thought (or don't care) about protection. You may want to do that though, unless you want a console-type OS like DexOS.


JAL

Re: Bloody Beginner 3: loading and executing programs

Posted: Mon Jul 14, 2008 8:24 am
by inflater
Well, e.g. DexOS uses a call-table. That's this point you've mentioned,
Use something like a translation table to which all method calls in the code jump and from where the actual procedure would be called (like a header). This makes it easier to "translate" the code, still requires IDs and identification of the method addresses though
But the easiest thing to do is just hook a OS interrupt, e.g. my OS hooks INT 30h, and make your own handler, for example your ISR for your OS INT will check AH for "function index number", like this:

Code: Select all

cmp ah,0
je TextInputFunctions
cmp ah,1
je DiskFunctions
...
TextInputFunctions:
cmp al,0
je PrintString
cmp al,1
je PrintChar
...
etc, etc. And you can in AL check for e.g. a "sub function" or some type. It depends how you'll design it. :)
And then, when you have your own working system interrupt with e.g. "print string" which requires ESI to the string, AH=01 and AL=00, you'll execute this in your program:

Code: Select all

mov ah,01    ;e.g. text output fncs
mov al,0        ;e.g. print string
mov esi,TheString
int 30h
...
and it'll print, if you programmed your functions and ISR handler properly. :)

Regards
inflater

Re: Bloody Beginner 3: loading and executing programs

Posted: Mon Jul 14, 2008 8:51 am
by hpclutz
Cool 8) thanks

I must confess, I did think along the line of a pure command line OS (I won't be going commercial anytime soon ;) ) and I have COMPLETELY forgotten about the option to use interrupts ( #-o indeed).

That gives me something to fiddle around with now, so thanks again for your helpful explanations

Re: Bloody Beginner 3: loading and executing programs

Posted: Mon Jul 14, 2008 10:30 am
by cr2
LBA hard disk access.

EDIT 1: Deleted The "Use LBA28" suggestion.

Re: Bloody Beginner 3: loading and executing programs

Posted: Mon Jul 14, 2008 8:58 pm
by quok
cr2 wrote:LBA hard disk access. (I suggest you use LBA28, LBA48 isn't supported by bochs)
Bochs 2.3.7 supposedly supports LBA48 now.

Re: Bloody Beginner 3: loading and executing programs

Posted: Mon Jul 14, 2008 9:24 pm
by 01000101
BOCHS 2.3.7 ChangeLog
7 - Implemented LBA48 support in BIOS
sweet. 8)

Re: Bloody Beginner 3: loading and executing programs

Posted: Tue Jul 15, 2008 5:02 am
by bewing
cr2 wrote:LBA hard disk access. (I suggest you use LBA28, LBA48 isn't supported by bochs)
Last time I looked at Dragoniz3r's code, it had at least one error in it. I think our wiki article is much better: ATA_PIO_Mode.

And bochs has supported LBA 48 in pmode since at least version 2.3.5.

Re: Bloody Beginner 3: loading and executing programs

Posted: Tue Jul 15, 2008 8:27 am
by quok
bewing wrote: And bochs has supported LBA 48 in pmode since at least version 2.3.5.
That's what I thought, too, but Changelogs never lie. :wink:

Re: Bloody Beginner 3: loading and executing programs

Posted: Tue Jul 15, 2008 12:54 pm
by AJ
7 - Implemented LBA48 support in BIOS
Wouldn't this simply imply new support for LBA48 via the BIOS extended read functions - it could have been available in PMode for a while.

Cheers,
Adam

[edit - rephrase!]