What Happens If I Won't Enable A20 line in PM ?
What Happens If I Won't Enable A20 line in PM ?
When I try to access memory address that are higher than 0xFFFFF without enabling A20 line not a lot happens..
So what does happen when tring to access memory ranges with bits 20+ set without enabling the A20 line?
does address bits 20+ are cleared in the memory bus?
Or when entering Protected Mode address bits 20 - 31 are enabled anyway ( regardless if A20 controllers bits are set or not ) ?
So what does happen when tring to access memory ranges with bits 20+ set without enabling the A20 line?
does address bits 20+ are cleared in the memory bus?
Or when entering Protected Mode address bits 20 - 31 are enabled anyway ( regardless if A20 controllers bits are set or not ) ?
Last edited by elad on Sat Oct 26, 2024 7:44 pm, edited 1 time in total.
Re: What Happens If I Won't Enable A20 line in PM ?
Hi,
The A20 line is just that, just the A20 line. All other bits (lines) are still intact. So, if you write to a memory address above 1 Meg, all writes will be to that address with bit 20 zero'd. If you are writing to an even meg address, you are fine. If you write to an odd meg address, you will actually write to the even meg address before it.
A20 = off
write to address 0x00E01234 = a write to address 0x00E01234
write to address 0x00F01234 = a write to address 0x00E01234
It is highly recommended that you make sure the A20 line is active before you use any address after the first Meg. Most machines, if not all new ones, will already have the A20 active, but it is wise to check to make sure.
To make sure, use this knowledge that if you write to an odd meg address with the A20 line off, the even meg address before it will be modified.
The bad thing about the A20 line, being a thing of the past, it was activated in different ways on different hardware. You have to have numerous techniques written into your code to activate it.
Hope this helps,
Ben
http://www.fysnet.net/the_universal_serial_bus.htm
The A20 line is just that, just the A20 line. All other bits (lines) are still intact. So, if you write to a memory address above 1 Meg, all writes will be to that address with bit 20 zero'd. If you are writing to an even meg address, you are fine. If you write to an odd meg address, you will actually write to the even meg address before it.
A20 = off
write to address 0x00E01234 = a write to address 0x00E01234
write to address 0x00F01234 = a write to address 0x00E01234
It is highly recommended that you make sure the A20 line is active before you use any address after the first Meg. Most machines, if not all new ones, will already have the A20 active, but it is wise to check to make sure.
To make sure, use this knowledge that if you write to an odd meg address with the A20 line off, the even meg address before it will be modified.
The bad thing about the A20 line, being a thing of the past, it was activated in different ways on different hardware. You have to have numerous techniques written into your code to activate it.
Hope this helps,
Ben
http://www.fysnet.net/the_universal_serial_bus.htm
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: What Happens If I Won't Enable A20 line in PM ?
Just to clarify for the OP, the A20 enabling sequence should be something like this, in this order as it starts with the least-risky option first.BenLunt wrote:You have to have numerous techniques written into your code to activate it.
1. Check if A20 is enabled, by writing a value to an odd megabyte address (i.e. 0x100000) and reading back a value from the same address with bit 20 cleared (i.e. 0x000000 for this example.) If the values are not equal (i.e. A20 is enabled) return from the function and don't do anything. Else, continue with step 2.
2. Enable A20 using BIOS INT 0x15 function 0x2401. It will return zero on success. If it succeeds, jump to step 4. If the function is not supported or failed, continue with step 3.
3. Enable A20 using the PS/2 controller method. This is described in the Wiki article about A20.
4. Check if A20 is enabled, with the same technique in step 1. If it is enabled, return from the function. Else, continue with step 5.
5. Enable A20 using the FAST method. Read a byte from I/O port 0x92, set bit 1, clear bit 0 and write it back to the same I/O port. A small delay (i.e. NOP or PAUSE in a loop) is useful here.
6. Check if A20 is enabled again, with the same technique in step 1. If it is enabled, return from the function. Else, display an error message, as there is apparently no way to enable A20 on this machine.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
-
- Member
- Posts: 5560
- Joined: Mon Mar 25, 2013 7:01 pm
Re: What Happens If I Won't Enable A20 line in PM ?
It depends.elad wrote:So what does happen when tring to access memory ranges with bits 20+ set without enabling the A20 line?
On 386 and lower, there's a circuit between the CPU and the RAM that forcibly sets A20 to 0 whenever the CPU tries to access memory between 1MB and 2MB (0x100000 - 0x1FFFFF becomes 0x000000 - 0x0FFFFF). On addresses below 1MB, it has no effect. On addresses above 2MB, the effect depends on how that circuit was designed. On some computers, the circuit forces A20 to always be 0, no matter what address the CPU requests. On other computers, the circuit only forces A20 to be 0 when the address is between 1MB and 2MB. (It might actually be more complicated than that; I've only ever checked to see if the BIOS ROM was still accessible with the A20 line disabled.)
On 486 and higher, the CPU has an input (either a physical pin or a series of bus cycles) that controls A20 behavior. The behavior of disabling A20 is only documented in real mode, and I recall reading at least one manual that explicitly states that it's undefined in all other modes. With my 486 in unreal mode, it behaves as if A20 is always forced to 0. I've never tested it in protected mode, nor have I tried anything newer than that, so there's no guarantee this is a typical result.
Re: What Happens If I Won't Enable A20 line in PM ?
Hi,
Note that A20 affects the entire physical address space, not just the first few MiB. For example, if you try to write to physical address 0x12345678 with A20 disabled then the write would actually go to physical address "0x12345678 & 0xFFEFFFFF = 0x12245678".
Essentially, every "odd MiB" of the physical address space can't be accessed and you'd access the preceding "even MiB' instead.
As a fun fault tolerance feature (which isn't necessarily practical beyond demonstration purposes); if my OS fails to enable A20 it continues to boot anyway - the physical memory manager just marks "odd MiBs" of RAM as unusable so that those pages aren't allocated. The real problem is for firmware tables and memory mapped PCI devices, which can be partially or completely inaccessible without A20 enabled.
Cheers,
Brendan
Note that A20 affects the entire physical address space, not just the first few MiB. For example, if you try to write to physical address 0x12345678 with A20 disabled then the write would actually go to physical address "0x12345678 & 0xFFEFFFFF = 0x12245678".
Essentially, every "odd MiB" of the physical address space can't be accessed and you'd access the preceding "even MiB' instead.
As a fun fault tolerance feature (which isn't necessarily practical beyond demonstration purposes); if my OS fails to enable A20 it continues to boot anyway - the physical memory manager just marks "odd MiBs" of RAM as unusable so that those pages aren't allocated. The real problem is for firmware tables and memory mapped PCI devices, which can be partially or completely inaccessible without A20 enabled.
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.
-
- Member
- Posts: 1146
- Joined: Sat Mar 01, 2014 2:59 pm
Re: What Happens If I Won't Enable A20 line in PM ?
You'll be unable to access every second megabyte of physical memory. Instead, it will map to the previous megabyte.
So for example if you try to access address 0x380000, which is halfway through the 4th megabyte of memory, it will be the same as accessing address 0x280000 (both for reading and writing).
Of course, this is what should happen in theory. In reality, leaving A20 disabled when accessing higher memory addresses should be considered undefined behaviour and what really happens may vary between different motherboards and at different addresses. This behaviour should not be relied upon.
So for example if you try to access address 0x380000, which is halfway through the 4th megabyte of memory, it will be the same as accessing address 0x280000 (both for reading and writing).
Of course, this is what should happen in theory. In reality, leaving A20 disabled when accessing higher memory addresses should be considered undefined behaviour and what really happens may vary between different motherboards and at different addresses. This behaviour should not be relied upon.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Re: What Happens If I Won't Enable A20 line in PM ?
thank you for the answers
Last edited by elad on Sat Oct 26, 2024 8:37 am, edited 1 time in total.
Re: What Happens If I Won't Enable A20 line in PM ?
If you find unable to enable the line A20 in a particular machine, you would probably do much better if you investigated why by writing test snippets and adding specific tricks later to your operating system code library.
The A20 gate is also supposed to be implemented as an OR gate array with a single output into the enabling of address bit 20, so if you enable it with more than one method, you will probably need to disable it again with those same methods.
And newer machines seem to always have it enabled by default, specially if they were designed when Windows Vista and 7 already existed and started to be very common.
The A20 gate is also supposed to be implemented as an OR gate array with a single output into the enabling of address bit 20, so if you enable it with more than one method, you will probably need to disable it again with those same methods.
And newer machines seem to always have it enabled by default, specially if they were designed when Windows Vista and 7 already existed and started to be very common.
YouTube:
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
Re: What Happens If I Won't Enable A20 line in PM ?
If you attempt to mess with PS/2 controller on a mac machine it just hangs. You want to check if PS/2 controller exists.omarrx024 wrote:Just to clarify for the OP, the A20 enabling sequence should be something like this, in this order as it starts with the least-risky option first.BenLunt wrote:You have to have numerous techniques written into your code to activate it.
1. Check if A20 is enabled, by writing a value to an odd megabyte address (i.e. 0x100000) and reading back a value from the same address with bit 20 cleared (i.e. 0x000000 for this example.) If the values are not equal (i.e. A20 is enabled) return from the function and don't do anything. Else, continue with step 2.
2. Enable A20 using BIOS INT 0x15 function 0x2401. It will return zero on success. If it succeeds, jump to step 4. If the function is not supported or failed, continue with step 3.
3. Enable A20 using the PS/2 controller method. This is described in the Wiki article about A20.
4. Check if A20 is enabled, with the same technique in step 1. If it is enabled, return from the function. Else, continue with step 5.
5. Enable A20 using the FAST method. Read a byte from I/O port 0x92, set bit 1, clear bit 0 and write it back to the same I/O port. A small delay (i.e. NOP or PAUSE in a loop) is useful here.
6. Check if A20 is enabled again, with the same technique in step 1. If it is enabled, return from the function. Else, display an error message, as there is apparently no way to enable A20 on this machine.
http://wiki.osdev.org/%228042%22_PS/2_C ... ler_Exists
- iocoder
- Member
- Posts: 208
- Joined: Sun Oct 18, 2009 5:47 pm
- Libera.chat IRC: iocoder
- Location: Alexandria, Egypt | Ottawa, Canada
- Contact:
Re: What Happens If I Won't Enable A20 line in PM ?
You don't enable/disable the A20 line. Your code actually enables a circuitry that we call 'A20 gate' which controls the A20 line in IBM-compatible machines. There are no such 'gates' for other address lines. It was added in the original IBM AT design for compatibility purposes (as the article on the wiki explains). The circuit simply looked like this:elad wrote:When I try to access memory address that are higher than 0xFFFFF without enabling A20 line not a lot happens..
So what does happen when tring to access memory ranges with bits 20+ set without enabling the A20 line?
does address bits 20+ are cleared in the memory bus?
Or when entering Protected Mode address bits 20 - 31 are enabled anyway ( regardless if A20 controllers bits are set or not ) ?
The programmer chooses whether to enable the AND gate or disable it (by controlling the so-called 'A20 GATE' output pin of the micro-controller that was mainly used as a keyboard controller). If the AND gate is disabled, the value of the A20 line will always be zero. This is necessary for IBM AT to stay compatible with old DOS programs that made use of memory wrap around behavior of the original 8086.
Re: What Happens If I Won't Enable A20 line in PM ?
Just note that if a motherboard implement more than one method to enable the A20 line, all those methods are implemented as circuits apart, and all of them end up in a final OR gate (just expand the same previous schematic with an array of A20-enabling circuits that go into an OR).
So if you enable more than one of those circuits, then the A20 will be kept enabled by more than one source, and then if you want to disable it again you will have to disable all of those sources. I haven't tested it because I barely need to enable the A20 line (it seems to always be already enabled on any machine with SATA ports or with 64-bit-capable CPU), and I don't want risking locking the machine if the A20 gate is already enabled by an unknown source before loading a boot sector.
Known sources are the KBC, the Fast A20, and the BIOS services could use some of those means, more commonly the KBC.
So if you enable more than one of those circuits, then the A20 will be kept enabled by more than one source, and then if you want to disable it again you will have to disable all of those sources. I haven't tested it because I barely need to enable the A20 line (it seems to always be already enabled on any machine with SATA ports or with 64-bit-capable CPU), and I don't want risking locking the machine if the A20 gate is already enabled by an unknown source before loading a boot sector.
Known sources are the KBC, the Fast A20, and the BIOS services could use some of those means, more commonly the KBC.
YouTube:
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
Re: What Happens If I Won't Enable A20 line in PM ?
Hi,
Fortunately; for BIOS (including an 80x86 Apple Mac running "Boot Camp"), the sequence above usually stops at "step 1" or "step 2". It's mostly only very old computers (Pentium or older?) that might not support the BIOS function, and very old computers always have a PS/2 controller, so (without checking if the PS/2 controller exists beforehand) you can be "extremely confident" that you'll never have a problem at "step 3".
For EFI/UEFI (including 80x86 Apple Mac without "Boot Camp"); A20 is always "enabled by default" and may not exist, so you wouldn't do any of steps listed above.
Cheers,
Brendan
No. Usually the ACPI tables are placed near the "end of RAM below 4 GiB", which is almost always an "odd MiB", which means that you need to enable A20 before you can access the ACPI tables, which means that you can't use ACPI tables to determine if the PS/2 controller exists until after A20 is enabled.bluemoon wrote:If you attempt to mess with PS/2 controller on a mac machine it just hangs. You want to check if PS/2 controller exists.omarrx024 wrote:Just to clarify for the OP, the A20 enabling sequence should be something like this, in this order as it starts with the least-risky option first.
1. Check if A20 is enabled, by writing a value to an odd megabyte address (i.e. 0x100000) and reading back a value from the same address with bit 20 cleared (i.e. 0x000000 for this example.) If the values are not equal (i.e. A20 is enabled) return from the function and don't do anything. Else, continue with step 2.
2. Enable A20 using BIOS INT 0x15 function 0x2401. It will return zero on success. If it succeeds, jump to step 4. If the function is not supported or failed, continue with step 3.
3. Enable A20 using the PS/2 controller method. This is described in the Wiki article about A20.
4. Check if A20 is enabled, with the same technique in step 1. If it is enabled, return from the function. Else, continue with step 5.
5. Enable A20 using the FAST method. Read a byte from I/O port 0x92, set bit 1, clear bit 0 and write it back to the same I/O port. A small delay (i.e. NOP or PAUSE in a loop) is useful here.
6. Check if A20 is enabled again, with the same technique in step 1. If it is enabled, return from the function. Else, display an error message, as there is apparently no way to enable A20 on this machine.
http://wiki.osdev.org/%228042%22_PS/2_C ... ler_Exists
Fortunately; for BIOS (including an 80x86 Apple Mac running "Boot Camp"), the sequence above usually stops at "step 1" or "step 2". It's mostly only very old computers (Pentium or older?) that might not support the BIOS function, and very old computers always have a PS/2 controller, so (without checking if the PS/2 controller exists beforehand) you can be "extremely confident" that you'll never have a problem at "step 3".
For EFI/UEFI (including 80x86 Apple Mac without "Boot Camp"); A20 is always "enabled by default" and may not exist, so you wouldn't do any of steps listed above.
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.
Re: What Happens If I Won't Enable A20 line in PM ?
I enabled the A20 line this way:
1)in real mode code I put :
mov ax,0x2401
int 15h
2)after jumping to Protected mode (EIP points to even megabyte) I checked if A20 is enabled using:
;original code btw:)
is_a20_on?:
pushad
mov edi,0x112345
mov esi,0x012345
mov [esi],esi
mov [edi],edi
cmpsd
popad
jne a20_on
ret
a20_on:
3)if that doesn't work ,I tried to enable A20 using the ps/2 keyboard controller:
call a20wait
mov al,0xad ;disable the ps/2 keyboard
out 0x64,al
call a20wait
mov al,0xdd ;enable A20 line command
out 0x64,al
call a20wait
mov al,0xae ; enable the ps/2 keyboard
out 0x64,al
call a20wait
(a20wait:
in al,0x64
test al,2
jnz a20wait
ret)
4) check if A20 is enabled using Step 2's code.
3)if even that doesn't work ,I tried to enable A20 using the 0x92 port:
in al,0x92
or al,2
and al,0xfe
out 0x92,al
5)same as Step 4.
6)enable A20 line using port 0xee:
in al,0xee
7)same as Step 4.
last but not least ) if all that doesn't work, halt the system using:
cli
halt:
hlt
jmp halt
1)in real mode code I put :
mov ax,0x2401
int 15h
2)after jumping to Protected mode (EIP points to even megabyte) I checked if A20 is enabled using:
;original code btw:)
is_a20_on?:
pushad
mov edi,0x112345
mov esi,0x012345
mov [esi],esi
mov [edi],edi
cmpsd
popad
jne a20_on
ret
a20_on:
3)if that doesn't work ,I tried to enable A20 using the ps/2 keyboard controller:
call a20wait
mov al,0xad ;disable the ps/2 keyboard
out 0x64,al
call a20wait
mov al,0xdd ;enable A20 line command
out 0x64,al
call a20wait
mov al,0xae ; enable the ps/2 keyboard
out 0x64,al
call a20wait
(a20wait:
in al,0x64
test al,2
jnz a20wait
ret)
4) check if A20 is enabled using Step 2's code.
3)if even that doesn't work ,I tried to enable A20 using the 0x92 port:
in al,0x92
or al,2
and al,0xfe
out 0x92,al
5)same as Step 4.
6)enable A20 line using port 0xee:
in al,0xee
7)same as Step 4.
last but not least ) if all that doesn't work, halt the system using:
cli
halt:
hlt
jmp halt
Last edited by elad on Sat Oct 26, 2024 7:43 pm, edited 4 times in total.
Restart any PC in the easy way around:
mov eax,cr0
xor al,1
mov cr0,eax
lidt [illegal_idtr]
jmp 0:$
; done:)
mov eax,cr0
xor al,1
mov cr0,eax
lidt [illegal_idtr]
jmp 0:$
; done:)
Re: What Happens If I Won't Enable A20 line in PM ?
See my public domain BOOTCFG project. I have mastered detecting the state of the A20 line and enabling/disabling it via KBC/Fast A20/BIOS to a fair degree:
http://f.osdev.org/viewtopic.php?p=276636
Look at the root directory of the source code, there is a fully 16-bit program called "01_64_rm.asm" that is able to detect whether the A20 line is enabled or not, solely by manipulating memory in the first Megabyte+65536-16 area, so it's safe to use even under very old machines, in pure 16-bit mode without Unreal Mode, very important to avoid locking up under, say, a 286, or dealing unnecessarily with A20 enabling circuits to detect, enable or disable.
Here is the current version of that program at this time. You can find the rest of A20 enabling option snippets in the project's ZIP file:
http://f.osdev.org/viewtopic.php?p=276636
Look at the root directory of the source code, there is a fully 16-bit program called "01_64_rm.asm" that is able to detect whether the A20 line is enabled or not, solely by manipulating memory in the first Megabyte+65536-16 area, so it's safe to use even under very old machines, in pure 16-bit mode without Unreal Mode, very important to avoid locking up under, say, a 286, or dealing unnecessarily with A20 enabling circuits to detect, enable or disable.
Here is the current version of that program at this time. You can find the rest of A20 enabling option snippets in the project's ZIP file:
Code: Select all
_01_64_RM:
bits 16
org 100h
cld
;Compare:
;
;DS:SI==0000:0000 (phys. 000000-00FFF0)
;ES:DI==FFFF:0010 (phys. 100000-10FFF0)
;
;(Those are 65536-16 bytes to test).
;If they are different, then A20 is currently enabled.
;
;They are potentially the same address in a contiguous
;even/odd Megabyte pair, if A20 is disabled.
;;
push ds
push es
push word 0
pop ds
xor si,si
push word 0xFFFF
pop es
mov di,16
mov cx,65536-16
;Use the LOOP instruction to give
;these memory regions more time
;to become more altered which
;will help to differentiate them
;even more (remember that the LOOP
;instruction is extremely slow even in
;the newest CPUs):
;;
.loop1:
cmpsb
jne .loop1_END
loop .loop1
.loop1_END:
pop es
pop ds
test cx,cx
jnz .A20On
;If CX is 0, then the A20 line
;is disabled because the first and second
;Megabytes were identical despite being
;tested for differences in the first 65536-16 bytes
;via the CMPSB instruction:
;;
mov ah,9
mov dx,strA20Off
int 21h
mov al,0 ;Return code==enabled FALSE
jmp .END
.A20On:
mov ah,9
mov dx,strA20On
int 21h
mov al,1 ;Return code==enabled TRUE
.END:
;Exit to DOS:
;;
mov ah,4Ch
int 21h
strAppName db "01_64_RM.COM: $"
strA20On db "01_64_RM.COM: A20 detected enabled from pure 16-bit Real Mode...",13,10,"$"
strA20Off db "01_64_RM.COM: A20 detected disabled from pure 16-bit Real Mode...",13,10,"$"
;EOF
YouTube:
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
http://youtube.com/@AltComp126
My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... ip?viasf=1
-
- Member
- Posts: 1146
- Joined: Sat Mar 01, 2014 2:59 pm
Re: What Happens If I Won't Enable A20 line in PM ?
Does it work?elad wrote:If you're interted ,I enabled the A20 line this way:
The only thing I might consider adding is checking if A20 is enabled before you begin, avoiding the (possibly unimplemented) BIOS call if it is. Although this might be awkward if you're checking in protected mode and using a real-mode interrupt to enable it - you'll need a way to check if it is enabled using real mode, such as using the code below (copied from the wiki):
Code: Select all
check_a20:
pushf
push ds
push es
push di
push si
cli
xor ax, ax ; ax = 0
mov es, ax
not ax ; ax = 0xFFFF
mov ds, ax
mov di, 0x0500
mov si, 0x0510
mov al, byte [es:di]
push ax
mov al, byte [ds:si]
push ax
mov byte [es:di], 0x00
mov byte [ds:si], 0xFF
cmp byte [es:di], 0xFF
pop ax
mov byte [ds:si], al
pop ax
mov byte [es:di], al
mov ax, 0
je check_a20__exit
mov ax, 1
check_a20__exit:
pop si
pop di
pop es
pop ds
popf
ret
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing