From: smackinla@cc.curtin.edu.au
Subject: Re: Breaking 64k + 64k on 286 Minix
Organization: Curtin University of Technology
Date: Mon, 6 Apr 1992 14:44:33 GMT

In article <PETRI.VIRKKULA.92Apr2152108@vipunen.hut.fi>, Petri.Virkkula@hut.fi
(Petri Virkkula) writes:
> In article <1992Apr1.164850.1@cc.curtin.edu.au> smackinla@cc.curtin.edu.au
> (Patrick Mackinlay) writes:
> 
> How exactly do you use 32 bit pointers on a 286????
> 
>> Ok, You can use only 30 bit pointers or 29 bit pointers; 29
>> bit pointers when process can only access memory in local
>> descriptor table.

There is a slight confusion in terminology here. I was thinking (incorrectly)
that the offset by itself would be considered the pointer, but I now realise
that the SELECTOR:OFFSET pair make a pointer on the 286.

> To access a given memory location on a 286 (in protected mode of course), you
> need to specify a 16 bit descriptor and a 16 bit offset, correct?
> 
>> No! You need specify 16 bit offset and 16 bit selector which is
>> just a 13 bit index to local or global descriptor table which
>> determines where the actual memory resides in 24 bit address
>> space. That 16 bit selector contains also bit indicating

[stuff about protection bits deleted]

Another problem with terminology. I used the word "descriptor" where I should
have used "selector". Physical addresses are calculated by using the selector
as an index into a descriptor table, which gives the descriptor, a 24 bit base
(plus other stuff) that has the offset added to it to form the physical address.

> Ok, the problem is the fact that you would need enough descriptors set up to
> allow access to the entire 24 bit address space. In my books, that'd make 
> 256 selectors, a small problem to
> 
>> But you don't have to give to process access to 16Mb of memory.
>> You can alwayslimit size of local descriptor table to any
>> number between 1 and 8192, in Minix it is limited to 2.
>> (Maximum size of descriptor table= 64kb, size of one
>> descriptor=8 bytes, 64kb/8b = 8192)

Ok, point taken. But what about when you _need_ to access physical memory? I
have a problem with this in trying to port mini-X to 286 Minix at the moment.
I think the only solution to this is to have a global descriptor pointing to
the start of the screen RAM or for any other areas of physical memory required.

> begin with, and then you'd need to worry about address comparisons etc. The
> only _sane_ way to deal with it would be to convert the address to a "flat"
> 24 bit address when you wanted to increment/decrement/compare/whatever it,
> 
>> Programs protected mode have only 30 bit virtual addresses, it
>> can't access the physical addresses, the prossessor itself
>> make the conversion using local and global descriptor tables.
>> So increment/decrement/compare/whatever is safe as long you
>> don't cross the limit specified in descriptor table.

I do understand that the processor uses the selector specified to calculate the
physical address required by way of the descriptor tables. The problem is being
able to access any arbitrary physical address upon demand, such as video RAM or
any other memory mapped I/O devices, which requires a set of selectors for (on
an IBM compatible) at least the first 1 meg of memory.

Because the maximum size of a segment remains 64k, it is necessary to resort to
quite a deal of acrobatics to manipulate objects that fall outside this limit.
For example, if a block of dynamic memory larger than 64k is required (from
malloc() or whatever), it is impossible to return a pointer to the new block,
as it in effect needs more than one pointer. This is where my thoughts of the
conversion to flat addresses came in, if the malloc() function is written to
return a "flat" 24 bit physical address, and we have a standard method of
converting this to and from the SELECTOR:OFFSET form, it becomes possible to
handle chunks bigger than 64k. Unfortunately, this introduces a big performance
problem...

[stuff about performance deleted]

I have come to realise that my original posting did not adequately explain my
thoughts. Two major points that I did not describe well were the assumption
that access to arbitrary physical memory locations would be required, and that
it is blocks of memory _larger_ than 64k that I am interested in. The first of
these points prevented me from thinking about the virtual memory system on the
286 the way Intel had obviously intended.

I still believe that the only sensible way to access blocks of memory larger
than 64k on the 286 is to convert addresses into a 24 bit "flat" form whenever
pointer arithmetic is needed.

Pat -- have a day!