linux內核
-
內核組成
- 內存管理
- /proc/meminfo 可以查看物理內存以及交換區大小
- ipcs -m 可以查看共享內存使用情況
- 設備管理
- 插入設備驅動代碼
- 將驅動代碼編譯進內核代碼
- 將驅動代碼插入到運行的內核
- 設備文件類型
- 字節類型
- 塊類型
- 網絡類型
- 插入設備驅動代碼
- 文件系統管理
- 文件類型
文件系統 描述 affs Amiga 文件系統 ext linux擴展文件系統 ext2 二代 ext3 3代 hpfs OS/2 高性能文件系統 iso9660 ISO 9660 文件系統 minix MINIX文件系統 msdos Microsoft FAT16 ncp Netware 文件系統 proc 訪問系統信息 reiserfs Journaling 文件系統 sysv 老一代UNIX文件系統 ufs BSD文件系統 umsdos 類UNIX文件系統 vfat Windows 95文件系統 - 進程管理
- 命令
ps options
- 命令
- 內存管理
-
內核版本
- 內核格式
linux-a.b.c - 命令
uname -a
- 內核格式
系統調用
-
查找系統調用
- 查找文件
/usr/include/asm/unistd.h
- 查找文件
-
查找系統調用定義
- 命令示例
man 2 exit - 說明
2 : 幫助文檔的第二部分 - 結構
- 名稱: 系統調用的名稱
- 大綱: 系統調用的用法
- 描述: 系統調用的基本描述
- 返回值: 系統調用的返回值
- 命令示例
-
一般的系統調用
- 內存訪問相關
系統調用 | 描述 |
---|---|
brk | 變更數據段大小 |
mlock | 關閉部分內存的分頁 |
mlockall | 關閉調度進程的分頁 |
mmap | 映射文件或設備到內存 |
mprotect | 控制一段內存的訪問 |
mremap | 重新映射一段虛擬內存 |
msync | 同步文件和內存的映射 |
munlock | 打開一段內存的分頁 |
munlockall | 打開調用進程的所有分頁 |
munmap | 關閉文件或者設備到內存的映射 |
* 設備訪問相關
系統調用 | 描述 |
---|---|
access | 檢查設備的權限 |
chmod | 改變一個設備的權限 |
chown | 改變一個設備的所有者 |
close | 關閉設備的文件描述符 |
dup | 複製設備文件描述符 |
fcntl | 管理文件描述符 |
fstat | 獲得設備狀態 |
ioctl | 控制設備參數 |
link | 給文件描述符分配一個新名字 |
lseek | 重新分配文件描述符的偏移 |
mknod | 爲一個設備新建一個文件描述符 |
open | 爲一個文件或設備打開一個文件描述符 |
read | 從一個設備文件描述符讀數據 |
write | 向一個設備文件描述符寫數據 |
- 文件系統相關
|系統調用| 描述|
|chdir| 改變工作目錄|
|chroot| 改變根目錄|
|flock|應用或移除一個文件的公告鎖|
|statfs|獲得一個文件系統的狀態|
|getcwd|獲得當前工作目錄|
|mkdir|創建目錄|
|rmdir|移除目錄|
|symlink|爲一個文件重新命名|
|umask|設置文件的掩碼|
|mount|掛載或者解除掛載文件系統|
|swpon|開始交換內存到文件系統|
|swapoff|結束交換內存到文件系統|
- 進程系統相關
系統調用 | 描述 |
---|---|
acct | 打開或關閉文件計數 |
capget | 獲得進程權限 |
capset | 設置進程權限 |
clone | 克隆一個子進程 |
execve | 執行一個程序 |
exit | 結束當前進程 |
fork | 創建一個子進程 |
getgid | 獲得組id |
getpgrp | 獲得或設置進程組 |
getppid | 獲得進程標識 |
getpriority | 獲得進程調度級別 |
getuid | 獲得用戶標識 |
kill | 發送一個信號殺死進程 |
nice | 改變進程的優先級 |
vfork | 創建一個子進程並阻塞父進程 |
使用系統調用
- 系統調用的格式
- 系統調用的值
- movl $1, %eax #1 系統調用的值
- int $0x80
- 系統調用輸入值
- EBX (第一個參數)
- ECX(第二個參數)
- EDX(第三個參數)
- ESI(第四個參數)
- EDI(第五個參數)
- 如果超過五個參數使用ebx存儲參數的內存指針,參數在內存中順序存儲
- 示例
- 系統調用的值
# syscalltest.s - An example of passing input values to a system call
# ssize_t write(int fd, const void *buf, size_t count)
.section .data
output:
ascii "This is a test message.\n"
output_end
.equ len, out_end - output
.section .text
.globl _start
_start:
movl $4, %eax
movl $1, %ebx
movl $output, %ecx
movl $len, %edx
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80
* 系統調用返回值
* 格式
EAX存儲返回值
* 示例
#syscalltest.s - An example of getting a return value from a system call
.section .bss
.lcomm pid, 4
.lcomm uid, 4
.lcomm gid, 4
.section .text
.globl _start
_start:
movl $20, %eax # getpid
int $0x80
movl %eax, pid
movl $24, %eax # getuid
int $0x80
movl %eax, uid
movl $47, %eax # getgid
int $0x80
movl %eax, pid
movl $1, %eax
movl $0, %ebx
int $0x80
高級系統調用返回值
- sysinfo 系統調用
-
說明
NAME
sysinfo -return information on overall system statistics
SYNOPSIS
#include<sys/sysinfo.h>int sysinfo(struct sysinfo *info); struct sysinfo{ long uptime; /*運行的秒數*/ unsigned long loads[3]; /*1,5,15分鐘的平均負載*/ unsigned long totalram; /* 當前使用的內存*/ unsigned long freeram; /*可用內存數*/ unsigned long sharedram; /*共享內存數*/ unsigned long bufferram; /* 緩存內存大小*/ unsigned long totalswap; /* 交換空間大小*/ unsigned long freeswap; /* 可用的交換空間大小*/ unsigned long procs; /*當前進程數*/ unsigned long totalhigh; /*當前高內存數*/ unsigned long mem_unit;/*內存單元字節數*/ char _f[20-2*sizeof(long)-sizeof(int)]; /*libc5的填充
- 示例
-
# sysinfo.s - Retrieving system information via kernal system calls
.section .data
result:
uptime:
.int 0
load1:
.int 0
load5:
.int 0
load15:
.int 0
totalram:
.int 0
freeram:
.int 0
sharedram:
.int 0
bufferram:
.int 0
totalswap:
.int 0
freeswap:
.int 0
procs:
.byte 0x00, 0x00
totalhigh:
.int 0
memuint:
.int 0
.section .text
.globl _start
_start:
nop
movl $result, %ebx
movl $116, %eax
int $0x80
movl $0, %ebx
movl $1, %eax
int $0x80
跟蹤系統調用
- strace 程序
- strace ./exec
- strace -c ./exec
- strace 的高級參數
參數 | 描述 |
---|---|
-c | 統計每個系統調用的時間,錯誤信息等 |
-d | 顯示strace的調試信息 |
-e | 指定一個輸出的過濾器 |
-f | 跟蹤子進程 |
-ff | 如果寫入輸出文件,每個進程寫一個單獨文件 |
-i | 打印系統調用的指令指針 |
-o | 指定輸出文件 |
-p | 附加到一個pid |
-q | 抑制附加信息 |
-r | 打印一個相對的時間戳 |
-t | 每一行附加時間 |
-tt | 附加毫秒時間 |
-ttt | 附加微妙時間 |
-T | 顯示每個系統調用的耗時 |
-v | 打印詳細的系統調用版本 |
-x | 用16進制打印非ASCII字符 |
-xx | 用16進制打印所有字符串 |
- 跟蹤一個運行的程序
- 示例
# nanotest.s - Another example of using system calls
.section .data
timespec:
.int 5, 0
output:
.ascii "This is a test\n"
output_end:
.equ len, output_end - output
.section .bss
.lcomm rem, 8
.section .text
.globl _start
_start:
nop
movl $10, %ecx
loop1:
pushl %ecx
movl $4, %eax
movl $1, %ebx
movl $output, %ecx
movl $len, %edx
int $0x80
movl $162, %eax # nanosleep
movl $timespec, %ebx
movl $rem, %ecx
int $0x80
popl %ecx
loop loop1
movl $1, %eax
movl $0, %ebx
int $0x80
* 說明
SYNOPSIS:
#include <time.h>
int nanosleep(const struct *req, struct timespec *rem);
struct timespec
{
time_t tv_sec; /* 秒*/
long tv_nsec; /* 納秒*/
};
* 運行
./nanotest &
ps ax | grep nanotest
strace -p $pid
系統調用和C庫
- 使用c庫實現上節功能
#cfunctest.s - An example of using C functions */
.section .data
output:
.asciz "This is a test\n"
.section .text
.globl _start
_start:
movl $10, %ecx
loop1:
pushl %ecx
pushl $output
call printf
addl $4, %esp
pushl $5
call sleep
addl $4, %esp
popl %ecx
loop loop1
pushl $0
call exit
-
運行
- as -o cfunctest.o cfunctest.s
- ld -dynamic-linker /lib/ld-linux.so.2 -lc -o cfunctest cfunctest.o
- strace -c ./cfunctest
-
對比使用C庫和直接使用系統調用發現
- 使用系統調用的優點
- 由於不引入外部庫,因此可執行文件小
- 執行速度快
- 不依賴外部庫
- 使用c庫的優點
- C庫方法比較豐富
- c庫可移植性好
- c庫可以使用動態鏈接庫從而減少內存使用
- 使用系統調用的優點