【我所认知的BIOS】-反汇编BIOS之Bootblock(9)

news/2024/7/23 11:29:18 标签: 汇编, byte, table, function, express, performance

【我所认知的BIOS->汇编BIOSBootblock(9)

-- Memory initial 函数

By Lightseed

06/24/2010

1BIOS的主流程

为什么会有bootblock和非bootblock这么一说呢?其实就是因为有没有真正的内存可以用的区别。这个章节里我们一起来看看经过之前那些章节的讨论后,BIOS在初始化memory之前会做的一些动作。(稍微比较琐碎点,看起来比较枯燥。)Memory initial这个函数里面,会再做一些前期的准备工作。比如8259的中断控制器的初始化,PCIE的初始化,等等然后进入到intel提供的MRC里面去。那么这节就讲讲这个函数里面具体接触的东西。

1 BIOS主流程

2CT_Memory_Init整个函数的架构

_F000:36E0 CT_Memory_Init:                         ; CODE XREF: _F000:E377j

 

Call Power_Managment_init;伪代码

 

_F000:370C Power_Managment_init_Exit:              ; CODE XREF: _F000:8850j

 

Call PCIExpressInit      ;伪代码

 

Call Memory_INIT       ; There are too many registers which intel do not release, so I have not plan to comment it.

                                                  ; We usually call these code "MRC", it means memory refrence code. As I know, Award and AMI

                                                  ; MRC are the same.

                           ;中间省略N

Call     IGDDetect         ; 伪代码

 

Ret

上面是memory initial的整个函数反汇编出来的代码。架构也很清晰,正如之前说的那些,8259初始化好了后,继续Power management的初始化,然后再是PCIE的初始化,然后是真正进入到intelMRCdetect和初始化内存。一条线,比较简单。

3、关于南桥那面Power management的初始化

_F000:3709这行中可以看出,在8259初始化好了以后,程序就会进入到初始化power management的函数里去。那我们来看看这个函数里面具体都做了什么。

_F000:8834 Power_Managment_init:                   ; CODE XREF: _F000:3709j

_F000:8834                 mov     si, 880Ch

_F000:8837                 mov     dh, 40h ; '@'   ; PM IO

_F000:8839

_F000:8839 Power_Managment_init_loop:              ; CODE XREF: _F000:884Ej

_F000:8839                 mov     dl, cs:[si]     ; offset

_F000:883C                 mov     al, cs:[si+1]   ; get the value to store

_F000:8840                 out     dx, al          ; set

_F000:8841                 out     0EBh, al

_F000:8843                 out     0EBh, al

_F000:8845                 out     0EBh, al

_F000:8847                 add     si, 2

_F000:884A                 cmp     si, 8834h       ; Table end?

_F000:884E                 jnz     Power_Managment_init_loop

看到上面的函数是不是大家都有比较熟悉的感觉呀?一开始进来就是给SI找到一个tableoffset,然后就是按照结构体的元素来初始化各个寄存器。而这个结构体就比较简单了,总共两个byte。第一个byte是在Power management base address(还记得么?在前面的文章里有讲,PM IO base address4000H)上的偏移。关于table里面的东西,我就不多收了,我觉得我写的挺详细的,只要你对照ICHdatasheet一切都能查到对应的描述。

_F000:880C ;[]--------------------------------------------[]

_F000:880C This table is very easy, so I will not comment them one by one.

_F000:880C I choose the important register to comment. :)

_F000:880C ;[]--------------------------------------------[]

_F000:880C Power_Managment_init_table db    2 ;    ; Power Management 1 Enable Register Low byte

_F000:880D                 db    0 ;               ;

_F000:880D                                         ;

_F000:880E                 db    3 ;               ; Power Management 1 Enable Register High byte

_F000:880F                 db    0 ;               ;

_F000:880F                                         ;

_F000:8810                 db    0 ;               ; Power Management 1 Status Register low byte

_F000:8811                 db 0FFh ;               ; clear all status

_F000:8811                                         ;

_F000:8812                 db    1 ; 

_F000:8813                 db 0FFh ;               ; Power Management 1 Status Register high byte

_F000:8813                                         ;

_F000:8814                 db  11h ;               ; Processor Control Register

_F000:8815                 db    0 ;               ; No forced throttling, No clock throttling is occurring (maximum processor performance).

_F000:8815                                         ;

_F000:8816                 db  28h ; (             ; General Purpose Event 0 Status Register low byte

_F000:8817                 db 0FFh ;               ;

_F000:8817                                         ;

_F000:8818                 db  29h ; )             ; General Purpose Event 0 Status Register high byte

_F000:8819                 db 0FFh ;               ;

_F000:8819                                         ;

_F000:881A                 db  2Ah ; *

_F000:881B                 db 0FFh ;               ;

_F000:881B                                         ;

_F000:881C                 db  2Bh ; +

_F000:881D                 db 0FFh ;               ; clear all GPE0 status

_F000:881D                                         ;

_F000:881E                 db  2Ch ; ,             ; General Purpose Event 0 Enables Register the 1st byte

_F000:881F                 db    0 ;               ;

_F000:881F                                         ;

_F000:8820                 db  2Dh ; -

_F000:8821                 db    0 ;               ;

_F000:8821                                         ;

_F000:8822                 db  2Eh ; .

_F000:8823                 db    0 ;               ;

_F000:8823                                         ;

_F000:8824                 db  2Fh ; /

_F000:8825                 db    0 ;               ; all GPE0 disable

_F000:8825                                         ;

_F000:8826                 db  30h ; 0             ; SMI Control and Enable Register 1st byte

_F000:8827                 db  20h ;               ; Enables writes to the APM_CNT register to cause an SMI#.

_F000:8827                                         ;

_F000:8828                 db  31h ; 1

_F000:8829                 db    0 ;               ; Other function disable

_F000:8829                                         ;

_F000:882A                 db  34h ; 4             ; SMI Status Register 1st byte

_F000:882B                 db 0FFh ;               ;

_F000:882B                                         ;

_F000:882C                 db  35h ; 5             ; SMI Status Register 2nd byte

_F000:882D                 db 0FFh ;               ; clear all SMI status

_F000:882D                                         ;

_F000:882E                 db  41h ; A             ; I can not find the remark of this register in datasheet...:(

_F000:882F                 db  30h ; 0             ;

_F000:882F                                         ;

_F000:8830                 db  44h ; D             ; Device Activity Status Register low byte

_F000:8831                 db 0FFh ;               ;

_F000:8831                                         ;

_F000:8832                 db  45h ; E             ; Device Activity Status Register high byte

_F000:8833                 db 0FFh ;               ; clear all status

4PCIE的初始化

关于这部分的说明,我觉得很惭愧,据我所了解,这部分的代码绝对多数是为了解决一些bug才放在这里的。而且这些bug应该还都是北桥那面的一些东西,intel也没公布相关的说明,所以我也不知道究竟这里面的寄存器是有啥用。这下这段代码就是PCIE初始化的函数被反汇编出来的源码。不过我把这个函数的地址贴出来,而且这里的基本上BIOS是不会动的,所以平时我也没有深入进去研究。

_F000:394A ;[]----------------------------------------[]

_F000:394A PCIExpressInit:

_F000:394A The function of this subrutine is to initial Northbridge

_F000:394A I think you can check with the datasheet by yourself.

_F000:394A Because some of the register, I do not research before .

_F000:394A What's more, we do not touch these code. If you are

_F000:394A interest into it, you can dig into.

_F000:394A ;[]----------------------------------------[]

_F000:394A

_F000:394A PCIExpressInit:                         ; CODE XREF: _F000:3745j

_F000:394A                 mov     cx, 54h ; 'T'   ; bus 0# dev 0# func 0# Reg 54h

_F000:3A90                 jmp     di              ; PCIExpressInit return

PCIE初始化后面,还有关于北桥那面的寄存器操作,比如:MMIO base address的初始化(后面要用到的哦,尤其是intelMRC也会频繁使用的。),MCHBAR的打开呀什么的,都比较简单啦。不过要提的一下是PCIE的访问方法:(我想网上应该有不少的说明,怎么去访问PCIE的配置空间。)

Register Location = PCI Express Base Address + Bus number* 100000h + device

number * 8000h + function * 1000h + Address Offset

 

5、进入到MRC

BIOS就真正进入到intelMRC,有两点需要说明一下:

第一,我们再看看_F000:37A8之前有三个byte的数据是没有用到的(如果你反汇编BIOS,如果没有,直接跳过具体的地址)。也许有人会很纳闷,为什么会这样呀?答案是在BIOS中,写code的时候用了aglin 4的动作。从而代指有三个byte是无意义的。所以我们应该跳过去看。

第二,正如我上面的注释里有说,Memory_INIT这个函数里面有太多的寄存器是intel没有release的了,所以我也不想挨着挨着深入。如果您有兴趣可以看看intel的一本橘皮书,好像是ICH BIOS spec吧。具体我不记得了。里面有详细的描述。

6Memory初始化完了后

内存初始化完了以后,在awardbios里面还会继续detect IGD。代码很简单:

主要是操作北桥的相关寄存器(52H,详细的说明查一下北桥的datasheet)来做的。

都挺简单的,对照着北桥的datasheet就可以查清楚了。(你们查不到的寄存器,我也查不到了。。。。所以有些东西,我其实也不清楚,究竟某些寄存器有啥用。)

8、小结

至此关于BIOSbootblock部分最最重要的目的就算是完成了。因为BIOSrom里面跑而且还没有堆栈,真的很费事,而且速度还慢。所以才要尽快地把内存初始化好,然后把放在ROM里面的BIOS源码都copy到内存中来执行。这样的话不仅提高了BIOS初始化主板的速度,还显得让程序更好写。大致的过程可以看看图1所示。

 

1 BIOS在不同时期的运行过程图

我要简单描述一下图1的意思。左边其实就是BIOS一直在ROM里面跑的过程。(由于北桥开关的原因,FFFF_0000会被映射到F_0000上去,之前有讲在这里再提一下。)所以在图上仍然以F000段开说明,不要混淆哦。然后到内存初始化好了以后,bootblock的解压缩函数就会把BIOS解压缩到内存中去,然后继续执行(这个时候的BIOS就是真的在实模式下执行的了哦,北桥的开关也就是真的把内存和实际的CPU低端寻址对应了。)。

Bootblock的这部分,我们基本就要结束了,后续我们会看到BIOScopy呀什么的操作。让我们拭目以待吧!!

 


http://www.niftyadmin.cn/n/959299.html

相关文章

虚拟主播上线:多模态将改变人机交互的未来

现在,看在线视频已经成为很多人的一种生活习惯,人们乐于在忙完一天的工作和家庭生活后抽空看视频放松娱乐一下。然而,由于在线视频平台众多,视频资源丰富,现在的观众们已不满足于视频本身好不好看和视频资源的丰富度了…

import sys是什么意思_路由器指示灯分别是什么意思 路由器指示灯作用分析【图文】...

相信很多朋友都遇到过这种情况,就是当你看视频或者玩着游戏的时候电脑突然断网了,不知道什么原因,当然排除因为宽带时间到期或者被人限速拉黑的情况下,那么为什么上不了网呢?是电脑问题?还是内部线路的问题?或者是电信、移动、…

【我所认知的BIOS】-反汇编BIOS之Bootblock(10)

【我所认知的BIOS】->反汇编BIOS之Bootblock(10) -- 基本的内存检测copy BIOS to RAM By Lightseed 6/28/2010 1、BIOS的主流程 BIOS执行到这里,bootblock任务基本完成。内存初始化好了以后,为了能够安全地把BIOS copy到内存中,还需要…

unity 3d水的资源包_最后3天137款3D优质资源5折大促

Unity Asset Store资源商店中137款3D优质资源正在5折热销中~ 促销信息促销时间:截止至北京时间10月13日7点 (最后3天时间啦~~)促销地址:https://assetstore.unity.com/?on_saletrue温馨提醒:你可以访问Ass…

MyBatis --- 配置步骤

本文并非具体的细节,而是主要的配置步骤概述 MyBatis 是半自动的ORM 框架,在MyBatis 整合 Spring Boot 的时候步骤比较繁琐,所以写下此篇纪录一下步骤。 使用 MyBatis 框架需要了解 Entity, Dao, Mapper ,S…

python爬取b站评论_Python爬虫框架:scrapy抓取B站博人传评论数据

1. B站博人传评论数据爬取简介 今天想了半天不知道抓啥,去B站看跳舞的小姐姐,忽然看到了评论,那就抓取一下B站的评论数据,视频动画那么多,也不知道抓取哪个,选了一个博人传跟火影相关的,抓取看看…

有关java(初学笔记)

JAVA的主要优势:跨平台性,可以在Linux,windows,mac三个系统上运行。 跨平台的核心:JAVA虚拟机--JVM 原理就是将Java语言在这个系统上翻译。JAVA在jvm上运行,jvm进行翻译。 JRE:java的运行环境&a…

python图形界面开发pyqt_python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法...

QMainWindow QMainWindow类中比较重要的方法 方法 描述 addToolBar() 添加工具栏 centralWidge() 返回窗口中心的一个控件,未设置时返回NULL menuBar() 返回主窗口的菜单栏 setCentralWidget() 设置窗口中心的控件 setStatusBar() 设置状态栏 statusBar() 获得状态栏…