A20 Line: Difference between revisions

no edit summary
[unchecked revision][unchecked revision]
No edit summary
No edit summary
Line 15:
==Testing the A20 line==
Before enabling the A20 with any of the methods described below it better to test whether the A20 address line is already enabled by the [[BIOS]]. This can be achieved by comparing, at boot time in real mode, the bootsector identifier (0xAA55) located at address 0000:7DFE with the value 1 MiB higher which is at address FFFF:7E0E. When the two values are different it means that the A20 is already enabled otherwise if the values are identical it must be ruled out that this is not by mere chance. Therefore the bootsector identifier needs to be changed, for instance by rotating it left by 8 bits, and again compared to the 16 bits word at FFFF:7E0E. When they are still the same then the A20 address line is disabled otherwise it is enabled. Don't forget to restore the original bootsector identifier.
 
The following code performs a check:
<pre>
; The following code is public domain licenced
 
[bits 16]
 
; Function: check_a20
; Returns: 0 in ax if the a20 line is disabled (memory wraps around)
; 1 in ax if the a20 line is enabled (memory does not wrap around)
 
check_a20:
cli
 
push fs
push gs
push di
push si
 
xor ax, ax ; ax = 0
mov fs, ax
 
not ax ; ax = 0xFFFF
mov gs, ax
 
mov di, 0x0500
mov si, 0x0510
 
mov al, byte [fs:di]
push ax
 
mov al, byte [gs:si]
push ax
 
mov byte [fs:di], 0x00
mov byte [gs:si], 0xFF
 
cmp byte [fs:di], 0xFF
 
pop ax
mov byte [gs:si], al
 
pop ax
mov byte [fs:di], al
 
xor ax, ax
je check_a20__exit
 
mov al, 1
 
check_a20__exit:
pop si
pop di
pop gs
pop fs
 
sti
 
ret
</pre>
 
==Enabling==
5

edits