From 72c8bf17b841b5bb91851c3a34cbd45d34b10a9c Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 4 Sep 2003 19:14:16 +0000 Subject: [PATCH] Support for switches=/e[[:]nnnn] and for moving the EBDA (with Lucho) git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@675 6ac86273-5f31-0410-b378-82cca8765d1b --- kernel/config.c | 48 +++++++++++++++++++++++++++++++++++++++-------- kernel/init-mod.h | 6 +++++- kernel/initoem.c | 46 +++++++++++++++++++++++++++++++-------------- 3 files changed, 77 insertions(+), 23 deletions(-) diff --git a/kernel/config.c b/kernel/config.c index fcb7e44..5c337e3 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -70,11 +70,12 @@ struct config Config = { , 0 /* amount required memory */ , 0 /* pointer to loaded data */ , 0 /* strategy for command.com is low by default */ + , 0xFFFF /* default value for switches=/E:nnnn */ }; /* MSC places uninitialized data into COMDEF records, - that end up in DATA segment. this can't be tolerated + that end up in DATA segment. this can't be tolerated in INIT code. - please make sure, that ALL data in INIT is initialized !! + please make sure, that ALL data in INIT is initialized !! */ STATIC seg base_seg = 0; STATIC seg umb_base_seg = 0; @@ -285,7 +286,8 @@ void PreConfig(void) void PreConfig2(void) { struct sfttbl FAR *sp; - + unsigned ebda_size; + /* initialize NEAR allocated things */ /* Initialize the file table */ @@ -297,7 +299,7 @@ void PreConfig2(void) /* Initialize the base memory pointers from last time. */ /* - if the kernel could be moved to HMA, everything behind the dynamic + if the kernel could be moved to HMA, everything behind the dynamic near data is free. otherwise, the kernel is moved down - behind the dynamic allocated data, and allocation starts after the kernel. @@ -305,15 +307,24 @@ void PreConfig2(void) base_seg = LoL->first_mcb = FP_SEG(AlignParagraph((BYTE FAR *) DynLast() + 0x0f)); + ebda_size = ebdasize(); + if (ebda_size > Config.ebda2move) + ebda_size = Config.ebda2move; + ram_top += ebda_size / 1024; + /* We expect ram_top as Kbytes, so convert to paragraphs */ mcb_init(base_seg, ram_top * 64 - LoL->first_mcb - 1, MCB_LAST); - if (UmbState == 2) - umb_init(); sp = LoL->sfthead; sp = sp->sftt_next = KernelAlloc(sizeof(sftheader) + 3 * sizeof(sft), 'F', 0); sp->sftt_next = (sfttbl FAR *) - 1; sp->sftt_count = 3; + + if (ebda_size) /* move the Extended BIOS Data Area from top of RAM here */ + movebda(ebda_size, FP_SEG(KernelAlloc(ebda_size, 'I', 0))); + + if (UmbState == 2) + umb_init(); } /* Do third pass initialization. */ @@ -991,6 +1002,28 @@ STATIC VOID CfgSwitches(BYTE * pLine) case 'F': InitKernelConfig.SkipConfigSeconds = 0; break; + case 'E': /* /E[[:]nnnn] Set the desired EBDA amount to move in bytes */ + { /* Note that if there is no EBDA, this will have no effect */ + char *p; + int n = 0; + if (*++pLine == ':') + pLine++; /* skip optional separator */ + if ((p = GetNumArg(pLine, &n)) == 0) { + Config.ebda2move = 0; + break; + } + pLine = p - 1; /* p points past number */ + /* allowed values: [0..1024] bytes, multiples of 16 + * e.g. AwardBIOS: 48, AMIBIOS: 1024 + * (Phoenix, MRBIOS, Unicore = ????) + */ + if (n >= 48 && n <= 1024) + { + Config.ebda2move = (n + 15) & 0xfff0; + break; + } + /* else fall through (failure) */ + } default: CfgFailure(pLine); } @@ -998,7 +1031,7 @@ STATIC VOID CfgSwitches(BYTE * pLine) CfgFailure(pLine); } pLine = skipwh(pLine+1); - } + } commands[0].pass = 1; } @@ -1349,7 +1382,6 @@ void FAR * KernelAlloc(size_t nBytes, char type, int mode) /* prealloc */ lpTop = MK_FP(FP_SEG(lpTop) - nPara, FP_OFF(lpTop)); return AlignParagraph(lpTop); - } else { diff --git a/kernel/init-mod.h b/kernel/init-mod.h index 9de5163..9cc39a5 100644 --- a/kernel/init-mod.h +++ b/kernel/init-mod.h @@ -109,6 +109,8 @@ struct config { /* where the loaded data is for PostConfig() */ UBYTE cfgP_0_startmode; /* load command.com high or not */ + unsigned ebda2move; + /* value for switches=/E:nnnn */ }; extern struct config Config; @@ -139,7 +141,9 @@ int MoveKernelToHMA(void); VOID FAR * HMAalloc(COUNT bytesToAllocate); /* initoem.c */ -UWORD init_oem(void); +unsigned init_oem(void); +void movebda(int bytes, unsigned new_seg); +unsigned ebdasize(void); /* intr.asm */ diff --git a/kernel/initoem.c b/kernel/initoem.c index ca0b094..d07b3f9 100644 --- a/kernel/initoem.c +++ b/kernel/initoem.c @@ -35,20 +35,38 @@ static BYTE *RcsId = "$Id$"; #endif -UWORD init_oem(void) -{ - UWORD top_k = 0; +#define EBDASEG 0x40e +#define RAMSIZE 0x413 -#ifdef __TURBOC__ - __int__(0x12); - top_k = _AX; -#elif defined(I86) - asm - { - int 0x12; - mov top_k, ax; - } -#endif - return top_k; +unsigned init_oem(void) +{ + iregs r; + init_call_intr(0x12, &r); + return r.a.x; } +void movebda(size_t bytes, unsigned new_seg) +{ + unsigned old_seg = peek(0, EBDASEG); + fmemcpy(MK_FP(new_seg, 0), MK_FP(old_seg, 0), bytes); + poke(0, EBDASEG, new_seg); + poke(0, RAMSIZE, ram_top); +} + +unsigned ebdasize(void) +{ + unsigned ebdaseg = peek(0, EBDASEG); + unsigned ramsize = ram_top; + + if (ramsize * 64 == ebdaseg && ramsize < 640 && peek(0, RAMSIZE) == ramsize) + { + unsigned ebdasz = peekb(ebdaseg, 0); + + /* sanity check: is there really no more than 63 KB? + * must be at 640k (all other values never seen and are untested) + */ + if (ebdasz <= 63 && ramsize + ebdasz == 640) + return ebdasz * 1024U; + } + return 0; +}