linux执行cd会使用系统调用,深入理解Linux系统调用
一、實驗環境配置
系統環境:Ubuntu16.04
實驗說明:本人學號末兩位70,對應__64x_sys_msgrcv系統調用
注:不能在上次實驗的基礎上做,要重新下載解壓linux-5.4.34文件
1、安裝開發工具
1 sudo apt install build-essential2 sudo apt install qemu # installQEMU3 sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
2、下載內核源碼
1 sudo apt installaxel2 axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/
3 linux-5.4.34.tar.xz4 xz -d linux-5.4.34.tar.xz5 tar -xvf linux-5.4.34.tar
6 cd linux-5.4.34
3、配置內核選項
make defconfig # Default configuration is based on 'x86_64_defconfig'
makemenuconfig
# 打開debug相關選項
Kernel hacking--->Compile-time checks and compiler options --->[*] Compile the kernel with debug info[*] Provide GDB scripts forkernel debugging
[*] Kernel debugging
# 關閉KASLR,否則會導致打斷點失敗
Processor type and features---->[] Randomize the address of the kernel image (KASLR)
4、編譯和運行內核
1 make -j$(nproc) # nproc gives the number of CPU cores/threads2 available3 # 測試?下內核能不能正常加載運?,因為沒有?件系統最終會kernel panic4 qemu-system-x86_64 -kernel arch/x86/boot/bzImage
5、制作根文件系統
1 ?先從https://www.busybox.net下載 busybox源代碼解壓,解壓完成后,跟內核?樣先配置編譯,并安裝。
2 axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2
3 tar -jxvf busybox-1.31.1.tar.bz24 cd busybox-1.31.1
1 makemenuconfig2 記得要編譯成靜態鏈接,不?動態鏈接庫。3 Settings --->
4 [*] Build static binary (no shared libs)5 然后編譯安裝,默認會安裝到源碼?錄下的 _install ?錄中。6 make -j$(nproc) && make install
1 然后制作內存根?件系統鏡像,?致過程如下:2 mkdirrootfs3 cd rootfs4 cp ../busybox-1.31.1/_install/*./ -rf5 mkdir dev proc sys home6 sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
1 準備init腳本?件放在根?件系統跟?錄下(rootfs/init),添加如下內容到init?件。2 #!/bin/sh
3 mount -t proc none /proc4 mount -t sysfs none /sys5 echo "Wellcome MengningOS!"
6 echo "--------------------"
7 cd home8 /bin/sh
9 給init腳本添加可執?權限10 chmod +x init
1 打包成內存根?件系統鏡像(rootfs目錄下)2 find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz3 測試掛載根?件系統,看內核啟動完成后是否執?init腳本4 qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz
可以看到init腳本已被執行
二、使用gdb跟蹤調試
1、gdb問題處理
在用gdb打斷點的時候,出現Remote ‘g’ packet reply is too long錯誤,查詢得到參考解決辦法https://blog.csdn.net/superking3188/article/details/8477574。
改完代碼后進行重新編譯和安裝
./configuremake
make install
2、驗證內核初始化
啟動虛擬機
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s
在linux-5.4.34目錄下啟動gdb
gdb vmlinux
target remote:1234
在start_kernel、trap_init、cou_init、syscall_init位置打上斷點
依次執行,可以清晰的看出系統內核初始化的順序為start_kernel->trap_init->cou_init->syscall_init
3、跟蹤70號系統調用
在linux-5.4.34/arch/x86/entry/syscalls/syscall_64.tbl文件中可以查看70對應的系統調用為__64x_sys_msgrcv
為了觀察該系統調用,在rootfs/home目錄下寫一個程序來觸發系統調用
intmain()
{
asmvolatile("movl $0x46,%eax\n\t" //使?EAX傳遞系統調?號70
"syscall\n\t" //觸發系統調?
);return 0;
}
對該程序進行靜態編譯
gcc testSys.c -o testSys -static
重新打包內存跟文件系統鏡像
?nd . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
啟動虛擬機
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s
在linux-5.4.34目錄下啟動gdb調試
gdb vmlinux
target remote:1234b __64x_sys_msgrcv
c
此時可以看到home目錄下已經存在我們剛剛生成的可執行文件,執行該文件即可觸發70號系統調用
獲取到了70號系統調用的返回信息
使用bt命令查看棧信息
可以看到該系統調用涉及到do_syscall_64和entry_SYSCALL_64兩個內核函數。
三、系統調用的保存和恢復現場
系統調用入口為entry_SYSCALL_64,其中使用了swapgs這一方法來快照式的保存現場,加快了系統調用,隨后對一些相關寄存器進行壓棧操作。
隨后執行了do_syscall_64函數
在do_syscall_64函數中,獲取到系統調用號所對應的入口,跳轉執行。
隨后便執行相關的系統調用
調用結束后恢復現場
四、總結
本次實驗中,學習了gdb工具,使用gdb斷點調試完成了內核初始化順序的驗證;查看了70號系統調用的調用過程,詳細了解了系統調用的保存和恢復現場。
總結
以上是生活随笔為你收集整理的linux执行cd会使用系统调用,深入理解Linux系统调用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言中 c2059错误是,解决erro
- 下一篇: Linux文件系统和文本编辑器