linux0.12 head.s代碼解析

  1. 重新設置IDT和GDT,為256個中斷門設置默認的中斷處理函數
  2. 檢查A20地址線是否啟用
  3. 設置數學協處理器
  4. 將main函數相關的參數壓棧
  5. 設置分頁機制,將頁表映射到0~16MB的物理內存上
  6. 返回main函數執行

源碼詳細注釋如下:

/**  linux/boot/head.s**  (C) 1991  Linus Torvalds*//**  head.s contains the 32-bit startup code.** NOTE!!! Startup happens at absolute address 0x00000000, which is also where* the page directory will exist. The startup code will be overwritten by* the page directory.*/
.text
.globl _idt,_gdt,_pg_dir,_tmp_floppy_area
_pg_dir:
startup_32:
# 段寄存器先指向setup.S中的數據段movl $0x10,%eaxmov %ax,%dsmov %ax,%esmov %ax,%fsmov %ax,%gslss _stack_start,%esp # 設置棧指針和棧段寄存器
# 設置IDT和GDTcall setup_idtcall setup_gdt
# 重新加載段寄存器和棧movl $0x10,%eaxmov %ax,%dsmov %ax,%esmov %ax,%fsmov %ax,%gslss _stack_start,%esp
# 檢查A20地址線是否啟用xorl %eax,%eax
1:	incl %eax            # check that A20 really IS enabledmovl %eax,0x000000   # loop forever if it isn'tcmpl %eax,0x100000je 1b
/** NOTE! 486 should set bit 16, to check for write-protect in supervisor* mode. Then it would be unnecessary with the "verify_area()"-calls.* 486 users probably want to set the NE (#5) bit also, so as to use* int 16 for math errors.*/movl %cr0,%eax          # check math chipandl $0x80000011,%eax   # 清楚其他位,保留PG PE ET位orl $2,%eax             # set MP位,表示啟用數學協處理器movl %eax,%cr0          # 寫回CR0寄存器call check_x87jmp after_page_tables# 設置協處理器
check_x87:fninit                  # 初始化協處理器fstsw %ax               # 取協處理器狀態字到ax寄存器cmpb $0,%alje 1f                   # 如果協處理器狀態字為0,則有協處理器,跳轉1movl %cr0,%eaxxorl $6,%eax            # 清除MP、設置EM位movl %eax,%cr0ret
.align 2
1:	.byte 0xDB,0xE4         # 等價于fsetpm,用于設置協處理器模式retsetup_idt:
/** %eax:* 位31-16: 0x0008 (段選擇子)* 位15-0:  ignore_int地址的低16位* %edx:* 位31-16: 0x8E00 (中斷門屬性)* 位15-0:  ignore_int地址的高16位
*/lea ignore_int,%edxmovl $0x00080000,%eaxmovw %dx,%axmovw $0x8E00,%dxlea _idt,%edi          # edi指向IDT的基地址mov $256,%ecx          # 256個中斷門
rp_sidt:movl %eax,(%edi)movl %edx,4(%edi)addl $8,%edi           # 移動到下一個中斷門描述符dec %ecx               # 循環計數器減1jne rp_sidtlidt idt_descr         # 加載IDT描述符ret/**  setup_gdt**  This routines sets up a new gdt and loads it.*  Only two entries are currently built, the same*  ones that were built in init.s. The routine*  is VERY complicated at two whole lines, so this*  rather long comment is certainly needed :-).*  This routine will beoverwritten by the page tables.*/
setup_gdt:lgdt gdt_descrret/** 物理地址    內容          大小      用途* 0x0000   頁目錄(_pg_dir)  4KB      頁目錄表* 0x1000   頁表0(pg0)      4KB       映射0-4MB物理內存* 0x2000   頁表1(pg1)      4KB       映射4-8MB物理內存  * 0x3000   頁表2(pg2)      4KB       映射8-12MB物理內存* 0x4000   頁表3(pg3)      4KB       映射12-16MB物理內存* 0x5000   軟盤緩沖區      4KB       軟盤DMA緩沖區*/
.org 0x1000
pg0:
.org 0x2000
pg1:
.org 0x3000
pg2:
.org 0x4000
pg3:
.org 0x5000
/** tmp_floppy_area is used by the floppy-driver when DMA cannot* reach to a buffer-block. It needs to be aligned, so that it isn't* on a 64kB border.*/
_tmp_floppy_area:.fill 1024,1,0after_page_tables:pushl $0pushl $0pushl $0               # 這些是main函數的參數pushl $L6              # 如果main函數決定返回,則返回地址為L6pushl $_main           # main函數地址壓棧jmp setup_paging       # 跳轉設置分頁機制
L6:jmp L6                 # main應該永遠不會返回,以防萬一,我們不知道會發生什么# 默認中斷處理程序
int_msg:.asciz "Unknown interrupt\n\r"
.align 2
ignore_int:pushl %eaxpushl %ecxpushl %edxpush %dspush %espush %fsmovl $0x10,%eaxmov %ax,%dsmov %ax,%esmov %ax,%fspushl $int_msgcall _printkpopl %eaxpop %fspop %espop %dspopl %edxpopl %ecxpopl %eaxiret.align 2
setup_paging:
# 清零頁目錄和頁表區域movl $1024*5,%ecxxorl %eax,%eaxxorl %edi,%edicld;rep;stosl
# 設置頁目錄項movl $pg0+7,_pg_dirmovl $pg1+7,_pg_dir+4movl $pg2+7,_pg_dir+8movl $pg3+7,_pg_dir+12
# 通過循環將頁表映射到物理內存,從高地址向低地址填充movl $pg3+4092,%edimovl $0xfff007,%eaxstd
1:	stoslsubl $0x1000,%eaxjge 1bxorl %eax,%eaxmovl %eax,%cr3          # 設置CR3寄存器,指向頁目錄的起始地址movl %cr0,%eaxorl $0x80000000,%eaxmovl %eax,%cr0          # 啟用分頁機制ret                     # 由于之前壓棧了main,返回main函數執行.align 2
.word 0
idt_descr:.word 256*8-1		# idt contains 256 entries.long _idt
.align 2
.word 0
gdt_descr:.word 256*8-1		# so does gdt (not that that's any.long _gdt		# magic number, but it works for me :^).align 3
_idt:	.fill 256,8,0		# idt is uninitialized_gdt:	.quad 0x0000000000000000	/* NULL descriptor */.quad 0x00c09a0000000fff	    /* 內核代碼段 16Mb */.quad 0x00c0920000000fff	    /* 內核數據段 16Mb */.quad 0x0000000000000000	    /* 暫時未使用 */.fill 252,8,0			        /* space for LDT's and TSS's etc */

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

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

相關文章

Maven動態控制版本號秘籍:高效發包部署,版本管理不再頭疼!

作者:唐叔在學習 專欄:唐叔的Java實踐 關鍵詞:Maven版本控制、versions插件、動態版本號、持續集成、自動化部署、Java項目管理 摘要:本文介紹如何使用Maven Versions插件動態控制項目版本號和依賴組件版本號,實現無需…

簡述:普瑞時空數據建庫軟件(國土變更建庫)之一(變更預檢查部分規則)

簡述:普瑞時空數據建庫軟件(國土變更建庫)之一(變更預檢查部分規則) 主要包括三種類型:常規檢查、行政區范圍檢查、20X異常滅失檢查 本blog地址:https://blog.csdn.net/hsg77

shell中命令小工具:cut、sort、uniq,tr的使用方式

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄前言一、cut —— 按列或字符截取1. 常用選項2. 示例二、sort —— 排序(默認按行首字符升序)1. 常用選項常用 sort 命令選項三、uniq —— 去…

【Linux】Linux開發必備:Git版本控制與GDB調試全指南

前言:在Linux開發流程中,版本控制與程序調試是保障項目穩定性和開發效率的兩大核心環節。Git作為當前最主流的分布式版本控制系統,能高效管理代碼迭代、追蹤修改記錄并支持多人協同開發;GDB(GNU調試器)是Li…

實現 TypeScript 內置工具類型(源碼解析與實現)

目標讀者:已經熟悉 TypeScript 基礎語法、泛型、條件類型的同學。本文按常見工具類型的分類與順序實現并解釋 Partial、Required、Readonly、Pick、Omit、Record、Exclude、Extract、NonNullable、ReturnType、Parameters、ConstructorParameters、InstanceType、Th…

Spring Boot + Nacos 配置中心示例工程

1?? 工程結構 nacos-demo├── pom.xml└── src├── main│ ├── java│ │ └── com.example.nacosdemo│ │ ├── NacosDemoApplication.java│ │ ├── config│ │ │ └── AppProperties.java│ │ └── cont…

(二)文件管理-基礎命令-pwd命令的使用

文章目錄1. 命令格式2. 基本用法3. 高級用法4. 注意事項1. 命令格式 pwd [OPTION]...[OPTION]: 可選選項,用于改變命令的默認行為。最主要的兩個選項是 -L 和 -P。它不需要任何參數(如文件名或目錄名) 2. 基本用法 用法:pwd 是…

Leetcode_202.快樂數_三種方法解決(普通方法解決,哈希表解決,循環鏈表的性質解決_快慢指針)

目錄第一種方法:暴力解法暴力ac代碼:第二種方法:哈希表哈希表ac代碼:第三種方法:根據循環鏈表的性質(快慢指針)第一種方法:暴力解法 最暴力的思路就是直接使用循環往下一直計算,這樣特別浪費時間&#xff…

代碼隨想錄刷題Day48

這次博客主要是對做過的關于二叉樹系列的題目進行整理和分類。二叉樹,要處理整個樹,一般少不了遍歷。遍歷主要可以分為:遞歸系列、層序遍歷。如果不遍歷的話,那就是處理特殊的樹了,比如完全二叉樹。遞歸系列基本的遞歸…

汽車工裝結構件3D掃描尺寸測量公差比對-中科米堆CASAIM

汽車制造過程中,工裝結構件的尺寸精度對整車裝配質量和生產進度有重要影響。傳統測量工具如卡尺和三坐標測量機采用接觸式工作方式,檢測過程耗時較長,對于具有復雜曲面特征的工件,難以全面獲取尺寸數據。激光三維掃描技術改變了傳…

Docker Pull 代理配置方法

本文介紹通過網絡代理加速Docker鏡像拉取的方法。 配置方法 當執行docker pull從Docker Hub 拉取鏡像時,其網絡連接由守護進程docker daemon進行維護。 要修改其代理設置,可配置其systemd服務,步驟如下: (1&#xf…

機電裝置:從基礎原理到前沿應用的全方位解析

本文由「大千AI助手」原創發布,專注用真話講AI,回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我,一起撕掉過度包裝,學習真實的AI技術! 1 機電裝置的基本概念與發展歷程 機電裝置(Mechatronic D…

《SVA斷言系統學習之路》【03】關于布爾表達式

序列中使用的表達式基于其所含變量的采樣值進行評估。表達式評估的結果為布爾值,其解釋方式與過程性if語句條件中的表達式完全相同:若表達式計算結果為X、Z 或 0,則被解釋為假;否則即為真。但是,對可出現在并發斷言中的…

指針高級(2)

6.數組指針#include <stdio.h> int main() {/*練習&#xff1a;利用指針遍歷數組*///1.定義數組int arr[] { 10,20,30,40,50 };int len sizeof(arr) / sizeof(int);//2.獲取數組的指針//實際上獲取的&#xff1a;數組的首地址int* p1 arr;int* p2 &arr[0];printf…

如何高效記單詞之:抓住首字母——以find、fund、fond、font為例

find、fund、fond、font這幾個單詞&#xff0c;你都認識嗎&#xff1f;這幾個單詞&#xff0c;意思大體如下&#xff1a; find v.找到&#xff1b;發現fund n.基金fond a.喜歡的&#xff1b;喜愛的&#xff1b;深情的font n.字體&#xff0c;字型&#xff0c;字形 這幾個單詞在…

Ubuntu下把 SD 卡格式化為 FAT32

在 Ubuntu 下把 SD 卡格式化為 FAT32&#xff0c;按下面做&#xff08;會抹掉整卡數據??&#xff09;&#xff1a; 1) 找到你的 SD 卡設備名 lsblk -p記下整盤設備&#xff0c;比如 /dev/sdb&#xff08;USB 讀卡器常見&#xff09;或 /dev/mmcblk0&#xff08;內置讀卡器&am…

涉私數據安全與可控匿名化利用機制研究(上)

文章目錄前言一、涉私數據的概述及分類&#xff08;一&#xff09;涉私數據的“知情同意原則”&#xff08;二&#xff09;涉私數據的分類二、涉私數據可控匿名化利用機制&#xff08;一&#xff09;數據產品與涉私數據的利用形式&#xff08;二&#xff09;通過可信數據空間受…

Redis 的跳躍表:像商場多層導航系統一樣的有序結構

目錄 一 、從 "超市貨架" 的痛點看跳躍表的價值 1.1、跳躍表與商場導航系統的結構對應 1. 1.1、zskiplistNode&#xff1a;帶導航標記的 "商品"&#xff08;跳躍表節點&#xff09; 1.1.1.1、level []&#xff1a;商品上的多層導航標記 1.1.1.2、back…

小程序點擊之數據綁定

<return /><view class"all-wrap" style"padding-top:{{topHeight}}px;"><view class"my-title">我的收藏</view><scroll-viewclass"collect-list-container"scroll-yscroll-top"{{scrollTop}}"…

數據結構——順序表和單向鏈表(2)

目錄 前言 一、單向鏈表 1、基本概念 2、單向鏈表的設計 &#xff08;1&#xff09;節點設計 &#xff08;2&#xff09;初始化空單向鏈表 &#xff08;3&#xff09;、初始化數據節點 &#xff08;4&#xff09;數據節點 &#xff08;5&#xff09;判斷鏈表是否為空 …