cheng long wrote:
As the "Understanding the Linux Kernel" says in Appendix A, when
reset, CPU begin execution at physical address 0xFFFFFFF0. So in
section2.5, the author says, the physical address range
0xFFFF0000-0xFFFFFFFF is mapped by the hardware to the BIOS's ROM chip
.
Appendix A also says BIOS uses Real Mode addresses, which can only
address 1M space. If so, how does the CPU addresses
0xFFFF0000-0xFFFFFFFF?
Some article said the BIOS was mapped at physical address range
0xF0000-0xFFFF, but article (in
http://www.x86.org/productivity/a20reset.htm) said that the execution
did begins at 0xFFFFFFF0.
Would any people tell me the truth?
Yes, the CPU starts up in real-mode and yes, it starts executing at
0xFFFFFFF0. You are right that normally real-mode can only access the
first megabyte, so this is done through a trick.
As with the original 8086, the CS:IP power-on value is 0xF000:0xFFF0 but
while this normally would make for a physical address of 0x000FFFF0 (1M
- 16) the "hidden" part of the CS descriptor register which is normally
used only in protected mode is initialized with a base value of
0xFFF00000 meaning the actual physical address ends up as
base + (cs << 4) + ip = 0xFFF00000 + 0x000F0000 + 0x0000FFF0 =
0xFFFFFFF0 = 4G - 16
What this trick accomplishes is that a system builder could elect to
place the ROM not below 1M but just below 4G instead, while still
allowing a bootup in real-mode.
The PC has never used this though. On the PC, the BIOS (at poweron) is
simply doubly mapped; the chipset routes both 0x000F0000-0x000FFFFF and
0xFFFF0000-0xFFFFFFFF to the BIOS chip. Furthermore, if you disassemble
the first instruction of the BIOS:
# dd if=/dev/mem bs=16 skip=$((0xFFFF)) count=1 | ndisasm -
you will find it's a:
00000000 EA5BE000F0 jmp 0xf000:0xe05b
That is, a far jump. This far jump immediately resets that "base" value
of the CS descriptor to 0 as is normal for real-mode meaning that after
this you are executing simply at physical address 0xFE05B (where as said
the BIOS also lives).
On the PC then, you can for all intents and purposes just forget that
the CPU starts executing at 4G - 16 and pretend it starts at 1M - 16 as
the 8086 did.
Another question: when CPU in Read Mode, the A20 address line is
disabled, isn't it?
This is not something the CPU itself arranges; it's the motherboard that
needs to enable or disable A20 (through a bit in port 0x92, or by going
through the keyboard controller). The A20 thing is...
The 8086 with its 1M of addressspace simply wrapped at 1M. An address
such as 0xFFFF:0x0010 = 0x100000 would just have it's 20th bit chopped
off to end up as 0 again. The 286 expanded the address space to 16M
meaning all of a sudden this 20th bit did _not_ get chopped of anymore
and that same 0xFFFF:0x0010 address now actually addressed physical
address 0x100000.
As with anything in the sorded PC history though, some programs at the
time actually relied on this wrap-around (with the microsoft linker
being the important one) meaning the A20 hack was implemented -- simply
shut off (pull down) address line 20 at the board level. While the CPU
may feel it's addressing physical address 1M then, it's again actually
addressing physical address 0 again. Rejoice.
The PC boots up with A20 disabled. Obviously, you'll want to enable it
when going into protected mode and using memory above 1M but even DOS
enabled it in real-mode -- the DOS memory map was rather cramped and
with a "DOS=HIGH" statement in CONFIG.SYS it enabled A20 and then copied
itself to the 64K now additionally available at segment 0xFFFF (in its
terms, the "HMA", High Memory Area).
Anyways, the point; the CPU doesn't control the A20 thing, the
motherboard does.
Rene.
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/