日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

《操作系统真象还原》-阅读笔记(上)

發布時間:2023/12/10 windows 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《操作系统真象还原》-阅读笔记(上) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第一章

配置bochs,進入bochs simulator后一直是黑屏,原來默認是調試模式,需要輸入C(continue)來讓調試繼續。

第二章

主講MBR及進入MBR前的步驟
1.實模式只能訪問1MB的內存空間。
2.BIOS在ROM中。
3.開機上電后CS:IP指向內存0xfff0,這里有個跳轉語句,轉到fe05b才是真正的BIOS程序,之后檢測內存,顯卡燈,建立數據結構,中斷向量表和填寫中斷例程。

第三章

主講實模式
段的大小統一64KB,段基址代表內存的起始,偏移地址代表段內偏移量。
section:節,只是為了讓程序員在邏輯上將程序劃分為幾個部分,偽指令
vstart:告訴編譯器以新的數字作為后面數據的地址的起始值

第四章

進入保護模式
段描述符:專門用來描述一個內存段,大小為8字節


全局描述符(GDT):


1.相當于描述符的數組,可以用選擇子中提供的下標在全局描述符表中索引描述符。
2.位于內存中,需要GDTR寄存器指向他CPU才知道在哪。通過lgdt加載GDTR,指令格式是:lgdt48位內存數據,48位前16位是以字節為單位的界限值,后32位是GDT的起始地址。2^16=65536,65536/8=8192,所以最多存儲8192個段或門。
3.在保護模式下由于段基址已經存入段描述符,段寄存器沒必要再存段基址了,所以段寄存器存入選擇子,通過選擇子在GDT中找到段描述符從而得到內存段起始地址和段界限值。選擇子低2位存儲了RPL(可以表示0、1、2、3四種特權級),第2位是TI位用來選擇是GDT還是LDT索引描述符。而選擇子的索引部分有13位,所以最多索引8192個段,和GDT存儲的數量相同

?

注意:GDT中第0個段描述符是不可用的,原因是如果選擇子忘記初始化則值為0,為避免誤操作如果訪問第0個描述符處理器將發出異常。


局部描述符(LDT)


現代操作系統中很少使用LDT
CPU廠商建議每個任務的私有內存段都應該放到自己的段描述符表中,該表就是LDT,即每個任務都有自己的LDT,隨著任務切換,也要切換相應任務的LDT。下面是Linux0.11內核中描述符的關系


從相應的內核代碼中,我們看到在task_struct的聲明中,有如下內容:

struct task_struct {
??? ...
??? struct desc_struct ldt[3];
??? struct tss_struct tss;
};

?

這說明ldt是和每個task有關。每當需要創建新的process時,就需要在內存中把一塊相應的區域劃分給這個process的LDT。
(部分參考自http://blog.csdn.net/aotony_1988/article/details/50935897)

第五章

先回憶下上章內容并解釋一些不清楚的地方。
一個進程的地址空間,從用戶的角度看,是由若干的段(segment)組成的,這些段可以分為兩種:私有段(private)、共享段(shared)。cpu也是按照用戶的邏輯進行內存管理的(分段),Intel Pentium規定了每種段最多有8K個,每個segment最大4G。一個cpu對應有一個GDT(global descriptor table),該表詳細描述了shared segment,這個表為所有進程共享的;一個process對應有一個LDT(local),該表詳細描述了該process的private segment,這個表是進程私有的。
我們的程序是處在一個個的Segment中的,無論是指令還是數據。我們在程序中打印出一個變量的地址其實是段內的偏移地址(32位),程序的16bit段號由操作系統分配管理,我們是看不見的,但是的確存在。
注意注意注意:以上的解釋中,為簡單,沒有說明分頁!

總之,SegmentSelector(16bit) + 段內Offset(32bit) = 一個32bit的地址值
其實這個就是虛擬地址。將這個地址轉換為物理地址就需要用他到頁目錄表中找到頁表的地址,再到頁表中找到真實物理地址。
(部分參考自http://blog.csdn.net/yleek/article/details/8204393)

??????? 如果存儲器采用基本分頁機制,那么操作系統會為每個進程或任務建立一個頁表(這個頁表可能是一級的也可能是多級的)。整個操作系統中有多個進程在運行,那么系統就會有多個頁表。頁表在內存中的存儲位置由寄存器CR3給出。
??????? 如果存儲器采用基本分段機制,那么操作系統會為每個進程或任務建立一個段表(一般不用多級),用于記錄數據段、代碼段等各類段在內存中的具體位置。
??????? 如果采用段頁式結合的機制,那么一般一個進程或任務,操作系統會給其建立一個段表,而段表中的每個段又會對應一個頁表,也就是說,段頁式機制的每個進程有一個段表,有多個頁表。
??????? 對于典型的Linux系統而言,操作系統會維護一個全局描述符表(相當于系統的段表),全局描述符表中用于記錄系統任務和用戶任務的描述符,其中用戶任務的描述符又指向用戶任務的局部描述符表(相當于用戶任務的段表)。因此要說linux中的分段機制用的是一張大表,我個人認為也是有道理的。

這本書里采用的是第一種方案,一個進程一個頁表,這個頁表是二級的。將頁目錄表和頁表緊挨在一起,如下圖所示
?

這里將兩個表都存在內核空間的低端內存處,這樣通過cr3的物理地址可以馬上找到頁表(因為內核空間是真實線性的,即虛擬地址和物理地址一樣)。每一個進程的頁表都放在一起,其實還有其他的放置方法可見此貼http://bbs.csdn.net/topics/390956135?page=1

快表

虛擬地址到物理地址轉換有一個緩存器,快表,存儲少量的轉換關系,能加快轉換速度。轉換時一般先查快表查不到再查頁表項。

啟動分頁流程

1:準備好目錄表和頁表
2:將頁表地址寫入控制寄存器cr3 (又稱為頁目錄基址寄存器)
3:寄存器cr0的PG位置1
tips
在64位的Linux下,gcc 編譯 32 位程序需要添加參數 -m32 ,ld需要添加參數是 -m elf_i386。

第六章

本章講了一些函數調用 ,匯編和C語言混合編程等知識
1.cdecl調用,由調用者清理棧空間,即將棧頂往上加。
2.LINUX系統調用入口只有一個 0X80 中斷描述符表中的一項 具體調用子功能由eax指定。
3.調用函數,當輸入的參數小于等于 5 個時, Linux 用寄存器傳遞參數。當參數個數大于 5 個時,把參數按照順序放入連續的內存區域,并將該區域的首地址放到 ebx 寄存器。
tips
fatal error: sys/cdefs.h: No such file or directory|
Try these:
sudo apt-get purge libc6-dev
sudo apt-get install libc6-dev

In case of -m32:
sudo apt-get install libc6-dev-i386

源碼中LOADER_STRAT_SELECTOR一直在boot.inc里定義位0x2 所以Loader.bin應放到硬盤第二個扇區
--------------------- ?
作者:月黑風高云游詩人 ?
來源:CSDN ?
原文:https://blog.csdn.net/lqygame/article/details/73801091 ?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

總結

以上是生活随笔為你收集整理的《操作系统真象还原》-阅读笔记(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。