Line A20

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
yee1
Member
Member
Posts: 42
Joined: Sun Feb 10, 2013 4:02 pm

Line A20

Post by yee1 »

Hey,

I wanted to do some tests and I did this code:

Added new entery to GDT like:

Code: Select all

segment_over_1mb: ; selector 0x48
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0

And i have tested such code (in protected mode activated if matters):

Code: Select all

mov ax, 0x48
mov es, ax

mov word [es:0], 0x66 ; accessing 0x0 address
mov bx, word [es:0] ; will set BX= 0x66

mov word [es:0x1400000], 0xDAF ; accessing 20mb
mov bx, word [es:0x1400000] ; will set BX= 0xDAF

mov word [es:0xC2100000], 0x78ad ; accessing above 3GB
mov bx, word [es:0xC2100000] ; will set BX= 0xFFFF

mov word [es:0xffc00000], 0x1b6 ; accessing above 3GB
mov bx, word [es:0xffc00000] ; will set BX= 0xFFFF

Tested with Bochs and VirtualBox and no exception was thrown while accessing this memory.

Dunno what to think about this. First of all I though it makes memory rolling over and over 1 MB of memory, but it doesn't seem so. When I want to see memory map for 0xC2100000 in Bochs it returns message "address range was not legal memory". For 0x1400000 it's fine. Huh ? Why ?

After that I have enabled Line A20 as here http://wiki.osdev.org/A20_Line using code for keyboard controller and results were the same!

Why was it accessible without enabling line a20, at least why was 0x1400000 accessible properly ?
bigorenski
Posts: 14
Joined: Thu May 09, 2013 5:51 pm

Re: Line A20

Post by bigorenski »

Are you using GRUB?
Octocontrabass
Member
Member
Posts: 5617
Joined: Mon Mar 25, 2013 7:01 pm

Re: Line A20

Post by Octocontrabass »

yee1 wrote:Why was it accessible without enabling line a20,
Some emulators don't (or can't) disable A20. My copy of Bochs always boots with A20 enabled.

Some bootloaders will enable A20 for you.
yee1 wrote:at least why was 0x1400000 accessible properly ?
That address is not affected by the A20 gate:

Code: Select all

0x1400000 & ~(1 << 20) = 0x1400000
yee1
Member
Member
Posts: 42
Joined: Sun Feb 10, 2013 4:02 pm

Re: Line A20

Post by yee1 »

Octocontrabass wrote:
yee1 wrote:Why was it accessible without enabling line a20,
Some emulators don't (or can't) disable A20. My copy of Bochs always boots with A20 enabled.

Some bootloaders will enable A20 for you.
yee1 wrote:at least why was 0x1400000 accessible properly ?
That address is not affected by the A20 gate:

Code: Select all

0x1400000 & ~(1 << 20) = 0x1400000
I am using my own bootloader and I didnt activate a20.

Well seems I don't understand idea of A20 and can't find good info that would explain it to me. So far I have only found info that until a20 line is not activated i am able to use only addressing with 20 bits (so 1mb addressing max). When a20 line is activated I can use address of full 32 bits. Is it right or not ?

You have written such code:

Code: Select all

0x1400000 & ~(1 << 20) = 0x1400000
Why did you roll bit "1" 20 positions to left ?

Please for explain because I am a bit confused a bot, because after reading this http://wiki.osdev.org/A20_Line I understood activating line a20 as a receipt to set a20 bit and disable wrapping memory around 1mb of memory.

Where am I wrong in A20 ?
Octocontrabass
Member
Member
Posts: 5617
Joined: Mon Mar 25, 2013 7:01 pm

Re: Line A20

Post by Octocontrabass »

yee1 wrote:So far I have only found info that until a20 line is not activated i am able to use only addressing with 20 bits (so 1mb addressing max). When a20 line is activated I can use address of full 32 bits. Is it right or not ?
Wrong.

The A20 gate only affects bit 20 of the address. The remaining 31 bits are not affected, so you can still access some addresses above 1MB.

For example:

0x00200000 & ~(1<<20) = 0x00200000: You can always access this address.
0x00700000 & ~(1<<20) = 0x00600000: If A20 is disabled, you will access the wrong address (but it's still above 1MB).

(P.S. Some really old computers might not work this way, but you aren't programming for those, are you?)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Line A20

Post by Combuster »

yee1 wrote:

Code: Select all

0x1400000 & ~(1 << 20) = 0x1400000
Why did you roll bit "1" 20 positions to left ?
1: It's called the shift operator, not roll or rotate where shifted bits reappear at the other end.
2: What kind of number does (1 << x) yield?
3: What number can be found in "A20" and in "1 << 20"?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
yee1
Member
Member
Posts: 42
Joined: Sun Feb 10, 2013 4:02 pm

Re: Line A20

Post by yee1 »

Ok, but how about 1MB wrapping around memory ?

According to http://wiki.osdev.org/A20_Line
It should be not possible to access memory over 1MB + a few bytes
According to wiki it would wrap around 1MB, so

if i access memory 0x0 and 0x0+1MB and 0x0+2*1MB and 0x0+200*1MB, then it should return same result. Yes or not ?

And so on... You are telling that until my address won't be using bit number 20 of address then accessing memory will be fine. '


So who is wrong ? Wikipedia or you guys ? :P Please explain it for me with more details, because I can't even debbug for it with Bochs ;-/ and I would like to understand it.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Line A20

Post by Brendan »

Hi,
yee1 wrote:Ok, but how about 1MB wrapping around memory ?

According to http://wiki.osdev.org/A20_Line
It should be not possible to access memory over 1MB + a few bytes
According to wiki it would wrap around 1MB, so

if i access memory 0x0 and 0x0+1MB and 0x0+2*1MB and 0x0+200*1MB, then it should return same result. Yes or not ?
Think of it like forcing bit 20 of the physical address to 0:
  • for addresses from 0x00000000 to 0x000FFFFF, bit 20 of the address is clear anyway so forcing it to zero does nothing
  • for addresses from 0x00100000 to 0x001FFFFF, bit 20 of the address is set and become 0x00000000 to 0x000FFFFF
  • for addresses from 0x00200000 to 0x002FFFFF, bit 20 of the address is clear anyway so forcing it to zero does nothing
  • for addresses from 0x00300000 to 0x003FFFFF, bit 20 of the address is set and become 0x00200000 to 0x002FFFFF
    ...
  • for addresses from 0xFFE00000 to 0xFFEFFFFF, bit 20 of the address is clear anyway so forcing it to zero does nothing
  • for addresses from 0xFFF00000 to 0xFFFFFFFF, bit 20 of the address is set and become 0xFFE00000 to 0xFFEFFFFF
When A20 is disabled, this pattern continues throughout the entire physical address space (e.g. up to however large physical addresses can be in long mode) - every "odd MiB" ends up being the same as the "even MiB" before it.

When a CPU is in real mode it can only address slightly more than 1 MiB. For example, the real mode segmented address 0xFFFF:0x1210 would be physical address 0x00101200 (with A20 enabled) and would become 0x00001200 with A20 disabled. This creates the illusion of addresses wrapping for real mode code, because real mode code can't access any address that is high enough to break the illusion of wrapping.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply