Linux 0.12 内核中断描述符表(IDT)完整实现代码

以下是基于 setup 程序扩展的完整代码,包含中断描述符表(IDT)的定义、初始化及中断处理程序,可直接用于实验验证:

asm

/* setup.s —— 4 扇区(2048 B),含IDT设置的完整实现 */
.code16
.text
.global _start_setup/* 段地址定义 */
INITSEG  = 0x9000      /* 硬件信息存储段地址 */
SETUPSEG = 0x9020      /* setup程序自身段地址 */
IDT_BASE  = 0x0000      /* 中断描述符表基地址(物理地址0x00000) */
IDT_LIMIT = 0x7FFF      /* IDT长度(8192字节,256个描述符) */_start_setup:/* 初始化段寄存器 */movw    %cs, %axmovw    %ax, %dsmovw    %ax, %es/* 收集硬件信息:光标位置 */movb    $0x03, %alxor     %bh, %bhint     $0x10movw    %dx, (0)/* 收集硬件信息:内存大小 */movb    $0x88, %ahint     $0x15movw    %ax, (2)/* 打印"setup is running" */movw    $setup_msg, %axmovw    %ax, %bpmovw    $0x1301, %axmovw    $0x000C, %bx      /* 页0 + 亮红 */movw    $16, %cxmovb    $3, %dhmovb    $0, %dlint     $0x10/* 收集显示信息 */movw    $INITSEG, %axmovw    %ax, %dsmovb    $0x0f, %ahint     $0x10movw    %bx, (4)movw    %ax, (6)/* 复制硬盘参数表 */movw    $0x0000, %axmovw    %ax, %dsldsw    (4 * 0x41), %simovw    $INITSEG, %axmovw    %ax, %esmovw    $0x0080, %dimovw    $0x10, %cxrepmovsb/* 获取第二块硬盘数据 */movw    $0x0000, %axmovw    %ax, %dsldsw    (4 * 0x46), %simovw    $INITSEG, %axmovw    %ax, %esmovw    $0x0090, %dimovw    $0x10, %cxrepmovsb/* 检查第二块硬盘是否存在 */movw    $0x1500, %axmovb    $0x81, %dlint     $0x13jc      no_disk1cmpb    $3, %ahje      is_disk1
no_disk1:movw    $INITSEG, %axmovw    %ax, %esmovw    $0x0090, %dimovw    $0x10, %cxmovw    $0x00, %axrepstosb
is_disk1:/* 准备进入保护模式:移动内核到低地址 */climovw    $0x0000, %axcld
do_move:movw    %ax, %esaddw    $0x1000, %axcmpw    $0x9000, %axjz      end_movemovw    %ax, %dsxorw    %di, %dixorw    %si, %simovw    $0x8000, %cxrepmovswjmp     do_move
end_move:/* 显示字符'A'表示准备完成 */movw    $0xb800, %axmovw    %ax, %gsmovb    $0xf, %ah         /* 黑底白字 */movb    $0x41, %al        /* 字符'A' */movl    $0x100, %edi      /* 显示位置 */movw    %ax, %gs:(%edi)/* 加载全局描述符表(GDT) */movw    $SETUPSEG, %axmovw    %ax, %dslgdt    gdt_48/* 初始化8259A中断控制器 */call    empty_8042movb    $0xD1, %aloutb    %al, $0x64call    empty_8042movb    $0xDF, %aloutb    %al, $0x60call    empty_8042movb    $0x11, %aloutb    %al, $0x20.word   0x00eb, 0x00eb    /* 短延迟 */outb    %al, $0xA0.word   0x00eb, 0x00ebmovb    $0x20, %aloutb    %al, $0x21.word   0x00eb, 0x00ebmovb    $0x28, %aloutb    %al, $0xA1.word   0x00eb, 0x00ebmovb    $0x04, %aloutb    %al, $0x21.word   0x00eb, 0x00ebmovb    $0x02, %aloutb    %al, $0xA1.word   0x00eb, 0x00ebmovb    $0x01, %aloutb    %al, $0x21.word   0x00eb, 0x00eboutb    %al, $0xA1.word   0x00eb, 0x00ebmovb    $0xff, %aloutb    %al, $0x21.word   0x00eb, 0x00eboutb    %al, $0xA1/* 切换到保护模式 */movl    %cr0, %eaxxorb    $1, %almovl    %eax, %cr0/* 跳转到32位代码 */.byte   0x66, 0xea.long   protected_mode_start.word   0x0008            /* 代码段选择子 *//* 32位保护模式代码段 */
.code32
protected_mode_start:/* 初始化数据段寄存器 */movl    $0x10, %eaxmovw    %ax, %dsmovw    %ax, %esmovw    %ax, %fsmovw    %ax, %gsmovw    %ax, %ssmovl    $0x90000, %esp    /* 设置栈指针 *//* 初始化中断描述符表(IDT) */call    setup_idtlidt    idt_48            /* 加载IDT寄存器 *//* 开启中断 */sti/* 触发测试中断(向量0x30) */int     $0x30/* 显示测试完成信息 */movl    $0xb8000 + 2*80, %edi  /* 第2行起始位置 */movb    $'O', %almovb    $0x0A, %ah         /* 绿底黑字 */movw    %ax, (%edi)movb    $'K', %almovw    %ax, 2(%edi)loop:jmp     loop              /* 无限循环 *//* 初始化IDT:填充所有中断门 */
setup_idt:movw    $IDT_BASE, %axmovw    %ax, %es          /* ES指向IDT基地址 */xorl    %edi, %edi        /* 偏移地址从0开始 */movl    $256, %ecx        /* 256个中断向量 */movl    $default_int_handler, %edx  /* 中断处理程序地址 */
idt_fill:/* 填充中断门低16位偏移 */movw    %dx, %es:(%edi)/* 填充代码段选择子(0x0008 = 内核代码段) */movw    $0x0008, %es:2(%edi)/* 填充属性(中断门、DPL=0) */movw    $0x8E00, %es:4(%edi)/* 填充中断门高16位偏移 */movw    %dx, %es:6(%edi)   /* 简化处理:高16位暂用低16位值 */addl    $8, %edi          /* 移动到下一个描述符 */loop    idt_fillret/* 默认中断处理程序 */
default_int_handler:pushal                   /* 保存所有通用寄存器 *//* 显示中断发生标志 */movl    $0xb8000 + 3*80, %edi  /* 第3行显示 */movb    $'I', %al         /* 'I'表示中断 */movb    $0x0C, %ah        /* 红底黑字 */movw    %ax, (%edi)/* 发送中断结束信号(EOI) */movb    $0x20, %aloutb    %al, $0x20        /* 主8259A */outb    %al, $0xA0        /* 从8259A */popal                    /* 恢复寄存器 */iret                     /* 中断返回 *//* 等待8042控制器空闲 */
empty_8042:.word   0x00eb, 0x00eb    /* 短延迟 */inb     $0x64, %altestb   $2, %aljnz     empty_8042ret/* 全局描述符表(GDT) */
gdt:.word   0, 0, 0, 0                /* 空描述符 */.word   0x07ff, 0x0000, 0x9A00, 0x00C0  /* 代码段:基址0,限长32MB */.word   0x07ff, 0x0000, 0x9200, 0x00c0  /* 数据段:基址0,限长32MB */.word   0xffff, 0x8000, 0x920b, 0x00c0  /* 视频段:基址0xb8000 */gdt_48:.word   0x800                     /* GDT长度 */.word   512 + gdt, 0x9            /* GDT基地址 *//* 中断描述符表(IDT)寄存器加载结构 */
idt_48:.word   IDT_LIMIT                 /* IDT长度 */.word   IDT_BASE + idt, 0x0       /* IDT基地址 *//* 数据区 */
setup_msg:.ascii  "setup is running"
idt:                                  /* IDT实际存储位置(从IDT_BASE开始) */.fill   2048 - (.-_start_setup), 1, 0  /* 填充到2048字节 */

编译与运行步骤

1. 编译代码

bash

# 汇编生成目标文件(32位模式兼容16位代码)
as -32 -o setup.o setup.s# 链接生成二进制文件(确保为2048字节)
ld -m elf_i386 -Ttext 0x0 -s --oformat binary -e _start_setup -o setup setup.o# 验证文件大小
ls -l setup | awk '{print $5 " bytes (应显示2048)"}'

2. 制作完整镜像

bash

# 假设已有引导扇区文件bootsect(512字节)
cat bootsect setup > linux.img# 若需添加内核主体,可继续拼接(可选)
# cat bootsect setup system >> linux.img

3. 使用 QEMU 运行

bash

qemu-system-i386 -fda linux.img -boot a -vga std -no-reboot

实验现象验证

运行后 QEMU 窗口将显示以下内容,表明 IDT 设置成功:

  1. 第 3 行显示红色的 "setup is running"(setup 程序运行标志)
  2. 第 2 行显示绿色的 "OK"(保护模式初始化完成)
  3. 第 3 行显示红色的 "I"(中断 0x30 触发成功)

若能观察到以上现象,说明中断描述符表已正确设置,保护模式下的中断机制可正常工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919109.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919109.shtml
英文地址,请注明出处:http://en.pswp.cn/news/919109.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手机实时提取SIM卡打电话的信令声音-当前现状与思考

手机实时提取SIM卡打电话的信令声音-当前现状与思考 --纯手机-无外置配件的方案规划 上一篇:手机实时提取SIM卡打电话的信令声音-新的篇章(篇外小结与思考) 下一篇:手机实时提取SIM卡打电话的信令声音-整体解决方案规划 一、前言 我们在2024年09月的…

【车联网kafka】常用参数及其命令总结(第八篇)

目录 1、kafka参数 1.1 、消费者消息批次发送 1.2 、消息大小的配置(环环相扣的消息大小,调整时需要一起调整) 1.3 、消息重试发送幂等 1.4、消息提交 1.5、分区分配策略(自己看的设置) 1.6、文件存储 2、kafka命令 2.1 常用命令一览…

基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统

🔥作者:it毕设实战小研🔥 💖简介:java、微信小程序、安卓;定制开发,远程调试 代码讲解,文档指导,ppt制作💖 精彩专栏推荐订阅:在下方专栏&#x1…

17.4 合并购物车

分析 用户登录后,将Cookie中的购物车商品合并到redis数据库中。如果此时redis中已经有相同id的商品,则使用Cookie中的数据覆盖redis中的数据。 合并功能需要在用户登录后实现,但登录视图中应避免过多与登录逻辑无关的逻辑,所以考虑…

RK3588消费级8K VR一体机 是否有坑?

​​芯片平台​​​​定位场景​​​​核心优势​​​​消费级功能性短板​​全志H8/RK3288入门级VR低成本、基础性能稳定算力弱(4*A55)、无NPU、显示分辨率仅1080P高通XR1中端VR/AR均衡性能(Adreno 615 GPU)仅WiFi5、续航≤4小时…

基于Spring Boot校园二手交易平台系统设计与实现 二手交易系统 交易平台小程序

🔥作者:it毕设实战小研🔥 💖简介:java、微信小程序、安卓;定制开发,远程调试 代码讲解,文档指导,ppt制作💖 精彩专栏推荐订阅:在下方专栏&#x1…

Nginx 服务器常用操作

一. Nginx 常用配置 1. Nginx 总配置文件 nginx 安装目录下的 nginx.conf 文件: # 指定 Nginx worker 进程运行的系统用户 user nginx; # 自动根据 CPU 核心数启动相应数量的 worker 进程,充分利用多核。 worker_processes auto; # 自动将 worker 进程绑定到特定 …

PHP官方及第三方下载地址全指南(2025最新版)

PHP官方及第三方下载地址全指南(2025最新版) 本文整理了PHP官方及主流第三方下载渠道,包含PHP 5.5至8.4各版本的直接下载链接,助您快速获取安全可靠的PHP环境。 一、PHP官方下载渠道 1.1 全球主站下载 网址:https://…

深度剖析Redisson分布式锁项目实战

今天在练手项目中也是遇到了许多新的技术,其中我认为最深刻的还是Redisson分布式锁,这里我就结合一下我项目中用到Redisson分布式锁的代码来讲述一下Redisson分布式锁,希望可以帮助大家更深刻地理解这项技术。在之前的文章中我已经讲过Rediss…

第四天-创建一个Classic CAN(经典CAN2.0)/CANFD的系统描述ARXML文件

【ARXML专题】-构建CAN/CANFD通信系统:ARXML实战指南 汽车神经系统的"高速公路" 想象一辆现代汽车如同人体,电子控制单元(ECU)是器官,而CAN总线就是连接它们的神经系统。在自动驾驶时代,传统CAN2.0的"乡间小路"已无法满足数据传输需求,CANFD的"…

用架构建模工具Sparx EA绘制企业转型路线图

企业数字化转型面临诸多挑战:信息壁垒导致各部门协同困难,资源投入缺乏科学评估,潜在风险难以提前预判。这些问题不仅拖慢转型进程,还可能引发高昂的试错成本。 本文将阐述如何运用架构建模工具Sparx EA的核心功能——可视化路线…

STM32——GPIO

总 :STM32——学习总纲 参考资料: STM32F1系列参考手册-V10(中) 一、GPIO简介 1.1 GPIO 特点 1.2 GPIO 电气特性* stm32芯片资料STM32F103ZET6(English) 1.3 GPIO 引脚分布 电源引脚:V开头 晶振引脚: …

NUX MG-400 吉他效果器功能原理介绍

NUX MG-400 是一款多功能数字吉他效果器,它的核心原理就是把吉他的模拟信号,通过 A/D 转换变成数字信号 → 在 DSP 芯片上做建模运算 → 再通过 D/A 转换还原成模拟信号输出。 它的硬件 软件协作设计,基本可以拆成几个模块来看: …

Linux——进程管理和计划任务管理

文章目录前言一、程序与进程的关系1.1 程序与进程的定义1.2 父进程与子进程二、查看进程信息2.1 ps 命令(重点)2.2 动态查看进程信息top命令(重点)2.3 pgrep命令查询进程信息2.4 pstree命令以树形结构列出进程信息三、进程的启动方…

阿里云TranslateGeneral - 机器翻译SDK-自己封账单文件版本—仙盟创梦IDE

仙盟创梦IDE代码<?php /*** 阿里云机器翻译通用版API调用工具* 文档参考&#xff1a;https://help.aliyun.com/zh/machine-translation/developer-reference/api-alimt-2018-10-12-translategeneral*/ class AliyunTranslate {// 阿里云访问密钥private $accessKeyId;priva…

新字符设备驱动实验

经过前两章实验的实战操作&#xff0c;我们已经掌握了 Linux 字符设备驱动开发的基本步骤&#xff0c;字符 设备驱动开发重点是使用 register_chrdev 函数注册字符设备&#xff0c;当不再使用设备的时候就使用 unregister_chrdev 函数注销字符设备&#xff0c;驱动模块加载成功…

【更新公告】C++算法·线段树

之前的线段树知识都忘了qwq 现在在重新学线段树 下一篇就是写线段树了&#xff0c;例题已经找好了 A了1遍&#xff0c;但是用的玄学代码ee 下面是更新公告 更新公告 更新模式改为2~3天1篇 但是绝对高质量&#xff01;&#xff01; (平均质量分93够吗qwq) 如果例题好找尽量给出2…

pyqtgraph 库 右键菜单栏插件汉化

第一步&#xff0c;打开pyqtgraph文件夹。 第二步&#xff1a;打开graphicsItems&#xff0c;将PlotItem和ViewBox中的.py文件中的英文替换为中文&#xff0c;运行软件即可看到插件右键的菜单栏成为中文。 第三步&#xff1a;GraphicsScene中的&#xff0c;等找到相应的右键菜单…

docker镜像解决的一些问题

1 概述Docker镜像技术通过创新性的设计&#xff0c;彻底解决了应用交付领域的核心痛点&#xff0c;已经成为已成为云原生时代的事实标准。其核心价值在于​​通过标准化封装实现"一次构建&#xff0c;处处运行"​​&#xff0c;从根本上改变了软件交付的生命周期。2 …

10.从开始写LINUX内核——时钟中断

Linux 0.12 内核时钟中断实现&#xff1a;从初始化到中断响应时钟中断是操作系统中最基础且最重要的中断之一&#xff0c;它为系统提供时间基准&#xff0c;支持进程调度、定时器等核心功能。本文将基于 Linux 0.12 内核的 setup 程序框架&#xff0c;详细介绍时钟中断的完整实…