Reputation: 661
I have written a simple bootloader, in which I have made the switch from real to protected mode. I want to enable A20 address line. Here is my code (It is incorrect):
EnableA20:
.try0:
call .checkenabled
cmp eax,0
jne .done
.fail:
jmp $
.checkenabled:
push ebx
mov eax,0x1234
mov [0x10],eax
mov ebx,[0x100010]
sub eax,ebx
pop ebx
ret
.done:
It shows that my address line is enabled by default... Is that possible??
Where have I gone wrong? The method that I have used is to write 0x1234 to address 0x10 and read the value from address 0x100010. If the value that I have written is the same as the value present in the address (due to wrap around), I know that the line should not be enabled.
I'm using qemu as my emulator:
qemu-system-i386 myos.bin
EDIT: It seems like A20 is enalbed by default. However, if I try to do this:
.try1: ;Using keyboard controller to enable A20
mov al,0xdd
out 0x64,al
call .checkenabled
cmp eax,0
jne .done
It goes to fail! I've read that moving 0xdd to port 0x64 enables A20, and does not disable it. What is the problem here?
Upvotes: 1
Views: 974
Reputation:
According to the osdev wiki, the method of enabling the A20 line in protected mode varies wildly form one chipset to another. And in some it can even be enabled by the bios/bootrom on boot. Therefore the common practice is to first write a routine that can check if the A20 line is enabled (by writing data to an accessible ram region and looking for that data to be mirrored in higher ram addresses)which you did, and your approach seems correct as far as i can tell. Only if the bios/bootrom has not enabled it do you try other methods.
When your PC boots, the A20 gate is always disabled, but some BIOSes do enable it for you, as do some high-memory managers (HIMEM.SYS) or bootloaders (GRUB). Once you have this check, you can then try all the methods foi wnabling it one by one and see which one works for the system
The recommended procedure for enablig it is:
Because there are several different methods that may or may not be supported, and because some of them cause problems on some computers; the recommended method is to try all of them until one works in the "order of least risk". Essentially:
Test if A20 is already enabled - if it is you don't need to do anything at all Try the BIOS function. Ignore the returned status. Test if A20 is enabled (to see if the BIOS function actually worked or not) Try the keyboard controller method. Test if A20 is enabled in a loop with a time-out (as the keyboard controller method may work slowly) Try the Fast A20 method last Test if A20 is enabled in a loop with a time-out (as the fast A20 method may work slowly) If none of the above worked, give up
for more information see the A20 line page on osdev wiki: https://wiki.osdev.org/A20
Upvotes: 4