Thunder wrote:
How to select a specific load address for kernel?
And what it should be ?
Based on you earlier posting, I'm assumng that you're coding in NASM at this point, and that the second stage of the mini-kernel is in real mode. If you're in p-mode, then issues are somewhat different, and even moreso if you're coding in C.
In any case, you are really asking three questions: where should the boot code load the second stage, where should the boot loader jump to in the loaded code, and how do you set up the second stage code itself to begin at the desired origin?
The first question is fairly easy to answer. At the stage where you are loading the second stage, the only areas you don't have free to use in memory are:
the first 256 bytes (the interrupt table);
the 512 bytes from 0000:7C00 to 0000:7D00, containing the bootstrap;
the segment where you defined the stack for the boot loader, if any;
and
the system areas starting at A000:0000.
In principle, you can load the second stage code anywhere else that you'd like; in a real OS, you'd probably be limited by the design as to where you can put it. You can also relocate the stack, or, if you really wanted to, the boot code itself; unless you have a compelling reason to do so, however, I'd recommend against it.
The easiest solution is: if the second stage is the main kernel, and fits within 31K, you can load it at 0010:0000 (absolute address 0x00100), just above interrupt table; otherwise, load it at some convienent point above the boot loader, such as 0100:0000 (absolute address 0x01000).
The next question is more troublesome, but still at least one fairly straightforward answer, which also provides the easiest solutio to question three. This is to simply assume that the entry point of the code is at offset 0x0000 in the segment it is loaded into. Given this, you can simply push the segment address, push zero, and perform a RETF to transfer to the entry point.
Ironically, the earlier version of your kernel had code to do this (in the subroutine 'begin'), but at this point, unless you are loading a third stage,it is not needed; this is should have occurred in the boot loader already.
To coninue, you now have to make sure that the second stage code entry point matches the address the boot code transfers to. In this case, the simple solution is to set the code as [org 0000], and place the entry point at *very* start of code. This means that it must come before anything else that anything that actually causes code or data to be emitted into the binary stream: op codes, subroutines, DBs, RESBs, etc. Comments, EQUates, %macro and %struct definitions *can* be before this in the source code, but you must be careful not do anything that will put a byte into the binary directly. You can, however, use a JMP to a farther point and then define you subroutines between the two areas, if you truly wish to.
Another interesting solution, used by Myke Predko in <i>PC PhD</i>, is to push the segment offset followed by 0x0100, then RETF; you then use [org 0100] instead of [org 0000], and proceed otherwise the same way. The advantage of this is that you can use it to load and run any DOS COM file from a self-booting floppy, providing it makes no DOS calls and the boot loader can load all of it correctly.
In point of fact, you can put the entry point more or less wherever you want within your code, but this is of only academic interest unless your design absolutely calls for it. In any case, the key is to make sure that the address which the boot strap transfers control to is the same as that of the actual entry point. Since this could involve some rather messy calculations on your part to get it right, it is best simply to leave it as simple as possible.