纯x86汇编实现的多线程操作系统实践 - 第三章 BSP的守护执行

本文详细讲述了BSP如何初始化32位保护模式,包括系统中断、APIC、IOAPIC的配置,以及键盘、鼠标、HPETtimer0的初始化。此外,还介绍了如何处理键盘和鼠标中断,显示系统时间和AP状态,以及安装和处理系统调用。最后,阐述了BSP的守护循环,涉及鼠标和键盘的输入处理以及AP状态的显示。

本章我们将详细讲解BSP剩下的执行代码,它们被安排在bp_32.asm文件中。

bp_32.asm主要完成以下功能:

  1. 系统中断初始化

  1. 加载字符图形数据到内存区域

  1. 将AP的启动代码和32位保护模式下的代码分别加载到内存中

  1. 显示主界面以及系统启动信息

  1. 向所有AP群发启动命令

  1. 进入守护线程的大循环:

  • 接收并处理鼠标数据,在界面上显示鼠标

  • 接收并显示键盘输入

  • 显示两个AP用户线程的实时状态

  • 显示BSP已经执行的时间 时:分:秒

3.1 启动系统中断

3.1.1总体初始化

BSP这部分的32位代码从0x80016000地址处开始执行。cli指令关中断,再调用init_interrupt_function函数设置系统中断,最后sti指令开启系统中断。

我们使用APIC来设置和使能系统中断。APIC全称Advanced Programmable InterruptController。每个执行内核都有一个APIC,称为LocalAPIC(LAPIC)。每个LAPIC包含一系列的寄存器,这些寄存器控制LAPIC如何将中断信号发送到执行内核中。

LAPIC架构图

APIC根据实现不同,分成LAPIC和x2APIC,这两个APIC寄存器基本一样,唯一不同的是LAPIC通过内存访问APIC寄存器,x2APIC通过MSR寄存器访问APIC寄存器。

1. xAPIC:APIC寄存器被映射到4KB大小的MMIO内存区,操作系统通过MMIO内存访问APIC。

2. x2APIC: 一部分MSR地址区间为APIC寄存器预留,访问APIC是通过MSR。这样的好处是不用再担心内存地址的冲突问题。

LAPIC可以从以下几个来源接收到中断:

  • Locallyconnected I/O devices: 直接连接到处理器的本地中断引脚(LINT0和LINT1)的I/O设备触发的中断

  • Externallyconnected I/O devices :外部链接的I/O设备发出的中断

  • Inter-processor interrupts (IPIs) :执行内核可以使用IPI机制向系统总线上的其它执行内核发送中断

  • APICtimer generated interrupts:APIC定时器中断

  • Performancemonitoring counter interrupts :性能计数器中断

  • ThermalSensor interrupts :热传感器中断 (power)

  • APICinternal error interrupts :APIC内部异常中断

Local APIC的使能需要设置两个寄存器:IA32_APIC_BASE寄存器的第11位(置1)、SVR寄存器的第8位(置1)

IA32_APIC_BASE寄存器为MSR(Model-Specific Register),对应的编号为0x1B。需要使用RDMSR/WRMSR来读写,命令格式为:

mov ecx, 0x1B

rdmsr

操作MSR寄存器时,须先将MSR寄存器的编号写入ecx,读出的MSR寄存器值放在EDX:EAX中,高位在EDX,低位在EAX。

IA32_APIC_BASE寄存器的第12位以上还保存着APIC寄存器的物理基地址。默认情况下该物理基地址值为0xFEE00000

SVR寄存器地址为0xFEE00010

经过BIOS的初始化,IA32_APIC_BASE寄存器第11位以及SVR寄存器的第8位都为1,Local APIC默认就是启动的,我们无需再设。

下面是IO APIC的初始化。外部设备先与IO APIC对接,产生的中断由IO APIC通过总线发送到Local APIC,之后再发送到执行内核。

init_interrupt_function函数完成IO APIC的初始化。

对IO APIC进行操作,首先要做两件事:

  1. 设置IO APIC寄存器的默认地址(index/data/EOI这三个寄存器);

  1. 启动IO APIC功能。

IO APIC寄存器默认地址对应OIC寄存器的0~7bits位,IOAPIC的使能控制位于OIC寄存器的第8位。正常情况下,IO APIC三个寄存器的默认地址就是index-0xFEC00000data-0xFEC00010EOI-0xFEC00040

IO APIC其它寄存是都是通过index和data寄存器来间接访问,各寄存器的index值为:

index

寄存器

Size

0x0

ID

32位

0x1

Version

32位

0x2~0x0F

Reserved

0x10~0x11

Redirection table 0

64位

0x12~0x13

Redirection table 1

64位

0x3C~0x3D

Redirection table 22

64位

0x3E~0x3F

Redirection table 23

64位

0x40~0xFF

Reserved

IO APIC寄存器对应index值

启动IOC APIC:

OIC寄存器位于RCBA(root complex base address)寄存器的0x31FE偏移上。READ_PCI_DWORD 0,31,0,0x0f0 以及 and eax, 0xFFFFC000用于获取RCBA寄存器的地址。

之后,mov esi, [eax +0x31fe]获取OIC寄存器的值。然后第8位置1,使能IO APIC功能,同时0~7位置0,将IO APIC寄存器的基地址设置为0xFEC00000起始。最后再写入OIC寄存器,完成设置。

IO APIC的index寄存器写入0,选择IO APIC的ID寄存器。之后,IO APIC的data寄存器写入0x0F0000000,将BSP对应的IO APIC的ID号设置位0x0F

下面,开始设置操作系统需要使用到的各个中断,包括键盘、高精度HPET0时钟、鼠标。

对于该类外部中断,IO APIC都需要使用Redirection table寄存器进行设置。Redirection table寄存器格式如下:

中断在配置时需要至少提供4类数据:

  1. 中断服务程序的Vector值(中断向量号)

  1. 中断的Delivery mode:Fixed、lowestpriority、SMI、NMI、INIT或ExtINT模式

  1. 触发模式:edge或是level触发模式

  1. 目标执行内核:physical或logical目标模式,并在destionation中提供目标执行内核的ID号(BSP的ID号就是0)

同时,IO APIC对应的IRQ为:

IRQ

中断源

对应配置寄存器

0

连接8259中断控制器

Redirection table 0

1

Keyboard(键盘)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值