- 論壇徽章:
- 0
|
我看過一些資料,可能是錯(cuò)誤的,僅供參考,切勿笑話。
1,386以后的cpu沒有什么真正的實(shí)模式,執(zhí)行第一條指令時(shí),也就是"jmp far f000:e05b"的時(shí)候就是所謂32位的分段機(jī)制(就是用GDT,IDT來分段的那個(gè)什么來著),32位CPU在實(shí)模式下的分段機(jī)制其實(shí)就是加了一些限制的32位分段機(jī)制,很明顯,執(zhí)行第一條指令的時(shí)候A20是開啟的。這個(gè)問題說起來話長(zhǎng),這里就不多說了,就此打住。我的觀點(diǎn)是這個(gè)跳轉(zhuǎn)是跳到1M以下的那個(gè)BIOS,在bochs里面就可以看到,第一條指令的地址是0xFFFFFFFF0,而第二條則位于0x000FE0FD.
2,據(jù)我了解,應(yīng)該是拷貝的, 在bochs源代碼中,有一個(gè)BIOS的實(shí)現(xiàn),包括rombios.c,rombois32.c等文件,大致流程是,先切換到32位模式,然后把flash rom中的bios拷貝到一個(gè)臨時(shí)區(qū)域,再告訴北橋芯片組將原先分配給flash BIOS的地址重新分配給DRAM bios.關(guān)于這一點(diǎn),我們可以在rombios32.c的源代碼中看到:
static int find_bios_table_area(void)
{
unsigned long addr;
for(addr = 0xf0000; addr < 0x100000; addr += 16) {
if (*(uint32_t *)addr == 0xaafb4442) {
bios_table_cur_addr = addr + 8;
bios_table_end_addr = bios_table_cur_addr + *(uint32_t *)(addr + 4);
BX_INFO("bios_table_addr: 0x%08lx end=0x%08lx\n",
bios_table_cur_addr, bios_table_end_addr);
return 0;
}
}
return -1;
}
static void bios_shadow_init(PCIDevice *d)
{
int v;
if (find_bios_table_area() < 0)
return;
/* remap the BIOS to shadow RAM an keep it read/write while we
are writing tables */
memcpy((void *)BIOS_TMP_STORAGE, (void *)0x000f0000, 0x10000); //將BIOS拷貝到臨時(shí)區(qū)域
v = pci_config_readb(d, 0x59);
v = (v & 0x0f) | (0x30);
pci_config_writeb(d, 0x59, v); //這里估計(jì)就是所謂的重新映射
memcpy((void *)0x000f0000, (void *)BIOS_TMP_STORAGE, 0x10000); //從臨時(shí)區(qū)域拷貝到剛映射的DRAM中。
i440_pcidev = *d;
} |
|