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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux shell 宏定义_linux内核修炼之系统调用

發(fā)布時(shí)間:2023/12/1 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux shell 宏定义_linux内核修炼之系统调用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

fork()這個(gè)系統(tǒng)調(diào)用是有兩個(gè)返回值的,在子進(jìn)程中的返回值是0,在父進(jìn)程中的返回值是PID,如下

圖 fork一次 返回兩次

關(guān)于0x80中斷和特權(quán)級(jí)檢查

在mian函數(shù)的sched_init()函數(shù)中調(diào)用宏:set_system_gate(0x80,&system_call);將0x80號(hào)中斷安裝到中斷表里。可見(jiàn)將0x80中斷安裝進(jìn)了head.s中定義的IDT表中的第0x80項(xiàng),將中斷函數(shù)入口偏移地址設(shè)置為system_call,將特權(quán)級(jí)設(shè)置為3。至于為什么沒(méi)有看見(jiàn)可以自定義段描述符的地方,因?yàn)閟et_system_gate這個(gè)宏的作用是用來(lái)安裝系統(tǒng)調(diào)用中斷,而系統(tǒng)調(diào)用函數(shù)是內(nèi)核函數(shù),內(nèi)核所在的代碼段描述符值是0x8,這個(gè)是已經(jīng)定死了的。安裝描述符時(shí)不需要修改。

IDT表項(xiàng)安裝好后,一旦用戶程序執(zhí)行0x80中斷,則首先進(jìn)行特權(quán)檢查,用戶程序的CPL為3,0x80中斷的DPL也為3,因此可以執(zhí)行該中斷,中斷將跳入內(nèi)核函數(shù)中執(zhí)行,硬件會(huì)自動(dòng)得將0x8寫(xiě)入CS,將偏移地址寫(xiě)入EIP,從而執(zhí)行systemcall,且CPL此時(shí)也已被修改為0,從而完成了特權(quán)級(jí)切換。

當(dāng)使用jumpi指令進(jìn)行段間跳轉(zhuǎn)的時(shí)候會(huì)對(duì)比CS中的CPL和目標(biāo)GDT中的代碼段的DPL,段內(nèi)跳轉(zhuǎn)不對(duì)比;當(dāng)使用mov的指令進(jìn)行段間內(nèi)存訪問(wèn)會(huì)對(duì)比DS中的CPL和目標(biāo)GDT中的代碼段的DPL,段內(nèi)內(nèi)存訪問(wèn)不對(duì)比,使用中斷跳到中斷服務(wù)程序的時(shí)候也會(huì)發(fā)生段間跳轉(zhuǎn),此時(shí)會(huì)對(duì)比CS中的CPL和IDT表項(xiàng)中的DPL。

圖 安裝中斷的宏

使用bochs進(jìn)行實(shí)驗(yàn)時(shí),需要關(guān)注兩個(gè)文件,一個(gè)是源碼文件夾linux-0.11下的image文件,一個(gè)是oslab文件夾下的hdc-0.11-new.img 文件,源碼文件夾下的image文件每次編譯源碼時(shí)都會(huì)重新生成,是內(nèi)核代碼文件;而.img是一個(gè)根文件系統(tǒng)鏡像,他與/linux-0.11文件夾下的源碼無(wú)關(guān)。

Bochs會(huì)虛擬出一個(gè)軟盤(pán)和一個(gè)硬盤(pán),軟盤(pán)中放image,硬盤(pán)中放.img,bochs在啟動(dòng)是會(huì)從軟盤(pán)啟動(dòng),從而將image中的之前講的bootset 、setup、 head和 sys內(nèi)核程序按照之前講過(guò)的順序邊讀入內(nèi)存邊執(zhí)行。當(dāng)執(zhí)行到main()中的init()函數(shù)時(shí),這個(gè)函數(shù)的第一句話 setup((void *) &drive_info); 就是調(diào)用setup系統(tǒng)調(diào)用,安裝根目錄文件系統(tǒng),如果此時(shí)沒(méi)有.img文件,則可以在虛擬機(jī)頁(yè)面中看到loading system…之后便報(bào)錯(cuò),報(bào)錯(cuò)的語(yǔ)句是printk("Unable to read partition table of drive %dnr", 可以在代碼中搜到,即在執(zhí)行setup系統(tǒng)調(diào)用時(shí)報(bào)錯(cuò)。

文件系統(tǒng)加載完成后,就可以在shell中用ls查看各種文件和目錄。當(dāng)然也可以不啟動(dòng)linux0.11,而是在Ubuntu中將.img文件mount到某個(gè)目錄下,則點(diǎn)進(jìn)去看到的東西跟啟動(dòng)linux0.11后的根文件目錄ls后看到的一樣。

李志軍老師的系統(tǒng)調(diào)用試驗(yàn)新增三個(gè)文件:who.c 、iam.c和whoami.c三個(gè)文件。其中who.c是新增的內(nèi)核文件,寫(xiě)好放在源碼的kernel文件夾下,至于為什么要用get_fs_byte來(lái)實(shí)現(xiàn)內(nèi)存的訪問(wèn),因?yàn)閮?nèi)核中的ds描述符默認(rèn)是內(nèi)核數(shù)據(jù)段,而我們實(shí)際也需要訪問(wèn)用戶數(shù)據(jù)段,需要用到fs描述符,因此要加一層封裝,這點(diǎn)在李老師書(shū)里詳細(xì)說(shuō)明。

who.c 寫(xiě)好后需要重新編譯內(nèi)核然后bochs加載進(jìn)入shell,在shell中新建iam.c和whoami.c然后進(jìn)行編譯。編譯出來(lái)的是用戶程序,這兩個(gè)c文件在編譯的時(shí)候需要 編譯一個(gè)_syscall2(int, whoami, char*, name, unsigned int, size);這種宏,宏中有一個(gè)變量是在unistd.h中定義的,要修改這個(gè)文件不應(yīng)該在linux0.11的源碼中找,而應(yīng)該需要在文件系統(tǒng)中的/usr/include文件夾中找到并修改,因?yàn)樵创a此時(shí)已經(jīng)編譯成內(nèi)核轉(zhuǎn)載軟驅(qū)載入內(nèi)存中在跑,修改源碼的源文件無(wú)意義。在shell的環(huán)境中找到include的文件,并進(jìn)行修改。

#include <string.h> #include <errno.h> #include <asm/segment.h>char msg[24];int sys_iam(const char * name) {char tep[26];int i = 0;for(; i < 26; i++){tep[i] = get_fs_byte(name+i);if(tep[i] == '0') break;}if (i > 23) return -(EINVAL);strcpy(msg, tep);return i; }int sys_whoami(char * name, unsigned int size) {int len = 0;for (;msg[len] != '0'; len++);if (len > size) {return -(EINVAL);}int i = 0;for(i = 0; i < size; i++){put_fs_byte(msg[i], name+i);if(msg[i] == '0') break;}return i; }

圖 who.c代碼

總結(jié)

以上是生活随笔為你收集整理的linux shell 宏定义_linux内核修炼之系统调用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。