linux內核設計與實現---從內核出發

獲取、編譯、安裝內核

  • 1 獲取內核源碼
    • 安裝內核源代碼
      • 何處安裝源碼
    • 使用補丁
  • 2 內核源碼樹
  • 3 編譯內核
    • 減少編譯的垃圾信息
    • 衍生多個編譯作業
    • 安裝內核
      • 啟用指定內核作為引導
  • 4 內核開發的特點
    • 沒有libc庫
      • 頭文件
    • 沒有內存保護機制
    • 容積小而固定的棧

1 獲取內核源碼

在linux內核官方網站http://www.kernel.org,可以獲得當前最新版本Linux源碼碼。如果想找一些老版本的源代碼,可以:https://mirrors.edge.kernel.org/pub/linux/kernel/下載。

安裝內核源代碼

內核壓縮以GNU zip(gzip)和bzip2兩種形式發布。以bzip2形式發布的Linux內核叫做linux-x.y.z.tar.bz2,這里x.y.z是內核源碼的具體版本。如果壓縮形式是bzip2,則運行:

tar rvjf linux-x.y.z.tar.bz2

如果壓縮形式是GNU的zip,則運行:

tar xvzf linux-x.y.z.tar.gz

何處安裝源碼

內核源碼一般安裝在/usr/src/具體linux版本 目錄下。不要以root身份對內核進行修改,而應當是,建立自己的主目錄。僅以root身份安裝新內核,即使在安裝新內核時,/usr/src/linux目錄都應當原封不動。

使用補丁

在linu內核社區中,補丁是通用語。你可以以補丁的形式發布對代碼的修改,也可以以補丁的形式接收其他人所做的修改。內核版本不斷更新,增量補丁可以作為版本轉移的橋梁。你不在需要下載內核源碼的全部壓縮,而只需給舊版本打上一個增量補丁,讓其舊貌換新顏,更新內核版本。只需運行:

patch-p1 < ../patch-x.y.z

一般來說,一個給定版本的內核補丁總是打在前一個版本上。

2 內核源碼樹

內核源碼樹由很多目錄組成,而大多數目錄又包含更多子目錄。源碼樹的根目錄及其子目錄如下表:

目錄描述
arch特定體系結構的源碼
cryptoCrypto API
Documentation內核源碼文檔
drivers設備驅動程序
fsVFS和各種文件系統
include內核頭文件
init內核引導和初始化
ipc進程間通信代碼
kernel像調度程序這樣的核心子系統
lib通用內核函數
mm內存管理子系統和VM
net網絡子系統
scrripts編譯內核所用的腳本
securityLinux安全模塊
sound語音子系統
usr早期用戶空間代碼

在源碼樹根目錄中,COPYING是內核許可證,CREDITS是開發者列表。MAINTAINERS是維護者列表,維護內核子系統和驅動程序。最后,Makefile是Makefile內核的基礎

3 編譯內核

在編譯內核之前,首先你必須配置它。可以配置的各種選項,以CONFIG_FEATURE形式表示,其前綴為CONFIG。例如,對稱處理器(SMP)的配置選項為CONFIG_SMP。如果設置了該選項,則SMP啟用,否則,SMP不起作用。
這些配置項要么是二選一,要么是三選一。二選一就是yes或no。三選一可以是yes、no或module。module意味著該配置項被選定了,但編譯的時候這部分功能的實現代碼是以模塊(一種可以動態安裝的獨立代碼段)的形式生成。在三選一的情況下,yes表示把代碼編譯進內核映射中,而不是作為一個模塊。

內核提供了各種不同的工具來簡化內核配置。最簡單的一種是基于文本的命令行工具:

make config

該工具會挨個遍歷所有配置項,要求用戶選擇yes、no或module。
在這里插入圖片描述
如果該命令不能執行,說明沒有安裝一些工具,可以根據提示安裝,我的需要安裝make、gcc、bison、flex

sudo apt-get install make gcc bison flex

這個過程很耗費時間,所以,除非你的工作是按小時計費的,否則你應該多利用基于ncuse編譯的圖形界面工具。

make menuconfig

或者基于X11的圖形工具

make xconfig

或用基于gtk+圖形工具

make gconfig

這三種工具將所有配置項分門別類放置,比如按處理器類別和特點,你可以按類移動、瀏覽內核選項,當然也可以修改其值。
命令:

make defconfig

通過這條命令為你的體系結構創建一個默認的配置。盡管這些默認值有點隨意性,但是,如果你從未配置過內核,那就會提供一個良好的開端。
在這里插入圖片描述
執行完,幫我配置的是x86_64_defconfig。這些配置項會存放在內核代碼樹根目錄下的.config文件中,我們也可修改它,打開看看
在這里插入圖片描述
再修改過配置文件之后,或者在用舊的配置文件配置新的代碼樹的時候,應該驗證和更新配置:

make oldconfig

一旦內核配置好了,就可以編譯它了,執行命令:

make

在這里插入圖片描述

減少編譯的垃圾信息

我們希望在編譯時看到錯誤和警告消息,但對匆匆掠過屏幕的垃圾信息不感興趣,可以使用如下命令

make > /dev/null

就可以把無用的輸出信息重定向到永無返回值的黑洞/dev/null

衍生多個編譯作業

多個作業獨立并發運行,可以提高處理器系統上的編譯過程。默認情況下,make只衍生一個作業。為了可以以多個作業編譯內核,使用一下命令:

make -jn

n是要衍生的作業數,在實際中,每個處理器一般衍生一個或者兩個作業。例如,在一個雙處理器上,可以輸入如下命令:

make -j4

安裝內核

在內核編譯好了之后,還需要安裝它。怎么安裝就和體系架構以及啟動引導工具(boot loader)息息相關了—查閱啟動引導工具的說明,按照它的指導將內核映像拷貝到合適的位置,并且按照啟動要求安裝它。一定要保證隨時有一個或兩個可以啟動的內核,以放新編譯的內核出現問題。
安裝命令:

sudo  make install

模塊的安裝是自動的,也是獨立于體系結構的。以root身份,只要運行:

sudo make modules_install

就可以把所有編譯號的模塊安裝到正確的主目錄/lib下
在這里插入圖片描述
在這里插入圖片描述
可以看到,編譯的內核版本號是5.0.0
在這里插入圖片描述
同時也列出了還有那個內核
在這里插入圖片描述
查看現在使用的內核版本
在這里插入圖片描述

啟用指定內核作為引導

輸入下列命令將內核作為引導,將數字更改為你自己編譯的版本號:

sudo  update-initramfs -c -k 5.0.0

在這里插入圖片描述
跟新一下grub:

sudo update-grub

在這里插入圖片描述
之后重啟即可在啟動界面選擇需要重啟的內核。如果看不到重啟選擇界面,執行以下操作。
輸入命令:

sudo  vim /etc/default/grub

注釋掉hidden那一行,將timeout更改為較大值,這里改為了10
在這里插入圖片描述
之后執行

sudo update-grub

重啟即可看到下面此單,選擇高級選項,進入后選擇編譯安裝好的內核進入即可,
在這里插入圖片描述
選擇我們剛剛編譯好的內核,5.0.0,倒數第二個
在這里插入圖片描述
可以看到是我們編譯的內核
在這里插入圖片描述

4 內核開發的特點

沒有libc庫

與用戶空間的應用程序不同,內核不能鏈接使用標準C函數庫。最主要的原因是對于內核來說,完整的C庫太大了,影響速度和大小。
大部分常用的C庫函數在內核中都已經得到了實現。比如說操作字符串的函數組就位與lib/string.c文件中。只要包含<linux/string.h>頭文件就可以使用。

頭文件

內核源代碼文件不能包含外部頭文件,所說的頭文件是指組成內核源代碼樹的內核頭文件。
在沒有實現的函數中,最著名的就數printf()函數了。內核代碼雖然無法調用printf(),但它可以調用printk()函數。printk()函數負責把格式化好的字符串拷貝到內核日志緩存區上,這樣,syslog程序就可以通過讀取緩沖區來獲取內核信息。

沒有內存保護機制

如果一個用戶程序試圖進行一次非法的內存訪問,內核會出現這個錯誤,發送SIGSEGV,并結束整個進程。然而,如果是內核自己非法訪問了內存,那后果就很難控制了。內核中發生的內存錯誤會導致oops,這是內核中常見的一類錯誤。
此外,內核中的內存都不分頁,也就是說,每用掉一個字節,物理內存就減少一個字節。所以,在你想往內核加入什么新功能的時候,要記住這一點。

容積小而固定的棧

內核棧的準確大小隨體系結構而變,但都是兩頁。每個處理器都有自己的棧

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

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

相關文章

MySQL在DOS下的基本命令操作

啟動net start mysql 重置root密碼 方法一:在my.ini的[mysqld]字段加入&#xff1a; skip-grant-tables 重啟mysql服務&#xff0c;這時的mysql不需要密碼即可登錄數據庫然后進入mysql mysql>use mysql;mysql>更新 user set passwordpassword(新密碼) WHERE Userroot; …

strlen的神奇實現

https://blog.delphij.net/2012/04/freebsd-strlen3.html 與 Pascal 等語言不同&#xff0c;C 的字符串并不保存串的長度&#xff0c;而是在字符串末尾以 nul 字符&#xff08;\0&#xff09;來表示字符串結束。這個設計決策是上世紀 60 年代作出的&#xff0c;有都市傳說是為了…

python求和_Python程序查找特殊求和系列的解決方案

python求和We are going to design a special sum series function which has following characteristics: 我們將設計一個特殊的求和系列函數&#xff0c;該函數具有以下特征&#xff1a; f(0) 0f(1) 1f(2) 1f(3) 0f(x) f(x-1) f(x-3)Python solution of the above sum…

linux內核設計與實現---進程管理

進程管理1 進程描述符及任務結構分配進程描述符進程描述符的存放進程狀態設置當前進程狀態進程上下文進程家族樹2 進程創建寫時拷貝fork()vfork()3 線程在Linux中的實現內核線程4 進程終結刪除進程描述符孤兒進程造成的進退微谷5 小結進程的另一個名字叫做任務&#xff08;task…

JS錯誤代碼解釋大全+VBS錯誤代碼解釋大全

JScript 運行時錯誤 JScript 運行時錯誤是指當 JScript 腳本試圖執行一個系統不能運行的動作時導致的錯誤。當正在運行腳本、計算變量表達式、或者正在動態分配內存時出現 JScript 運行時錯誤時。 錯誤號 描述 5029 數組長度必須為一有限正整數 5030 必須賦給數組長度一個有…

生日蠟燭(藍橋杯)

某君從某年開始每年都舉辦一次生日party&#xff0c;并且每次都要吹熄與年齡相同根數的蠟燭。 現在算起來&#xff0c;他一共吹熄了236根蠟燭。 請問&#xff0c;他從多少歲開始過生日party的&#xff1f; 請填寫他開始過生日party的年齡數。 注意&#xff1a;你提交的應該是…

python日歷模塊_Python日歷模塊| firstweekday()方法與示例

python日歷模塊Python calendar.firstweekday()方法 (Python calendar.firstweekday() Method) firstweekday() method is an inbuilt method of the calendar module in Python. It works on simple text calendars and returns the current setting for the weekday to start…

php 處理 mysql to json, 前臺js處理

public function GetJson(){$query"select * from table";$result mysql_query($query);$rows array();while($row mysql_fetch_array($result)){$rows [] $row;}echo json_encode($rows); } js處理 $.get( "./bll.php", option,function(data ) {var j…

Linux內核設計與實現---進程調度

進程調度1 策略I/O消耗型和處理器消耗型的進程進程優先級時間片進程搶占2 Linux調度算法可執行隊列優先級數組重新計算時間片schedule()計算優先級和時間片睡眠和喚醒負載平衡程序3 搶占和上下文切換用戶搶占內核搶占4 實時5 與調度相關的系統調用與調度策略和優先級相關的系統…

ServletContext(核心內容)

什么是ServletContext對象 ServletContext代表是一個web應用的環境&#xff08;上下文&#xff09;對象&#xff0c;ServletContext對象 內部封裝是該web應用的信息&#xff0c;ServletContext對象一個web應用只有一個 一個web應用有多個servlet對象 ServletContext對象的生…

【轉載】[TC]飛船動畫例子--《C高級實用程序設計》

【聲明和備注】本例子屬于轉載來源于《C高級實用程序設計》&#xff08;王士元&#xff0c;清華大學出版社&#xff09;第11章&#xff0c;菜單設計與動畫技術&#xff0c;第11.5節&#xff0c;一個動畫例子。 本例講解的是在一個繁星背景下&#xff0c;一個由經緯線組成的藍色…

math.sqrt 有問題_JavaScript中帶有示例的Math.SQRT2屬性

math.sqrt 有問題JavaScript | Math.SQRT2屬性 (JavaScript | Math.SQRT2 Property) Math.SQRT2 is a property in math library of JavaScript that is used to find the value of square root of 2. It is generally used to solve problems related to circular figures. Ma…

Linux內核設計與實現---系統調用

系統調用1 API、POSIX和C庫2 系統調用系統調用號3 系統調用處理程序指定恰當的系統調用參數傳遞4 系統調用的實現參數驗證5 系統調用上下文綁定一個系統調用的最后步驟從用戶空間訪問系統調用為什么不通過系統調用的方式實現1 API、POSIX和C庫 API&#xff1a;應用編程接口。一…

內核編譯配置選項含義

Linux 2.6.19.x 內核編譯配置選項簡介 作者&#xff1a;金步國 版權聲明 本文作者是一位自由軟件愛好者&#xff0c;所以本文雖然不是軟件&#xff0c;但是本著 GPL 的精神發布。任何人都可以自由使用、轉載、復制和再分發&#xff0c;但必須保留作者署名&#xff0c;亦不得對聲…

js編碼處理(轉)

js編碼處理(轉) 1. 使用 JS 中的 encodeURIComponent 或 encodeURI 方法。 說明&#xff1a; encodeURIComponent(String) 對傳遞參數進行設置。不編碼字符有 71 個&#xff1a; ! &#xff0c; &#xff0c; ( &#xff0c; ) &#xff0c; * &#xff0c; - &#…

手動去設置HTTP響應行、響應頭、響應體

①手動去設置HTTP響應行中的狀態碼&#xff0c;這里用到了response的setStatus(int sc);這個方法 package com.itheima.line;import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpSer…

Java SecurityManager checkListen()方法與示例

SecurityManager類的checkListen()方法 (SecurityManager Class checkListen() method) checkListen() method is available in java.lang package. checkListen()方法在java.lang包中可用。 checkListen() method invokes checkPermission with the given SocketPermission(&q…

基本的二分查找、尋找第一個和最后一個數的二分查找

二分查找1 二分查找的框架2 尋找一個數&#xff08;基本的二分搜索&#xff09;3 尋找左側邊界的二分搜索4 尋找右側邊界的二分查找5 合并二分查找場景&#xff1a;有序數組尋找一個數、尋找左側邊界&#xff08;有序數組第一個等目標數的下標&#xff09;、尋找右側邊界&#…

PostgreSQL 中的遞歸查詢 與oracle 的比較

PostgreSQL 中的遞歸查詢&#xff0c;2種方法&#xff1a; 1、用with decursive WITH RECURSIVE d AS (SELECT d1.id,d1.parent_id,d1.caption FROM course_types d1 where d1.dr 0 and d1.idtypeId union ALL SELECT d2.id,d2.parent_id,d2.caption FROM course_types d2, d …

教你如何玩轉GitHub

使用GitHub ①目的&#xff1a;借助GitHub托管項目代碼 基本概念&#xff1a; ①倉庫(Repository)&#xff1a; 用來存放項目代碼&#xff0c;每個項目對應一個倉庫&#xff0c;多個開源項目對應多個倉庫 ②收藏(Star)&#xff1a; 收藏項目&#xff0c;方便下次查看 ③…