【日常積累】Linux之init系統學習

init系統簡介:

Linux 操作系統的啟動首先從 BIOS 開始,接下來進入 boot loader,由 bootloader 載入內核,進行內核初始化。內核初始化的最后一步就是啟動 pid 為 1 的 init 進程,這個進程是系統的第一個進程,它負責產生其他所有用戶進程。

init 的一些特點

  • init是Linux系統操作中不可缺少的程序之一。
  • 所謂的init進程,它是由內核啟動的第一個用戶級進程。內核自行啟動(已被裝入內存,開始運行,并已初始化所有的設備驅動程序和數據結構等)之后,就通過啟動一個用戶級程序init的方式,完成引導進程。所以,init始終是第一個進程(其進程編號始終為1)。
  • 僅僅將內核運行起來是毫無實際用途的,必須由 init 系統將系統代入可操作狀態。比如啟動外殼 shell 后,便有了人機交互,這樣就可以讓計算機執行一些預訂程序完成有實際意義的任務(這其實就是就是后面所說的內核態到用戶態的轉變)。內核會在過去曾使用過init的幾個地方查找它,它的正確位置(對Linux系統來說)是/sbin/init。如果內核找不到init,它就會試著運行/bin/sh,如果運行失敗,系統的啟動也會失敗。

Linux下的三個特殊進程

Linux下有三個特殊的進程idle進程(PID=0),init進程(PID=1),和kthreadd(PID=2)

  • idle進程由系統自動創建,運行在內核態。idle進程其pid=0,其前身是系統創建的第一個進程,也是唯一一個沒有通過fork或者kernel_thread產生的進程。完成加載系統后,演變為進程調度、交換。
  • kthreadd進程由idle通過kernel_thread創建,并始終運行在內核空間,負責所有內核進程的調度和管理。它的任務就是管理和調度其他內核線程kernel_thread, 會循環執行一個kthread的函數,該函數的作用就是運行kthread_create_list全局鏈表中維護的kthread, 當我們調用kernel_thread創建的內核線程會被加入到此鏈表中,因此所有的內核線程都是直接或者間接的以kthreadd為父進程 。
  • init進程由idle通過kernel_thread創建,在內核空間完成初始化后,加載init程序。在這里我們就主要了解下init進程,init進程由0進程創建,完成系統的初始化,是系統中所有其他用戶進程的祖先進程
    Linux中的所有進程都是由init進程創建并運行的。首先Linux內核啟動,然后在用戶空間中啟動init進程,再啟動其他系統進程。在系統啟動完成后,init將變成為守護進程監視系統其他進程。(內核態轉變為用戶態)

大致過程為:0號進程->1號內核進程->1號用戶進程(init進程)->getty進程->shell進程

init進程完成從內核態向用戶態的轉變

在這里插入圖片描述

一個進程先后兩種狀態

init進程剛開始運行的時候是內核態,它屬于一個內核線程,然后運行一個用戶態下面的程序后(如/sbin/init),把自己轉成用戶態(后面的進程需要工作在用戶態下)。
init進程完成了從內核態到用戶態的過渡,因此后續的其他進程都可以工作在用戶態。

init進程在內核態下的工作內容

主要是掛載根文件系統,并試圖找到用戶態下的那個init程序。(這句話看出,init進程是早于init程序運行的。)

init進程要把自己轉成用戶態就必須運行一個用戶態的應用程序,要運行這個應用程序就必須得找到這個應用程序,要找到這個應用程序就必須得掛載根文件系統,因為所有的應用程序都在文件系統中。

內核源代碼中的所有函數都處于內核態,執行其中任何一個都不能脫離內核態。而應用程序必須不屬于內核源代碼,這樣才能保證應用程序處于用戶態。這里執行的init程序和內核不在一起,由根文件系統另外提供。

init進程在用戶態下的工作內容

init進程大部分有意義的工作都是在用戶態下進行的。init進程對操作系統的意義在于,其他所有的用戶進程都直接或者間接派生自init進程。

init進程如何從內核態跳躍到用戶態 ?還能回來不?

init進程處于內核態時,通過函數do_execve來執行一個用戶空間編譯鏈接的應用程序就跳躍到用戶態了。

  • 跳躍過程中進程號沒有改變,一直是進程1。
  • 跳躍過程是單向的,一旦執行init程序轉到用戶態,整個操作系統就算真正運轉起來了,以后只能在用戶態下工作,用戶態下想要進入內核態只能通過調用API。

1、init進程掛載了根文件系統
(1)prepare_namespace函數掛載根文件系統。

(2)根文件系統在哪里?根文件系統的文件系統類型是什么?

uboot通過傳參來告訴內核這些信息。
uboot傳參中的root=/dev/mmcblk0p2 rw 這一句就是告訴內核根文件系統在哪里。
uboot傳參中的rootfstype=ext3這一句就是告訴內核rootfs的類型。

(3)掛載結果

如果內核掛載根文件系統成功,則會打印出:VFS: Mounted root (ext3 filesystem) on device 179:2。(也可能其他數字)
如果掛載根文件系統失敗,則會打印:No filesystem could mount root, tried: yaffs2
(4)如果內核啟動時掛載rootfs失敗,則后面無法執行。

內核中設置了啟動失敗休息5s自動重啟的機制,因此這里會自動重啟,所以有時候大家會看到反復重啟的情況。
(5)如果掛載rootfs失敗,可能的原因有

最常見的錯誤就是uboot的bootargs設置不對。
rootfs燒錄失敗(fastboot燒錄不容易出錯)。
rootfs本身制作失敗的。

2、init進程執行init程序完成內核態到用戶態的轉變
(1)一旦掛載rootfs成功,則進入rootfs中尋找應用程序的init程序(在init_post()函數中),找到后用run_init_process去執行。

(2)如果確定init程序是誰?

先從uboot傳參cmdline中看有沒有指定,如果有指定先執行cmdline中指定的程序。比如init=/linuxrc表示rootfs的根目錄下的linuxrc程序就是init程序。
如果uboot傳參cmdline中沒有init=xx或者cmdline中指定的這個xx執行失敗,還有備用方案。第一備用:/sbin/init,第二備用:/etc/init,第三備用:/bin/init,第四備用:/bin/sh。如果以上都不成功,則沒有辦法了。
init=/linuxrc一般指向busybox。

3、init進程構建了用戶交互界面
(1)init進程是其他用戶進程的祖先。
linux系統中一個進程的創建是通過其父進程創建出來的。根據這個理論只要有一個父進程就能生出一堆子孫進程了。
(2)init啟動了login進程(用戶登錄進程)、命令行進程(提供命令行環境)、shell進程(提供命令解釋和執行)。

(3)shell進程啟動了其他用戶進程。

命令行和shell一旦工作,用戶就可以在命令行下通過./xx的方式來執行其他應用程序,每一個應用程序的運行就是一個進程。

4、init進程打開了控制臺

(1)linux系統中每個進程都有自己的一個文件描述符表,表中存儲的是本進程打開的文件。

(2)linux系統中一切皆是文件,因此設備也是以文件的方式來訪問的。要訪問一個設備,就要打開此設備對應的文件描述符。譬如/dev/fb0這個設備文件就代表LCD顯示器設備,/dev/buzzer代表蜂鳴器設備,/dev/console代表控制臺設備。

(3)這里打開了/dev/console文件,并且復制了2次文件描述符,一共得到了3個文件描述符。這三個文件描述符分別是0、1、2,就是所謂的標準輸入、標準輸出、標準錯誤這3個文件描述符。

(4)進程1打開了這3個文件描述符,因此進程1衍生出來的所有的進程默認都具有這3個文件描述符。

運行級別

簡單的說,運行級就是操作系統當前正在運行的功能級別。這個級別有多種,以centos為例,6和7版本的設置方法不同,具體對應關系如下。

init level (centos 6 /etc/inittab)systemctl target(centos 7)說明
0poweroff.target停機(千萬不能把initdefault 設置為0 )
1rescure.target單用戶(救援)模式
2multi-user.target多用戶,沒有 NFS
3multi-user.target完整的多用戶文本模式級別,登錄后進入到控制臺命令行模式
4未使用
5graphical.targetX11 (xwindow,能夠正常切換的前提是系統支持)
6reboot.target重新啟動
[root@k8s-m1 ~]# ll /usr/lib/systemd/system/runlevel*target
lrwxrwxrwx 1 root root 15 Feb 27 16:14 /usr/lib/systemd/system/runlevel0.target -> poweroff.target
lrwxrwxrwx 1 root root 13 Feb 27 16:14 /usr/lib/systemd/system/runlevel1.target -> rescue.target
lrwxrwxrwx 1 root root 17 Feb 27 16:14 /usr/lib/systemd/system/runlevel2.target -> multi-user.target
lrwxrwxrwx 1 root root 17 Feb 27 16:14 /usr/lib/systemd/system/runlevel3.target -> multi-user.target
lrwxrwxrwx 1 root root 17 Feb 27 16:14 /usr/lib/systemd/system/runlevel4.target -> multi-user.target
lrwxrwxrwx 1 root root 16 Feb 27 16:14 /usr/lib/systemd/system/runlevel5.target -> graphical.target
lrwxrwxrwx 1 root root 13 Feb 27 16:14 /usr/lib/systemd/system/runlevel6.target -> reboot.target

運行級別的配置

centos6設置默認的啟動級別

# 查看運行級別: centos7 也可以使用該命令。[root@k8s-m1 ~]# runlevel N 3
# 修改運行級別:臨時修改: init level(對應的級別即可)永久修改:需要修改 /etc/inittab 文件。
在最下面的一行中的語句 id:5:initdefault 中的數字5改成需要的啟動程度就可以了,一般是命令行模式 3

centos7設置默認的啟動級別

#centos7修改設置默認的系統級別
[root@k8s-m1 ~]#  systemctl set-default multi-user.target 
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target.
#centos7查看默認的系統級別
[root@k8s-m1 ~]#  systemctl get-default multi-user.target

參考:https://blog.csdn.net/m0_45406092/article/details/130660743

更多關于Linux的知識請前往博客主頁查看。

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

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

相關文章

銀河麒麟服務器v10 sp1 .Net6.0 上傳文件錯誤

上一篇:銀河麒麟服務器v10 sp1 部署.Net6.0 http https_csdn_aspnet的博客-CSDN博客 .NET 6之前,在Linux服務器上安裝 libgdiplus 即可解決,libgdiplus是System.Drawing.Common原生端跨平臺實現的主要提供者,是開源mono項目。地址…

封裝form表單

目錄 1. 源碼 2. 其他頁面引用 ps&#xff1a;請看完看明白再復用 1. 源碼 <template><div style"width: 100%; height: 100%" class"form-condition"><!-- 普通表單 --><el-card shadow"hover" class"cardheigh…

AQS的原理及應用

文章目錄 AQS引言AQS 的原理AQS 應用舉例1:Semaphore舉例2:ReentrantLockAQS 的案例分析問題背景解決方案AQS 引言 在我們的日常生活和工作中,往往需要協調各個線程之間的執行順序和資源使用,而AQS(AbstractQueuedSynchronizer)即為 Java 并發包中提供的一種解決辦法。…

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia 初環境與設備環境準備克隆模型代碼部署 ChatGLM-6B完整代碼 ChatGLM-6B 是一個開源的、支持中英雙語的對話語言模型&#xff0c;基于 General Language Model (GLM) 架構&#xff0c;具有 62 億參數。結合模型量化技術&#x…

力扣 322. 零錢兌換

題目來源&#xff1a;https://leetcode.cn/problems/coin-change/description/ C題解&#xff08;來源代碼隨想錄&#xff09;&#xff1a;題目中說每種硬幣的數量是無限的&#xff0c;可以看出是典型的完全背包問題。動規五部曲分析如下&#xff1a; 確定dp數組以及下標的含義…

深入理解設計模式-創建型之建造者模式(與工廠區別)

什么是建造者設計模式&#xff1f;和工廠設計模式有什么區別 建造者設計模式&#xff08;Builder Design Pattern&#xff09;和工廠設計模式&#xff08;Factory Design Pattern&#xff09;都是面向對象設計中的創建型模式&#xff0c;但它們解決的問題和應用場景有所不同。…

原碼、反碼、補碼,進制轉換,有符號數和無符號數轉換

計算機底層存儲數據時&#xff0c;存儲的是數據對應的二進制數字。對于整型數據&#xff0c;其二進制表示形式有三種&#xff0c;分別是&#xff1a;原碼、反碼、補碼&#xff0c;而實際存儲的是整型數據的補碼。 原碼、反碼以及補碼都是有符號的&#xff0c;其中最高位存放符…

帶你掌握Stable Diffution商業級玩法

課程介紹 學習地址 《Stable Diffusion商業級玩法》通過詳細講解AI繪畫技巧、實操演示和個性化指導&#xff0c;幫助您從零基礎成為繪畫高手&#xff0c;幫助您有效推廣產品或服務&#xff0c;提升市場份額。教您掌握穩定擴散繪畫技巧&#xff0c;開啟藝術創作新篇章。

Opencv 之ORB特征提取與匹配API簡介及使用例程

Opencv 之ORB特征提取與匹配API簡介及使用例程 ORB因其速度較快常被用于視覺SLAM中的位姿估計、視覺里程、圖像處理中的特征提取與匹配及圖像拼接等領域本文將詳細給出使用例程及實現效果展示 1. API 簡介 創建 static Ptr<ORB> cv::ORB::create (int nfeatures 500…

無涯教程-Perl - use函數

描述 此函數將MODULE導出的所有功能(或僅LIST引用的功能)導入當前包的名稱空間。有效等效于- BEGIN { require "Module.pm"; Module->import(); }也用于在當前腳本上強加編譯器指令(編譯指示),盡管從本質上講它們只是模塊。 請注意,use語句在編譯時進行判斷。在…

springcloud3 hystrix實現服務熔斷的案例配置3

一 hystrix的熔斷原理 1.1 hystrix的熔斷原理 在springcloud的框架里&#xff0c;熔斷機制是通過hystrix實現&#xff0c;hystrix會監控服務之間的調用。當失敗調用達到一定的閾值&#xff0c;默認是5s內失敗20次&#xff0c;就會啟用hystrix的熔斷機制&#xff0c;使用命Hy…

神經網絡基礎-神經網絡補充概念-44-minibatch梯度下降法

概念 小批量梯度下降法&#xff08;Mini-Batch Gradient Descent&#xff09;是梯度下降法的一種變體&#xff0c;它結合了批量梯度下降&#xff08;Batch Gradient Descent&#xff09;和隨機梯度下降&#xff08;Stochastic Gradient Descent&#xff09;的優點。在小批量梯…

Apache Doris大規模數據使用指南

目錄 發展歷史 架構介紹 彈性MPP架構-極簡架構 邏輯架構 基本訪問架構 分區 創建單分區表

【C++ 記憶站】缺省參數

文章目錄 缺省參數的概念缺省參數的分類1、全缺省參數2、半缺省參數 缺省參數實際應用場景 缺省參數的概念 缺省參數是聲明或定義函數時為函數的參數指定一個缺省值。在調用該函數時&#xff0c;如果沒有指定實參則采用該形參的缺省值&#xff0c;否則使用指定的實參 正常調用一…

音頻解碼及如何在Java實現

本人并不干這個&#xff0c;但是被迫下水了解了一下這個&#xff0c;稍微做了一下整理。再就是感覺現在網上以及ChatGPT在這方面給出的答案太水了&#xff0c;在此開辟一篇。無意放出代碼&#xff0c;這里只介紹一些可能重要的點。 本來以為有了ChatGPT寫這些就沒有必要了&…

Docker部署ES服務,canal全量同步的時候內存爆炸,ES/Canal Adapter自動關閉,CPU100%

文章目錄 問題解決方案1. 對ES的限制2. 對Canal-Adapter的限制 問題 使用canal-adapter全量同步&#xff08;參考Canal Adapter1.1.5版本API操作服務&#xff0c;手動同步數據&#xff08;4&#xff09;&#xff09;的時候 小批量數據可以正常運行&#xff08;幾千條&#xf…

Llama 2免費托管及API提供

Llama 2 是 Meta 最新的文本生成模型&#xff0c;目前其性能優于所有開源替代方案。 推薦&#xff1a;用 NSDT編輯器 快速搭建可編程3D場景 1、強大的Llama 2 它擊敗了 Falcon-40B&#xff08;之前最好的開源基礎模型&#xff09;&#xff0c;與 GPT-3.5 相當&#xff0c;僅低…

【uni-app】 .sync修飾符與$emit(update:xxx)實現數據雙向綁定

最近在看uni-app文檔&#xff0c;看到.sync修飾符的時候&#xff0c;覺得很有必要記錄一下 其實uni-app是一個基于Vue.js和微信小程序開發框架的跨平臺開發工具 所以經常會聽到這樣的說法&#xff0c;只要你會vue&#xff0c;uni-app就不難上手 在看文檔的過程中&#xff0c;發…

.netcore grpc客戶端工廠及依賴注入使用

一、客戶端工廠概述 gRPC 與 HttpClientFactory 的集成提供了一種創建 gRPC 客戶端的集中方式。可以通過依賴包Grpc.Net.ClientFactory中的AddGrpcClient進行gRPC客戶端依賴注入AddGrpcClient函數提供了許多配置項用于處理一些其他事項&#xff1b;例如AOP、重試策略等 二、案…

miniExcel 生成excel

一、nuget dotnet add package MiniExcel --version 1.31.2 二、新建表及數據 ExampleProducts 三、這里我用了Dapper.Query方法 讀取excel public virtual async Task<IActionResult> Anonymous(){try{//using (var connection _dbContext.GetDbConnection())//{//…