我对A20线检查代码的理解是否正确?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我对A20线检查代码的理解是否正确?相关的知识,希望对你有一定的参考价值。

我关注如何检查和启用A20系列的this tutorial。我想我明白了,但有人可以为我澄清一下吗?

该教程中已有的评论开始于; <comment>, 我的评论开始;<comment>

; The following code is public domain licensed

[bits 16]

; Function: check_a20
;
; Purpose: to check the status of the a20 line in a completely self-contained state-preserving way.
;          The function can be modified as necessary by removing push's at the beginning and their
;          respective pop's at the end if complete self-containment is not required.
;
; Returns: 0 in ax if the a20 line is disabled (memory wraps around)
;          1 in ax if the a20 line is enabled (memory does not wrap around)

check_a20:
    pushf                                  ;Backup the current flags onto the stack
                                           ;Backup the below registers onto the stack
    push ds                                ;|
    push es                                ;|
    push di                                ;|
    push si                                ;-----

    cli                                    ;Disable interupts

    xor ax, ax                             ; ax = 0
    mov es, ax                             ;es = ax

    not ax                                 ; ax = 0xFFFF
    mov ds, ax                             ; ds = ax

    mov di, 0x0500                         ;Boot signature part one (0x55)
    mov si, 0x0510                         ;Boot signature part two (0xAA)

    mov al, byte [es:di]                   ;al = value at AA:55
    push ax                                ;Backup ax register onto the stack

    mov al, byte [ds:si]                   ;al = value at 55:AA
    push ax                                ;Backup al onto the stack

    mov byte [es:di], 0x00                 ;Memory location AA:55 = 0
    mov byte [ds:si], 0xFF                 ;Memory location at 55:AA = 0xFF

    cmp byte [es:di], 0xFF                 ;Does value at AA:55 = 0xFF? If so, this means A20 is disabled

    pop ax                                 ;Restore saved ax register
    mov byte [ds:si], al                   ;Set 55:AA to al

    pop ax                                 ;Restore ax register
    mov byte [es:di], al                   ;set AA:55 to al

    mov ax, 0                              ;Return status of this function = 0 (Disabled)
    je check_a20__exit                     ;A20 is disabled. Go to check_a20__exit

    mov ax, 1                              ;Return status of this function = 1 (Enabled)

check_a20__exit:
                                           ;Backup registers
    pop si
    pop di
    pop es
    pop ds
    popf                                   ;Backup flags

    ret                                    ;Return

如果我不理解某些部分,你能解释一下原因吗?

答案

代码检查FFFF:05100000:0500是否通过写入两个来查看相同的地址,并查看写入一个地址是否覆盖另一个地址。

事实证明,FFFF:0510可以代表线性地址0x100500而不是0x500,但仅限于A20启用时。因此代码将所有零写入es:di(aka 0000:0500)中的字节,并将所有1写入ds:si(aka FFFF:0510)中的字节。如果A20被使能,那么两个段:偏移对指的是不同的地址,第一次写入将保持不变,而[es:di]将包含零。否则,两对引用相同的地址,第二次写入将破坏第一次,而[es:di]将包含0xff

(顺便说一句,0x550xAA不是这个的一部分;我不确定你从哪里得到这些数字。启动签名通常是0x7dfe,IIRC。)

另一答案

我想你在维基中错过了这一行:

以下代码执行检查(不像上面描述的那样 - 更直接)。

如果禁用A20,则这两个位置会互为别名。如果没有,他们不会。这就是为什么它会执行两个不同值的存储,然后检查以查看其中的内容。 (第二家商店是否有别名。)

如果您在高地址检查0xAA55签名,则只会进行加载。另外,地址(FFFF:05000000:0510)不等于0000:7DFE(引导扇区签名的位置)和FFFF:7E0E(可能是别名),即使在规范化之后也是如此。

你凭空捏造AA和55;它们不会出现在代码中的任何位置,并且您找到它们的地址没有任何负载。

以上是关于我对A20线检查代码的理解是否正确?的主要内容,如果未能解决你的问题,请参考以下文章

打开A20地址线

C:我对堆和堆栈分配细节的理解是不是正确?

我对缓冲区的理解正确吗?

以下代码片段 C++ 的说明

在纯 UEFI 中启动时谁启用了 A20 线?

分享前端开发常用代码片段