操作系統 4.2-鍵盤

鍵盤中斷初始化和處理

提取的代碼如下:

// con_init 函數,初始化控制臺(包括鍵盤)的中斷
void con_init(void) {set_trap_gate(0x21, &keyboard_interrupt);
}
?
// 鍵盤中斷處理函數
.globl _keyboard_interrupt
_keyboard_interrupt:inb $0x60, %al // 從端口0x60讀掃描碼call key_table(%eax, 4) // 調用key_table+eax*4push $0call _do_tty_interrupt

總結:

這段代碼描述了鍵盤中斷初始化和處理的過程:

  1. 鍵盤中斷初始化 (con_init 函數):

    • con_init 函數設置鍵盤中斷門(trap gate),將鍵盤中斷處理函數 keyboard_interrupt 地址加載到中斷向量 0x21

    • 這個函數是控制臺(包括鍵盤)初始化的一部分,確保鍵盤輸入能夠觸發中斷。

  2. 鍵盤中斷處理 (_keyboard_interrupt 函數):

    • 當鍵盤被敲擊時,產生中斷信號。

    • 中斷處理函數 _keyboard_interrupt 被調用,從端口 0x60 讀取鍵盤掃描碼。

    • 調用 key_table 函數處理掃描碼,key_table 是一個查找表,用于將掃描碼轉換為字符。

    • 0 壓棧,然后調用 _do_tty_interrupt 函數進一步處理字符輸出。

當用戶敲擊鍵盤時,觸發中斷,操作系統捕獲中斷并調用相應的中斷處理函數來讀取和處理鍵盤輸入。這是實現鍵盤輸入功能的關鍵步驟。

處理鍵盤輸入的掃描碼

提取的代碼如下:

// 在 kernel/chr_drv/keyboard.s 中定義的 key_table
key_table:.long none, do_self, do_self, do_self // 掃描碼00-03.long do_self, ..., func, scroll, cursor 等等
?
// do_self 函數
do_self:lea alt_map, %ebxtestb $0x20, mode // alt鍵是否同時按下jne 1flea shift_map, %ebxtestb $0x03, modejne 1flea key_map, %ebx
1:

總結:

這段代碼展示了 Linux 內核如何處理鍵盤輸入的掃描碼,并將它們轉換為字符輸出。具體來說:

  1. 定義 key_table 函數數組

    • key_table 是一個函數數組,用于處理不同的鍵盤掃描碼。每個條目對應一個掃描碼的處理函數。

  2. 處理掃描碼

    • 掃描碼 02 對應按鍵 101 對應 ESC12 對應 E 等。

  3. 處理函數 do_self

    • do_self 函數用于處理特定的掃描碼。

    • 它首先加載 alt_mapebx 寄存器。

    • 檢查 mode 寄存器,確定 alt 鍵是否被按下。

    • 如果 alt 鍵被按下,它加載 shift_mapebx 寄存器。

    • 否則,它加載 key_mapebx 寄存器。

    • key_mapshift_mapalt_map 是映射表,用于將掃描碼轉換為相應的字符。

  4. 映射表

    • 映射表(如 key_map)用于將掃描碼轉換為字符。例如,akey_map 映射為 a,而 shift_map 映射為 A

這個過程展示了如何通過映射表和條件邏輯將鍵盤掃描碼轉換為字符,并將它們輸出到屏幕上。這是鍵盤輸入處理的核心部分,它確保了用戶輸入能夠被正確識別和顯示。

key_map 中取出對應的 ASCII 碼

提取的代碼如下:

#if defined(KBD_US)
key_map: .byte 0,27 .ascii "1234567890-="
shift_map: .byte 0,27 .ascii "!@#$%^&*()_+"
#elif defined(KBD_GR)...
#endif
?
# 繼續do_self,從1f開始,ebx放的是map起始地址
1: movb (%ebx, %eax), %al // 掃描碼索引,ASCII碼->alorb %al, %al ? ? je none  // 沒有對應的ASCII碼testb $0x4c, mode  // 看caps是否亮je 2f ?cmpb $'a, %al  jb 2fcmpb $'}, %al ? ja 2f  subb $32, %al // 變大寫
2: testb $??, mode  // 處理其他模式,如ctrl同時按下
3: andl $0xff, %eax call put_queue
none: ret

總結:

這段代碼展示了如何從 key_map 中取出對應的 ASCII 碼,并根據鍵盤的模式(如大寫鎖定 Caps LockShift 鍵)進行相應的處理。以下是詳細步驟:

  1. 定義鍵盤映射表

    • key_mapshift_map 是兩個映射表,分別用于處理未按下 Shift 鍵和按下 Shift 鍵時的鍵盤輸入。

    • 這些映射表將鍵盤掃描碼轉換為 ASCII 碼。

  2. key_map 中取出 ASCII 碼

    • 根據掃描碼索引從 key_map 中取出對應的 ASCII 碼。

    • 如果沒有找到對應的 ASCII 碼,則跳轉到 none 標簽。

  3. 處理大寫鎖定

    • 檢查 Caps Lock 模式是否激活(testb $0x4c, mode)。

    • 如果激活,將小寫字母轉換為大寫字母(cmpb $'a, %alsubb $32, %al)。

  4. 處理其他模式

    • 檢查是否有其他模式激活,如 Ctrl 鍵同時按下(testb $??, mode)。

    • 根據需要處理這些模式。

  5. 將字符放入隊列

    • 將處理后的 ASCII 碼放入輸出隊列(put_queue)。

  6. 返回

    • 如果沒有找到對應的 ASCII 碼,則返回(none: ret)。

處理鍵盤輸入并將字符放入隊列中

提取的代碼如下:

// put_queue 函數
put_queue:movl _table_list, %edxmovl head(%edx), %ecx
1:movb %al, buf(%edx, %ecx)...
// do_tty_interrupt 函數
void do_tty_interrupt(int tty) {copy_to_cooked(tty_table + tty);
}
?
// copy_to_cooked 函數
void copy_to_cooked(struct tty_struct *tty) {GETCH(tty->read_q, c);if (L_ECHO(tty)) { // 回顯,也可以不回顯PUTCH(c, tty->write_q);tty->write(tty); } // 立刻顯示到屏幕上PUTCH(c, tty->secondary); // 完成copy_to_cooked... wake_up(&tty->secondary.proc_list);
}

總結:

這段代碼描述了 Linux 內核如何處理鍵盤輸入并將字符放入隊列中的過程:

  1. put_queue 函數

    • 該函數負責將字符放入 con.read_q 隊列中。

    • 它首先將 _table_list 地址加載到 edx 寄存器,然后獲取 head 指針到 ecx 寄存器。

    • 接著,它從緩沖區 buf 中取出字符并放入隊列中。

  2. do_tty_interrupt 函數

    • 該函數處理鍵盤中斷,調用 copy_to_cooked 函數來處理鍵盤輸入。

  3. copy_to_cooked 函數

    • 該函數從 tty->read_q 隊列中獲取字符。

    • 如果 L_ECHO 標志被設置(表示回顯),則將字符放入 tty->write_q 隊列中。

    • 然后調用 tty->write(tty) 函數將字符立刻顯示到屏幕上。

    • 將字符放入 tty->secondary 隊列中,完成 copy_to_cooked 操作。

    • 最后,喚醒等待在 tty->secondary.proc_list 隊列中的進程。

這個過程展示了如何將鍵盤輸入的字符處理并放入隊列中,以便后續顯示在屏幕上

鍵盤處理的步驟總結

  1. 中斷初始化

    • 鍵盤作為控制臺(console)的一部分,其中斷通過 con_init 函數進行初始化,設置中斷門(trap gate)以響應鍵盤事件。

  2. 中斷處理

    • 當用戶敲擊鍵盤時,產生中斷信號,操作系統通過中斷處理程序 keyboard_interrupt 來響應這個中斷。

    • 中斷處理程序從鍵盤的端口(通常是 0x60)讀取掃描碼。

  3. 掃描碼轉換

    • 根據讀取到的掃描碼,調用 key_table 函數數組來查找對應的處理函數或映射表。

    • 掃描碼對應鍵盤上的不同按鍵,如 02 對應數字鍵 101 對應 ESC 鍵等。

  4. 字符映射

    • 對于顯示字符,使用 key_map 映射表將掃描碼轉換為 ASCII 碼。

    • 如果按下 ShiftAlt 等修飾鍵,可能會使用 shift_mapalt_map 來獲取大寫字母或特殊字符。

  5. 隊列處理

    • 將轉換得到的 ASCII 碼放入 write_q 隊列中,等待顯示設備(如顯示器)來讀取并顯示。

    • 如果設置了回顯(L_ECHO),則同時將字符放入 read_q 隊列中,以便用戶可以看到自己輸入了什么。

  6. 顯示字符

    • con_write 函數負責從 write_q 隊列中取出字符并通過顯示器驅動程序 tty_write 輸出到屏幕上。

  7. 緩沖和回顯

    • copy_to_cooked 函數處理 read_q 隊列中的字符,可能包括回顯邏輯,即將字符回顯到屏幕上。

到顯示器和鍵盤的交互

這張圖展示了Linux內核中字符設備(特別是TTY設備)的讀寫流程。以下是流程的總結:

寫流程(從上到下):

  1. 系統調用 (write) :應用程序通過系統調用 write 向內核請求寫操作。

  2. 字符設備接口 (crw_table[]) :系統調用被路由到字符設備接口,具體到 char_dev.c 文件中的相關函數。

  3. TTY設備寫 (tty_write) :字符設備接口調用 tty_write 函數,該函數位于 tty_io.c 文件中。

  4. write_q隊列:寫操作的數據被放入 write_q 隊列中。

  5. 顯示器寫 (con_write) :數據從 write_q 隊列被取出并通過 con_write 函數寫入顯示器,該函數位于 console.c 文件中。

  6. 顯示器:最終數據被顯示在顯示器上。

讀流程(從下到上):

  1. 主機鍵盤:用戶通過鍵盤輸入數據。

  2. keyboard.S:鍵盤輸入的數據被處理并放入 read_q 隊列中。

  3. read_q隊列:鍵盤輸入的數據存儲在 read_q 隊列中。

  4. TTY設備讀 (tty_read) :應用程序通過系統調用 read 請求讀操作,該請求被路由到 tty_read 函數,該函數位于 tty_io.c 文件中。

  5. 字符設備接口 (crw_table[])tty_read 函數通過字符設備接口返回數據給應用程序。

  6. 系統調用 (read) :最終數據被返回給應用程序。

回顯流程:

  1. 回顯:鍵盤輸入的數據不僅被放入 read_q 隊列,還會被回顯到 write_q 隊列中。

  2. 顯示器寫 (con_write) :回顯的數據通過 con_write 函數寫入顯示器,顯示用戶輸入的內容。

總結:

  • 寫操作:從應用程序的 write 系統調用開始,經過字符設備接口、TTY設備寫、寫隊列,最終寫入顯示器。

  • 讀操作:從鍵盤輸入開始,經過鍵盤處理、讀隊列、TTY設備讀、字符設備接口,最終返回給應用程序的 read 系統調用。

  • 回顯:鍵盤輸入的數據會被同時寫入讀隊列和寫隊列,實現輸入內容的即時顯示。

這個流程展示了Linux內核中字符設備(特別是TTY設備)的讀寫機制,確保了數據的正確傳輸和顯示。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/77609.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/77609.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/77609.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入理解Softmax函數及其在PyTorch中的實現

Softmax函數簡介 Softmax函數在機器學習和深度學習中,被廣泛用于多分類問題的輸出層。它將一個實數向量轉換為概率分布,使得每個元素介于0和1之間,且所有元素之和為1。 Softmax函數的定義 給定一個長度為 K K K的輸入向量 z [ z 1 , z 2 …

Vue 3 響應式更新問題解析

在 Vue 3 中,即使使用 reactive 或 ref 創建的響應式數據,當數據量很大時也可能出現更新不及時的情況。以下是原因和解決方案: 核心原因 ??響應式系統優化機制??: Vue 3 使用 Proxy 實現響應式,比 Vue 2 更高效但為…

異形遮罩之QML中的 `OpacityMask` 實戰

文章目錄 🌧? 傳統實現的問題👉 效果圖 🌈 使用 OpacityMask 的理想方案👉代碼如下🎯 最終效果: ? 延伸應用🧠 總結 在 UI 設計中,經常希望實現一些“異形區域”擁有統一透明度或顏…

數據可視化 —— 堆形圖應用(大全)

一、案例一:溫度堆積圖 # 導入 matplotlib 庫中的 pyplot 模塊,這個模塊提供了類似于 MATLAB 的繪圖接口, # 方便我們創建各種類型的可視化圖表,比如折線圖、柱狀圖、散點圖等 import matplotlib.pyplot as plt # 導入 numpy 庫&…

python工程中的包管理(requirements.txt)

pip install -r requirements.txtpython工程通過requirements.txt來管理依賴庫版本,上述命令,可以一把安裝依賴庫,類似java中maven的pom.xml文件。 參考 [](

操作系統 3.4-段頁結合的實際內存管理

段與頁結合的初步思路 虛擬內存的引入: 為了結合段和頁的優勢,操作系統引入了虛擬內存的概念。虛擬內存是一段地址空間,它映射到物理內存上,但對用戶程序是透明的。 段到虛擬內存的映射: 用戶程序中的段首先映射到虛…

【Amazon EC2】為何基于瀏覽器的EC2 Instance Connect 客戶端連接不上EC2實例

文章目錄 前言📖一、報錯先知?二、問題復現😯三、解決辦法🎲四、驗證結果👍五、參考鏈接🔗 前言📖 這篇文章將講述我在 Amazon EC2 上使用 RHEL9 AMI 時無法連接到 EC2 實例時所遇到的麻煩😖 …

Python學習筆記(二)(字符串)

文章目錄 編寫簡單的程序一、標識符 (Identifiers)及關鍵字命名規則:命名慣例:關鍵字 二、變量與賦值 (Variables & Assignment)變量定義:多重賦值:變量交換:(很方便喲) 三、輸入與輸出 (In…

Hydra Columnar:一個開源的PostgreSQL列式存儲引擎

Hydra Columnar 是一個 PostgreSQL 列式存儲插件,專為分析型(OLAP)工作負載設計,旨在提升大規模分析查詢和批量更新的效率。 Hydra Columnar 以擴展插件的方式提供,主要特點包括: 采用列式存儲&#xff0c…

es的告警信息

Elasticsearch(ES)是一個開源的分布式搜索和分析引擎,在運行過程中可能會產生多種告警信息,以提示用戶系統中存在的潛在問題或異常情況。以下是一些常見的 ES 告警信息及其含義和處理方法: 集群健康狀態告警 信息示例…

健康與好身體筆記

文章目錄 保證睡眠飯后百步走,活到九十九補充鈣質一副好腸胃肚子咕咕叫 健康和工作的取舍 以前對健康沒概念,但是隨著年齡增長,健康問題凸顯出來。 持續維護該文檔,健康是個永恒的話題。 保證睡眠 一是心態要好,沾枕…

vue實現在線進制轉換

vue實現在線進制轉換 主要功能包括: 1.支持2-36進制之間的轉換。 2.支持整數和浮點數的轉換。 3.輸入驗證(雖然可能存在不嚴格的情況)。 4.錯誤提示。 5.結果展示,包括大寫字母。 6.用戶友好的界面,包括下拉菜單、輸…

智體知識庫:poplang編程語言是什么?

問:poplang語言是什么 Poplang 語言簡介 Poplang(OPCode-Oriented Programming Language)是一種面向操作碼(Opcode)的輕量級編程語言,主要用于智體(Agent)系統中的自動化任務處理、…

二分查找5:852. 山脈數組的峰頂索引

鏈接:852. 山脈數組的峰頂索引 - 力扣(LeetCode) 題解: 事實證明,二分查找不局限于有序數組,非有序的數組也同樣適用 二分查找主要思想在于二段性,即將數組分為兩段。本體就可以將數組分為ar…

下列軟件包有未滿足的依賴關系: python3-catkin-pkg : 沖突: catkin 但是 0.8.10-

下列軟件包有未滿足的依賴關系: python3-catkin-pkg : 沖突: catkin 但是 0.8.10- 解決: 1. 確認當前的包狀態 首先,運行以下命令來查看當前安裝的catkin和python3-catkin-pkg版本,以及它們之間的依賴關系: dpkg -l | grep ca…

深度學習:AI 大模型時代的智能引擎

當 Deepspeek 以逼真到難辨真假的語音合成和視頻生成技術橫空出世,瞬間引發了全球對 AI 倫理與技術邊界的激烈討論。從偽造名人演講、制造虛假新聞,到影視行業的特效革新,這項技術以驚人的速度滲透進大眾視野。但在 Deepspeek 強大功能的背后…

醫學分割新標桿!雙路徑PGM-UNet:CNN+Mamba實現病灶毫厘級捕捉

一、引言:醫學圖像分割的挑戰與機遇 醫學圖像分割是輔助疾病診斷和治療規劃的關鍵技術,但傳統方法常受限于復雜病理特征和微小結構。現有深度學習模型(如CNN和Transformer)雖各有優勢,但CNN難以建模長距離依賴&…

CV - 目標檢測

物體檢測 目標檢測和圖片分類的區別: 圖像分類(Image Classification) 目的:圖像分類的目的是識別出圖像中主要物體的類別。它試圖回答“圖像是什么?”的問題。 輸出:通常輸出是一個標簽或一組概率值&am…

高并發秒殺系統設計:關鍵技術解析與典型陷阱規避

電商、在線票務等眾多互聯網業務場景中,高并發秒殺活動屢見不鮮。這類活動往往在短時間內會涌入海量的用戶請求,對系統架構的性能、穩定性和可用性提出了極高的挑戰。曾經,高并發秒殺架構設計讓許多開發者望而生畏,然而&#xff0…

藍橋杯--結束

沖刺題單 基礎 一、簡單模擬(循環數組日期進制) (一)日期模擬 知識點 1.把月份寫為數組,二月默認為28天。 2.寫一個判斷閏年的方法,然后循環年份的時候判斷并更新二月的天數 3.對于星期數的計算&#…