偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我剛按下666,計算機發(fā)生了神奇的事情···

網(wǎng)絡(luò) 通信技術(shù)
計算機領(lǐng)域有一個經(jīng)典的問題:從你在瀏覽器中輸入URL并按下回車,到網(wǎng)頁渲染出來,這中間發(fā)生了什么?

 [[394490]]

計算機領(lǐng)域有一個經(jīng)典的問題:從你在瀏覽器中輸入URL并按下回車,到網(wǎng)頁渲染出來,這中間發(fā)生了什么?

通過這個問題,可以考察候選人對計算機網(wǎng)絡(luò)的理解程度,因此出現(xiàn)在數(shù)不清的面試場合。

毋庸置疑,這是一個好問題,我也看到不下100篇文章在探討這個問題的答案。

而今天,我想跟大家探討的是另外一個問題:從你在鍵盤上按下一個“6”,到屏幕上顯示出來,計算機發(fā)生了什么?

這個問題無論從空間尺度還是時間尺度比起開始那個問題都更小得多。

空間尺度上,這個問題探討的范圍只限于一臺計算機上,沒有跨越網(wǎng)絡(luò)。

時間尺度上,第一個問題的時間尺度在秒級別,而這個問題的時間尺度在毫秒級別。

尺度雖然小了但背后的技術(shù)知識并不少。

我相信,等你看完這篇文章,搞清楚這個問題的答案,你將對計算機組成原理、操作系統(tǒng)、CPU這些東西有完全不一樣的理解。

準備好,咱們出發(fā)!

0x01: 按下按鍵,鍵盤做了什么

早期的計算機,大部分都是PS2的接口,就是這玩意:

但這種接口插起來不方便,也不通用,近些年USB接口鍵盤越來越多了,所以咱們就以USB鍵盤為研究對象。

當你按下鍵盤按鍵的瞬間,這個按鍵位置下的電路“開關(guān)”將會被接通,而這樣的開關(guān)每一個按鍵下面都有,它們共同組成了一個矩陣:

全局矩陣就是這個樣子的:

如果你拆開鍵盤看過,你會發(fā)現(xiàn)在鍵盤的內(nèi)部有類似下面這樣的一個芯片,它負責周期性的掃描電路,檢測哪些位置的按鍵被按下。

當它檢測到按鍵按下事件,將拿到對應(yīng)鍵位的鍵盤掃描碼(注意按下和彈起對應(yīng)不同的掃描碼),然后通過USB接口的通信協(xié)議,封裝一個按鍵消息傳遞出去。在這個消息中,包含了你按下/彈起鍵位的掃描碼,如果有多個按鍵,消息中就會有多個掃描碼。

鍵盤USB連接頭連接到了計算機主板上的USB接口,USB接口背后是主板上的USB總線系統(tǒng),于是這個按鍵消息順著鍵盤的連線,穿過USB接口來到了USB總線上。

而USB總線上,連接了USB控制器芯片,是它在與USB設(shè)備進行“通話”。

0x02: 高級可編程中斷控制器APIC

USB控制器拿到了按鍵消息后,并不能直接提交給CPU,還要通過另外一個管事兒的投遞這個消息,這個管事兒的就是中斷控制器。

提到中斷控制器,你可能在很多地方看到過一個叫8259A的芯片:

然后會告訴你鍵盤通過IRQ1的中斷輸入源連接進去:

但現(xiàn)在請忘記它,這玩意已經(jīng)是上個世紀作古的產(chǎn)物,我保證你拆開你的計算機,一定找不到它。

究其原因,還是因為CPU多核技術(shù)的興起,8259A這個東西早已滿足不了時代的需要,換了另外一個更高級的中斷控制器,APIC。

沒錯,它的名字就是這么簡單直接:高級可編程中斷控制器。

這個更高級的管事兒的到底哪里高級呢?

首先,它不是一塊芯片,而是分了兩部分:Local APIC和I/O APIC。

Local APIC像是外包團隊一樣,入駐到了CPU的每個核心,負責中斷每個核。

I/O APIC則獨立在CPU外面,接收所有I/O設(shè)備的中斷源。

來看一個早期的IOAPIC芯片:82093AA

就是它代替了傳統(tǒng)的8259A的PIC來總管主板上這些外設(shè)的中斷信號,這家伙的管腳圖長這樣:

你可以數(shù)一下,負責中斷源的輸入引腳有INTIN0-INTIN23,總共24個,比傳統(tǒng)的兩塊8259A的芯片級聯(lián)起來的數(shù)量還要多。

如果你拆開你的電腦主板,我保證你依然看不到這個叫IOAPIC的芯片。因為這個家伙現(xiàn)在已經(jīng)被集成到了南橋之中了。

啥?南橋是啥?接下來需要補充一點計算機主板的知識了。

0x03: 計算機主板結(jié)構(gòu)

在傳統(tǒng)計算機主板上,分為了CPU+北橋+南橋的經(jīng)典架構(gòu):

北橋和南橋是主板上除CPU外最重要的2個芯片,所謂南北,是因為在畫圖位置上,上北下南,因而得名。

北橋聯(lián)通著CPU,負責連接內(nèi)存、顯卡等高速設(shè)備。

南橋聯(lián)通著北橋,負責連接網(wǎng)卡、硬盤、鍵盤、鼠標這些低速設(shè)備。

你可以這樣理解:CPU是整個主板上的大明星,主板上其他所有設(shè)備都要圍繞它來轉(zhuǎn),這明星有兩個經(jīng)紀人,一個負責對接速度快的,一個負責對接速度慢的。

從Intel的酷睿處理器開始(2008年),將北橋芯片的功能集成到了CPU之中,從此主板上就只剩一個南橋了,于是也沒有南北之分了,甚至改頭換面,換了個名字:PCH。

這個叫PCH的家伙可不簡單,它現(xiàn)在要對接CPU,還要對接PCI總線、ISA總線上的一堆設(shè)備。

我們的鍵盤連接到的是USB總線,也是對接到這個PCH芯片。

通過cpu-z工具,可以看到自己電腦主板上的PCH芯片型號:

如上圖所示,我的這臺電腦是B360芯片,你可以在Intel的官網(wǎng)查詢到它的詳細資料。

那這玩意兒在電腦主板哪個位置呢:

拿掉上面的散熱片,這家伙長這樣,其貌不揚:

在這個小小的芯片里,就集成有負責跟USB設(shè)備進行通信的USB控制器,還有前面說的負責中斷CPU的高級可編程中斷控制器IOAPIC,這兩個家伙在今天討論的問題中扮演了關(guān)鍵角色。

USB控制器負責與USB設(shè)備通信,它將拿到USB鍵盤傳輸過來的那個按鍵消息包。

0x04: 中斷信號的投遞

現(xiàn)在USB控制器和APIC已經(jīng)都集成到了PCH中,內(nèi)部的結(jié)構(gòu)不得而知,但總體來說,USB控制器拿到按鍵消息后,然后通過IOAPIC的中斷源輸入管腳發(fā)起通知:老哥,我這有情況,快幫我通知CPU老大。

在IOAPIC的內(nèi)部,有一個表格PRT,記錄了中斷分發(fā)的配置信息,24個中斷源就有24個表項(其實還有一部分保留的)。表格中的每一項叫RTE,每項占據(jù)64bit。

來自USB控制器的電信號輸入到IOAPIC之后,IOAPIC會根據(jù)事先編程配置的信息,通過對應(yīng)的表項RTE格式化出一條中斷消息,然后通過總線系統(tǒng)發(fā)出去。

在早期,IOAPIC和CPU內(nèi)部的Local APIC之間有專屬的APIC總線來聯(lián)系,但從奔騰4開始就取消了,使用公共的總線系統(tǒng)來傳遞中斷消息。

消息發(fā)出去后,誰來接收呢?

在這個中斷消息中,填寫有收件人:Local APIC的標識號。

總線系統(tǒng)上的信號通過CPU的針腳傳輸?shù)搅薈PU內(nèi)部,內(nèi)部所有核的Local APIC都能收到這個中斷消息,但只有一個核的Local APIC檢測后發(fā)現(xiàn)收件人是自己,其他人都會忽略這條消息。

發(fā)現(xiàn)收件人是自己的那個Local APIC,開始通知自己所在的這個核有中斷請求來了。

CPU的核心一直在不停的執(zhí)行指令,在每個指令周期的最后,都會去檢查一下是不是有中斷請求過來,在執(zhí)行完手頭這條指令后,它發(fā)現(xiàn)了Local APIC提交的中斷請求。

接下來,就是CPU開始來處理這個中斷消息的時候了。

0x05: 中斷處理

第一個動作,保存執(zhí)行上下文。

所謂中斷,從字面來講就是中途打斷的意思,就好比你正在寫著代碼,突然有產(chǎn)品來找你增加需求,你被打斷了。人倒還好,咱們有記憶能力,跟產(chǎn)品溝通完成后,還能回去接著原來的地方繼續(xù)寫代碼。但機器沒有記憶思維,在打斷去干別的事情之前,必須把原來做的事情保存起來,這樣一會兒才能回來繼續(xù)做剩下的事。

這個保存的過程,就叫執(zhí)行上下文保存。那保存在哪里呢?

答案就是線程的棧。

但是要注意,這里的棧,不是咱們平時看到的那個線程棧,而是另外一個位于內(nèi)核地址空間的棧。

不管是Windows還是Linux,基本上每個線程在執(zhí)行的時候都有兩個棧,一個用于我們編寫的應(yīng)用程序在用戶態(tài)模式下執(zhí)行代碼時使用,叫用戶棧,另一個用于程序因為系統(tǒng)調(diào)用、異常、中斷等情況進入內(nèi)核模式下執(zhí)行的時候使用,叫內(nèi)核棧,相比用戶棧,內(nèi)核棧的空間要小得多。

注意:也不是每個線程都有兩個棧,有一些操作系統(tǒng)的純內(nèi)核線程就只有內(nèi)核棧,沒有用戶棧。

發(fā)生中斷時,CPU將自動將當前執(zhí)行的上下文保存在內(nèi)核棧的頂部,所謂上下文,其實就是一堆寄存器的值。注意這個動作不是操作系統(tǒng)軟件完成的,而是CPU內(nèi)部的硬件電路自動完成。

第二個動作,執(zhí)行中斷處理函數(shù)

保存完上下文,接著就要去處理中斷了。怎么處理,那就是操作系統(tǒng)的工作了。

CPU的每一個核,都有一個中斷描述符表IDT,位于內(nèi)存之中,這個表有256項,每一個表項都記錄了一個處理函數(shù)的地址。每個核的內(nèi)部還有一個叫IDTR的寄存器,指向了這個表。

要注意,IDT雖然是叫做中斷描述符表,但里面的256項內(nèi)容卻不全是用來記錄中斷處理函數(shù)的,還有異常、陷阱(軟中斷)、任務(wù)這些。

表格中的處理函數(shù)地址,是操作系統(tǒng)在啟動之初就安排好了,這其中就有我們的鍵盤中斷處理函數(shù)。

當中斷發(fā)生時,CPU將根據(jù)中斷向量號,從IDTR寄存器指向的表格中,取出索引是向量號的那一個表項,跳轉(zhuǎn)到里面記錄的函數(shù)地址,開始執(zhí)行代碼,這個過程依然是CPU的硬件電路完成的。

那這個中斷向量號從哪兒來的呢?

答案是在IOAPIC發(fā)來的那條消息中,除了收件人Local APIC的標識,還有處理中斷所需要的中斷向量號。

再往前追溯,這個中斷向量號其實是配置在前面說的IOAPIC內(nèi)部的那個叫PRT的表格中的,操作系統(tǒng)啟動之初一項重要的工作就是對APIC進行編程(所謂編程其實就是寫他們內(nèi)部的這些配置表,也叫寄存器),設(shè)定好每一個中斷源對應(yīng)的中斷向量號是多少,這樣24個中斷源與對應(yīng)的中斷向量號之間的映射關(guān)系就被確立起來了。

除了給中斷源分配向量號,操作系統(tǒng)還有一項工作就是指定哪些核來處理哪些中斷。我之前寫過一篇趣文故事就是講的這部分知識:CPU明明8個核,網(wǎng)卡為啥拼命折騰一號核?

接下來就是操作系統(tǒng)(準確來說是操作系統(tǒng)中的設(shè)備驅(qū)動程序)開始來處理這個中斷消息了。

具體的驅(qū)動處理部分就不詳述了,不同版本的系統(tǒng)處理略有不同,在微軟的官網(wǎng)上,可以找到這么一張圖,針對USB輸入設(shè)備(鍵盤、鼠標)的驅(qū)動處理棧結(jié)構(gòu)圖:

總體來說,Windows操作系統(tǒng)介入中斷處理后,經(jīng)過一系列驅(qū)動程序(USB、HID等)的處理后,進行掃描碼的轉(zhuǎn)換,然后把按鍵的消息最終投遞到了一個叫Win32k.sys的家伙那里。

0x06: 操作系統(tǒng)介入

讓我們把視線從硬件部分轉(zhuǎn)移到操作系統(tǒng)上來。Windows是一個基于視窗的圖形化的操作系統(tǒng),絕大部分程序都是基于消息驅(qū)動。這一點,做過Windows客戶端開發(fā)的朋友應(yīng)該不會陌生。

Windows上有圖形窗口的程序形態(tài)各異,功能千差萬別,但它們都有一個共同之處:基于消息驅(qū)動。

這些消息可能來自于鍵盤、鼠標、其他進程甚至網(wǎng)絡(luò),一個典型的Windows程序,其主線程一定有一個下面的消息循環(huán):

  1. while(GetMessage()) { 
  2.   TranslateMessage(); 
  3.   DispatchMessage(); 

主線程不斷調(diào)用GetMessage() 獲取消息,然后分發(fā)處理,如果沒有消息,GetMessage將會阻塞。

這個GetMessage()是從哪里獲取消息呢?

答案是消息隊列。

每一個具有圖形可視化窗口的程序都有一個消息隊列,維護在內(nèi)核空間,GetMessage()就是從這里源源不斷的取出消息來處理。你的每一次鍵盤按鍵,每一次鼠標點擊,每一次鼠標移動,都會產(chǎn)生消息被投放到這個隊列中,等待取出處理。

那么問題又來了,你在鍵盤按下后產(chǎn)生的消息,是被誰投遞到了這里呢?還有,每一個窗口程序都有消息隊列,那我按下的鍵盤消息,到底該被投遞給誰呢?

答案正是在前面說的那個叫Win32k.sys的家伙之中!這是Windows內(nèi)核實現(xiàn)圖形用戶界面一個重要的模塊,里面有一個內(nèi)核線程在專門負責干這事——不斷從鍵盤驅(qū)動獲取按鍵事件,然后封裝成消息,再結(jié)合當前桌面激活的窗口,定位到對應(yīng)的消息隊列,把這個消息給投遞過去。

于是,應(yīng)用程序的消息循環(huán)中,GetMessage()函數(shù)將會拿到一個代表鍵盤按鍵被按下的WM_KEYDOWN消息。

再回過頭去看下那個消息循環(huán),拿到消息后會有一個“轉(zhuǎn)換動作”:TranslateMessage()。這個函數(shù)將對按鍵消息進行一次翻譯,翻譯成一個WM_CHAR消息,表示有字符輸入消息來了,這個消息的一個字段會標識輸入的是6這個字符。

最終,應(yīng)用程序終于收到了一個參數(shù)是6的WM_CHAR消息,知道用戶按了一個6,接下來就是在顯示器上把它給顯示出來了。

總結(jié)

文章有點長,現(xiàn)在來總結(jié)梳理下,按下鍵盤上的6以后,計算機到底發(fā)生了什么。

本文轉(zhuǎn)載自微信公眾號「編程技術(shù)宇宙」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系編程技術(shù)宇宙公眾號。

 

責任編輯:武曉燕 來源: 編程技術(shù)宇宙
相關(guān)推薦

2021-02-25 10:02:32

開機鍵Linux內(nèi)存

2020-09-01 11:40:01

HTTPJavaTCP

2023-08-29 16:26:20

Linux命令行

2020-10-09 08:59:55

輸入網(wǎng)址解密

2011-03-31 09:20:45

URLDNSWeb應(yīng)用程序

2023-09-29 11:44:54

2011-10-17 09:50:38

編程

2020-02-14 14:05:10

刪庫跑路發(fā)生

2021-04-14 10:47:56

瀏覽器網(wǎng)址TCP

2020-10-11 20:46:41

計算機人工智能技術(shù)

2020-04-17 11:06:49

IO設(shè)備

2014-01-08 09:35:54

計算機學習

2018-01-12 15:32:55

大數(shù)據(jù)DBA數(shù)據(jù)庫管理員

2021-11-23 10:15:57

Linux代碼匿名頁

2021-08-26 05:52:44

AI算法人工智能

2013-02-25 11:40:04

云計算大數(shù)據(jù)阿里云

2021-08-18 10:30:10

GitHub程序員論文

2010-08-30 11:12:42

2020-07-09 13:49:21

Python開發(fā)技術(shù)

2012-04-11 20:07:45

ASG云計算CloudFactor
點贊
收藏

51CTO技術(shù)棧公眾號