9.從零開始寫LINUX內核——設置中斷描述符表

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;詳細介紹時鐘中斷的完整實…