在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

圖文詳解Linux分段機(jī)制

程序員cxuan ? 來源:程序員cxuan ? 2023-05-08 16:24 ? 次閱讀

上一篇聊到分段機(jī)制是為了提供了隔絕代碼、數(shù)據(jù)和堆棧區(qū)域的機(jī)制,能夠使得多個程序運(yùn)行在同一個內(nèi)存空間中不會相互干擾,這是對內(nèi)存平坦模型的一種保護(hù)。內(nèi)存經(jīng)過分段機(jī)制后會變?yōu)橐粋€個的段,這稱為多段模型。多段模型能夠利用分段機(jī)制的功能提供由硬件增強(qiáng)代碼、數(shù)據(jù)結(jié)構(gòu)、程序和任務(wù)的保護(hù)措施。

現(xiàn)在我們知道了分段的目的是為了什么,但是我們好像還不知道什么是段,以及段有哪些特征。

段的定義

保護(hù)模式中的 80x86 架構(gòu)提供了 4GB 的物理地址空間。這是 CPU 在地址總線上可以尋址的地址空間。這段地址空間是一種平坦模型地址空間,地址范圍從 0 到 0xFFFFFFFF。

平坦模型:相對于多個段的模型來說,平坦模型指的就是一個段,比如在實(shí)模式下,處理器最大可尋址 64 KB(2 ^ 16)的地址空間,在保護(hù)模式下,處理器最大可尋址 4GB (2 ^ 32)的地址空間,如果訪問超過最大地址空間的數(shù)據(jù)指令,需要重新指定段。

需要注意下的是,段地址 + 偏移地址確實(shí)能尋址 1MB 的地址空間,但這卻不是平坦模型的訪問方式,而是多段模型。

再來啰嗦一下分段機(jī)制的目的:分段機(jī)制就是把虛擬地址空間中的虛擬內(nèi)存組織成一個個長度可變的段,這個段是虛擬地址到線性地址轉(zhuǎn)換的基礎(chǔ),一般來說,段由三部分組成:

段基址(Base address):段的初始地址,可以認(rèn)為是段的開始,段基址的段內(nèi)偏移為 0 。

段限長(limit):該段最大可用的偏移位置,它定義了段的長度,也是段內(nèi)偏移最大能夠?qū)ぶ返降奈恢谩?/p>

段屬性(Attributes):指的是該段的特性,比如段是否可讀、是否可寫、是否能夠作為程序執(zhí)行,段的特權(quán)級等。

段基址和段限長一起定義了段所映射的線性地址空間的范圍。段內(nèi)從 0 到 limit 地址范圍會對應(yīng)線性地址空間中的 base 到 base + limit ,偏移量是無法大于段限長的,如果偏移地址大于段限長會引發(fā)異常,除此之外,如果訪問的這個段沒有符合段屬性,也會引發(fā)異常。

不同的段可以映射到相同的線性地址空間,這種映射是操作系統(tǒng)所允許的。也就是說不同的段可以在線性地址空間中覆蓋或者完全重疊,如下圖所示

e8a85c58-ec2e-11ed-90ce-dac502259ad0.png

段基址、段限長和段屬性都存儲在段描述符這個結(jié)構(gòu)中,可以說段描述符就是能夠查找段重要信息的結(jié)構(gòu),在虛擬地址到線性地址的轉(zhuǎn)換過程中,就需要用到段描述符。那么段描述符被存儲在哪里呢?段描述符被存儲在段描述符表中,這個表就是一個數(shù)組,這個數(shù)組的下標(biāo)就是段選擇子,還記得我們上篇文章聊過段選擇子嗎?段選擇子中的 Index 是這么描述的:

e8c77f48-ec2e-11ed-90ce-dac502259ad0.pngimage-20230415223616884

為了把邏輯地址轉(zhuǎn)換成為線性地址,CPU 會執(zhí)行以下操作:

使用段選擇子中的 Index 屬性通過查詢 GDT/LDT 表定位相應(yīng)的段描述符。

利用段描述符檢驗(yàn)段的訪問權(quán)限和范圍,用于確保該段是可訪問并且偏移量位于段界限內(nèi)。

把段描述符中取得的段基地址加上 Index ,最后形成偏移地址。

e8da8ebc-ec2e-11ed-90ce-dac502259ad0.png

如果沒有開啟分頁機(jī)制,那么此時的線性地址就等同于物理地址;如果開啟分頁機(jī)制,那么此時的線性地址會經(jīng)過分頁機(jī)制轉(zhuǎn)換后才會把線性地址映射成為物理地址。

段選擇子

上篇文章提到了段選擇子,大致介紹了一下它的結(jié)構(gòu),并沒有細(xì)致說明,這篇文章就來細(xì)致說明一下。

段選擇子又稱段選擇符,它是一個 16 位的標(biāo)識符,如下圖所示,段選擇子并不指向段,它指向段描述符表中的段描述符。

e8f643dc-ec2e-11ed-90ce-dac502259ad0.png

段選擇子總共分為三個部分:

RPL(Request Privilege Level):請求特權(quán)級,表示進(jìn)程應(yīng)該以什么權(quán)限來訪問段,數(shù)值越大權(quán)限越小。

TI(Table Indicator):表示應(yīng)該查詢哪個表,TI = 0 查 GDT 表;TI = 1 查 LDT 表。

Index:CPU 會自動將 Index * 8,在加上 GDT 和 LDT 中的段基址,就是要加載的段描述符。

下面是幾幅段選擇子的示意圖,大家明白圖中所示也就明白段選擇子是如何表示的了。

e9030522-ec2e-11ed-90ce-dac502259ad0.png

需要注意的是,段選擇子 0x0008 和 段選擇子 0x000f 指向的是同一個段即段 1;段選擇子 0x0010 和 段選擇子 0x0017 也指向的是同一個段即段 2。段選擇子 0ffff 指向段 8191,而段選擇子 0x0000 指向的的是一個空段,因?yàn)?CPU 不使用 GDT 表中的第一項(xiàng),所以指向該段的選擇子用作空選擇子。當(dāng)把空選擇子加載到段寄存器(CS 和 SS 除外)中時,處理器不產(chǎn)生異常,但是當(dāng)含有空選擇子的段寄存器用于訪問內(nèi)存時,會產(chǎn)生異常。把空選擇子加載到 CS 和 SS 中也會產(chǎn)生異常。

段選擇子 a b c d 分別指向 linux 0.1x 中的內(nèi)核代碼段、內(nèi)核數(shù)據(jù)段、任務(wù)代碼段和任務(wù)數(shù)據(jù)段。

一般把段選擇子放在段寄存器中,每個寄存器支持特定類型的內(nèi)容引用,這部分引用可以是代碼、數(shù)據(jù)或者堆棧;每個程序都會把有效的段選擇子加載到 CS、SS 或者是 DS 中,另外,處理器還提供了另外三個段寄存器即 FS、GS、ES 作為輔助,這三個寄存器提供當(dāng)前 CPU 訪問段寄存器不夠時使用。

e9214f0a-ec2e-11ed-90ce-dac502259ad0.png

從上圖可以看到,每個段寄存器都由兩部分組成,一部分是段選擇子,一部分是 "段基址、段限長和段屬性信息",段選擇子是存在于段寄存器中顯示的部分,而段基址、段限長和段屬性是隱藏部分。

為什么會有隱藏部分呢?

隱藏部分也被稱為描述符緩沖或者是影子寄存器,當(dāng)一個段選擇子被加載到段寄存器中可見部分時,處理器也會同時把段基址等信息加載到段寄存器的隱藏部分,緩存在段寄存器中隱藏部分使得處理器在進(jìn)行地址轉(zhuǎn)換的時候不用再去段描述符中讀取段的相關(guān)信息。

段寄存器中的隱藏部分相當(dāng)于是段描述符的一個鏡像,或者說是拷貝。因此操作系統(tǒng)必須要確保對段描述符的改動反映在描述符緩沖中,如果更改了段描述符卻沒有在描述符緩沖中進(jìn)行修改,就會造成段不一致的現(xiàn)象。所以最快捷的方法就是在對描述附表做過改動之后就立刻重新加載 6 個段寄存器。這將會把描述附表中的相應(yīng)段信息加載到描述符緩沖中。

處理器提供了兩類加載指令用于加載段的相關(guān)信息:

一類是 MOV、POP、LDS、LES、LSS、LGS 以及 LFS 指令,這些指令顯示的直接引用段寄存器;

一類是隱式加載指令,例如 CALL、JMP 和 RET 指令、IRET、INTn、INTO 和 INT3 等指令。這些指令在操作過程中會附帶改變 CS 寄存器的內(nèi)容。

段描述符

段描述符是 GDT 和 LDT 表中的一個數(shù)據(jù)項(xiàng),用于向處理器提供有關(guān)一個段的位置和大小信息以及訪問控制的狀態(tài)信息。每個段描述符長度是 8 字節(jié),含有三個主要字段:段基址、段限長和段屬性,其他是一些細(xì)節(jié)字段。段描述符通常是由編譯器、鏈接器、加載器或者操作系統(tǒng)來創(chuàng)建。

e930700c-ec2e-11ed-90ce-dac502259ad0.png

這是一個比較詳細(xì)的段描述符的結(jié)構(gòu),下面來具體介紹一下這些字段的含義:

段限長字段 LIMIT --- Segment limit field

段限長用于指定段的長度,處理器會把段描述符中兩個段限長字段組合成一個 20 位的值,并且根據(jù)顆粒度標(biāo)志 G 來指定段限長 Limit 值的實(shí)際含義。如果 G = 0,則段長度 Limit 范圍可以從 1 到 1MB 字節(jié)。如果 G = 1,則段長度 Limit 的范圍可以是從 4KB 到 4GB ,單位是 4KB。

基地址字段 BASE --- Base address field

這個字段定義在 4GB 線性地址空間中一個段字節(jié) 0 所處的位置。處理器會把 3 個分立的基地址字段組合成為一個 32 位的值,段基址應(yīng)該對其 16 字節(jié)邊界,這樣做性能比較高。

段類型字段 TYPE --- Type field

類型字段指定段或門(Gate)的類型、說明段的訪問種類以及段的擴(kuò)展方向。這個字段依賴與描述符類型標(biāo)志 S 指明的是一個應(yīng)用描述符還是系統(tǒng)描述。TYPE 字段的編碼對代碼、數(shù)據(jù)或系統(tǒng)描述符都不同。

e93f8cd6-ec2e-11ed-90ce-dac502259ad0.png

e961abfe-ec2e-11ed-90ce-dac502259ad0.png

e970c8e6-ec2e-11ed-90ce-dac502259ad0.png

描述符類型標(biāo)志 S --- Descriptor type flag

表明描述符的類型,0 - 表示系統(tǒng)描述符,1 - 代碼或數(shù)據(jù)段描述符。

描述符特權(quán)級 --- DPL Descriptor priviledge level

DPL 表示描述符的特權(quán)級,特權(quán)級范圍從 0 - 3 ,3 最低,0 最高,DPL 用于控制對段的訪問;

我在內(nèi)核訪問相關(guān)的描述中也提到了一個特權(quán)級,大家還記得是啥嗎?

段存在標(biāo)志 --- P Segment present

P 標(biāo)志位表示一個段是在內(nèi)存中 p = 1 還是不在內(nèi)存中 p = 0。當(dāng)段描述符的 P 標(biāo)志為 0 時,那么把指向這個段描述符的選擇符加載進(jìn)段寄存器將導(dǎo)致產(chǎn)生一個段不存在異常。

D/B --- 默認(rèn)操作大小/默認(rèn)棧指針大小和/或上界限 Default operation size/default stack pointer size and/or upper bound

根據(jù)段描述符表示的是可執(zhí)行代碼段、下擴(kuò)數(shù)據(jù)段還是堆棧段,這個標(biāo)志具有不同的功能(如果是 32 位,這個標(biāo)志應(yīng)該設(shè)置為 1,16 位應(yīng)該設(shè)置為 0 )。如果是可執(zhí)行代碼段時,這個標(biāo)志是 D 標(biāo)志;如果是棧段和下擴(kuò)數(shù)據(jù)段,這個標(biāo)志是 B 標(biāo)志;

顆粒度標(biāo)志 --- G Granularity

這個字段用于確定段限長字段 Limit 值的單位,如果顆粒度標(biāo)志為 0 ,則段限長值的單位是字節(jié);如果設(shè)置了顆粒度標(biāo)志,則段限長使用 4KB 單位。

可用和保留比特位 --- Available and reserved bits

段描述符的第 2 個雙字的位 20 供系統(tǒng)軟件使用,位 21 是保留位并且設(shè)置為 0 。

段描述符表

段描述符表是存儲段描述符的一個數(shù)組,索引是由段選擇子提供。段描述符表的長度可變,最多可以包含 8192 個 8 字節(jié)的描述符,段描述符有兩種:即全局描述符表(Global descriptor table)和局部描述符表(Local descriptor table)。

e991f4c6-ec2e-11ed-90ce-dac502259ad0.png

描述符表由操作系統(tǒng)中的特殊數(shù)據(jù)結(jié)構(gòu)來維護(hù)著,并且由內(nèi)存管理硬件來引用。虛擬內(nèi)存空間被分割成大小相等的兩半,一半由 GDT 來映射變換成為線性地址,一半由 LDT 來映射,由于段描述符表最大可以包含 8192 個 8 字節(jié)的描述符,也就是 2 ^ 13 = 8192 ,所以整個虛擬地址空間是 2 ^ 14 = 16384 個段了,通過指定 TI = 1 or 0 就可以查找到指令的段描述符。

當(dāng)發(fā)生任務(wù)切換時,LDT 會更換成新任務(wù)的 LDT,但是 GDT 內(nèi)容卻不會變。因此可以看出,GDT 相當(dāng)于是全局共有的,系統(tǒng)中所有任務(wù)共享的段用 GDT 來映射,而 LDT 是當(dāng)前任務(wù)特有的,可以把 LDT 看成是操作系統(tǒng)的數(shù)據(jù)。

下面是一副關(guān)于 GDT、LDT 的映射圖。

e9b0dd50-ec2e-11ed-90ce-dac502259ad0.png

上圖中共有六個段,分別是用于任務(wù) A 的 CodeA 、DataA,任務(wù) B 的 CodeB、DataB,用于操作系統(tǒng)的 Codeos 和 Dataos,系統(tǒng)中的任務(wù) A 和 任務(wù)B 分別是兩個不同的應(yīng)用程序,并且每個任務(wù)都有自己的 Code 和 Data,在各自的 LDT 表中保存著 Code 和 Data。包含操作系統(tǒng)內(nèi)核的兩個段 Codeos 和 Dataos 在 GDT 中映射,并且 GDT 表示任務(wù) A 和任務(wù) B 共同享有的全局映射,GDT 表還保存著 LDTA 和 LDTB。

當(dāng)任務(wù) A 在運(yùn)行時,可訪問的段包括 LDTA 的 CodeA 和 DataA,加上 GDT 映射的 Codeos 和 Dataos,任務(wù) B 運(yùn)行時,可訪問的段包括 LDTB 的 CodeB 和 DataB,加上 GDT 映射的 Codeos 和 Dataos 。任務(wù) A 在運(yùn)行時,是無法訪問任務(wù) B 的兩個段的;同樣的任務(wù) B 在運(yùn)行時,也是無法訪問任務(wù) A 的,這正是虛擬地址提供的保護(hù)機(jī)制,還記得上篇文章寫到的嗎?

e9c68308-ec2e-11ed-90ce-dac502259ad0.png

GDT 本身并不是一個段,它只是線性地址空間中的一個數(shù)據(jù)結(jié)構(gòu)。GDT 的基地址 (Base Address)+ 段長度(Limit)會被直接加載進(jìn) GDTR 寄存器中。GDT 的基地址應(yīng)該進(jìn)行內(nèi)存 8 字節(jié)對齊,用已得到最佳的處理性能。GDT 的限長以字節(jié)為單位。

處理器并不會使用 GDT 表中的第 1 個描述符,第 1 個描述符也是空描述符,把這個描述符加載進(jìn)數(shù)據(jù)段寄存器 DS、FS、GS 和 ES 后不會產(chǎn)生異常,但是使用空描述符的段選擇符訪問內(nèi)存時就肯定會產(chǎn)生一般保護(hù)性異常。

訪問 LDT 表需要使用其段選擇符,為了在訪問 LDT 時減少地址轉(zhuǎn)換次數(shù),LDT 的段選擇符、基地址、段限長和訪問權(quán)限需要存儲在 LDTR 寄存器中。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19440

    瀏覽量

    231315
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5372

    瀏覽量

    121282
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    10911

    瀏覽量

    213144
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11351

    瀏覽量

    210505
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    573

    瀏覽量

    40240

原文標(biāo)題:圖文詳解 Linux 分段機(jī)制!

文章出處:【微信號:cxuangoodjob,微信公眾號:程序員cxuan】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    詳解Linux內(nèi)核搶占實(shí)現(xiàn)機(jī)制

    本文詳解Linux內(nèi)核搶占實(shí)現(xiàn)機(jī)制。首先介紹了內(nèi)核搶占和用戶搶占的概念和區(qū)別,接著分析了不可搶占內(nèi)核的特點(diǎn)及實(shí)時系統(tǒng)中實(shí)現(xiàn)內(nèi)核搶占的必要性。然后分析了禁止內(nèi)核搶占的情況和內(nèi)核搶占的時機(jī),最后介紹了實(shí)現(xiàn)搶占內(nèi)核所做的改動以及何時
    發(fā)表于 08-06 06:16

    詳解Linux能力機(jī)制

    Linux能力機(jī)制
    發(fā)表于 04-20 08:23

    圖文詳解T60機(jī)器拆解過程

    圖文詳解T60機(jī)器拆解過程.
    發(fā)表于 04-24 15:12 ?38次下載

    倒車影像安裝方法圖文詳解

    倒車影像安裝方法圖文詳解,感興趣的小伙伴們可以看看。
    發(fā)表于 08-03 16:15 ?85次下載

    IBM X40拆機(jī)圖文詳解

    IBM X40拆機(jī)圖文詳解
    發(fā)表于 12-09 14:50 ?0次下載

    linux內(nèi)核rcu機(jī)制詳解

    Linux內(nèi)核源碼當(dāng)中,關(guān)于RCU的文檔比較齊全,你可以在 /Documentation/RCU/ 目錄下找到這些文件。Paul E. McKenney 是內(nèi)核中RCU源碼的主要實(shí)現(xiàn)者,他也寫了很多RCU方面的文章。今天我們而主要來說說linux內(nèi)核rcu的
    發(fā)表于 11-13 16:47 ?8809次閱讀
    <b class='flag-5'>linux</b>內(nèi)核rcu<b class='flag-5'>機(jī)制</b><b class='flag-5'>詳解</b>

    供電系統(tǒng)電氣圖識圖使用圖文詳解

    供電系統(tǒng)電氣圖識圖使用圖文詳解
    的頭像 發(fā)表于 07-06 11:51 ?1.9w次閱讀
    供電系統(tǒng)電氣圖識圖使用<b class='flag-5'>圖文</b><b class='flag-5'>詳解</b>

    電子積木的使用1861例的詳細(xì)圖文詳解

    本文檔的主要內(nèi)容詳細(xì)介紹的是電子積木的使用1861例的詳細(xì)圖文詳解
    發(fā)表于 05-24 08:00 ?13次下載
    電子積木的使用1861例的詳細(xì)<b class='flag-5'>圖文</b><b class='flag-5'>詳解</b>

    圖文詳解:C++虛表的剖析

    圖文詳解:C++虛表的剖析
    的頭像 發(fā)表于 06-29 14:23 ?2598次閱讀
    <b class='flag-5'>圖文</b><b class='flag-5'>詳解</b>:C++虛表的剖析

    圖文詳解:C++的輸出輸入

    圖文詳解:C++的輸出輸入
    的頭像 發(fā)表于 06-29 14:53 ?3426次閱讀
    <b class='flag-5'>圖文</b><b class='flag-5'>詳解</b>:C++的輸出輸入

    圖文詳解:信號的時域和空域特性

    圖文詳解:信號的時域和空域特性
    發(fā)表于 07-15 10:25 ?2次下載
    <b class='flag-5'>圖文</b><b class='flag-5'>詳解</b>:信號的時域和空域特性

    圖文詳解:從零開始學(xué)電源資源下載

    圖文詳解:從零開始學(xué)電源資源下載
    發(fā)表于 04-25 16:11 ?103次下載
    <b class='flag-5'>圖文</b><b class='flag-5'>詳解</b>:從零開始學(xué)電源資源下載

    圖文詳解:無刷電機(jī)的繞制和接線方法

    圖文詳解:無刷電機(jī)的繞制和接線方法
    發(fā)表于 05-25 11:48 ?131次下載

    一文詳解linux的分頁模型

    也就是我們實(shí)際中編碼時遇到的內(nèi)存地址并不是對應(yīng)于實(shí)際內(nèi)存上的地址,我們編碼中使用的地址是一個邏輯地址,會通過分段和分頁這兩個機(jī)制把它轉(zhuǎn)為物理地址。而由于linux使用的分段
    的頭像 發(fā)表于 05-18 08:59 ?2198次閱讀
    一文<b class='flag-5'>詳解</b><b class='flag-5'>linux</b>的分頁模型

    圖文詳解Linux分頁機(jī)制

    分頁機(jī)制是 80x86 內(nèi)存管理機(jī)制的第二種機(jī)制分段機(jī)制用于把虛擬地址轉(zhuǎn)換為線性地址,而分頁機(jī)制
    發(fā)表于 05-30 09:10 ?506次閱讀
    <b class='flag-5'>圖文</b><b class='flag-5'>詳解</b><b class='flag-5'>Linux</b>分頁<b class='flag-5'>機(jī)制</b>
    主站蜘蛛池模板: 天天亚洲综合 | 最近在线观看免费完整视频 | 久久久久国产成人精品亚洲午夜 | 女人十六毛片 | 欧美xxxxbbbb| 九九热在线视频观看这里只有精品 | 干干人人 | 日本www色视频成人免费网站 | 亚洲免费网站 | 中文字幕在线观看第一页 | 成人国产永久福利看片 | 国产gav成人免费播放视频 | 天天爱添天天爱添天天爱添 | 欧美三四级片 | 女人午夜啪啪性刺激免费看 | 在线五月婷婷 | 色偷偷免费| 岛国毛片| 中文字幕视频一区二区 | 激情综合婷婷丁香六月花 | 久久草在线观看 | 一日本道加勒比高清一二三 | 一级不卡毛片 | 色老板在线视频一区二区 | 人人干狠狠操 | 亚洲午夜综合网 | 中国china体内裑精亚洲毛片 | 日韩一区二区在线观看 | 欧美人另类zooz | 欧美天天在线 | 三级黄色网 | 天天夜约 | 国产精品大片天天看片 | 色噜噜狠狠狠色综合久 | 中文字幕av一区二区三区 | 成年女人毛片免费观看97 | 免费观看高清视频 | 在线观看黄色x视频 | 在线色站 | 国产中出视频 | 男女交性高清视频无遮挡 |