x86_x64 linux模式,一起学习x86/x64知识

在vmware和真实机器上执行显示出SS值为0A0h,RSP值为08F0h,处理器已经从栈中POP出SS与SP值。

手册中的这一段描述与事实不符。这里阐述了实验作用之一:就是验证真伪。

下面一段话是关于中断优先级别的描述:

“Each interrupt vector is an 8-bit value. The interrupt-priority classis the value of bits 7:4 of the interrupt vector. The lowest interrupt-priority class is 1 and the highest is 15; interrupts with vectors in the range 0–15 (with interrupt-priority class 0) are illegal and are never delivered. Because vectors 0–31 are reserved for dedicated uses by

the Intel 64 and IA-32 architectures, software should configure interrupt vectors to use interrupt-priority classes in the range 2–15.

Each interrupt-priority class encompasses 16 vectors. The relative priority of interrupts within an interrupt-priority class is determined by the value of bits 3:0 of the vector number. The higher the value of those bits, the higher the priority within that interrupt-priority class. Thus, each interrupt vector comprises two parts, with the high 4 bits indicating its interrupt-priority class and the low 4 bits indicating its ranking within the interrupt-priority class.”

这段话描述8位的中断vector被分为两部分用来管理优先级,高4位是priority class,低4位是priority ranking。我们可以看作:高4位管理等级,低4位是等级内的排名。vector值大优先级别就高。

然而这里的描述会让我们产生困惑:同一个class内的ranking是否越大优先级别越高,实际上不是,处理器响应中断请求是按vector[7:4]值来仲裁:只有priority class大的才能响应。

viewspace-746140

上图所显示的是另一个测试实验,当我们对TPR(Task Priority Register)设置的值为0x32时,它的中断门坎的priority class值为3(第3级),同时PPR(Processor Priority Register)也被置为0x32,PPR的值受TPR与ISR影响。只有满足下列条件时中断请求才能被响应:

vector[7:4] > PPR[7:4]

因此:vector为0x33的中断请求发生时,将会被阻塞得不到响应的,只有vector的priority class值大于3时才会响应。

然而,Intel64手册里描述的并不清晰,我们只能通过实验来测试和验证,去除我们的困惑,这是实验的第二个作用。

我们可以想象到:由于OS的限制,大多数实验是并不适合在现有的OS平台里进行测试。因此我们需要选择要祼机上进行测试。

可以选择的运行环境有真实机器,bochs模拟器或者vmware虚拟机。那么我们可以选择的介质是U盘,硬盘映像文件或者软盘映像文件,并需要编写自己的boot程序来引导测试实验。根据不同的介质软件不同的格式:U盘和硬盘映像文件使用FAT32格式,软件映像文件可以直接将boot代码写入MBR中即可。

viewspace-746140

上面是启动boot程序的流程,FAT32文件格式中,我们的boot程序写入63号扇区(从0开始),BIOS将boot程序读入7C00h位置后,继续加载我们实验的后续模式。

以U盘和硬盘映像文件使用的FAT32文件格式为例,下面的映像文件组织:

viewspace-746140

我们实验中常用的模块是boot模块,setup模块,lib16模块,protected模块,lib32模块以及long模块。lib16与lib32模块是库代码,protected模块是32位保护模式执行代码,long模块是64位long模块执行代码,而boot模块引导它们,setup模块切入保护模式。

规定了这些模块在映像文件中的存放位置后,需要将这些模块代码写入映像文件中,可以使用最原始的方法,即:手工使用Hex类型软件合并写入。这种方法实在是太麻烦了。

这里使用自己编写的合并工具merge,根据它的配置文件批量写入到映像文件中,下面是配置文件的示例:

#输入文件,输入文件offset,输出文件,输出文件offset,写入block数( 1 block = 512 bytes)

# ****每一项用逗号分隔****

#

# example:

#

#模块名offset输出文件名offset count(1 count = 512 bytes)

#-------------------------------------------------

# boot, 0, demo.img, 0, 1

# setup, 0, demo.img, 1, 2

# init, 0, demo.img, 3, 5

#

#意思是:

# boot模块从block 0开始写入demo.img写入位置为block 0,写入1个block

# setup模块从block 0开始写入demo.img写入位置为block 1,写入2个block

# init模块从block 0开始写入demo.img写入位置为block 3,写入5个block

#下面是第2章中使用到的配置实例:

boot,0,demo.img,0,1

每一行有5个项目,以逗号分隔。分别是:源文件,源文件起始点,目标文件,目标文件起始点,写入的块数(以512字节为一块)。使用merge工具我们只需要在命令行执行merge命令即可。merge会帮助我们批量地写入目标文件相应的位置,省事且不会出错。

viewspace-746140

这里,就是U盘的设备名,当配置文件中添加写入U盘时(目标文件为U盘设备名),我们可以插入U盘到真实机器去运行。

接下来,需要编写自己的boot代码,下面是简短的示例片断:

; set BOOT_SEG environment

mov ax, cs

mov ds, ax

mov ss, ax

mov es, ax

mov sp, BOOT_SEG ;设stack底为BOOT_SEG

call clear_screen

mov si, hello

call print_message

mov si, 20 ; setup模块在第20号扇区里

mov di, SETUP_SEG - 2

call load_module ;使用load_module()读多个扇区

mov si, SETUP_SEG

call print_message

mov si, word [load_message_table + eax * 2]

call print_message

next:

jmp $

在这个boot示例里,主要的工作是调用load_module()函数来加载上述的某个模块,接下来,调用print_message()打印信息。

viewspace-746140

最后,每个测试实验下,都包括源代码文件,bochs配置文件,merge工具的配置文件,软盘映像文件(demo.img)以及硬盘映像文件(c.img)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值