Page 1 of 1
Line A20
Posted: Sat Jan 04, 2014 6:43 pm
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 ?
Re: Line A20
Posted: Sat Jan 04, 2014 9:20 pm
by bigorenski
Are you using GRUB?
Re: Line A20
Posted: Sat Jan 04, 2014 9:26 pm
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
Re: Line A20
Posted: Sun Jan 05, 2014 2:20 pm
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 ?
Re: Line A20
Posted: Sun Jan 05, 2014 2:30 pm
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?)
Re: Line A20
Posted: Sun Jan 05, 2014 3:37 pm
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"?
Re: Line A20
Posted: Sun Jan 05, 2014 10:42 pm
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 ?
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.
Re: Line A20
Posted: Mon Jan 06, 2014 12:25 am
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