資訊科技的飛速的發展,80x86系列不斷的出現新的產品,人們不由擔心乙個問題就是原來設計的軟體能不能在新的cpu上執行?實際上,因為80x86具有向下相容性,所以大部分的過去可以執行的軟體現在依然可以在新的cpu上執行。但是要提高相容性,必然導致功能的減弱。
新產品的出現,效能的提高,肯定有一些特性和原來不同,比如8086/8088和80286cpu的位址線根數就不一樣,直接定址的範圍也就不相同了,本篇文章將詳細談一下在實模式和保護模式中討論如何通過a20 gate功能來調整系統定址方面的相容性。
一 實位址模式
1 對於8086/8088來說計算實際位址是用絕對位址對1m求模。
2 對於80286或以上的cpu通過a20 gate來控制a20位址線
技術在發展,到了80286,系統的位址匯流排有原來的20根發展為24根,這樣能夠訪問的記憶體可以達到2^24=16m。intel在設計80286時提出的目標是向下相容。所以,在實模式下,系統所表現的行為應該和8086/8088所表現的完全一樣,也就是說,在實模式下,80286以及後續系列,應該和8086/8088完全相容。但最終,80286晶元卻存在乙個bug:因為有了80286有a20線,如果程式設計師訪問100000h-10ffefh之間的記憶體,系統將實際訪問這塊記憶體,而不是象8086/8088一樣從0開始。我們來看一副圖:
為了解決上述相容性問題,ibm使用鍵盤控制器上剩餘的一些輸出線來管理第21根位址線(從0開始數是第20根) 的有效性,被稱為a20 gate:
1 如果a20 gate被開啟,則當程式設計師給出100000h-10ffefh之間的位址的時候,系統將真正訪問這塊記憶體區域;
2 如果a20 gate被禁止,則當程式設計師給出100000h-10ffefh之間的位址的時候,系統仍然使用8086/8088的方式即取模方式(8086**)。絕大多數ibm pc相容機預設的a20 gate是被禁止的。現在許多新型pc上存在直接通過bios功能呼叫來控制a20 gate的功能。
上面所述的記憶體訪問模式都是實模式,在80286以及更高系列的pc中,即使a20 gate被開啟,在實模式下所能夠訪問的記憶體最大也只能為10ffefh,儘管它們的位址匯流排所能夠訪問的能力都大大超過這個限制。為了能夠訪問10ffefh以上的記憶體,則必須進入保護模式。
二 保護模式
從80286開始,系統出現了一種新的機制,被稱為保護模式。到了80386,保護模式得到了進一步的完善和發展,並且對於80386以後的晶元,保護模式的變化就非常小了。我們在上一節已經談到,如果要訪問更多的記憶體,則必須進入保護模式,那麼,在保護模式下,a20 gate對於記憶體訪問有什麼影響呢?
為了搞清楚這一點,我們先來看一看a20的工作原理。a20,從它的名字就可以看出來,其實它就是對於a20(從0開始數)的特殊處理(也就是對第21根位址線的處理)。如果a20 gate被禁止,對於80286來說,其位址為24根位址線,其位址表示為efffff;對於80386極其隨後的32根位址線晶元來說,其位址表示為ffefffff。這種表示的意思是
1如果a20 gate被禁止。則其第a20在cpu做位址訪問的時候是無效的,永遠只能被作為0。所以,在保護模式下,如果a20 gate被禁止,則可以訪問的記憶體只能是奇數1m段,即1m,3m,5m…,也就是00000-fffff, 200000-2fffff,300000-3fffff…
2如果a20 gate被開啟。則其第20-bit是有效的,其值既可以是0,又可以是1。那麼就可以使a20線傳遞實際的位址訊號。如果a20 gate被開啟,則可以訪問的記憶體則是連續的。
三 如何開啟a20 線
我們在實模式下只需要呼叫bios中斷就可以實現a20 gate的控制功能。這個bios中斷為 int 15h, ax=2401h。被稱為fast a20。
這個bios中斷為 int 15h, ax=2401h。被稱為fast a20。
movw $0x2401, %ax
int $0x15
四 怎樣測試a20gate端已經開啟了?
我們在之前已經提到,如果a20 gate被開啟了,則在實模式下,程式設計師可以直接訪問100000h~10ffefh之間的記憶體,如果a20 gate被禁止,則在實模式下,若程式設計師訪問100000h~10ffefh之間的記憶體,則會被硬體自動轉換為0h~0ffefh之間的記憶體,所以我們可以利用這個差異來檢測a20 gate是否被開啟,下面附乙個測試程式。
# this routine tests whether or not a20 is enabled. if so, it
# exits with zf = 0.
## the memory address used, 0x200, is the int $0x80 vector, which
# should be safe.
a20_test_addr = 4*0x80
a20_test_loops = 3
a20_test:
pushw %cx
pushw %ax
xorw %cx, %cx
movw %cx, %fs # low memory
decw %cx
movw %cx, %gs # high memory area
movw $a20_test_loops, %cx
movw %fs:(a20_test_addr), %ax
pushw %ax
a20_test_wait:
incw %ax
movw %ax, %fs:(a20_test_addr)
call delay # serialize and make delay constant
cmpw %gs:(a20_test_addr+0x10), %ax
loope a20_test_wait
popw %fs:(a20_test_addr)
popw %ax
popw %cx
retdelay:
outb %al,$0x80
ret
通過以上的討論和分析,我們知道了a20gate線對於我們實際程式設計的影響,並且了解了如何設定和調整它的狀態來達到我們要求。
A20 程式崩潰的除錯
1 首先找到log資訊中 backtrace 識別符號 backtrace 01 02 08 33 05.050 i debug 1258 00 pc 00016d94 system lib libc.so write 12 01 02 08 33 05.050 i debug 1258 01 pc...
A20使用日誌2015 5 26
嘗試opencv2.4.10版本,還是新增imgproc庫還是失敗,此庫比較重要。再嘗試opencv3.0版本,交叉編譯器為全志自帶的編譯工具。選中imgproc庫還是失敗,嘗試改用mini2440的交叉編譯工具。用arm linux gcc 4.4交叉編譯opencv2.4.10。選中了imgpr...
手動替換A20 映象中的檔案
parted picked.img gnu parted 2.3 parted p model file disk opt kaifaban a20 sdk2015 20160907 emmc flash.img 1615mb sector size logical physical 512b 51...