• 打开A20


    ;;来源:http://www.visopsys.org/osdev/index.html
    ;;他说这是他试过的最好的方式
    ;; enableA20.s (adapted from Visopsys OS-loader)
    ;;
    ;; Copyright (c) 2000, J. Andrew McLaughlin
    ;; You're free to use this code in any manner you like, as long as this
    ;; notice is included (and you give credit where it is due), and as long
    ;; as you understand and accept that it comes with NO WARRANTY OF ANY KIND.
    ;; Contact me at <andy@visopsys.org> about any bugs or problems.
    ;;

    enableA20:
    ;; This subroutine will enable the A20 address line in the keyboard
    ;; controller.  Takes no arguments.  Returns 0 in EAX on success,
    ;; -1 on failure.  Written for use in 16-bit code, see lines marked
    ;; with 32-BIT for use in 32-bit code.

    pusha

    ;; Make sure interrupts are disabled
    cli

    ;; Keep a counter so that we can make up to 5 attempts to turn
    ;; on A20 if necessary
    mov CX, 5

    .startAttempt1:
    ;; Wait for the controller to be ready for a command
    .commandWait1:
    xor AX, AX
    in AL, 64h
    bt AX, 1
    jc .commandWait1

    ;; Tell the controller we want to read the current status.
    ;; Send the command D0h: read output port.
    mov AL, 0D0h
    out 64h, AL

    ;; Wait for the controller to be ready with a byte of data
    .dataWait1:
    xor AX, AX
    in AL, 64h
    bt AX, 0
    jnc .dataWait1

    ;; Read the current port status from port 60h
    xor AX, AX
    in AL, 60h

    ;; Save the current value of (E)AX
    push AX ; 16-BIT
    ;; push EAX ; 32-BIT

    ;; Wait for the controller to be ready for a command
    .commandWait2:
    in AL, 64h
    bt AX, 1
    jc .commandWait2

    ;; Tell the controller we want to write the status byte again
    mov AL, 0D1h
    out 64h, AL

    ;; Wait for the controller to be ready for the data
    .commandWait3:
    xor AX, AX
    in AL, 64h
    bt AX, 1
    jc .commandWait3

    ;; Write the new value to port 60h.  Remember we saved the old
    ;; value on the stack
    pop AX ; 16-BIT
    ;; pop EAX ; 32-BIT

    ;; Turn on the A20 enable bit
    or AL, 00000010b
    out 60h, AL

    ;; Finally, we will attempt to read back the A20 status
    ;; to ensure it was enabled.

    ;; Wait for the controller to be ready for a command
    .commandWait4:
    xor AX, AX
    in AL, 64h
    bt AX, 1
    jc .commandWait4

    ;; Send the command D0h: read output port.
    mov AL, 0D0h
    out 64h, AL

    ;; Wait for the controller to be ready with a byte of data
    .dataWait2:
    xor AX, AX
    in AL, 64h
    bt AX, 0
    jnc .dataWait2

    ;; Read the current port status from port 60h
    xor AX, AX
    in AL, 60h

    ;; Is A20 enabled?
    bt AX, 1

    ;; Check the result.  If carry is on, A20 is on.
    jc .success

    ;; Should we retry the operation?  If the counter value in ECX
    ;; has not reached zero, we will retry
    loop .startAttempt1


    ;; Well, our initial attempt to set A20 has failed.  Now we will
    ;; try a backup method (which is supposedly not supported on many
    ;; chipsets, but which seems to be the only method that works on
    ;; other chipsets).


    ;; Keep a counter so that we can make up to 5 attempts to turn
    ;; on A20 if necessary
    mov CX, 5

    .startAttempt2:
    ;; Wait for the keyboard to be ready for another command
    .commandWait6:
    xor AX, AX
    in AL, 64h
    bt AX, 1
    jc .commandWait6

    ;; Tell the controller we want to turn on A20
    mov AL, 0DFh
    out 64h, AL

    ;; Again, we will attempt to read back the A20 status
    ;; to ensure it was enabled.

    ;; Wait for the controller to be ready for a command
    .commandWait7:
    xor AX, AX
    in AL, 64h
    bt AX, 1
    jc .commandWait7

    ;; Send the command D0h: read output port.
    mov AL, 0D0h
    out 64h, AL

    ;; Wait for the controller to be ready with a byte of data
    .dataWait3:
    xor AX, AX
    in AL, 64h
    bt AX, 0
    jnc .dataWait3

    ;; Read the current port status from port 60h
    xor AX, AX
    in AL, 60h

    ;; Is A20 enabled?
    bt AX, 1

    ;; Check the result.  If carry is on, A20 is on, but we might warn
    ;; that we had to use this alternate method
    jc .warn

    ;; Should we retry the operation?  If the counter value in ECX
    ;; has not reached zero, we will retry
    loop .startAttempt2


    ;; OK, we weren't able to set the A20 address line.  Do you want
    ;; to put an error message here?
    jmp .fail


    .warn:
    ;; Here you may or may not want to print a warning message about
    ;; the fact that we had to use the nonstandard alternate enabling
    ;; method

    .success:
    sti
    popa
    xor EAX, EAX
    ret

    .fail:
    sti
    popa
    mov EAX, -1
    ret
  • 相关阅读:
    Redis简介 安装 注册服务
    Supervisor Linux守护进程
    .Net5 控制台 读取配置文件+依赖注入
    Linux Gdip
    Net Core封装 踩坑
    Apollo 公共Namespace使用json
    Visual Studio 2019修改项目名
    【面向对象】--静态类与非静态类的区别
    win10设置默认中英文符号【程序员标配】
    MySQL 数据库访问驱动-版本问题
  • 原文地址:https://www.cnblogs.com/huqingyu/p/113653.html
Copyright © 2020-2023  润新知