創作內容

4 GP

手把手編譯linux與新增syscall

作者:W.Dinlon│2023-04-13 18:22:26│巴幣:8│人氣:1414
版權所有,禁止非授權轉載,尤其是中國網站。

這篇筆記主要是給我在作業系統核心課程上的同學看的,預設讀者已經熟悉C、linux故不會進行過多理論上的講解。不過這篇已經是手把手教你完成任務了,即使沒有相關知識也能完成。

這個筆記講述了如何於建立 VirtualBox 7.0 的 Ubuntu 22.0.10 上編譯 linux-6.0.1,並於其中加入指定 syscall。

以下是作業內容 :
  1. Write a system call, number_of_processes( ), which a C program can invoke to print out the number of processes existing (regardless their states) in the system.
  2. Write a system call, largest_process_id( ), which a C program can invoke to print out the largest process id currently in the system.

目錄

  • 虛擬機安裝
  • Ubuntu 命令列修復
  • 新增 system call 流程
  • 編譯 linux kernel 流程
  • 測試 syscall 方法
  • 參考內容

虛擬機安裝

這邊使用 VMbox,並使用 Ubuntu 22.0.10 進行作業。

1.安裝 VMbox (這部分請自己裝)

2. 下載 Ubuntu 22.0.10 映像檔 ( ubuntu-22.10-desktop-amd64.iso )

3. 安裝映像檔,工具>新增>輸入名稱、映像檔位置與資料

4.更換密碼 (預設為 “changeme”)

5. 設定記憶體與核心數( 越大越好,核心要編譯很久 )

6.設定記憶體與核心數( 越大越好,這東西要編譯很久 )

7. 開啟您的機器,並開始設定初始化
8. (可選) 編譯完成後把左邊的快捷圖示 unpin掉,留下檔案管理 、 terminal (需加入最愛)。


Ubuntu命令列修復
進入介面後,通常會打開terminal 來進行命令,但是你會發現打不開。這時候就需要進行此項修復操作。
1. 按下 ctrl + alt + F3 進入命令模式
2. 使用 “root” 與前面設定的密碼登入
3. 以下命令 ( 巴哈不能用code格式,哭阿 )

apt install vim
# 如果有出現 Y/N 選項,按下 Y

vim /etc/default/locale
# 這時候進入vim了,利用上下鍵把指標移到 LANG="en_US"
# 單點 i 進入編輯模式
# 把該行改成 LANG="en_US.UTF-8"

# 按下 esc 鍵入 :x (冒號與x)即可儲存

# 使用命令檢視文本,輸出應如下圖
cat /etc/default/locale


添加用戶至 sudoer

還記得在虛擬機安裝第 4 步時新增了一位用戶嗎 ?他並不是 sudoer 故無法使用 sudo 命令來提權。現在把她加入 sudoer。

vim /etc/sudoers
# 找到 root ALL=(ALL:ALL) ALL,在該行下行按下 i 編輯
# 添加
vboxuser ALL=(ALL:ALL) ALL
# 按下 esc 鍵入 :x! 儲存

完成後使用 reboot 重啟系統你會發現 terminal 可以開了。
測試 sudo 權限

sudo apt install sl
# 輸入密碼
sl
這時候看到一台火車就代表成功了

共用剪貼簿(可選)

把共用剪貼簿打開就不用打一堆字。

1. 看圖,依序按下這兩個


2.按下那個光碟片,找到  autorun.sh,右鍵 Run as Program,輸入密碼。

3. 完成後在光碟片上右鍵 rejet 退出碟片。使用 reboot 重啟。這時候你就完成共用剪貼簿的設置了。


新增system call流程 (前)

1. 首先,要升級並安裝編譯工具。以下是我整理出的一堆東西,超亂

sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
sudo apt-get install gcc
sudo apt-get install libncurses5-dev
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get install libssl-dev
sudo apt-get install libelf-dev
sudo apt-get install gedit
sudo apt-get update
sudo apt-get upgrade

複製、貼上、Enter、輸入密碼、看到 Y/N 就按Y

2. 下載 linux kernel source code。這邊使用交大鏡像站的這個檔案。強烈建議使用 6.0.1,新版是不一樣的編譯方法。

或是使用 links 進行連接

sudo apt install links
links http://kernel.cs.nycu.edu.tw/
# 找到目標檔案並下載他
# 完成後按下 ctrl-C 結束連接

tar -xf linux-6.0.1.tar.gz
poweroff   # 關機

3. 這時候已經完成核心下載了,避免你之後搞砸了,所以先關機存檔。
選到你的機器,按下擷取按鈕。

4. 完成後就可以啟動了

新增system call流程 (後)

這時候你終於可以寫關於核心的代碼了

1. 以下命令設好位置

# 你有存檔了 su 搞砸也沒關係 XD
su
# 進入你放 kernel 資料夾的目錄前一頁
mv linux-6.0.1 /usr/src/
cd /usr/src/linux-6.0.1/

2. 以下命令建立 syscall 代碼

mkdir myFunction
cd myFunction
gedit Makefile
# 輸入
obj-y := number_of_processes.o largest_process_id.o
# ctrl + S 存檔
3. 接下來是兩個 syscall 的代碼
備註 : 如果您有上這堂課,請改一下,不要直接抄襲。

gedit number_of_processes.c

#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/sched.h>

SYSCALL_DEFINE0(number_of_processes)
{
    struct task_struct *task;
    long process_count=0;
    for_each_process(task) {
        process_count++;
    }
    // 禁止非授權轉載,尤其是中國網站。
    printk(KERN_INFO "There are %d processes currently existing in the system\n", process_count);
    return process_count;
}

gedit largest_process_id.c

#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/sched.h>

SYSCALL_DEFINE0(largest_process_id)
{
    struct task_struct *task;
    pid_t m_pid = 0;
    
    for_each_process(task) {
        if (task->pid > m_pid) {
            m_pid = task->pid;
        }
    }
    
    printk(KERN_INFO "The largest process id currently in the system is %d\n", m_pid);
    // 禁止非授權轉載,尤其是中國網站。
    return m_pid;
}

4.設定引用文件
root@ubuntu02:/usr/src/linux-6.0.1/myFunction# cd ..
root@ubuntu02:/usr/src/linux-6.0.1#gedit Makefile

找到 1104 行 core-y,在行末加上 syscall 的資料夾並存檔

5.新增 syscall 到 table 上
root@ubuntu02:/usr/src/linux-6.0.1# gedit ./arch/x86/entry/syscalls/syscall_64.tbl

添加 syscall 至末尾 ( 編號為 最後syscall編號+1 )
548commonnumber_of_processessys_number_of_processes
549commonlargest_process_idsys_largest_process_id
如圖 :

6. 然後是函示宣告設定,記得分號要打
root@ubuntu02:/usr/src/linux-6.0.1# gedit ./include/linux/syscalls.h
添加至末尾
asmlinkage long sys_number_of_processes(void);
asmlinkage long sys_largest_process_id(void);


到這邊你已經完成,接下來就是編譯。這是漫長的流程,若您做到這邊,建議先建立還原映像點。


編譯 system call 流程

這邊是最簡單,但最多麻煩也最久的部分,祝你好運。

1.如果你剛剛有退出,請回到 su 模式

2.至設定把銀幕保護關閉( Screen Blank )

3.設定 .config 檔,如果這邊跳錯誤訊息請調整視窗至視窗化。
root@ubuntu02:/usr/src/linux-6.0.1# make menuconfig

方向鍵按下 Save,然後儲存後回來主選單,完成 Exit 即完成。

4. 設定憑證,這部分不會有顯示回應
scripts/config --disable SYSTEM_TRUSTED_KEYS
scripts/config --disable SYSTEM_REVOCATION_KEYS

5. 檢查核心數量 nproc ,記下有多少核心數。
6. 如果電腦有高效能模式請打開
7. 把電腦上會干擾速度的程式關掉,包括這個教學網頁
8. 開始編譯
make -j12 # j後面的數字是你的核心數,越多越快
# 然後有選項就直接按 Enter過去

9. 祈禱、去吃飯或看貓之類的,反正會跑很久。
10. 出現這行代表成功。若失敗的話可以往前面拉,找哪邊出 Error
Kernel: arch/x86/boot/bzImage is ready  (#1)

11. 使用以下命令進行安裝 (12為核心數)
sudo make modules_install -j12
sudo make install -j12
sudo update-grub
reboot

終於完成了
機器啟動後使用 uname -mrs 檢視系統版本,若如以下畫面即成功


測試 syscall 方法

當我們完成後,使用 C 來測試寫好的 syscall。以下是我的範例程式,當然,請不要抄襲 :

#include <linux/kernel.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define __NR_number_of_processes 548
#define __NR_largest_process_id 549

long number_of_processes(void)
{
  return syscall(__NR_number_of_processes);
}

long largest_process_id(void)
{
  return syscall(__NR_largest_process_id);
}

int main(){
  long max_process_id=0;
  long process_count=0;
  int sys_2f44=0;
  max_process_id=largest_process_id();
  process_count=number_of_processes();
  
  if(max_process_id<0){
    printf("max_process_id fail!%d\n",sys_2f44);
  }else{
    printf("success!\nlargest_process_id is : %ld\n",(long)max_process_id);
  }
  
  if(process_count<0){
    printf("process_count fail!%d\n",sys_2f44);
  }else{
    printf("success!\nProcess_count is : %ld\n",(long)process_count);
  }
  
  return 0;
}


參考內容

好久沒寫教學了,沒想到鐵人賽之後還有機會寫這類型的文。
最後再宣告一次,版權所有,禁止非授權轉載,尤其是中國網站。
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=5696940
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:linux kernel|程式|程式設計|linux

留言共 1 篇留言

偷偷做不會被發現

04-13 18:25

我要留言提醒:您尚未登入,請先登入再留言

4喜歡★ton200168 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:2022 年度回顧&am... 後一篇:在校外利用 SSH 看論...

追蹤私訊切換新版閱覽

作品資料夾

god44675566喜歡動畫的你
有許多動畫心得與點評出爐囉~ 可以上我的YT去看看,不知道會不會有你喜歡的呢?看更多我要大聲說昨天22:17


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】