Hi!
kernel.asm:
______________O\_/_________________________________\_/O______________
segment HMA_TEXT_START
global __HMATextAvailable
__HMATextAvailable
global __HMATextStart
__HMATextStart:
;
; the HMA area is filled with 1eh+3(=sizeof VDISK) = 33 byte dummy data,
; so nothing will ever be below 0xffff:0031
;
segment HMA_TEXT
begin_hma:
times 10h db 0 ; filler [ffff:0..ffff:10]
times 20h db 0
db 0
; to minimize relocations
global _DGROUP_
_DGROUP_ dw DGROUP
_____________________________________________________________________
O/~\ /~\O
1. _DGROUP_ variable not aligned to word boundary.
inithma.c:
______________O\_/_________________________________\_/O______________
#define HMAOFFSET 0x20
int MoveKernelToHMA()
MoveKernel(0xffff);
DosLoadedInHMA = TRUE;
InstallVDISK();
STATIC void InstallVDISK(void)
static struct { /* Boot-Sektor of a RAM-Disk */
...
} VDISK_BOOT_SEKTOR = {
...
if (!DosLoadedInHMA) return;
fmemcpy(MK_FP(0xffff, 0x0010), &VDISK_BOOT_SEKTOR, sizeof(VDISK_BOOT_SEKTOR));
*(WORD FAR *) MK_FP(0xffff, 0x002e) = 1024 + 64;
void MoveKernel(unsigned NewKernelSegment)
HMASource =
MK_FP(CurrentKernelSegment, (FP_OFF(_HMATextStart) & 0xfff0));
HMADest = MK_FP(NewKernelSegment, 0x0000);
len = (FP_OFF(_HMATextEnd) | 0x000f) - (FP_OFF(_HMATextStart) & 0xfff0);
if (NewKernelSegment == 0xffff)
{
> HMASource += HMAOFFSET;
> HMADest += HMAOFFSET;
> len -= HMAOFFSET;
}
for (i = 0, s = HMASource, d = HMADest; i < len; i++)
d[i] = s[i];
HMAFree = (FP_OFF(HMADest) + len + 0xf) & 0xfff0;
_____________________________________________________________________
O/~\ /~\O
2. As I understand, contents of VDISK_BOOT_SEKTOR (also as value 1024+64 at
offset 0x2E) from InstallVDISK may be moved into kernel.asm, thus
InstallVDISK() itself with quoted lines (with shifts by HMAOFFSET) in
MoveKernel() may be removed.
3. `len' is offset of last byte, thus it should be incremented by one (to be
length) or renamed to `last' and in loop should be used "i <= last".
Also, to get offset last byte, above used wrong expression (when
_HMATextEnd already aligned, there catched extra paragraph); should be:
len = (FP_OFF(_HMATextEnd) - (FP_OFF(_HMATextStart) & -16)
+ 15) & -16;
or
last = (FP_OFF(_HMATextEnd) - (FP_OFF(_HMATextStart) & -16)
- 1) | 15;
4. Because HMADest always =xxx0 and `last' always =xxxF, then HMAFree may be
calculated as "FP_OFF(HMADest)+last+1" (or "FP_OFF(HMADest)+len").
5. When kernel in low memory, initial portion (32 bytes) of HMA_TEXT_START
segment anyway present there and unused. There may help next trick in
MoveKernel():
HMADest = MK_FP(NewKernelSegment - HMAOFFSET / 16, HMAOFFSET);
HMASource += HMAOFFSET; len -= HMAOFFSET;
i.e. kernel segment will "overlap" with memory in front of it, but only
virtually (because initial portion of code segment isn't used). Of
course, this trick should be performed only when kernel moved finally
back to low memory and calling code (config.c::configDone()) should get
this shifted target segment (probably, there may be third argument for
MoveKernel(), which says "do overlapping").
main.c:
______________O\_/_________________________________\_/O______________
STATIC void init_kernel(void)
lpTop = MK_FP(ram_top * 64 - (FP_OFF(_init_end) + 15) / 16 -
(FP_OFF(_HMATextEnd) + 15) / 16, 0);
MoveKernel(FP_SEG(lpTop));
_____________________________________________________________________
O/~\ /~\O
6. Looks like here grabbed more than need, i.e. instead
FP_OFF(_HMATextEnd) + 15) / 16
should be used
(FP_OFF(_HMATextEnd) - (FP_OFF(_HMATextStart) & -16u) + 15) / 16
-------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
as in MoveKernel.
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
Freedos-kernel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freedos-kernel