最近在讀Linux的grub的stage1中看到「BIOS執行INT 0x19,加載MBR內容至0x7c00,而後跳轉執行」,爲何必定是0x7c00這個地址。html
做者恰好在下面推薦了這篇文件,恰好順手記錄一下。// 最下方有中文版,英語很差的同窗能夠跳到最下面ios
Do you know "0x7C00", a magic number, in x86 assembler programming ?
"0x7C00" is the memory address which BIOS loads MBR(Master Boot Record, a first sector in hdd/fdd) into. OS or bootloader developer must assume that their assembler codes are loaded and start from 0x7C00. git
But...1st, you may wonder. app
"I read all of Intel x86(32bit) programmers manual, but did not found the magic number 0x7C00." ide
Yes.0x7C00 is NOT related to x86 CPU. It's natural that you couldn't find out it in cpu specifications from intel. Then, you wonder, "Who decided it ?" ui
2nd, you may wonder: this
"0x7C00 is 32KiB - 1024B at decimal number. What's this number means ?" .net
Anyone decided it. But, why he/she decided such a halfway address? debug
Hum...There're TWO questions(mysteries) arround the magic number "0x7C00". code
Okay, let's dive into the secret of BIOS for "IBM PC 5150", ancestor of modern x86(32bit) PCs, with me...!!
Wandering arround the history of x86 IBM Compatible PC, you know IBM PC 5150 is the ancestor of modern x86(32bit) IBM PC/AT Compatible PCs.
This PC was released at 1981 August, with Intel 8088(16bit) and 16KiB RAM(for minimum memory model). BIOS and Microsoft BASIC was stored in ROM.
When power on, BIOS processes "POST"(Power On Self Test) procedure, and after, call INT 19h.
In INT 19h handler, BIOS checks that PC has any of floppy/hard/fixed diskette or not have.
If PC has any of available diskkete, BIOS loads a first sector(512B) of diskette into 0x7C00.
Now, you understand why you couldn't find out this magic number in x86 documents. This magic number belongs to BIOS specification.
Stories surrounding IBM PC DOS, Microsoft, and SCP's 86-DOS are famous stories. See: "A Short History of MS-DOS".
SCP's "86-DOS"(at 1980) is the reference OS for IBM PC DOS 1.0.
86-DOS(early called "QDOS") is CP/M compatible OS for 8086/8088 cpu. At 1979, Digital Research Inc didn't have developed CP/M for 8086/8088 cpu yet.
SCP sold two S-100 bus board, one is 8086 CPU board, two is "CPU Monitor" rom board.
"CPU Monitor" program provided bootloader and debugger. This "CPU Monitor" bootloader loaded MBR into "0x200", NOT "0x7C00". In 1981, IBM PC DOS was the NEXT CP/M like OS for 8086/8088.
So, I told you that "0x7C00 FIRST appeared in IBM PC 5150 ROM BIOS".
Previous one, SCP's CPU Monitor bootloader loads into 0x200, not 0x7C00.
There're THREE reasons about "0x200".
These reasons mean 0x200 - 0x3FF needed to be reserved and couldn't be in the way of an OS, no matter where 86-DOS or user application wanted to load.
So Tim Paterson (86-DOS developer) chose 0x200 for MBR load address.
"0x7C00" was decided by IBM PC 5150 BIOS developer team (Dr. David Bradley).
As mentioned above, this magic number was born at 1981 and "IBM PC/AT Compat" PC/BIOS vendors did not change this value for BIOS and OS's backward compatibility.
Not Intel(8086/8088 vendor) nor Microsoft(OS vendor) decided it.
IBM PC 5150 minimum memory model had only 16KiB RAM. So, you may have a question.
"Could minimum memory model (16KiB) load OS from diskette ? BIOS loads MBR into 32KiB - 1024B address, but physical RAM is not enough..."
No, that case was out of consideration. One of IBM PC 5150 ROM BIOS Developer Team Members, Dr. David Bradley says:
"DOS 1.0 required a minimum of 32KB, so we weren't concerned about attempting a boot in 16KB."
(Note: DOS 1.0 required 16KiB minimum ? or 32KiB ? I couldn't find out which correct. But, at least, in 1981's early BIOS development, they supposed that 32KiB is DOS minimum requirements.)
BIOS developer team decided 0x7C00 because:
Once OS loaded and started, boot sector is never used until power reset. So, OS and application can use the last 1024B of 32KiB freely.
After OS loaded, memory layout will be:
+--------------------- 0x0 | Interrupts vectors +--------------------- 0x400 | BIOS data area +--------------------- 0x5?? | OS load area +--------------------- 0x7C00 | Boot sector +--------------------- 0x7E00 | Boot data/stack +--------------------- 0x7FFF | (not used) +--------------------- (...)
That are the origin and reasons of "0x7C00", the magic number survived for about three decades in PC/AT Compat BIOS INT 19h handler.
86-DOS related:
IBM PC 5150 related:
Intel 8086/8088 data sheets:
CP/M related:
86-DOS related:
And all related Wikipedia pages.
Special Thanks To:
for japanese article, see:
"Assembler/なぜx86ではMBRが"0x7C00"にロードされるのか?(徹底版)"
https://www.glamenv-septzen.net/view/614
中文版:
https://www.douban.com/note/249471773/
Referer: