Email me: jollen # jollen.org

more: Jollen 的 Embedded Linux 教育訓練

« September 2006 | (回到Blog入口) | November 2006 »

October 2006 歸檔

October 2, 2006

嵌入式 Linux 應用: Mesh Networking 演講稿 (精簡版部份內容)

#2: 今天 Jollen 要介紹的題目是 "Mesh Router",實作平臺是 Kendin KS8695P 與 embedded Linux 系統。我們在 Kendin KS8695P (ARM9) 的平臺上嵌入 embedded Linux 系統,透過此平臺與 mesh wireless 的 embedded Linux 系統,將能實作出 mesh networking 的系統。

今天我們的重點 (Lecture 8) 是介紹 open source 解決方案與 mesh networking;同時我們也會做一個簡單的 demo。

簡報下載

#3: mesh networking 可以取代 Wi-Fi "hot spots" 的架構,並且簡省無線網路的佈署成本,由於我們以現有的 802.11a+g 的無線網卡來實作,因此可以使用許多現成的 open source 軟體來配合。以藉此達成單點對多點 (point to multipoint)、多點對多點 (multipoint to multipoint) 或是單點對單點 (point-to-point) 的架構實作。

#6: 這是我們所期望做到的規格 (specification),很有趣的是,開放源碼套件居然能滿足我們所開出的所有規格,這意謂我們的 project 需要自己開發軟體的機會幾乎是 0%;事實上,我們 90% 以上的工作都是在做系統整合 (Linux administration) 和 UI (web-based) 的開發。

#7: 這是一個實際 (real-world) 的案例,讓我們來說明我們倒底在 root filesystem 裡放了哪些東西,以及「如何加入」這些東西。

#8: 要 build 一個基本的 wireless 嵌入式 Linux 系統 (root filesystem),我們會需要這些基本的開放源碼套件,另外由於 zeroconf 遭遇到專利問題,因此我們並沒有在這份簡單裡展示 zeroconf IP 的功能。

#9: 再來是 Linux 的無線網路解決方案,在驅動程式方面,我們使用的 Atheros 與 Prism 晶片都有支援。在 user application 方面,wireless routing protocol 的解決方案是 quagga,這是一個相當知名的 open source 專案。另外,wireless tools 是必備的,因此我們要透過它來設定無線網路。

#16: 這是我們利用 iwconfig 在 Kendin 平臺上啟動無線網路的畫面,ath0 介面是 Atheros 網卡 (802.11g),eth2 是 Intersil 網路 (802.11b/g)。

#17: 我們把 ath0 設定成 "ad-hoc" 模式。

#18: 利用 'iwlist' 指令偵測 channel。

#19: 利用 'iwlist' 掃描 eth2 介面。

ps. 不知道大家還想要哪一頁的詳細講稿 @@"

October 3, 2006

Library Dependency 的議題要點

在建立 embedded Linux 系統 (root filesystem) 時,程式庫相依 (library dependencies) 的議題是相當重要的一個題目。

當 root filesystem 缺少必要的 library 時,程式當然是無法執行的,甚致系統也會無法順利啟動。依據 Jollen 在「Embedded Linux / ARM9 開發實戰」的課程所提的幾個觀念,我們可以了解到在建構 embedded Linux 系統時,應具備的正確觀念與基本能力。

我們把「如何找出所需的 library」方法整理出 3 項的基本要點,依照這 3 種基本款來加入 library 將能解決幾乎所有的 library dependency 問題,這 3 種項基本要點為:

(1) 先利用 cross toolchain 的 objdump 觀察「NEEDED」的項目,加入 library。
(2) 再檢查這些 library 是否相依其它 library。
(3) 最後要檢視應用程式是否使用到需要特定 library 的「service」。

要點 1. 跟 2. 對大家來說沒有什麼問題,要點 3. 在我們的 training 課程裡,我們以建構 thttpd (embedded Web server) 的實際案例來做講解。

關於建構 thttpd 的案例

thttpd 使用到 NSS (Name Service Switch),因此若沒有將 libnss_SERVICE.so 加到 root filesystem,thttpd 在執行時可能會遇到一些奇怪的問題。舉個例子,當 thttpd 透過 /etc/passwd 去尋找 (查詢) UNIX user 時,會用到 libnss_files.so (不讀 /etc/shadow),因此會看到以下的錯誤訊息:

unknown user - root

出現這個錯誤的原因是 thttpd 讀不到 'root' 使用者,要深入探討這個問題的原理,必須從以下的程式碼片斷開始探討:

    403     /* If we're root and we're going to become another user, get the uid        /gid
    404     ** now.
    405     */
    406     if ( getuid() == 0 )
    407         {
    408         pwd = getpwnam( user );
    409         if ( pwd == (struct passwd*) 0 )
    410             {
    411             syslog( LOG_CRIT, "unknown user - '%.80s'", user );
    412             (void) fprintf( stderr, "%s: unknown user - '%s'\n", argv0,         user );
    413             exit( 1 );
    414             }
    415         uid = pwd->pw_uid;
    416         gid = pwd->pw_gid;
    417         }

這段程式碼是 thttpd 2.25b 的程式片斷,位於 thttpd.c 的 main() 函數裡。關於 libnss_SERVICE.so 的議題,Jollen 打算另外再做討論,因為還會與 libc 有關係。

在這裡我們由系統建構的角度來看這個問題。因為我們已經習慣用 objdump 來觀察程式的相依 library,所以當 objdump 的畫面跟我們預期的不同時,經常一時無法反應過來。例如,以下的訊息是我們所「預期」的:

# /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-objdump -x thttpd|more
...
Dynamic Section:
  NEEDED      libcrypt.so.1
  NEEDED      libnss_files.so.2
  NEEDED      libc.so.6
...

但是實際的訊息卻是像這樣的:

# /opt/crosstool/gcc-3.4.1-glibc-2.3.3/arm-9tdmi-linux-gnu/bin/arm-9tdmi-linux-gnu-objdump -x thttpd|more
...
Dynamic Section:
  NEEDED      libcrypt.so.1
  NEEDED      libc.so.6
...

我們可以用一知半解的思考邏輯來解決問題:thttpd 呼叫到 getpwnam() 函數,此函數由 libnss_compat 提供,因此解決方案是把 libnss_files.so 加到 root filesystem 裡即可。

且慢!前面才講到 libnss_compat,怎麼後面是把 libnss_files 加到 root filesystem?是這樣的,libnss_compat 用來讀 /etc/shadow,但是現在我們只需要由 /etc/passwd 讀 Unix user,所以使用 libnss_files.so 就行了。

執行 thttpd 的話,再加上指定 username 的參數來執行:

# thttpd -p 80 -d /var/www -u root

libnss_SERVICE.so 是包含在 glibc 裡的程式庫,因此可以直接由 cross toolchain 裡取得,不必再另行建置。

有關 NSS (Name Service Switch) 可參考以下網頁:

Linux / Unix Command: nsswitch.conf - http://linux.about.com/od/commands/l/blcmdl5_nsswitc.htm

其它網路資源:

http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html
http://mirrors.usc.edu/pub/gnu/Manuals/glibc-2.2.3/html_chapter/libc_28.html

此處我們以「service」的角度來探討這個問題:因為 thttpd 使用到 Name Service Switch,所以需要加入 libnss_SERVICE.so。另外一種探討的角度是:由 programming 的角度來思考,大家可以試著去研究這個問題,還挺好玩的!

附帶一提,如果要讀 shadow passwd 的話,是使用 libnss_compat.so。

Name Service Switch 程式設計:基本觀念

有些 C 函數的運作會依據 localhost 的設定而有不同行為,而這些設定的做法是透過「設定檔」(eg. /etc/services) 來實現。目前在 GNU/Linux 系統底下,可以看到許多這樣的設定檔,我們把這些設定檔稱為 system database,這些資料庫主要是以文字檔方式儲存重要的系統資訊,例如: /etc/passwd 存放使用者名稱、/etc/services 存放網路服務的通訊埠 (port) 設定等等。

GNU C library 實作的 "Name Service Switch" 函數群便是用來讀取所有 system database 內容的介面!

System Database

NSS 支援 11 種資料庫名稱:aliases、ethers、group、hosts、netgroup、networks、protocols、passwd、rpc、services 與 shadow。分別說明如下。

aliases: Mail 別名

ethers: Ethernet 號碼

group: 使用者群組資料庫,即 /etc/group

hosts: Host names 與 IP 對應資料庫,即 /etc/hosts 或是利用 name server 轉換

netgroup: "hostname username domainname" 的組合稱為 netgroup

networks: 即 /etc/networks

protocols: 通訊協定資料庫,即 /etc/protocols

passwd: 使用者名稱資料庫,即 /etc/passwd

rpc: Remote procedure call 資料庫

services: 即 /etc/services 資料庫

shadow: 即 /etc/shadow 檔

NSS Service 與 Lookup

NSS 支援 7 種服務類型,說明如下。

1. nisplus (or nis+): 使用 NIS+ (NIS version 3) 服務
2, nis (or yp): 使用 NIS (NIS version 2) 服務 (也叫 YP, YellowPage)
3. dns: 使用 DNS (Domain Name Service) 服務
4. files: 使用一般的檔案讀取服務
5. db: 使用 database (.db) 檔案讀取服務
6. compat: 使用 NIS compat mode 服務
7. hesiod: 使用 Hesiod 服務做 user lookups

GNU 的實作是把每一個服務 (service) 實作成不同的 module (shared library),因此可以在 GNU/Linux 系統底下找到這些相對應的 shared libraries:

libnss_nisplus.so.2
libnss_nis.so.2
libnss_dns.so.2
libnss_files.so.2
libnss_compat.so.2
libnss_hesiod.so.2

不過其實還有下面 3 個:

/lib/libnss_ldap.so.2
/lib/libnss_winbind.so.2
/lib/libnss_wins.so.2

GNU 的 NSS module 是以 libnss_SERVICE.so.2 來命名。

在這些 module (library) 裡的函數,是無法讓程式直接使用的,因此了解這些 module 裡的函數如何被使用 (呼叫) 是一個重要且有趣的題目。

查詢前面所提 11 種資料庫資訊的動作稱為 lookup,lookup 的方法便是 NSS 的服務類型 (NSS service),也就是我們可以利用以上共 7 種方式來查詢 system database;不過,以 files、db、nis 與 nisplus 這 4 種方式是比較常用的。

由此可知,不同的 system database 可以用不同的服務來做查詢。因此,系統管理員必須告訴 NSS,我們想要他利用哪一種服務類型,來查詢 (lookup) 指定的 system database。這個動作的管理方式便是透過 /etc/nsswitch.conf 設定檔來完成。

/etc/nsswitch.conf

看一下 glibc-2.3.3 預設定 nsswitch.conf 設定檔內容如下:

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
#
passwd:         db files
group:          db files
shadow:         db files
hosts:          files dns
networks:       files dns
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
netgroup:       db files

這樣其實就很清楚了,例如:passwd 資料庫 (/etc/passwd) 的讀取方式 (lookup service) 有 db/files 二種。以 embedded Linux 系統來說,我們會這樣設定:

passwd: files

也就是說,直接以檔案讀取方式來查詢 /etc/passwd。那麼,之前提過的 embedded Linux 系統建置之 thttpd 個案分析,為何需要 libnss_files.so.2 檔案,觀念就很清楚了。

此外,大家也可以了解一下 red hat linux 或其它 Linux distribution 的 nsswitch.conf 設定佈署方式。

這個部份的文件主要是 glibc 的手冊,大家可參考 http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html#Name-Service-Switch

-- jollen
作者/陳俊宏
http://www.jollen.org

October 4, 2006

Name Service Switch 程式設計:原理探討

我們以一個 'gethostbyname' 的例子來說明 NSS 的運作原理

假設我們想要查詢網路上某台 host 的 IP 位址,那麼 GNU C Library 手冊告訴我們說,有一個 gethostbyname() 的函數可以使用。

不過,在真正寫 code 時,其實並不建議呼叫此函數,在說明原因前,有一句必名言是大家一定要銘記在心的:

Multi-threaded safe code must be reentrant.

由於 gethostbyname() 並非 reentrant 的版本;所以,呼叫 gethostbyname() 並不是正確寫法,我們必須改成呼叫 reentrant 的版本:gethostbyname_r()。

NSS module 裡 non-reentrant 的函數,是不能使用在 multi-threaded applications 的設計上的,但是根據 NSS manual 的解釋,其實 gethostbyename() 與 gethostbyname_r() 都會呼叫到 NSS module 裡相同的函數,原因是 NSS module 只提供 reentrant 版本的 gethostbyname() 服務。

接下來讓我們來討論,gethostbyname() 與 gethostbyname_r() 倒底會呼叫到 NSS module 裡的哪一個函數。

_nss_service_function

當我們呼叫 gethostbyname_r() 函數時 (或 gethostbyname),假設我們在 /etc/nsswitch.conf 裡有一行這樣的設定:

hosts: files

那麼根據之前 Jollen 在 Blog 裡的說明,此時會使用到的 NSS module 會是 libnss_files.so.2,並且以下的 routine 會被呼叫:

_nss_files_gethostbyname_r

查看一下:

# nm /lib/libnss_files.so.2 |egrep "gethostbyname"
00004320 T _nss_files_gethostbyname2_r
00003ba0 T _nss_files_gethostbyname_r

現在我們終於知道了,當我們呼叫查詢的函數 'function' 時,在 libnss_SERVICE.so.2 裡的相對應函數便會被呼叫,此函數的 naming 方式為:

_nss_service_function

另外,NSS module 僅包含 reentrant 的版本。

最後我們要講的是,gethostbyename() 與 gethostbyname_r(),或是之前提到的 getpwnam() 都是實作在 libc.so.6 裡的。For example:

# nm /lib/libc.so.6 |egrep "T.gethostbyname"
000f72b0 T gethostbyname
000f7480 T gethostbyname2
000f78c0 T gethostbyname2_r@GLIBC_2.0
000f7660 T gethostbyname2_r@@GLIBC_2.1.2
000f7b80 T gethostbyname_r@GLIBC_2.0
000f7930 T gethostbyname_r@@GLIBC_2.1.2

# nm /lib/libc.so.6 |egrep "T.getpwnam"
000acf50 T getpwnam
000ad5c0 T getpwnam_r@GLIBC_2.0
000ad440 T getpwnam_r@@GLIBC_2.1.2

這就是為什麼我們在 ldd (or objdump) 時,都看不到 libnss_SERVICE.so.6 的道理.當我們做查詢時,NSS 才去載入對應的 service module。

October 7, 2006

Linux 2.4.29 System Calls Table (LSCT)

以下是 Linux 2.4.29 的 system call 整理表格,提供給「Embedded Linux 嵌入式系統實作演練」的讀者您做參考。這是一張很方便的表格,可以取代 unistd.h 與 "man"。

這張工具表格可以幫助我們:

1. 最主要的目的:當然是研究作業系統,了解 Linux 提供的 sytsem call service。
2. Trace kernel.
3. Writing shellcode.

供您參考 :)
Linux (kernel 2.4.29) System Call Table

1. sys_ni_syscall 為保留號碼
2. 更新日期: 2006/10/07
3. 其實與 linux 2.4.22 是相同的,因此亦可參考我們之前 (3 年前) 整理的 LSCT。

no Syscall Prototype decl.
0 sys_ni_syscall long sys_ni_syscall(void) 
1 sys_exit long sys_exit(int error_code) 
2 sys_fork int sys_fork(struct pt_regs regs) 
3 sys_read ssize_t sys_read(unsigned int fd, char *buf, size_t count) 
4 sys_write ssize_t sys_write(unsigned int fd, const char *buf, size_t count) 
5 sys_open long sys_open(const char *filename, int flags, int mode) 
6 sys_close long sys_close(unsigned int fd) 
7 sys_waitpid long sys_waitpid(pid_t pid, unsigned int *stat_addr, int options) 
8 sys_creat long sys_creat(const char *pathname, int mode) 
9 sys_link long sys_link(const char *oldname, const char *newname) 
10 sys_unlink long sys_unlink(const char *pathname) 
11 sys_execve int sys_execve(struct pt_regs regs) 
12 sys_chdir long sys_chdir(const char *filename) 
13 sys_time long sys_time(int *tloc) 
14 sys_mknod long sys_mknod(const char *filename, int mode, dev_t dev) 
15 sys_chmod long sys_chmod(const char *filename, mode_t mode) 
16 sys_lchown16 long sys_lchown16(const char *filename, old_uid_t user, old_gid_t group) 
17 sys_ni_syscall long sys_ni_syscall(void) 
18 sys_stat long sys_stat(char *filename, struct __old_kernel_stat *statbuf) 
19 sys_lseek off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) 
20 sys_getpid long sys_getpid(void) 
21 sys_mount long sys_mount(char *dev_name, char *dir_name, char *type, unsigned long flags, void *data) 
22 sys_oldumount long sys_oldumount(char *name) 
23 sys_setuid16 long sys_setuid16(old_uid_t uid) 
24 sys_getuid16 long sys_getuid16(void) 
25 sys_stime long sys_stime(int *tptr) 
26 sys_ptrace int sys_ptrace(long request, long pid, long addr, long data) 
27 sys_alarm unsigned long sys_alarm(unsigned int seconds) 
28 sys_fstat long sys_fstat(unsigned int fd, struct __old_kernel_stat *statbuf) 
29 sys_pause int sys_pause(void) 
30 sys_utime long sys_utime(char *filename, struct utimbuf *times) 
31 sys_ni_syscall long sys_ni_syscall(void) 
32 sys_ni_syscall long sys_ni_syscall(void) 
33 sys_access long sys_access(const char *filename, int mode) 
34 sys_nice long sys_nice(int increment) 
35 sys_ni_syscall long sys_ni_syscall(void) 
36 sys_sync long sys_sync(void) 
37 sys_kill long sys_kill(int pid, int sig) 
38 sys_rename long sys_rename(const char *oldname, const char *newname) 
39 sys_mkdir long sys_mkdir(const char *pathname, int mode) 
40 sys_rmdir long sys_rmdir(const char *pathname) 
41 sys_dup long sys_dup(unsigned int fildes) 
42 sys_pipe int sys_pipe(unsigned long *fildes) 
43 sys_times long sys_times(struct tms *tbuf) 
44 sys_ni_syscall long sys_ni_syscall(void) 
45 sys_brk unsigned long sys_brk(unsigned long brk) 
46 sys_setgid16 long sys_setgid16(old_gid_t gid) 
47 sys_getgid16 long sys_getgid16(void) 
48 sys_signal unsigned long sys_signal(int sig, __sighandler_t handler) 
49 sys_geteuid16 long sys_geteuid16(void) 
50 sys_getegid16 long sys_getegid16(void) 
51 sys_acct long sys_acct(const char *name) 
52 sys_umount long sys_umount(char *name, int flags) 
53 sys_ni_syscall long sys_ni_syscall(void) 
54 sys_ioctl long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 
55 sys_fcntl long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) 
56 sys_ni_syscall long sys_ni_syscall(void) 
57 sys_setpgid long sys_setpgid(pid_t pid, pid_t pgid) 
58 sys_ni_syscall long sys_ni_syscall(void) 
59 sys_olduname int sys_olduname(struct oldold_utsname *name) 
60 sys_umask long sys_umask(int mask) 
61 sys_chroot long sys_chroot(const char *filename) 
62 sys_ustat long sys_ustat(dev_t dev, struct ustat *ubuf) 
63 sys_dup2 long sys_dup2(unsigned int oldfd, unsigned int newfd) 
64 sys_getppid long sys_getppid(void) 
65 sys_getpgrp long sys_getpgrp(void) 
66 sys_setsid long sys_setsid(void) 
67 sys_sigaction int sys_sigaction(int sig, const struct old_sigaction *act, struct old_sigaction *oact) 
68 sys_sgetmask long sys_sgetmask(void) 
69 sys_ssetmask long sys_ssetmask(int newmask) 
70 sys_setreuid16 long sys_setreuid16(old_uid_t ruid, old_uid_t euid) 
71 sys_setregid16 long sys_setregid16(old_gid_t rgid, old_gid_t egid) 
72 sys_sigsuspend int sys_sigsuspend(int history0, int history1, old_sigset_t mask) 
73 sys_sigpending long sys_sigpending(old_sigset_t * set) 
74 sys_sethostname long sys_sethostname(char *name, int len) 
75 sys_setrlimit long sys_setrlimit(unsigned int resource, struct rlimit *rlim) 
76 sys_old_getrlimit long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim) 
77 sys_getrusage long sys_getrusage(int who, struct rusage *ru) 
78 sys_gettimeofday long sys_gettimeofday(struct timeval *tv, struct timezone *tz) 
79 sys_settimeofday long sys_settimeofday(struct timeval *tv, struct timezone *tz) 
80 sys_getgroups16 long sys_getgroups16(int gidsetsize, old_gid_t * grouplist) 
81 sys_setgroups16 long sys_setgroups16(int gidsetsize, old_gid_t * grouplist) 
82 old_select int old_select(struct sel_arg_struct *arg) 
83 sys_symlink long sys_symlink(const char *oldname, const char *newname) 
84 sys_lstat long sys_lstat(char *filename, struct __old_kernel_stat *statbuf) 
85 sys_readlink long sys_readlink(const char *path, char *buf, int bufsiz) 
86 sys_uselib long sys_uselib(const char *library) 
87 sys_swapon long sys_swapon(const char *specialfile, int swap_flags) 
88 sys_reboot long sys_reboot(int magic1, int magic2, unsigned int cmd, void *arg) 
89 old_readdir int old_readdir(unsigned int fd, void *dirent, unsigned int count) 
90 old_mmap int old_mmap(struct mmap_arg_struct *arg) 
91 sys_munmap long sys_munmap(unsigned long addr, size_t len) 
92 sys_truncate long sys_truncate(const char *path, unsigned long length) 
93 sys_ftruncate long sys_ftruncate(unsigned int fd, unsigned long length) 
94 sys_fchmod long sys_fchmod(unsigned int fd, mode_t mode) 
95 sys_fchown16 long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) 
96 sys_getpriority long sys_getpriority(int which, int who) 
97 sys_setpriority long sys_setpriority(int which, int who, int niceval) 
98 sys_ni_syscall long sys_ni_syscall(void) 
99 sys_statfs long sys_statfs(const char *path, struct statfs *buf) 
100 sys_fstatfs long sys_fstatfs(unsigned int fd, struct statfs *buf) 
101 sys_ioperm int sys_ioperm(unsigned long from, unsigned long num, int turn_on) 
102 sys_socketcall long sys_socketcall(int call, unsigned long *args) 
103 sys_syslog long sys_syslog(int type, char *buf, int len) 
104 sys_setitimer long sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) 
105 sys_getitimer long sys_getitimer(int which, struct itimerval *value) 
106 sys_newstat long sys_newstat(char *filename, struct stat *statbuf) 
107 sys_newlstat long sys_newlstat(char *filename, struct stat *statbuf) 
108 sys_newfstat long sys_newfstat(unsigned int fd, struct stat *statbuf) 
109 sys_uname int sys_uname(struct old_utsname *name) 
110 sys_iopl int sys_iopl(unsigned long unused) 
111 sys_vhangup long sys_vhangup(void) 
112 sys_ni_syscall long sys_ni_syscall(void) 
113 sys_vm86old int sys_vm86old(struct vm86_struct *v86) 
114 sys_wait4 long sys_wait4(pid_t pid, unsigned int *stat_addr, int options, struct rusage *ru) 
115 sys_swapoff long sys_swapoff(const char *specialfile) 
116 sys_sysinfo long sys_sysinfo(struct sysinfo *info) 
117 sys_ipc int sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) 
118 sys_fsync long sys_fsync(unsigned int fd) 
119 sys_sigreturn int sys_sigreturn(unsigned long __unused) 
120 sys_clone int sys_clone(struct pt_regs regs) 
121 sys_setdomainname long sys_setdomainname(char *name, int len) 
122 sys_newuname long sys_newuname(struct new_utsname *name) 
123 sys_modify_ldt int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) 
124 sys_adjtimex long sys_adjtimex(struct timex *txc_p) 
125 sys_mprotect long sys_mprotect(unsigned long start, size_t len, unsigned long prot) 
126 sys_sigprocmask long sys_sigprocmask(int how, old_sigset_t * set, old_sigset_t * oset) 
127 sys_create_module unsigned long sys_create_module(const char *name_user, size_t size) 
128 sys_init_module long sys_init_module(const char *name_user, struct module *mod_user) 
129 sys_delete_module long sys_delete_module(const char *name_user) 
130 sys_get_kernel_syms long sys_get_kernel_syms(struct kernel_sym *table) 
131 sys_quotactl long sys_quotactl(unsigned int cmd, const char *special, qid_t id, caddr_t addr) 
132 sys_getpgid long sys_getpgid(pid_t pid) 
133 sys_fchdir long sys_fchdir(unsigned int fd) 
134 sys_bdflush long sys_bdflush(int func, long data) 
135 sys_sysfs long sys_sysfs(int option, unsigned long arg1, unsigned long arg2) 
136 sys_personality long sys_personality(u_long personality) 
137 sys_ni_syscall long sys_ni_syscall(void) 
138 sys_setfsuid16 long sys_setfsuid16(old_uid_t uid) 
139 sys_setfsgid16 long sys_setfsgid16(old_gid_t gid) 
140 sys_llseek long sys_llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t * result, unsigned int origin) 
141 sys_getdents long sys_getdents(unsigned int fd, void *dirent, unsigned int count) 
142 sys_select long sys_select(int n, fd_set * inp, fd_set * outp, fd_set * exp, struct timeval *tvp) 
143 sys_flock long sys_flock(unsigned int fd, unsigned int cmd) 
144 sys_msync long sys_msync(unsigned long start, size_t len, int flags) 
145 sys_readv ssize_t sys_readv(unsigned long fd, const struct iovec * vector, unsigned long count) 
146 sys_writev ssize_t sys_writev(unsigned long fd, const struct iovec * vector, unsigned long count) 
147 sys_getsid long sys_getsid(pid_t pid) 
148 sys_fdatasync long sys_fdatasync(unsigned int fd) 
149 sys_sysctl long sys_sysctl(struct __sysctl_args *args) 
150 sys_mlock long sys_mlock(unsigned long start, size_t len) 
151 sys_munlock long sys_munlock(unsigned long start, size_t len) 
152 sys_mlockall long sys_mlockall(int flags) 
153 sys_munlockall long sys_munlockall(void) 
154 sys_sched_setparam long sys_sched_setparam(pid_t pid, struct sched_param *param) 
155 sys_sched_getparam long sys_sched_getparam(pid_t pid, struct sched_param *param) 
156 sys_sched_setscheduler long sys_sched_setscheduler(pid_t pid, int policy, struct sched_param *param) 
157 sys_sched_getscheduler long sys_sched_getscheduler(pid_t pid) 
158 sys_sched_yield long sys_sched_yield(void) 
159 sys_sched_get_priority_max long sys_sched_get_priority_max(int policy) 
160 sys_sched_get_priority_min long sys_sched_get_priority_min(int policy) 
161 sys_sched_rr_get_interval long sys_sched_rr_get_interval(pid_t pid, struct timespec *interval) 
162 sys_nanosleep long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp) 
163 sys_mremap unsigned long sys_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) 
164 sys_setresuid16 long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) 
165 sys_getresuid16 long sys_getresuid16(old_uid_t * ruid, old_uid_t * euid, old_uid_t * suid) 
166 sys_vm86 int sys_vm86(unsigned long subfunction, struct vm86plus_struct *v86) 
167 sys_query_module long sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, size_t * ret) 
168 sys_poll long sys_poll(struct pollfd *ufds, unsigned int nfds, long timeout) 
169 sys_nfsservctl  
170 sys_setresgid16 long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) 
171 sys_getresgid16 long sys_getresgid16(old_gid_t * rgid, old_gid_t * egid, old_gid_t * sgid) 
172 sys_prctl long sys_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) 
173 sys_rt_sigreturn int sys_rt_sigreturn(unsigned long __unused) 
174 sys_rt_sigaction long sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, size_t sigsetsize) 
175 sys_rt_sigprocmask long sys_rt_sigprocmask(int how, sigset_t * set, sigset_t * oset, size_t sigsetsize) 
176 sys_rt_sigpending long sys_rt_sigpending(sigset_t * set, size_t sigsetsize) 
177 sys_rt_sigtimedwait long sys_rt_sigtimedwait(const sigset_t * uthese, siginfo_t * uinfo, const struct timespec *uts, size_t sigsetsize) 
178 sys_rt_sigqueueinfo long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t * uinfo) 
179 sys_rt_sigsuspend int sys_rt_sigsuspend(sigset_t * unewset, size_t sigsetsize) 
180 sys_pread ssize_t sys_pread(unsigned int fd, char *buf, size_t count, loff_t pos) 
181 sys_pwrite ssize_t sys_pwrite(unsigned int fd, const char *buf, size_t count, loff_t pos) 
182 sys_chown16 long sys_chown16(const char *filename, old_uid_t user, old_gid_t group) 
183 sys_getcwd long sys_getcwd(char *buf, unsigned long size) 
184 sys_capget long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) 
185 sys_capset long sys_capset(cap_user_header_t header, const cap_user_data_t data) 
186 sys_sigaltstack int sys_sigaltstack(const stack_t * uss, stack_t * uoss) 
187 sys_sendfile ssize_t sys_sendfile(int out_fd, int in_fd, off_t * offset, size_t count) 
188 sys_ni_syscall long sys_ni_syscall(void) 
189 sys_ni_syscall long sys_ni_syscall(void) 
190 sys_vfork int sys_vfork(struct pt_regs regs) 
191 sys_getrlimit long sys_getrlimit(unsigned int resource, struct rlimit *rlim) 
192 sys_mmap2 long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) 
193 sys_truncate64 long sys_truncate64(const char *path, loff_t length) 
194 sys_ftruncate64 long sys_ftruncate64(unsigned int fd, loff_t length) 
195 sys_stat64 long sys_stat64(char *filename, struct stat64 *statbuf, long flags) 
196 sys_lstat64 long sys_lstat64(char *filename, struct stat64 *statbuf, long flags) 
197 sys_fstat64 long sys_fstat64(unsigned long fd, struct stat64 *statbuf, long flags) 
198 sys_lchown long sys_lchown(const char *filename, uid_t user, gid_t group) 
199 sys_getuid long sys_getuid(void) 
200 sys_getgid long sys_getgid(void) 
201 sys_geteuid long sys_geteuid(void) 
202 sys_getegid long sys_getegid(void) 
203 sys_setreuid long sys_setreuid(uid_t ruid, uid_t euid) 
204 sys_setregid long sys_setregid(gid_t rgid, gid_t egid) 
205 sys_getgroups long sys_getgroups(int gidsetsize, gid_t * grouplist) 
206 sys_setgroups long sys_setgroups(int gidsetsize, gid_t * grouplist) 
207 sys_fchown long sys_fchown(unsigned int fd, uid_t user, gid_t group) 
208 sys_setresuid long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) 
209 sys_getresuid long sys_getresuid(uid_t * ruid, uid_t * euid, uid_t * suid) 
210 sys_setresgid long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) 
211 sys_getresgid long sys_getresgid(gid_t * rgid, gid_t * egid, gid_t * sgid) 
212 sys_chown long sys_chown(const char *filename, uid_t user, gid_t group) 
213 sys_setuid long sys_setuid(uid_t uid) 
214 sys_setgid long sys_setgid(gid_t gid) 
215 sys_setfsuid long sys_setfsuid(uid_t uid) 
216 sys_setfsgid long sys_setfsgid(gid_t gid) 
217 sys_pivot_root long sys_pivot_root(const char *new_root, const char *put_old) 
218 sys_mincore long sys_mincore(unsigned long start, size_t len, unsigned char *vec) 
219 sys_madvise long sys_madvise(unsigned long start, size_t len, int behavior) 
220 sys_getdents64 long sys_getdents64(unsigned int fd, void *dirent, unsigned int count) 
221 sys_fcntl64 long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) 
222 sys_ni_syscall long sys_ni_syscall(void) 
223 sys_ni_syscall long sys_ni_syscall(void) 
224 sys_gettid long sys_gettid(void) 
225 sys_readahead ssize_t sys_readahead(int fd, loff_t offset, size_t count) 
226 sys_setxattr long sys_setxattr(char *path, char *name, void *value, size_t size, int flags) 
227 sys_lsetxattr long sys_lsetxattr(char *path, char *name, void *value, size_t size, int flags) 
228 sys_fsetxattr long sys_fsetxattr(int fd, char *name, void *value, size_t size, int flags) 
229 sys_getxattr ssize_t sys_getxattr(char *path, char *name, void *value, size_t size) 
230 sys_lgetxattr ssize_t sys_lgetxattr(char *path, char *name, void *value, size_t size) 
231 sys_fgetxattr ssize_t sys_fgetxattr(int fd, char *name, void *value, size_t size) 
232 sys_listxattr ssize_t sys_listxattr(char *path, char *list, size_t size) 
233 sys_llistxattr ssize_t sys_llistxattr(char *path, char *list, size_t size) 
234 sys_flistxattr ssize_t sys_flistxattr(int fd, char *list, size_t size) 
235 sys_removexattr long sys_removexattr(char *path, char *name) 
236 sys_lremovexattr long sys_lremovexattr(char *path, char *name) 
237 sys_fremovexattr long sys_fremovexattr(int fd, char *name) 
238 sys_tkill long sys_tkill(int pid, int sig) 
239 sys_sendfile64 ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t * offset, size_t count) 
240 sys_ni_syscall long sys_ni_syscall(void) 
241 sys_ni_syscall long sys_ni_syscall(void) 
242 sys_ni_syscall long sys_ni_syscall(void) 
243 sys_ni_syscall long sys_ni_syscall(void) 
244 sys_ni_syscall long sys_ni_syscall(void) 
245 sys_ni_syscall long sys_ni_syscall(void) 
246 sys_ni_syscall long sys_ni_syscall(void) 
247 sys_ni_syscall long sys_ni_syscall(void) 
248 sys_ni_syscall long sys_ni_syscall(void) 
249 sys_ni_syscall long sys_ni_syscall(void) 
250 sys_ni_syscall long sys_ni_syscall(void) 
251 sys_ni_syscall long sys_ni_syscall(void) 
252 sys_ni_syscall long sys_ni_syscall(void) 
253 sys_ni_syscall long sys_ni_syscall(void) 
254 sys_ni_syscall long sys_ni_syscall(void) 
255 sys_ni_syscall long sys_ni_syscall(void) 
256 sys_ni_syscall long sys_ni_syscall(void) 
257 sys_ni_syscall long sys_ni_syscall(void) 
258 sys_ni_syscall long sys_ni_syscall(void) 
259 sys_ni_syscall long sys_ni_syscall(void) 

Linux 2.6.11 System Calls Table (LSCT)

以下是 Linux 2.6.11 的 system call 整理表格,提供給「Embedded Linux 嵌入式系統實作演練」的讀者您做參考。這是一張很方便的表格,可以取代 unistd.h 與 "man"。

這張工具表格可以幫助我們:

1. 最主要的目的:當然是研究作業系統,了解 Linux 提供的 sytsem call service。
2. Trace kernel.
3. Writing shellcode.

供您參考 :)

Linux (kernel 2.6.11) System Call Table

1. sys_ni_syscall 為保留號碼
2. 更新日期: 2006/10/07
3. 第一次發佈 2.6 kernel 的 LSCT

no Syscall Prototype decl.
0 sys_restart_syscall long sys_restart_syscall(void) 
1 sys_exit long sys_exit(int error_code) 
2 sys_fork int sys_fork(struct pt_regs regs) 
3 sys_read ssize_t sys_read(unsigned int fd, char __user * buf, size_t count) 
4 sys_write ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count) 
5 sys_open long sys_open(const char __user * filename, int flags, int mode) 
6 sys_close long sys_close(unsigned int fd) 
7 sys_waitpid long sys_waitpid(pid_t pid, int __user * stat_addr, int options) 
8 sys_creat long sys_creat(const char __user * pathname, int mode) 
9 sys_link long sys_link(const char __user * oldname, const char __user * newname) 
10 sys_unlink long sys_unlink(const char __user * pathname) 
11 sys_execve int sys_execve(struct pt_regs regs) 
12 sys_chdir long sys_chdir(const char __user * filename) 
13 sys_time long sys_time(time_t __user * tloc) 
14 sys_mknod long sys_mknod(const char __user * filename, int mode, unsigned dev) 
15 sys_chmod long sys_chmod(const char __user * filename, mode_t mode) 
16 sys_lchown16 long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) 
17 sys_ni_syscall long sys_ni_syscall(void) 
18 sys_stat long sys_stat(char __user * filename, struct __old_kernel_stat __user * statbuf) 
19 sys_lseek off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) 
20 sys_getpid long sys_getpid(void) 
21 sys_mount long sys_mount(char __user * dev_name, char __user * dir_name, char __user * type, unsigned long flags, void __user * data) 
22 sys_oldumount long sys_oldumount(char __user * name) 
23 sys_setuid16 long sys_setuid16(old_uid_t uid) 
24 sys_getuid16 long sys_getuid16(void) 
25 sys_stime long sys_stime(time_t __user * tptr) 
26 sys_ptrace int sys_ptrace(long request, long pid, long addr, long data) 
27 sys_alarm unsigned long sys_alarm(unsigned int seconds) 
28 sys_fstat long sys_fstat(unsigned int fd, struct __old_kernel_stat __user * statbuf) 
29 sys_pause long sys_pause(void) 
30 sys_utime long sys_utime(char __user * filename, struct utimbuf __user * times) 
31 sys_ni_syscall long sys_ni_syscall(void) 
32 sys_ni_syscall long sys_ni_syscall(void) 
33 sys_access long sys_access(const char __user * filename, int mode) 
34 sys_nice long sys_nice(int increment) 
35 sys_ni_syscall long sys_ni_syscall(void) 
36 sys_sync long sys_sync(void) 
37 sys_kill long sys_kill(int pid, int sig) 
38 sys_rename long sys_rename(const char __user * oldname, const char __user * newname) 
39 sys_mkdir long sys_mkdir(const char __user * pathname, int mode) 
40 sys_rmdir long sys_rmdir(const char __user * pathname) 
41 sys_dup long sys_dup(unsigned int fildes) 
42 sys_pipe int sys_pipe(unsigned long __user * fildes) 
43 sys_times long sys_times(struct tms __user * tbuf) 
44 sys_ni_syscall long sys_ni_syscall(void) 
45 sys_brk unsigned long sys_brk(unsigned long brk) 
46 sys_setgid16 long sys_setgid16(old_gid_t gid) 
47 sys_getgid16 long sys_getgid16(void) 
48 sys_signal unsigned long sys_signal(int sig, __sighandler_t handler) 
49 sys_geteuid16 long sys_geteuid16(void) 
50 sys_getegid16 long sys_getegid16(void) 
51 sys_acct long sys_acct(const char __user * name) 
52 sys_umount long sys_umount(char __user * name, int flags) 
53 sys_ni_syscall long sys_ni_syscall(void) 
54 sys_ioctl long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) 
55 sys_fcntl long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) 
56 sys_ni_syscall long sys_ni_syscall(void) 
57 sys_setpgid long sys_setpgid(pid_t pid, pid_t pgid) 
58 sys_ni_syscall long sys_ni_syscall(void) 
59 sys_olduname int sys_olduname(struct oldold_utsname __user * name) 
60 sys_umask long sys_umask(int mask) 
61 sys_chroot long sys_chroot(const char __user * filename) 
62 sys_ustat long sys_ustat(unsigned dev, struct ustat __user * ubuf) 
63 sys_dup2 long sys_dup2(unsigned int oldfd, unsigned int newfd) 
64 sys_getppid long sys_getppid(void) 
65 sys_getpgrp long sys_getpgrp(void) 
66 sys_setsid long sys_setsid(void) 
67 sys_sigaction int sys_sigaction(int sig, const struct old_sigaction __user * act, struct old_sigaction __user * oact) 
68 sys_sgetmask long sys_sgetmask(void) 
69 sys_ssetmask long sys_ssetmask(int newmask) 
70 sys_setreuid16 long sys_setreuid16(old_uid_t ruid, old_uid_t euid) 
71 sys_setregid16 long sys_setregid16(old_gid_t rgid, old_gid_t egid) 
72 sys_sigsuspend int sys_sigsuspend(int history0, int history1, old_sigset_t mask) 
73 sys_sigpending long sys_sigpending(old_sigset_t __user * set) 
74 sys_sethostname long sys_sethostname(char __user * name, int len) 
75 sys_setrlimit long sys_setrlimit(unsigned int resource, struct rlimit __user * rlim) 
76 sys_old_getrlimit long sys_old_getrlimit(unsigned int resource, struct rlimit __user * rlim) 
77 sys_getrusage long sys_getrusage(int who, struct rusage __user * ru) 
78 sys_gettimeofday long sys_gettimeofday(struct timeval __user * tv, struct timezone __user * tz) 
79 sys_settimeofday long sys_settimeofday(struct timeval __user * tv, struct timezone __user * tz) 
80 sys_getgroups16 long sys_getgroups16(int gidsetsize, old_gid_t __user * grouplist) 
81 sys_setgroups16 long sys_setgroups16(int gidsetsize, old_gid_t __user * grouplist) 
82 old_select int old_select(struct sel_arg_struct __user * arg) 
83 sys_symlink long sys_symlink(const char __user * oldname, const char __user * newname) 
84 sys_lstat long sys_lstat(char __user * filename, struct __old_kernel_stat __user * statbuf) 
85 sys_readlink long sys_readlink(const char __user * path, char __user * buf, int bufsiz) 
86 sys_uselib long sys_uselib(const char __user * library) 
87 sys_swapon long sys_swapon(const char __user * specialfile, int swap_flags) 
88 sys_reboot long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg) 
89 old_readdir long old_readdir(unsigned int fd, struct old_linux_dirent __user * dirent, unsigned int count) 
90 old_mmap int old_mmap(struct mmap_arg_struct __user * arg) 
91 sys_munmap long sys_munmap(unsigned long addr, size_t len) 
92 sys_truncate long sys_truncate(const char __user * path, unsigned long length) 
93 sys_ftruncate long sys_ftruncate(unsigned int fd, unsigned long length) 
94 sys_fchmod long sys_fchmod(unsigned int fd, mode_t mode) 
95 sys_fchown16 long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) 
96 sys_getpriority long sys_getpriority(int which, int who) 
97 sys_setpriority long sys_setpriority(int which, int who, int niceval) 
98 sys_ni_syscall long sys_ni_syscall(void) 
99 sys_statfs long sys_statfs(const char __user * path, struct statfs __user * buf) 
100 sys_fstatfs long sys_fstatfs(unsigned int fd, struct statfs __user * buf) 
101 sys_ioperm long sys_ioperm(unsigned long from, unsigned long num, int turn_on) 
102 sys_socketcall long sys_socketcall(int call, unsigned long __user * args) 
103 sys_syslog long sys_syslog(int type, char __user * buf, int len) 
104 sys_setitimer long sys_setitimer(int which, struct itimerval __user * value, struct itimerval __user * ovalue) 
105 sys_getitimer long sys_getitimer(int which, struct itimerval __user * value) 
106 sys_newstat long sys_newstat(char __user * filename, struct stat __user * statbuf) 
107 sys_newlstat long sys_newlstat(char __user * filename, struct stat __user * statbuf) 
108 sys_newfstat long sys_newfstat(unsigned int fd, struct stat __user * statbuf) 
109 sys_uname int sys_uname(struct old_utsname __user * name) 
110 sys_iopl long sys_iopl(unsigned long unused) 
111 sys_vhangup long sys_vhangup(void) 
112 sys_ni_syscall long sys_ni_syscall(void) 
113 sys_vm86old int sys_vm86old(struct pt_regs regs) 
114 sys_wait4 long sys_wait4(pid_t pid, int __user * stat_addr, int options, struct rusage __user * ru) 
115 sys_swapoff long sys_swapoff(const char __user * specialfile) 
116 sys_sysinfo long sys_sysinfo(struct sysinfo __user * info) 
117 sys_ipc int sys_ipc(uint call, int first, int second, int third, void __user * ptr, long fifth) 
118 sys_fsync long sys_fsync(unsigned int fd) 
119 sys_sigreturn int sys_sigreturn(unsigned long __unused) 
120 sys_clone int sys_clone(struct pt_regs regs) 
121 sys_setdomainname long sys_setdomainname(char __user * name, int len) 
122 sys_newuname long sys_newuname(struct new_utsname __user * name) 
123 sys_modify_ldt int sys_modify_ldt(int func, void __user * ptr, unsigned long bytecount) 
124 sys_adjtimex long sys_adjtimex(struct timex __user * txc_p) 
125 sys_mprotect long sys_mprotect(unsigned long start, size_t len, unsigned long prot) 
126 sys_sigprocmask long sys_sigprocmask(int how, old_sigset_t __user * set, old_sigset_t __user * oset) 
127 sys_ni_syscall long sys_ni_syscall(void) 
128 sys_init_module long sys_init_module(void __user * umod, unsigned long len, const char __user * uargs) 
129 sys_delete_module long sys_delete_module(const char __user * name_user, unsigned int flags) 
130 sys_ni_syscall long sys_ni_syscall(void) 
131 sys_quotactl long sys_quotactl(unsigned int cmd, const char __user * special, qid_t id, void __user * addr) 
132 sys_getpgid long sys_getpgid(pid_t pid) 
133 sys_fchdir long sys_fchdir(unsigned int fd) 
134 sys_bdflush long sys_bdflush(int func, long data) 
135 sys_sysfs long sys_sysfs(int option, unsigned long arg1, unsigned long arg2) 
136 sys_personality long sys_personality(u_long personality) 
137 sys_ni_syscall long sys_ni_syscall(void) 
138 sys_setfsuid16 long sys_setfsuid16(old_uid_t uid) 
139 sys_setfsgid16 long sys_setfsgid16(old_gid_t gid) 
140 sys_llseek long sys_llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t __user * result, unsigned int origin) 
141 sys_getdents long sys_getdents(unsigned int fd, struct linux_dirent __user * dirent, unsigned int count) 
142 sys_select long sys_select(int n, fd_set __user * inp, fd_set __user * outp, fd_set __user * exp, struct timeval __user * tvp) 
143 sys_flock long sys_flock(unsigned int fd, unsigned int cmd) 
144 sys_msync long sys_msync(unsigned long start, size_t len, int flags) 
145 sys_readv ssize_t sys_readv(unsigned long fd, const struct iovec __user * vec, unsigned long vlen) 
146 sys_writev ssize_t sys_writev(unsigned long fd, const struct iovec __user * vec, unsigned long vlen) 
147 sys_getsid long sys_getsid(pid_t pid) 
148 sys_fdatasync long sys_fdatasync(unsigned int fd) 
149 sys_sysctl long sys_sysctl(struct __sysctl_args __user * args) 
150 sys_mlock long sys_mlock(unsigned long start, size_t len) 
151 sys_munlock long sys_munlock(unsigned long start, size_t len) 
152 sys_mlockall long sys_mlockall(int flags) 
153 sys_munlockall long sys_munlockall(void) 
154 sys_sched_setparam long sys_sched_setparam(pid_t pid, struct sched_param __user * param) 
155 sys_sched_getparam long sys_sched_getparam(pid_t pid, struct sched_param __user * param) 
156 sys_sched_setscheduler long sys_sched_setscheduler(pid_t pid, int policy, struct sched_param __user * param) 
157 sys_sched_getscheduler long sys_sched_getscheduler(pid_t pid) 
158 sys_sched_yield long sys_sched_yield(void) 
159 sys_sched_get_priority_max long sys_sched_get_priority_max(int policy) 
160 sys_sched_get_priority_min long sys_sched_get_priority_min(int policy) 
161 sys_sched_rr_get_interval long sys_sched_rr_get_interval(pid_t pid, struct timespec __user * interval) 
162 sys_nanosleep long sys_nanosleep(struct timespec __user * rqtp, struct timespec __user * rmtp) 
163 sys_mremap unsigned long sys_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) 
164 sys_setresuid16 long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) 
165 sys_getresuid16 long sys_getresuid16(old_uid_t __user * ruid, old_uid_t __user * euid, old_uid_t __user * suid) 
166 sys_vm86 int sys_vm86(struct pt_regs regs) 
167 sys_ni_syscall long sys_ni_syscall(void) 
168 sys_poll long sys_poll(struct pollfd __user * ufds, unsigned int nfds, long timeout) 
169 sys_nfsservctl  
170 sys_setresgid16 long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) 
171 sys_getresgid16 long sys_getresgid16(old_gid_t __user * rgid, old_gid_t __user * egid, old_gid_t __user * sgid) 
172 sys_prctl long sys_prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) 
173 sys_rt_sigreturn int sys_rt_sigreturn(unsigned long __unused) 
174 sys_rt_sigaction long sys_rt_sigaction(int sig, const struct sigaction __user * act, struct sigaction __user * oact, size_t sigsetsize) 
175 sys_rt_sigprocmask long sys_rt_sigprocmask(int how, sigset_t __user * set, sigset_t __user * oset, size_t sigsetsize) 
176 sys_rt_sigpending long sys_rt_sigpending(sigset_t __user * set, size_t sigsetsize) 
177 sys_rt_sigtimedwait long sys_rt_sigtimedwait(const sigset_t __user * uthese, siginfo_t __user * uinfo, const struct timespec __user * uts, size_t sigsetsize) 
178 sys_rt_sigqueueinfo long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user * uinfo) 
179 sys_rt_sigsuspend int sys_rt_sigsuspend(struct pt_regs regs) 
180 sys_pread64 ssize_t sys_pread64(unsigned int fd, char __user * buf, size_t count, loff_t pos) 
181 sys_pwrite64 ssize_t sys_pwrite64(unsigned int fd, const char __user * buf, size_t count, loff_t pos) 
182 sys_chown16 long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) 
183 sys_getcwd long sys_getcwd(char __user * buf, unsigned long size) 
184 sys_capget long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) 
185 sys_capset long sys_capset(cap_user_header_t header, const cap_user_data_t data) 
186 sys_sigaltstack int sys_sigaltstack(unsigned long ebx) 
187 sys_sendfile ssize_t sys_sendfile(int out_fd, int in_fd, off_t __user * offset, size_t count) 
188 sys_ni_syscall long sys_ni_syscall(void) 
189 sys_ni_syscall long sys_ni_syscall(void) 
190 sys_vfork int sys_vfork(struct pt_regs regs) 
191 sys_getrlimit long sys_getrlimit(unsigned int resource, struct rlimit __user * rlim) 
192 sys_mmap2 long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) 
193 sys_truncate64 long sys_truncate64(const char __user * path, loff_t length) 
194 sys_ftruncate64 long sys_ftruncate64(unsigned int fd, loff_t length) 
195 sys_stat64 long sys_stat64(char __user * filename, struct stat64 __user * statbuf) 
196 sys_lstat64 long sys_lstat64(char __user * filename, struct stat64 __user * statbuf) 
197 sys_fstat64 long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf) 
198 sys_lchown long sys_lchown(const char __user * filename, uid_t user, gid_t group) 
199 sys_getuid long sys_getuid(void) 
200 sys_getgid long sys_getgid(void) 
201 sys_geteuid long sys_geteuid(void) 
202 sys_getegid long sys_getegid(void) 
203 sys_setreuid long sys_setreuid(uid_t ruid, uid_t euid) 
204 sys_setregid long sys_setregid(gid_t rgid, gid_t egid) 
205 sys_getgroups long sys_getgroups(int gidsetsize, gid_t __user * grouplist) 
206 sys_setgroups long sys_setgroups(int gidsetsize, gid_t __user * grouplist) 
207 sys_fchown long sys_fchown(unsigned int fd, uid_t user, gid_t group) 
208 sys_setresuid long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) 
209 sys_getresuid long sys_getresuid(uid_t __user * ruid, uid_t __user * euid, uid_t __user * suid) 
210 sys_setresgid long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) 
211 sys_getresgid long sys_getresgid(gid_t __user * rgid, gid_t __user * egid, gid_t __user * sgid) 
212 sys_chown long sys_chown(const char __user * filename, uid_t user, gid_t group) 
213 sys_setuid long sys_setuid(uid_t uid) 
214 sys_setgid long sys_setgid(gid_t gid) 
215 sys_setfsuid long sys_setfsuid(uid_t uid) 
216 sys_setfsgid long sys_setfsgid(gid_t gid) 
217 sys_pivot_root long sys_pivot_root(const char __user * new_root, const char __user * put_old) 
218 sys_mincore long sys_mincore(unsigned long start, size_t len, unsigned char __user * vec) 
219 sys_madvise long sys_madvise(unsigned long start, size_t len_in, int behavior) 
220 sys_getdents64 long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * dirent, unsigned int count) 
221 sys_fcntl64 long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) 
222 sys_ni_syscall long sys_ni_syscall(void) 
223 sys_ni_syscall long sys_ni_syscall(void) 
224 sys_gettid long sys_gettid(void) 
225 sys_readahead ssize_t sys_readahead(int fd, loff_t offset, size_t count) 
226 sys_setxattr long sys_setxattr(char __user * path, char __user * name, void __user * value, size_t size, int flags) 
227 sys_lsetxattr long sys_lsetxattr(char __user * path, char __user * name, void __user * value, size_t size, int flags) 
228 sys_fsetxattr long sys_fsetxattr(int fd, char __user * name, void __user * value, size_t size, int flags) 
229 sys_getxattr ssize_t sys_getxattr(char __user * path, char __user * name, void __user * value, size_t size) 
230 sys_lgetxattr ssize_t sys_lgetxattr(char __user * path, char __user * name, void __user * value, size_t size) 
231 sys_fgetxattr ssize_t sys_fgetxattr(int fd, char __user * name, void __user * value, size_t size) 
232 sys_listxattr ssize_t sys_listxattr(char __user * path, char __user * list, size_t size) 
233 sys_llistxattr ssize_t sys_llistxattr(char __user * path, char __user * list, size_t size) 
234 sys_flistxattr ssize_t sys_flistxattr(int fd, char __user * list, size_t size) 
235 sys_removexattr long sys_removexattr(char __user * path, char __user * name) 
236 sys_lremovexattr long sys_lremovexattr(char __user * path, char __user * name) 
237 sys_fremovexattr long sys_fremovexattr(int fd, char __user * name) 
238 sys_tkill long sys_tkill(int pid, int sig) 
239 sys_sendfile64 ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t __user * offset, size_t count) 
240 sys_futex long sys_futex(u32 __user * uaddr, int op, int val, struct timespec __user * utime, u32 __user * uaddr2, int val3) 
241 sys_sched_setaffinity long sys_sched_setaffinity(pid_t pid, unsigned int len, unsigned long __user * user_mask_ptr) 
242 sys_sched_getaffinity long sys_sched_getaffinity(pid_t pid, unsigned int len, unsigned long __user * user_mask_ptr) 
243 sys_set_thread_area int sys_set_thread_area(struct user_desc __user * u_info) 
244 sys_get_thread_area int sys_get_thread_area(struct user_desc __user * u_info) 
245 sys_io_setup long sys_io_setup(unsigned nr_events, aio_context_t __user * ctxp) 
246 sys_io_destroy long sys_io_destroy(aio_context_t ctx) 
247 sys_io_getevents long sys_io_getevents(aio_context_t ctx_id, long min_nr, long nr, struct io_event __user * events, struct timespec __user * timeout) 
248 sys_io_submit long sys_io_submit(aio_context_t ctx_id, long nr, struct iocb __user * __user * iocbpp) 
249 sys_io_cancel long sys_io_cancel(aio_context_t ctx_id, struct iocb __user * iocb, struct io_event __user * result) 
250 sys_fadvise64 long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) 
251 sys_ni_syscall long sys_ni_syscall(void) 
252 sys_exit_group void sys_exit_group(int error_code) 
253 sys_lookup_dcookie long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) 
254 sys_epoll_create long sys_epoll_create(int size) 
255 sys_epoll_ctl long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user * event) 
256 sys_epoll_wait long sys_epoll_wait(int epfd, struct epoll_event __user * events, int maxevents, int timeout) 
257 sys_remap_file_pages long sys_remap_file_pages(unsigned long start, unsigned long size, unsigned long __prot, unsigned long pgoff, unsigned long flags) 
258 sys_set_tid_address long sys_set_tid_address(int __user * tidptr) 
259 sys_timer_create long sys_timer_create(clockid_t which_clock, struct sigevent __user * timer_event_spec, timer_t __user * created_timer_id) 
260 sys_timer_settime long sys_timer_settime(timer_t timer_id, int flags, const struct itimerspec __user * new_setting, struct itimerspec __user * old_setting) 
261 sys_timer_gettime long sys_timer_gettime(timer_t timer_id, struct itimerspec __user * setting) 
262 sys_timer_getoverrun long sys_timer_getoverrun(timer_t timer_id) 
263 sys_timer_delete long sys_timer_delete(timer_t timer_id) 
264 sys_clock_settime long sys_clock_settime(clockid_t which_clock, const struct timespec __user * tp) 
265 sys_clock_gettime long sys_clock_gettime(clockid_t which_clock, struct timespec __user * tp) 
266 sys_clock_getres long sys_clock_getres(clockid_t which_clock, struct timespec __user * tp) 
267 sys_clock_nanosleep long sys_clock_nanosleep(clockid_t which_clock, int flags, const struct timespec __user * rqtp, struct timespec __user * rmtp) 
268 sys_statfs64 long sys_statfs64(const char __user * path, size_t sz, struct statfs64 __user * buf) 
269 sys_fstatfs64 long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user * buf) 
270 sys_tgkill long sys_tgkill(int tgid, int pid, int sig) 
271 sys_utimes long sys_utimes(char __user * filename, struct timeval __user * utimes) 
272 sys_fadvise64_64 long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) 
273 sys_ni_syscall long sys_ni_syscall(void) 
274 sys_mbind long sys_mbind(unsigned long start, unsigned long len, unsigned long mode, unsigned long __user * nmask, unsigned long maxnode, unsigned flags) 
275 sys_get_mempolicy long sys_get_mempolicy(int __user * policy, unsigned long __user * nmask, unsigned long maxnode, unsigned long addr, unsigned long flags) 
276 sys_set_mempolicy long sys_set_mempolicy(int mode, unsigned long __user * nmask, unsigned long maxnode) 
277 sys_mq_open long sys_mq_open(const char __user * u_name, int oflag, mode_t mode, struct mq_attr __user * u_attr) 
278 sys_mq_unlink long sys_mq_unlink(const char __user * u_name) 
279 sys_mq_timedsend long sys_mq_timedsend(mqd_t mqdes, const char __user * u_msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user * u_abs_timeout) 
280 sys_mq_timedreceive ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user * u_msg_ptr, size_t msg_len, unsigned int __user * u_msg_prio, const struct timespec __user * u_abs_timeout) 
281 sys_mq_notify long sys_mq_notify(mqd_t mqdes, const struct sigevent __user * u_notification) 
282 sys_mq_getsetattr long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user * u_mqstat, struct mq_attr __user * u_omqstat) 
283 sys_ni_syscall long sys_ni_syscall(void) 
284 sys_waitid long sys_waitid(int which, pid_t pid, struct siginfo __user * infop, int options, struct rusage __user * ru) 
285 sys_ni_syscall long sys_ni_syscall(void) 
286 sys_add_key long sys_add_key(const char __user * _type, const char __user * _description, const void __user * _payload, size_t plen, key_serial_t ringid) 
287 sys_request_key long sys_request_key(const char __user * _type, const char __user * _description, const char __user * _callout_info, key_serial_t destringid) 
288 sys_keyctl long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) 

October 11, 2006

Linux 2.6 的 System Call:12 大類

把 Linux 提供的 sytsem call service 依分類做整理,並提供實作檔案。本表使用於 Jollen 的「2. GNU Toolchains 與 Embedded Linux Programming」課程中,在此提供給大家做參考。目前依據 Linux 2.6.11 原始碼製成,請搭配 2.6.11 以上的版本做研究。

no Syscall name Implementation file in Linux 2.6.11 (or above)

目前大致把 Linux 2.6.11 的 system call 分成以下幾個類別:

最後一個欄位列出該 system call 實作的檔案 (以 Linux 2.6.11 為主)。請注意,Blog 裡並沒有該檔案的 hyperlink,您可以複制本 blog,並準備一份 Linux 2.6.11 (or above) 的原始碼,以方便 link 到檔案做查詢。

Machine-dependent (i386)
101 sys_ioperm linux/arch/i386/kernel/ioport.c
110 sys_iopl linux/arch/i386/kernel/ioport.c
123 sys_modify_ldt linux/arch/i386/kernel/ldt.c
2 sys_fork linux/arch/i386/kernel/process.c
11 sys_execve linux/arch/i386/kernel/process.c
120 sys_clone linux/arch/i386/kernel/process.c
190 sys_vfork linux/arch/i386/kernel/process.c
243 sys_set_thread_area linux/arch/i386/kernel/process.c
244 sys_get_thread_area linux/arch/i386/kernel/process.c
26 sys_ptrace linux/arch/i386/kernel/ptrace.c
67 sys_sigaction linux/arch/i386/kernel/signal.c
72 sys_sigsuspend linux/arch/i386/kernel/signal.c
119 sys_sigreturn linux/arch/i386/kernel/signal.c
173 sys_rt_sigreturn linux/arch/i386/kernel/signal.c
179 sys_rt_sigsuspend linux/arch/i386/kernel/signal.c
186 sys_sigaltstack linux/arch/i386/kernel/signal.c
42 sys_pipe linux/arch/i386/kernel/sys_i386.c
59 sys_olduname linux/arch/i386/kernel/sys_i386.c
82 old_select linux/arch/i386/kernel/sys_i386.c
90 old_mmap linux/arch/i386/kernel/sys_i386.c
109 sys_uname linux/arch/i386/kernel/sys_i386.c
117 sys_ipc linux/arch/i386/kernel/sys_i386.c
192 sys_mmap2 linux/arch/i386/kernel/sys_i386.c
113 sys_vm86old linux/arch/i386/kernel/vm86.c
166 sys_vm86 linux/arch/i386/kernel/vm86.c
Filesystem
245 sys_io_setup linux/fs/aio.c
246 sys_io_destroy linux/fs/aio.c
247 sys_io_getevents linux/fs/aio.c
248 sys_io_submit linux/fs/aio.c
249 sys_io_cancel linux/fs/aio.c
36 sys_sync linux/fs/buffer.c
118 sys_fsync linux/fs/buffer.c
134 sys_bdflush linux/fs/buffer.c
148 sys_fdatasync linux/fs/buffer.c
183 sys_getcwd linux/fs/dcache.c
253 sys_lookup_dcookie linux/fs/dcookies.c
254 sys_epoll_create linux/fs/eventpoll.c
255 sys_epoll_ctl linux/fs/eventpoll.c
256 sys_epoll_wait linux/fs/eventpoll.c
86 sys_uselib linux/fs/exec.c
41 sys_dup linux/fs/fcntl.c
55 sys_fcntl linux/fs/fcntl.c
63 sys_dup2 linux/fs/fcntl.c
221 sys_fcntl64 linux/fs/fcntl.c
135 sys_sysfs linux/fs/filesystems.c
54 sys_ioctl linux/fs/ioctl.c
143 sys_flock linux/fs/locks.c
9 sys_link linux/fs/namei.c
10 sys_unlink linux/fs/namei.c
14 sys_mknod linux/fs/namei.c
38 sys_rename linux/fs/namei.c
39 sys_mkdir linux/fs/namei.c
40 sys_rmdir linux/fs/namei.c
83 sys_symlink linux/fs/namei.c
21 sys_mount linux/fs/namespace.c
22 sys_oldumount linux/fs/namespace.c
52 sys_umount linux/fs/namespace.c
217 sys_pivot_root linux/fs/namespace.c
169 sys_nfsservctl linux/fs/nfsctl.c
5 sys_open linux/fs/open.c
6 sys_close linux/fs/open.c
8 sys_creat linux/fs/open.c
12 sys_chdir linux/fs/open.c
15 sys_chmod linux/fs/open.c
30 sys_utime linux/fs/open.c
33 sys_access linux/fs/open.c
61 sys_chroot linux/fs/open.c
92 sys_truncate linux/fs/open.c
93 sys_ftruncate linux/fs/open.c
94 sys_fchmod linux/fs/open.c
99 sys_statfs linux/fs/open.c
100 sys_fstatfs linux/fs/open.c
111 sys_vhangup linux/fs/open.c
133 sys_fchdir linux/fs/open.c
193 sys_truncate64 linux/fs/open.c
194 sys_ftruncate64 linux/fs/open.c
198 sys_lchown linux/fs/open.c
207 sys_fchown linux/fs/open.c
212 sys_chown linux/fs/open.c
268 sys_statfs64 linux/fs/open.c
269 sys_fstatfs64 linux/fs/open.c
131 sys_quotactl linux/fs/quota.c
89 old_readdir linux/fs/readdir.c
141 sys_getdents linux/fs/readdir.c
220 sys_getdents64 linux/fs/readdir.c
3 sys_read linux/fs/read_write.c
4 sys_write linux/fs/read_write.c
19 sys_lseek linux/fs/read_write.c
140 sys_llseek linux/fs/read_write.c
145 sys_readv linux/fs/read_write.c
146 sys_writev linux/fs/read_write.c
180 sys_pread64 linux/fs/read_write.c
181 sys_pwrite64 linux/fs/read_write.c
187 sys_sendfile linux/fs/read_write.c
239 sys_sendfile64 linux/fs/read_write.c
142 sys_select linux/fs/select.c
168 sys_poll linux/fs/select.c
18 sys_stat linux/fs/stat.c
28 sys_fstat linux/fs/stat.c
84 sys_lstat linux/fs/stat.c
85 sys_readlink linux/fs/stat.c
106 sys_newstat linux/fs/stat.c
107 sys_newlstat linux/fs/stat.c
108 sys_newfstat linux/fs/stat.c
195 sys_stat64 linux/fs/stat.c
196 sys_lstat64 linux/fs/stat.c
197 sys_fstat64 linux/fs/stat.c
62 sys_ustat linux/fs/super.c
226 sys_setxattr linux/fs/xattr.c
227 sys_lsetxattr linux/fs/xattr.c
228 sys_fsetxattr linux/fs/xattr.c
229 sys_getxattr linux/fs/xattr.c
230 sys_lgetxattr linux/fs/xattr.c
231 sys_fgetxattr linux/fs/xattr.c
232 sys_listxattr linux/fs/xattr.c
233 sys_llistxattr linux/fs/xattr.c
234 sys_flistxattr linux/fs/xattr.c
235 sys_removexattr linux/fs/xattr.c
236 sys_lremovexattr linux/fs/xattr.c
237 sys_fremovexattr linux/fs/xattr.c
Linux Kernel
51 sys_acct linux/kernel/acct.c
184 sys_capget linux/kernel/capability.c
185 sys_capset linux/kernel/capability.c
136 sys_personality linux/kernel/exec_domain.c
1 sys_exit linux/kernel/exit.c
7 sys_waitpid linux/kernel/exit.c
114 sys_wait4 linux/kernel/exit.c
252 sys_exit_group linux/kernel/exit.c
258 sys_set_tid_address linux/kernel/fork.c
240 sys_futex linux/kernel/futex.c
104 sys_setitimer linux/kernel/itimer.c
105 sys_getitimer linux/kernel/itimer.c
128 sys_init_module linux/kernel/module.c
129 sys_delete_module linux/kernel/module.c
162 sys_nanosleep linux/kernel/posix-timers.c
259 sys_timer_create linux/kernel/posix-timers.c
260 sys_timer_settime linux/kernel/posix-timers.c
261 sys_timer_gettime linux/kernel/posix-timers.c
262 sys_timer_getoverrun linux/kernel/posix-timers.c
263 sys_timer_delete linux/kernel/posix-timers.c
264 sys_clock_settime linux/kernel/posix-timers.c
265 sys_clock_gettime linux/kernel/posix-timers.c
266 sys_clock_getres linux/kernel/posix-timers.c
267 sys_clock_nanosleep linux/kernel/posix-timers.c
103 sys_syslog linux/kernel/printk.c
Scheduling
34 sys_nice linux/kernel/sched.c
154 sys_sched_setparam linux/kernel/sched.c
155 sys_sched_getparam linux/kernel/sched.c
156 sys_sched_setscheduler linux/kernel/sched.c
157 sys_sched_getscheduler linux/kernel/sched.c
158 sys_sched_yield linux/kernel/sched.c
159 sys_sched_get_priority_max linux/kernel/sched.c
160 sys_sched_get_priority_min linux/kernel/sched.c
161 sys_sched_rr_get_interval linux/kernel/sched.c
241 sys_sched_setaffinity linux/kernel/sched.c
242 sys_sched_getaffinity linux/kernel/sched.c
Signals
0 sys_restart_syscall linux/kernel/signal.c
29 sys_pause linux/kernel/signal.c
37 sys_kill linux/kernel/signal.c
48 sys_signal linux/kernel/signal.c
68 sys_sgetmask linux/kernel/signal.c
69 sys_ssetmask linux/kernel/signal.c
73 sys_sigpending linux/kernel/signal.c
126 sys_sigprocmask linux/kernel/signal.c
174 sys_rt_sigaction linux/kernel/signal.c
175 sys_rt_sigprocmask linux/kernel/signal.c
176 sys_rt_sigpending linux/kernel/signal.c
177 sys_rt_sigtimedwait linux/kernel/signal.c
178 sys_rt_sigqueueinfo linux/kernel/signal.c
238 sys_tkill linux/kernel/signal.c
270 sys_tgkill linux/kernel/signal.c
Systems
43 sys_times linux/kernel/sys.c
57 sys_setpgid linux/kernel/sys.c
60 sys_umask linux/kernel/sys.c
65 sys_getpgrp linux/kernel/sys.c
66 sys_setsid linux/kernel/sys.c
74 sys_sethostname linux/kernel/sys.c
75 sys_setrlimit linux/kernel/sys.c
76 sys_old_getrlimit linux/kernel/sys.c
77 sys_getrusage linux/kernel/sys.c
88 sys_reboot linux/kernel/sys.c
96 sys_getpriority linux/kernel/sys.c
97 sys_setpriority linux/kernel/sys.c
121 sys_setdomainname linux/kernel/sys.c
122 sys_newuname linux/kernel/sys.c
132 sys_getpgid linux/kernel/sys.c
147 sys_getsid linux/kernel/sys.c
172 sys_prctl linux/kernel/sys.c
191 sys_getrlimit linux/kernel/sys.c
203 sys_setreuid linux/kernel/sys.c
204 sys_setregid linux/kernel/sys.c
205 sys_getgroups linux/kernel/sys.c
206 sys_setgroups linux/kernel/sys.c
208 sys_setresuid linux/kernel/sys.c
209 sys_getresuid linux/kernel/sys.c
210 sys_setresgid linux/kernel/sys.c
211 sys_getresgid linux/kernel/sys.c
213 sys_setuid linux/kernel/sys.c
214 sys_setgid linux/kernel/sys.c
215 sys_setfsuid linux/kernel/sys.c
216 sys_setfsgid linux/kernel/sys.c
149 sys_sysctl linux/kernel/sysctl.c
Time
13 sys_time linux/kernel/time.c
25 sys_stime linux/kernel/time.c
78 sys_gettimeofday linux/kernel/time.c
79 sys_settimeofday linux/kernel/time.c
124 sys_adjtimex linux/kernel/time.c
Kernel Timer & Process
20 sys_getpid linux/kernel/timer.c
27 sys_alarm linux/kernel/timer.c
64 sys_getppid linux/kernel/timer.c
116 sys_sysinfo linux/kernel/timer.c
199 sys_getuid linux/kernel/timer.c
200 sys_getgid linux/kernel/timer.c
201 sys_geteuid linux/kernel/timer.c
202 sys_getegid linux/kernel/timer.c
224 sys_gettid linux/kernel/timer.c
16-bit uid (wrapper functions)
16 sys_lchown16 linux/kernel/uid16.c
23 sys_setuid16 linux/kernel/uid16.c
24 sys_getuid16 linux/kernel/uid16.c
46 sys_setgid16 linux/kernel/uid16.c
47 sys_getgid16 linux/kernel/uid16.c
49 sys_geteuid16 linux/kernel/uid16.c
50 sys_getegid16 linux/kernel/uid16.c
70 sys_setreuid16 linux/kernel/uid16.c
71 sys_setregid16 linux/kernel/uid16.c
80 sys_getgroups16 linux/kernel/uid16.c
81 sys_setgroups16 linux/kernel/uid16.c
95 sys_fchown16 linux/kernel/uid16.c
138 sys_setfsuid16 linux/kernel/uid16.c
139 sys_setfsgid16 linux/kernel/uid16.c
164 sys_setresuid16 linux/kernel/uid16.c
165 sys_getresuid16 linux/kernel/uid16.c
170 sys_setresgid16 linux/kernel/uid16.c
171 sys_getresgid16 linux/kernel/uid16.c
182 sys_chown16 linux/kernel/uid16.c
Memory Management
250 sys_fadvise64 linux/mm/fadvise.c
225 sys_readahead linux/mm/filemap.c
257 sys_remap_file_pages linux/mm/fremap.c
219 sys_madvise linux/mm/madvise.c
218 sys_mincore linux/mm/mincore.c
150 sys_mlock linux/mm/mlock.c
151 sys_munlock linux/mm/mlock.c
152 sys_mlockall linux/mm/mlock.c
153 sys_munlockall linux/mm/mlock.c
45 sys_brk linux/mm/mmap.c
91 sys_munmap linux/mm/mmap.c
125 sys_mprotect linux/mm/mprotect.c
163 sys_mremap linux/mm/mremap.c
144 sys_msync linux/mm/msync.c
Swapfile
87 sys_swapon linux/mm/swapfile.c
115 sys_swapoff linux/mm/swapfile.c
Socket
102 sys_socketcall linux/net/socket.c

Linux System Calls' Forum, #1:(第20號系統服務) sys_getpid

對於 Linux system call 的研究,我們採取的策略是「依分類」來做討論,而不是依 system call 編號依序討論。透過 system call (kernel-space 端) 的研究,我們除了可以更深入了解作業系統外,更能一探 Linux kernel 的奧妙。

20 sys_getpid linux/kernel/timer.c
類別:Kernel Timer & Process
原型宣告:long sys_getpid(void);
用途說明:取得目前 process 的 thread ID (process ID)。
Kernel (2.6.11 or above) 實作:
/**
 * sys_getpid - return the thread group id of the current process
 *
 * Note, despite the name, this returns the tgid not the pid.  The tgid and
 * the pid are identical unless CLONE_THREAD was specified on clone() in
 * which case the tgid is the same in all threads of the same group.
 *
 * This is SMP safe as current->tgid does not change.
 */
asmlinkage long sys_getpid(void)
{
	return current->tgid;
}

Jollen 的說明

「Linux system calls 討論」系列,我們略過關於 user-space 端的說明,因此大家必須先了解以下主題:

  • system call 的 wrapper function (glibc)
  • 0x80 號軟體中斷 (i386)

sys_getpid 透過 current 巨集取得目前 process 的 ID,kernel code 都可以存取 current 巨集 (我們把此巨集當做 kernel 的 global symbol 來看) 來存取目前 process 的狀態。

current 的 data structure 為 struct task_struct

// include/linux/sched.h

struct task_struct {
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	struct thread_info *thread_info;
	atomic_t usage;
	unsigned long flags;	/* per process flags, defined below */
	unsigned long ptrace;
	int lock_depth;		/* BKL lock depth */
#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
	int oncpu;
#endif
	int prio, static_prio;
	struct list_head run_list;
	prio_array_t *array;
	unsigned short ioprio;
	unsigned int btrace_seq;
	unsigned long sleep_avg;
	unsigned long long timestamp, last_ran;
	unsigned long long sched_time; /* sched_clock time spent running */
	enum sleep_type sleep_type;
	unsigned long policy;
	cpumask_t cpus_allowed;
	unsigned int time_slice, first_time_slice;
#ifdef CONFIG_SCHEDSTATS
	struct sched_info sched_info;
#endif
	struct list_head tasks;
	/*
	 * ptrace_list/ptrace_children forms the list of my children
	 * that were stolen by a ptracer.
	 */
	struct list_head ptrace_children;
	struct list_head ptrace_list;
	struct mm_struct *mm, *active_mm;
/* task state */
	struct linux_binfmt *binfmt;
	long exit_state;
	int exit_code, exit_signal;
	int pdeath_signal;  /*  The signal sent when the parent dies  */
	/* ??? */
	unsigned long personality;
	unsigned did_exec:1;
	pid_t pid;
	pid_t tgid;
	/* 
	 * pointers to (original) parent process, youngest child, younger sibling,
	 * older sibling, respectively.  (p->father can be replaced with 
	 * p->parent->pid)
	 */
	struct task_struct *real_parent; /* real parent process (when being debugged) */
	struct task_struct *parent;	/* parent process */
	/*
	 * children/sibling forms the list of my children plus the
	 * tasks I'm ptracing.
	 */
	struct list_head children;	/* list of my children */
	struct list_head sibling;	/* linkage in my parent's children list */
	struct task_struct *group_leader;	/* threadgroup leader */
	/* PID/PID hash table linkage. */
	struct pid_link pids[PIDTYPE_MAX];
	struct list_head thread_group;
	struct completion *vfork_done;		/* for vfork() */
	int __user *set_child_tid;		/* CLONE_CHILD_SETTID */
	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */
	unsigned long rt_priority;
	cputime_t utime, stime;
	unsigned long nvcsw, nivcsw; /* context switch counts */
	struct timespec start_time;
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
	unsigned long min_flt, maj_flt;
  	cputime_t it_prof_expires, it_virt_expires;
	unsigned long long it_sched_expires;
	struct list_head cpu_timers[3];
/* process credentials */
	uid_t uid,euid,suid,fsuid;
	gid_t gid,egid,sgid,fsgid;
	struct group_info *group_info;
	kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
	unsigned keep_capabilities:1;
	struct user_struct *user;
#ifdef CONFIG_KEYS
	struct key *request_key_auth;	/* assumed request_key authority */
	struct key *thread_keyring;	/* keyring private to this thread */
	unsigned char jit_keyring;	/* default keyring to attach requested keys to */
#endif
	int oomkilladj; /* OOM kill score adjustment (bit shift). */
	char comm[TASK_COMM_LEN]; /* executable name excluding path
				     - access with [gs]et_task_comm (which lock
				       it with task_lock())
				     - initialized normally by flush_old_exec */
/* file system info */
	int link_count, total_link_count;
/* ipc stuff */
	struct sysv_sem sysvsem;
/* CPU-specific state of this task */
	struct thread_struct thread;
/* filesystem information */
	struct fs_struct *fs;
/* open file information */
	struct files_struct *files;
/* namespace */
	struct namespace *namespace;
/* signal handlers */
	struct signal_struct *signal;
	struct sighand_struct *sighand;
	sigset_t blocked, real_blocked;
	sigset_t saved_sigmask;		/* To be restored with TIF_RESTORE_SIGMASK */
	struct sigpending pending;
	unsigned long sas_ss_sp;
	size_t sas_ss_size;
	int (*notifier)(void *priv);
	void *notifier_data;
	sigset_t *notifier_mask;
	void *security;
	struct audit_context *audit_context;
	seccomp_t seccomp;
/* Thread group tracking */
   	u32 parent_exec_id;
   	u32 self_exec_id;
/* Protection of (de-)allocation: mm, files, fs, tty, keyrings */
	spinlock_t alloc_lock;
/* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */
	spinlock_t proc_lock;
#ifdef CONFIG_DEBUG_MUTEXES
	/* mutex deadlock detection */
	struct mutex_waiter *blocked_on;
#endif
/* journalling filesystem info */
	void *journal_info;
/* VM state */
	struct reclaim_state *reclaim_state;
	struct dentry *proc_dentry;
	struct backing_dev_info *backing_dev_info;
	struct io_context *io_context;
	unsigned long ptrace_message;
	siginfo_t *last_siginfo; /* For ptrace use.  */
/*
 * current io wait handle: wait queue entry to use for io waits
 * If this thread is processing aio, this points at the waitqueue
 * inside the currently handled kiocb. It may be NULL (i.e. default
 * to a stack based synchronous wait) if its doing sync IO.
 */
	wait_queue_t *io_wait;
/* i/o counters(bytes read/written, #syscalls */
	u64 rchar, wchar, syscr, syscw;
#if defined(CONFIG_BSD_PROCESS_ACCT)
	u64 acct_rss_mem1;	/* accumulated rss usage */
	u64 acct_vm_mem1;	/* accumulated virtual memory usage */
	clock_t acct_stimexpd;	/* clock_t-converted stime since last update */
#endif
#ifdef CONFIG_NUMA
  	struct mempolicy *mempolicy;
	short il_next;
#endif
#ifdef CONFIG_CPUSETS
	struct cpuset *cpuset;
	nodemask_t mems_allowed;
	int cpuset_mems_generation;
	int cpuset_mem_spread_rotor;
#endif
	struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
	struct compat_robust_list_head __user *compat_robust_list;
#endif
	atomic_t fs_excl;	/* holding fs exclusive resources */
	struct rcu_head rcu;
	/*
	 * cache last used pipe for splice
	 */
	struct pipe_inode_info *splice_pipe;
};
struct task_struct 是 Linux kernel 表示 task 的標準資料結構。sys_getpid 傳回 current->tgid 即完成工作,其中 tgid 表示 thread group ID 即 PID。

--作者/陳俊宏 (www.jollen.org)

October 12, 2006

Linux System Calls' Forum, #2:(第199,201,200,202,224號系統服務) sys_getuid, sys_geteuid, sys_getgid, sys_getegid, sys_gettid


199 sys_getuid linux/kernel/timer.c
類別:Kernel Timer & Process
原型宣告:long sys_getuid(void);
用途說明:取得目前 process 的 real user ID (UID)。
Kernel (2.6.11 or above) 實作:
asmlinkage long sys_getuid(void)
{
        /* Only we change this so SMP safe */
        return current->uid;
}

201 sys_geteuid linux/kernel/timer.c
類別:Kernel Timer & Process
原型宣告:long sys_geteuid(void);
用途說明:取得目前 process 的 effective real user ID (file ID bit)。
Kernel (2.6.11 or above) 實作:
asmlinkage long sys_geteuid(void)
{
        /* Only we change this so SMP safe */
        return current->euid;
}

Jollen 的說明

struct task_struct 裡紀錄了 task (process) 的所有資訊,其中我們最為熟悉的 process ID 與 user ID (and group ID) 都可以由這個資料結構裡取得。讓我們來看看 wrapper function 'getuid' 的用法 (from man):

NAME
       getuid, geteuid - get user identity
                                                                                
SYNOPSIS
       #include 
       #include 
 
       uid_t getuid(void);
       uid_t geteuid(void);
 
DESCRIPTION
       getuid returns the real user ID of the current process.
 
       geteuid returns the effective user ID of the current process.
 
       The  real  ID corresponds to the ID of the calling process.  The effec-
       tive ID corresponds to the set ID bit on the file being executed.

'getuid' 所對應的 system call service 為 sys_getuid,讓我們來看一下 Linux 的實作:

asmlinkage long sys_getuid(void)
{
        /* Only we change this so SMP safe */
        return current->uid;
}

嗯,果然是非常的好懂,只要懂 current 巨集的用途即可!另外,要提醒的是,'current->uid' 並非直接 return 給 user-space 的 wrapper function (getuid in our example)。(那是 return 給誰?)

在 Linux 裡有許多類似 getuid 的 system call 實作,比如 sys_geteuid 的程式碼也是直接回傳 struct task_struct 裡的 field,並不難懂。

以下是 sys_getgidsys_getegid 的整理。

200 sys_getgid linux/kernel/timer.c
類別:Kernel Timer & Process
原型宣告:long sys_getgid(void);
用途說明:取得目前 process 的 real group ID (GID)。
Kernel (2.6.11 or above) 實作:
asmlinkage long sys_getgid(void)
{
        /* Only we change this so SMP safe */
        return current->gid;
}

202 sys_getegid linux/kernel/timer.c
類別:Kernel Timer & Process
原型宣告:long sys_getegid(void);
用途說明:取得目前 process 的 effective group ID (EGID)。
Kernel (2.6.11 or above) 實作:
asmlinkage long sys_getegid(void)
{
        /* Only we change this so SMP safe */
        return  current->egid;
}

這 4 個 Linux system call 都非常的容易了解,由 Linux System Calls' Forum #1,#2 我們了解到 2 個重要的 Kernel 議題:

  • 1. struct task_struct;
  • 2. The current macro.

最後還有一個 sys_gettid 的實作。

224 sys_gettid linux/kernel/timer.c
類別:Kernel Timer & Process
原型宣告:long sys_gettid(void);
用途說明:取得 task 的 "pid"。
Kernel (2.6.11 or above) 實作:
/* Thread ID - the internal kernel "pid" */
asmlinkage long sys_gettid(void)
{
        return current->pid;
}

October 13, 2006

ext4 檔案系統現身了!

新一代的檔案儲存 (storage) 檔案系統 (filesystem) - ext4 已經出現在Linux 2.16.19rc1-mm1 的核心原始碼裡了!ext4 是更先進的檔案系統,他前身就是知名的 ext3 檔案系統;ext3 是目前 Linux 普遍使用的知名檔案系統。

ext4 加入了 "extent file writing" 技術的支援,這是一個能減少 "fragmentation" 並增進效能的技術。有興趣的朋友可以閱讀 Linux-watch 上的官方新聞:

http://www.linux-watch.com/news/NS3183866977.html

'-mm' 系列的 2.6 kernel 是由 Andrew Morton 所釋出的 Linux 分支,主要性質以「實驗」與「新功能」為主;'ext4' 一睹為快,搶鮮下載 (mm patch 下載官網):

ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.19-rc1/2.6.19-rc1-mm1/

並且也要下載新的 e2fsprogs 套件:

ftp://ftp.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs-interim/

使用方法 (ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.19-rc1/2.6.19-rc1-mm1/announce.txt):

# mke2fs -j /dev/hda1 (格式化)
# mount /dev/hda1 /wherever -t ext4dev (filesystem type 'ext4dev')

如果要使用 'extent' 功能:

# mount /dev/hda1 /wherever -t ext4dev -o extents

October 14, 2006

Linux System Calls' Forum, #3:(第64號系統服務) sys_getppid

sys_getppid 是很有趣的一個實作常式。

當 process fork 新的 process 後,便成為該 process 的 parent process,當然,新的 process 便成為 child process。在 UNIX 的 multithreaded 程式設計的理論中,process 之間的關係是相當重要的,比如說,只有 related process (e.g. parent process v.s. child process) 可以透過 pipe 的機制來交換資料。

process 呼叫 fork() 函數(更正確的說法是 fork system call 的 wrapper function)後,fork() 便傳回 child process 的 PID;child process 則可以透過 getppid() system call 來取得 parent process 的 PID。

64 sys_getppid linux/kernel/timer.c
類別:Kernel Timer & Process
原型宣告:long sys_getppid(void);
用途說明:取得 parent process 的 PID。
Kernel (2.6.11 or above) 實作:
/*
 * Accessing ->group_leader->real_parent is not SMP-safe, it could
 * change from under us. However, rather than getting any lock
 * we can use an optimistic algorithm: get the parent
 * pid, and go back and check that the parent is still
 * the same. If it has changed (which is extremely unlikely
 * indeed), we just try again..
 *
 * NOTE! This depends on the fact that even if we _do_
 * get an old value of "parent", we can happily dereference
 * the pointer (it was and remains a dereferencable kernel pointer
 * no matter what): we just can't necessarily trust the result
 * until we know that the parent pointer is valid.
 *
 * NOTE2: ->group_leader never changes from under us.
 */
asmlinkage long sys_getppid(void)
{
	int pid;
	struct task_struct *me = current;
	struct task_struct *parent;

	parent = me->group_leader->real_parent;
	for (;;) {
		pid = parent->tgid;
#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
{
		struct task_struct *old = parent;

		/*
		 * Make sure we read the pid before re-reading the
		 * parent pointer:
		 */
		smp_rmb();
		parent = me->group_leader->real_parent;
		if (old != parent)
			continue;
}
#endif
		break;
	}
	return pid;
}		

Jollen 的說明

Linux kernel 內部的 getppid 實作常式 (routine) - sys_getppid 的程式碼並不難懂, 在這裡我們先忽略 SMP 與 preemptive scheduling 的議題,因此有一段落的程式碼我們故意視而不見,讓我們來討論剩下的程式碼:

asmlinkage long sys_getppid(void)
{
	int pid;
	struct task_struct *me = current;
	struct task_struct *parent;

	parent = me->group_leader->real_parent;
	for (;;) {
		pid = parent->tgid;
#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
{
 	...
}
#endif
		break;
	}
	return pid;
}	
struct task_struct 的 field - 'group_leader' 是一個 pointer,指向 thread (process) group 的 leader;struct task_struct 的 field - 'real_parent' 是一個 pointer,指向 task 的 "real parent":
struct task_struct {
	...
	/* real parent process (when being debugged) */
	struct task_struct *real_parent;
	struct task_struct *parent; /* parent process */
	...
	/* threadgroup leader */
	struct task_struct *group_leader;
	...
}	

real_parent 與 parent

struct task_struct 裡,我們發現一件有趣的事:怎麼會有 real_parent parent 二個 field 呢?

我們姑且不去說明 parent 的用義,real_parent 指的是建立(create)此 process(task)的 process,當建立該 process 的 process(real_parent)已經不存在時(eg. terminate),real_parent 便指向 init process。

好囉,我們知道一件重要的事情了,要找到「我的爸爸」 kernel code 寫法是:

struct task_struct *me = current;   /* 我自己 */

struct task_struct *parent;   /* 我爸 */

parent = me->real_parent;   /* 我真正的爸(生下我的)*/

但這裡的寫法並不正確。讓我們繼續往下討論。

Group Leader

每一個 process 都是某些 process group 的成員,所有的 process group 都有一個帶班的 process(group leader)。比如說,當 GNU/Linux 系統開機時,init process 就是所有 process 的 group leader。

因此 process 的 parent process 應該是「group leader 的 real parent」,所以我們要先索引到 process descriptor 的 group_leader 欄位,然後再索引到 group leader 的 real_parent

TIP

   借用一下作業系統的說法:struct task_struct 就是 process 的 process descriptor。

所以,正確的 kernel code 寫法是:

struct task_struct *me = current;   /* 我自己 */

struct task_struct *parent;   /* 我爸 */

parent = me->group_leader->real_parent;   /* 領班的真正爸,才是我的爸 = = " */

這樣就能理解 Linux 2.6 的 sys_getppid 實作了,雖然有一點不太直覺,不過看起來是頗有學問的設計。知道怎麼找到 parent process 後,再由 process descriptor 裡把 PID 拿出來就行了:

parent->tgid;

作業系統還真是有趣。

--jollen

作者/陳俊宏
http://www.jollen.org

October 15, 2006

Linux System Calls' Forum, #4:(第34號系統服務) sys_nice

nice() 是用來變更 process 優先序(priority)的 system call,nice() system call 叫用(invoke)的 system call 實作常式為 sys_nicesys_nice 服務常式(service routine)是 Linux 排程(scheduling)相關的服務常式中最基本(也是最古老)的一個。

34 sys_nice linux/kernel/sched.c
類別:Scheduling
原型宣告:long sys_nice(int increment);
用途說明:變更 process 的優先序。
Kernel (2.6.11 or above) 實作:
/*
 * sys_nice - change the priority of the current process.
 * @increment: priority increment
 *
 * sys_setpriority is a more generic, but much slower function that
 * does similar things.
 */
asmlinkage long sys_nice(int increment)
{
	int retval;
	long nice;

	/*
	 * Setpriority might change our priority at the same moment.
	 * We don't have to worry. Conceptually one call occurs first
	 * and we have a single winner.
	 */
	if (increment < -40)
		increment = -40;
	if (increment > 40)
		increment = 40;

	nice = PRIO_TO_NICE(current->static_prio) + increment;
	if (nice < -20)
		nice = -20;
	if (nice > 19)
		nice = 19;

	if (increment < 0 && !can_nice(current, nice))
		return -EPERM;

	retval = security_task_setnice(current, nice);
	if (retval)
		return retval;

	set_user_nice(current, nice);
	return 0;
}

Jollen 的說明

首先,讓我們先看一下 NICE(2) 的內容:

NAME
       nice - change process priority

SYNOPSIS
       #include 

       int nice(int inc);

DESCRIPTION
       nice  adds  inc  to  the nice value for the calling pid.  (A large nice
       value means a low priority.)  Only the superuser may specify a negative
       increment, or priority increase.

參數 inc 是所要改變的 priority 數量,inc 可以是正數也可以是負數。正數表示 priority 變多(多加上 inc,表示  low priority),若要提升 priority,inc 只要指定為負數即可;根據 NICE(2) 的說明,只有 superuser 才能指定負數,也就是把提高優先序。

nice() 會把 process 的 priority 變更為 "priority+ inc"。

sys_nice() 的實作

以下是 sys_nice() service routine 的原型:

long sys_nice(int increment)

increment 就是前面所提到的 inc 參數(透過 system call 機制傳遞,並非函數呼叫傳值)。increment 的範圍被 kernel 限定在 [40,-40] 的範圍內:

	if (increment < -40)
		increment = -40;
	if (increment > 40)
		increment = 40;

所以如果呼叫 nice() 時,指定的優先改變量超過 [40,-40] 時,是得不到預期效果的。sys_nice 接著先把 process 的 "priority" 數值轉算成 "nice" 值,然後再加上 increment(因為 increment 是一個 "nice" 值,不是 "priority" 值):

	nice = PRIO_TO_NICE(current->static_prio) + increment;

得到的 "nice" 值,必須限定在 [19,-20] 的範圍內:

	if (nice < -20)
		nice = -20;
	if (nice > 19)
		nice = 19;

再來,如果 increment 小於 0,也就是 user 的 "nice" 值是負的,那就要檢查是不是可以變更此 process 的 "priority":

	if (increment < 0 && !can_nice(current, nice))
		return -EPERM; 

不過這裡的重點是 can_nice() 所呼叫的 kernel API - capable(),並非 can_nice() 本身,再追一下 can_nice() 的原始碼可以找到這段:

capable(CAP_SYS_NICE)

capable() 用來檢查 process 的 "capability",不過我們先在這裡略過這個主題。

Process capability 若允許變更 priority,就修改 process 的 priority,否則 return -EPERM

更多關於 sys_nice()

sys_nice() 目前大概是為了要向後相容而持續存在於 Linux 原始碼裡,目前已經推薦改用 sys_setpriority() 服務常式了。因此在 Linux programming 上,我們也要改用 setpriority() system call 來取代 nice()。以下是 GETPRIORITY(2):

NAME
       getpriority, setpriority - get/set program scheduling priority

SYNOPSIS
       #include 
       #include 

       int getpriority(int which, int who);
       int setpriority(int which, int who, int prio);
TIP

  "priority" 表示 process 的優先序,數字越大表示優先序越低;"nice" 指的是要改變的 priority 量,例如 -10 表示要把 priority 減少 10,即提高優先序。

--jollen

作者/陳俊宏
http://www.jollen.org

Embedded Linux 的系統管理,#5: './configure' 與 Software Stack

'./configure' 的設定決定 root filesystem 的架構(architecture),即 software stack 的設計。以我們「Embedded Linux 的系統管理 (x86)」課程舉出的 Nano-X project 案例來說,我們可以規劃出 2 種架構:

1. 典型的 Desktop (PC) 使用的架構 - ffplay + SDL + x11。
2. 讓 ffplay 在 Nano-X 介面裡撥放影片 - ffplay + SDL + Nano-X。

其中第 2 點是最有趣的架構,可以讓同學練習 software stack 有關的 './configure' 設定。

首先,同學要先把 FFmpeg 在 x86 上編譯完成,然後我們透過不同的 SDL 管理觀念,讓 ffplay 能夠在 X11 與 Nano-X 的介面上撥放。

不管是在 X11 上撥放影片,或是在 Nano-X 上撥放,都不必動到 FFmpeg(ffplay)。(why?)

嵌入式 Linux 系統管理 - Software Stack 的設定

如果使用 Red Hat Linux 9 (or Fedora) 預設的 SDL,ffplay 的執行畫面如下圖。

ffplay_x11.jpg
圖一:在 X11 上執行的 ffplay

這時 SDL 的編譯設定 (configure) 應該是類似這樣的:

# ./configure --prefix=/usr --enable-video-x11 --disable-video-fbcon --disable-nano-direct-fb --disable-video-nanox --disable-nanox-share-memory --disable-alsatest --with-nanox-pixel-type=0888

我們修改 configure 參數如下:

# ./configure --prefix=/usr --disable-video-x11 --disable-video-fbcon --enable-nano-direct-fb --enable-video-nanox --enable-nanox-share-memory --disable-alsatest --with-nanox-pixel-type=0888

重新編譯並安裝 SDL 後,ffplay 就能在 Nano-X 的介面下撥放影片。如果 Nano-X 的設定是支援 X11 的話,執行後的結果會是下圖的畫面。

ffplay_nanox.jpg
圖二:在 Nano-X 上執行的 ffplay (Nano-X with X11)

我們怎麼讓 ffplay 可以在開機後,直接透過 VGA framebuffer 來撥放影片,而不用再進入 X11 呢?做法是:把 Nano-X 設定成支援 VGA framebuufer 即可(Nano-X with VGA FB),至於 SDL 的話,是不用再做任何調整的了!(why?) 當然 ffplay 也不用變動。所以,關於第 2 點的架構做法,可以再細分成:

2.1 ffplay + SDL + Nano-X + X11
2.2 ffplay + SDL + Nano-X + VGA fb

很值得用來練習編譯設定與觀念討論的例子。

Embedded Linux 的考量

「ffplay + SDL + Nano-X」這個架構是適合 Embedded Linux 使用的,只要讓 Nano-X 能完整支援 target device,並把 SDL 與 FFmpeg 移植到 target device,便能在 target device 上撥放影片檔。

October 17, 2006

getpriority() 與 setpriority() 程式設計

前幾天介紹到 Linux 的一個排程(Scheduling)系統服務叫做 sys_nice(),與 sys_nice() 相關的 system call service 是 sys_getpriority()sys_setpriority(),不過在看 kernel code 前,我們應該先試著了解 getpriority()setpriority() 二個 system call 的用法。

先來了解一下 getpriority() 的用途,GETPRIORITY(2):

SYNOPSIS #include <sys/time.h> #include <sys/resource.h> int getpriority(int which, int who);

getpriority()which 參數用來指定要取得 priority 對象:process、process group 或 user ID。

最容易學習的方式就是讀範例,所以我們將會設計 2 個範例來執行。

which 參數:

  • PRIO_PROCESSwho 參數指定 process ID,傳回 process 的 priority。
  • PRIO_PGRPwho 參數指定 process group ID,傳回 process group 的 priority。
  • PRIO_USERwho 參數指定 user ID,傳回 user 的 priority 。
Jollen 寫了二個程式:setpriority.cgetpriority.c。先來測試一下。

實測結果

隨便找一個對象下手:

# ps ax ... 17349 ? S 0:02 [httpd] ...

把 PID 17349 的 scheduling priority 往上提升一級:

# ./getpriority 17349 Process (17349) Priority is 0. # ./setpriority Usage: ./setpriority [pid] [priority (-20~19)] # ./setpriority 17349 -1 OK. # ./getpriority 17349 Process (17349) Priority is -1.
另外,系統指令 nice 可以用來設定執行命令的 process priority:
NICE(1) FSF NICE(1) NAME nice - run a program with modified scheduling priority SYNOPSIS nice [OPTION] [COMMAND [ARG]...] DESCRIPTION Run COMMAND with an adjusted scheduling priority. With no COMMAND, print the current scheduling priority. ADJUST is 10 by default. Range goes from -20 (highest priority) to 19 (lowest). -n, --adjustment=ADJUST increment priority by ADJUST first --help display this help and exit --version output version information and exit

程式碼

/* Program: getpriority.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>

int main(int argc, char *argv[])
{
   /* getpriority() 傳回的類別是 int */
   int prio_process, prio_pgroup, prio_user;
   pid_t pid;

   if (argc != 2)
      return -1;

   pid = atoi(argv[1]);
   prio_process = getpriority(PRIO_PROCESS, pid);

   printf("Process (%d) Priority is %d.\n", pid, prio_process);
   return 0;
}
/* Program: setpriority.c */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>

int main(int argc, char *argv[])
{
   int errno, prio;
   pid_t pid;

   if (argc != 3) {
      printf("Usage: %s [pid] [priority (-20~20)]\n", argv[0]);
      return -1;
   }

   pid = atoi(argv[1]);
   prio = atoi(argv[2]);
   errno = setpriority(PRIO_PROCESS, pid, prio);

   printf("OK.\n");

   return 0;
}
了解 setpriority()getpriority() 後,就可以開始研究 system call service - 'sys_setpriority' 與 'sys_getpriority' 了。

October 18, 2006

是蟲啦,不是警告。

是蟲啦,不是警告。在 Linux kernel 的 mailing list 看到一則有意思的張貼,全文如下,Jollen 把重點用紅色標示出來:

* Jeremy Fitzhardinge  wrote:

> A warning is a warning, not a BUG.

> - printk("BUG: warning at %s:%d/%s()n", __FILE__,
> + printk("WARNING at %s:%d %s()n", __FILE__,

i'm not really happy about this change.

Firstly, 
most WARN_ON()s are /bugs/, not warnings ... 
If it's a real
warning, a KERN_INFO printk should be done.

Secondly, the reason i changed it to the 'BUG: ...' format is that i
tried to make it easier for automated tools (and for users) to figure
out that a kernel bug happened.

Ingo
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/ 

很重要,一定要看的概念。在 Linux kernel 裡,WARN_ON() 所秀出來的訊息格式為「BUG: xxx」,表示這是一個臭蟲。如果是警告訊息,則是用 loglevel 'KERN_INFO' 來列印訊息。

所以,這位老兄解釋的很清楚,這類的 "warning" 訊息是 kernel 的 "bug",並不是字面上所表示的「警告」訊息!

October 19, 2006

座談演講投影片下載

跟學弟妹的座談演講,分享自己的工作經驗,並且簡單介紹該如何進入嵌入式 Linux 領域。請按我下載

Linux System Calls' Forum, #5:(第96號系統服務) sys_getpriority

nice() 是用來變更 process 優先序(priority)的 system call 也是最古老的一個,sys_getpriority()sys_setpriority() 則是取代 sys_nice() 的新實作,今天我們先討論一下 'sys_getpriority'。

96 sys_getpriority linux/kernel/sys.c
類別:Systems
原型宣告:long sys_getpriority(int which, int who);
用途說明:取得 process 的排程優先序(Priority)。
Kernel (2.6.11 or above) 實作:
/*
 * Ugh. To avoid negative return values, "getpriority()" will
 * not return the normal nice-value, but a negated value that
 * has been offset by 20 (ie it returns 40..1 instead of -20..19)
 * to stay compatible.
 */
asmlinkage long sys_getpriority(int which, int who)
{
	struct task_struct *g, *p;
	struct user_struct *user;
	long niceval, retval = -ESRCH;

	if (which > 2 || which < 0)
		return -EINVAL;

	read_lock(&tasklist_lock);
	switch (which) {
		case PRIO_PROCESS:
			if (!who)
				who = current->pid;
			p = find_task_by_pid(who);
			if (p) {
				niceval = 20 - task_nice(p);
				if (niceval > retval)
					retval = niceval;
			}
			break;
		case PRIO_PGRP:
			if (!who)
				who = process_group(current);
			do_each_task_pid(who, PIDTYPE_PGID, p) {
				niceval = 20 - task_nice(p);
				if (niceval > retval)
					retval = niceval;
			} while_each_task_pid(who, PIDTYPE_PGID, p);
			break;
		case PRIO_USER:
			user = current->user;
			if (!who)
				who = current->uid;
			else
				if ((who != current->uid) && !(user = find_user(who)))
					goto out_unlock;	/* No processes for this user */

			do_each_thread(g, p)
				if (p->uid == who) {
					niceval = 20 - task_nice(p);
					if (niceval > retval)
						retval = niceval;
				}
			while_each_thread(g, p);
			if (who != current->uid)
				free_uid(user);		/* for find_user() */
			break;
	}
out_unlock:
	read_unlock(&tasklist_lock);

	return retval;
}

Jollen 的說明

讓我們來看一下 system call service - 'sys_getpriority' 的程式實作。首先是 sys_getpriority() 的參數:whichwho,這二個參數對應到 getpriority() which who 參數;如果您不是很清楚 which/who 的話,請參閱前幾天的日記

我們拿底下的程式片斷來討論:

	switch (which) { /* 請看 1. */
		case PRIO_PROCESS: /* 請看 2. */
			if (!who) /* 請看 2. */
				who = current->pid;
			p = find_task_by_pid(who); /* 請看 3. */
			if (p) { /* 請看 4. */
				niceval = 20 - task_nice(p); /* 請看 5. */
				if (niceval > retval)
					retval = niceval;
			}
			break;
		...
	}

說明如下:

  1. 判斷 which 參數,假設我們想要取得 process 的 priority,那麼 which 的值就是 PRIO_PROCESS
  2. which = PRIO_PROCESS,則 who 的值就是 process ID。因為 who 不應該為 0,所以如果 who 是 0 的話,就指定為 current 的 PID。
  3. find_task_by_pid() 是 kernel API,用來取得 PID 的 process descriptor。
  4. 如果 p 不是 NULL,就呼叫 task_nice(),取得 process 的「nice 值」,然後傳回 nice 值。
  5. kernel 的 nice 值範圍為 [-20..19],但 user-space 的 nice 值是 [40,1],所以要做換算:[20-(-20)..20-19] = [40..1]。

喔!要取得 process priority 的 kernel 實作看起來還挺簡單的。我們又學到了:

  • kernel API - find_task_by_pid():傳入 PID,取得該 process 的 process descriptor。
  • kernel API - task_nice():傳入 process descriptor,取得該 process 的 priority(nice 值)。
TIP
  • 所謂的「nice 值」就是 process 的優先序(優先等級、priority)。

 

跟上我們的腳步:請讀以下的文章,再看這篇日記!

Kernel 2.6 的 KVM (Kernel Virtual Machine) 驅動程式來了

在伺服器(server)技術的發展藍圖中(roadmap),虛擬伺服器(virtual server)是 Intel 近來所著墨的重點。由以往單一硬體對單一作業系統(operating system)的伺服器架構(1 physical server v.s. 1 OS),未來將會演進成為單一硬體對多個作業系統的架構(1 physical server v.s. multiple OS)。

Intel 的 Virtualization Technology 就是一個這樣的新技術。Intel 的 Virtualization Technology 可以讓處理器支援多個 OS,不過這其實是基於我們所熟悉的虛擬機器軟體(例如:VMware、QEMU、Xen等)才能達到的,所以這是一個由「processor + chipsets + BIOS + 虛擬機器軟體」互相運作所實現的技術。

Virtual Machine Monitor (VMM)

軟體實作的虛擬機器在此技術領域中被統稱為「VMM - Virtual Machine Monitor」,現在已經有支援 Intel Virtualization Technology 的 VMM 了,那就是知名的 Xen。相關的參考網址如下:

Extending Xen with Intel Virtualization Technology - http://www.intel.com/technology/itj/2006/v10i3/3-xen/1-abstract.htm
Xen - http://www.xensource.com/index.html

接下來,就是我們今天在網路上所看到的重點了!

KVM: Kernel-based Virtual Machine

今天,看到了 2.6 kernel 的 KVM patch。KVM(Kernel Virtual Machine)是 Intel's virtualization technology 的驅動程式!KVM 驅動程式目前支援 i386 與 x86_64 "host",且「All combinations are allowed except x86_64 guest on i386 host.」。

比較特殊的是 Linux 2.6 的 KVM 驅動程式支援三種模式:kernel mode、user mode 與 guest mode。KVM 驅動程式的 user-space 介面是 '/dev/kvm',因此 process 可以執行自己的 virtual machine,在一台電腦上也能執行多個 virtual machine。Guest mode:

「Guest mode has its own address space mapping guest physical memory (which is accessible to user mode by mmap()ing /dev/kvm). Guest mode has no access to any I/O devices; any such access is intercepted and directed to user mode for emulation. 」。

取得 Patch 與追踪主題

[PATCH 0/7] KVM: Kernel-based Virtual Machine
[PATCH 1/7] KVM: userspace interface
[PATCH 2/7] KVM: Intel virtual mode extensions definitions
[PATCH 3/7] KVM: kvm data structures
[PATCH 5/7] KVM: mmu virtualization
[PATCH 6/7] KVM: x86 emulator
[PATCH 7/7] KVM: plumbing

關於更多 Intel 的 Virtualization Technology

可以參考的網址如下:

Make virtualization a reality - http://www.intel.com/cd/channel/reseller/asmo-na/eng/products/server/processors/250640.htm
Server Virtualization Technology - http://www.intel.com/business/bss/products/server/virtualization_wp.pdf

October 20, 2006

再探 sys_getpriority()

getpriority() 若指定 whichPRIO_PGRP 的話,那麼便能取得 process group 裡的「最大 priority 值」。先節錄相關 kernel code 如下:

asmlinkage long sys_getpriority(int which, int who)
{
		...
		case PRIO_PGRP:
			if (!who)
				who = process_group(current);
			do_each_task_pid(who, PIDTYPE_PGID, p) {
				niceval = 20 - task_nice(p);
				if (niceval > retval)
					retval = niceval;
			} while_each_task_pid(who, PIDTYPE_PGID, p);
			break;
		...
}

接續昨天的 sys_getpriority(),讓我們再來看一下 PRIO_PGRP 參數的實作:

1. 如果 who 是 0 的話,先呼叫 process_group() 取得 group ID。
2. 使用 do_each_task_pidwhile_each_task_pid 巨集做迴圈。
3. 在迴圈裡面,呼叫 task_nice() 取得 process 的 priority,然後判斷目前的 nice 值是否大於先前的 nice 值。這麼做的用意是「找到 process group 裡最大的 nice 值 (lowest priority) 後回傳」。
跟上我們的腳步:請讀以下的文章,再看這篇日記!

Linux System Calls' Forum, #6:(第97號系統服務) sys_setpriority

了解 sys_getpriority() 後,要看懂 sys_setpriority() 就不是問題了。

97 sys_setpriority linux/kernel/sys.c
類別:Systems
原型宣告:long sys_setpriority(int which, int who, int niceval);
用途說明:變更 process 的排程優先序(Priority)。
Kernel (2.6.11 or above) 實作:
asmlinkage long sys_setpriority(int which, int who, int niceval)
{
	struct task_struct *g, *p;
	struct user_struct *user;
	int error = -EINVAL;

	if (which > 2 || which < 0)
		goto out;

	/* normalize: avoid signed division (rounding problems) */
	error = -ESRCH;
	if (niceval < -20)
		niceval = -20;
	if (niceval > 19)
		niceval = 19;

	read_lock(&tasklist_lock);
	switch (which) {
		case PRIO_PROCESS:
			if (!who)
				who = current->pid;
			p = find_task_by_pid(who);
			if (p)
				error = set_one_prio(p, niceval, error);
			break;
		case PRIO_PGRP:
			if (!who)
				who = process_group(current);
			do_each_task_pid(who, PIDTYPE_PGID, p) {
				error = set_one_prio(p, niceval, error);
			} while_each_task_pid(who, PIDTYPE_PGID, p);
			break;
		case PRIO_USER:
			user = current->user;
			if (!who)
				who = current->uid;
			else
				if ((who != current->uid) && !(user = find_user(who)))
					goto out_unlock;	/* No processes for this user */

			do_each_thread(g, p)
				if (p->uid == who)
					error = set_one_prio(p, niceval, error);
			while_each_thread(g, p);
			if (who != current->uid)
				free_uid(user);		/* For find_user() */
			break;
	}
out_unlock:
	read_unlock(&tasklist_lock);
out:
	return error;
}

Jollen 的說明

程式一開始先判斷 which 參數的正確性,並且將 user process 所指定的 nice 值限定在 [-20..19] 的範圍內:

	if (which > 2 || which < 0)
		goto out;

	/* normalize: avoid signed division (rounding problems) */
	error = -ESRCH;
	if (niceval < -20)
		niceval = -20;
	if (niceval > 19)
		niceval = 19;

底下我們來討論 PRIO_PROCESSPRIO_PGRP 參數的實作,強烈建議您先行閱讀本文最後所整理的文章,再回頭來看以下的說明,才能得到最佳學習效果。

變更 priority:PRIO_PROCESS

主要的程式片斷如下:

	case PRIO_PROCESS:   /* 請看 1. */
		if (!who)
			who = current->pid;   /* 請看 1. */
		p = find_task_by_pid(who);   /* 請看 2. */
		if (p)   /* 請看 3. */
			error = set_one_prio(p, niceval, error);   /* 請看 3. */
		break;

說明:

  1. which = PRIO_PROCESS,則 who 的值就是 process ID。因為 who 不能為 0,所以如果 who 是 0 的話,就指定為 current 的 PID。
  2. find_task_by_pid() 是 kernel API,用來取得 PID 的 process descriptor。我們已經學過了!
  3. 如果 p 不是 NULL,就呼叫 set_one_prio(),修改 p 的「nice 值」為 niceval

變更 priority:PRIO_PGRP

主要的程式片斷如下:

	case PRIO_PGRP:
		if (!who)
			who = process_group(current);
		do_each_task_pid(who, PIDTYPE_PGID, p) {   /* 請看 1. */
			error = set_one_prio(p, niceval, error);   /* 請看 1. */
		} while_each_task_pid(who, PIDTYPE_PGID, p);   /* 請看 1. */
		break;

說明:

  1. 在迴圈裡,逐一修改 process group 裡的 process,將其優先序變更為 niceval。這樣的迴圈,在 sys_getpriority() 也看過一次!

二段 kernel code 都呼叫到此 kernel API:

  • kernel API - set_one_prio():傳入 process descriptor 與新的 nice 值,將 process 的 priorioty 做變更。
TIP
  • "*_PGRP"(process group)是 kernel 2.4 的 sematics,「current->pgrp」是 kernel 2.4 的寫法。我們未來有機會的話再做說明。

 

跟上我們的腳步:請讀以下的文章,再看這篇日記!

October 22, 2006

Jollen 的 Linux 核心分享包,#1: 《開工篇》

Jollen 計畫在自己的 Blog 陸續與大與分享一些 Linux kernel 的研究心得,我們的寫作方向是以重點式的心得整理為主,不過希望加入一些教學性的風格,希望對大家有幫助。到目前為止,我們與大家分享了 Linux system call service 的幾篇日記,接下來仍會再討論幾個系統服務。

故事是這樣開始的

「Linux System Calls' Forum(LSCT)」旨在討論重要的系統服務(system service),以便將來我們能用最有效率的方式研究 kernel;「Jollen 的 Linux 核心分享包」則是在討論 Linux kernel 與作業系統有關的主題,方向是「討論 kernel 實作」。

Jollen 打算以「講義配合 Blog 開講」的方式跟大家一起玩核心!「一份講義」會以多篇日記方式跟大家討論,這裡的講義是從以前的筆記、演講、內訓課程或是討論會節錄並整理而成(需要時當然也會重新編製),Jollen 打算以講義的形式來整理,因此可能並不適合當做「教材」來使用;因此,在與朋友分享這份講義的同時,也要請大家一同分享 Jollen's Blog 網站。

第一份講義請由本文最後的網址下載,在開始看 kernel 前,以下的準備工作是很重要的:

1. 準備一份 Linux 2.6.11 以上的 kernel source code。請參考以下的幾張投影片,大略了解 kernel code 的分佈與原始碼結構。
2. 準備 Source Insight。這個工具非常熱門,所以我想大家都己經有了!
3. 先備知識(enabling technology):作業系統原理是一定要啦。大家在學校都修過這門必修課,不過日記偶而也會提到參考章節,所以可以的話,也能準備一份在手邊。

發佈計畫

以目前的手稿整理狀況來看,大約會以一星期 1~2 篇日記的進度刊出,第一份講義計畫以 10 篇的篇幅來講解。

Kernel Source 結構

kernel_tree%20%281%29.JPG

kernel_tree%20%283%29.JPG

重要目錄:

  • System Call Interfaces: 實作程式碼散落於各目錄
  • Network System: net/ 目錄
  • File System: fs/ 目錄
  • Memory Management: mm/ 目錄, 一些 helper-routine 實作於 arch/ 目錄
  • Process Management: 大部份實作於 kernel/ 目錄
  • Interprocess Communication: ipc/ 目錄
  • Device Drivers: drivers/ 目錄
  • SELinux (Security Enhanced Linux): security/ 目錄 (only kernel 2.6 or kernel 2.4 for mobile phone)

下載講義

本系列專欄旨在銜接以下的文章

October 23, 2006

網路上的 ext4 filesystem benchmark

網路上已經有人發表初步的 ext4 filesystem benchmark 數據了,該測試報告的作者將 ext4 的 "extents" 模式開啟,I/O scheduler 為 CFQ。CFQ 是 kernel 2.6.18 之後預設的 I/O 排程法

由這篇測試報告來看,ext4 在「寫入」的效能表現上,大幅領先 ext3 與 raiser4;不過在其它測試項,ext4 則是與 ext3/raiser4 互有領先。但是整體來看,ext4 的整體效能表現確實比 ext3 來得優秀。

該測試報告也提到,由於 ext4 仍在開發測試階段,一切都要等穩定版出現後,再來做更進一步的評估了。測試報告原文:

http://linux.inet.hr/first_benchmarks_of_the_ext4_file_system.html

Linux-kernel mailing list 也有討論串:

http://forum.jollen.org/index.php?showtopic=6705

Also See

GNU gv 設定與使用心得

GNU gv 是用來讀取 PostScript 與 PDF 格式文件的利器,GNU gv 其實只是一個前端界面 (front-end),實際上 GNU gv 是由 ghostview 1.5 衍生而來的,並且使用 ghostscript 來直譯文件。

GNU gv 的官方網站:http://www.gnu.org/software/gv/

gv 的使用

我們可以在 X Window System 底下直接下命令,例如:

linux# gv Trans.PS.gz

這是利用 gv 觀看 Trans.PS.gz 文件的範例,特別的是,經由 gzip 壓縮過的 PostScript 或 PDF 文件不需解壓即可直接利用 gv 閱讀,非常的方便。

利用 gv 也可以閱讀 PDF 文件,例如:

linux# gv imug.pdf

gv 命令列的參數:

□ -ad

讀取 資源檔。-ad 參數的優先權較 -style 來得高。

□ -antialias,-noantialias

是否要使用 antialiasing 功能。

□ -arguments

gv 是 ghostscript 的 front-end,在這裡的 是要傳給 ghostscript 的參數。

□ -center,-nocenter

是否要使用自動置中功能。

□ -dsc,-nodsc

是否要使用 DSC (document structuring convention)。如果不使用 DSC (-nodsc),gv 就不會檢查文件的結構,並且直接將整個檔案傳給 ghostscript。在 -nodsc 模式下,閱讀文件時不會有頁數顯示,而且無法在文件裡移動。

□ -eof,-noeof

使用 -eof 時,當遇到結束的註解時,即表示文件的結束。有些文件,例如將兩個文件合併,雖然有結束的註解,但不表示檔案的結束,這時加上 -noeof 參數才能閱讀全部內容。

□ -pixmap,-nopixmap

如果使用 -pixmap 參數,gv 會以 pixmap 的方式將顯示過的內容保存下來,反之,-nopixmap 參數表示是由 X Server 負責這項工作,而不是 gv。

□ -v

查詢版本編號。

□ -h,-?

顯示求助畫面 (參數用法)。

□ -help

顯示較清楚的求助畫面。

□ -scale

是一個整數,指定文件的放大倍數。

□ -scalebase

設定預設的放大倍數。

□ -monochrome, -grayscale, -color

設定調色盤,即文件的顏色樣式。

□ -media

設定紙張大小。

□ -page

指定文件的標名。

□ -portrait,-landscape,-seascape,-upsidedown

設定文件的顯示位置。

□ -quiet,-noquiet

是否要以 -dQUIET 參數執行 ghostscript。

□ -resize,-noresize

設定gv是否可以自動依視窗大小調整文件的大小。

□ -safer,-nosafer

是否要以 -dSAFER 參數執行 ghostscript。

□ -spartan

和 -style gv_spartan.dat 同義。

□ -style

指定設定檔 (resource file)。這個參數的優先權比 -ad 高。

□ -swap,-noswap

是否要交換 landscape 與 seascape 的顯示方式。

□ -watch,-nowatch

使用 -watch 參數的話,預設是 gv 每一秒會檢查一次文件內容是否有改變,如果有的話,gv 即顯示新的內容。

gv 的設定

如果嫌每次都要打一堆煩人的參數,其實我們可以把這些常用的參數編輯在一個檔案裡 (resource file)。

gv 會先使用由 XFILESEARCHPATH 環境變數所指定的 resource file,如果沒有 XFILESEARCHPATH 環境變數,則使用 /usr/X11R6/lib/X11/app-defaults/GV,系統資源檔可以設定 gv 的預設執行環境。

我們可以依我們平時閱讀的習慣來設定自己的 gv 環境,個人化的 resource file 位於 ~/.gv,gv 會優先使用 ~/.gv 這個 resource file。

gv 也有提供我們 resource file 的設定範例,請由 /usr/X11R6/lib/X11/gv/ 將 gv_user.ad 複製到 ~/.gv:

linux# cp /usr/X11R6/lib/X11/gv/gv_user.ad ~/.gv

GNU gv 提供以下 3 個設定範例:

1. /usr/X11R6/lib/X11/gv/gv_class.ad
2. /usr/X11R6/lib/X11/gv/gv_system.ad
3. /usr/X11R6/lib/X11/gv/gv_user.ad

gv_user.ad 是 gv 個人 resource file 的設定範例,gv_system.ad 是系統 resource file 的設定範例,但新裝好的 gv,實際上這兩個檔案內容是一樣的。

gv 的 resource file (gv_user.ad):


!
! gv_user.ad
! User specific application defaults for gv
! Copyright (C) 1995, 1996, 1997 Johannes Plass
!

!########## gv_user_res.dat

!##### Application specific Resources

GV.pageMedia: automatic
GV.orientation: automatic
GV.fallbackOrientation: portrait
GV.swapLandscape: False
GV.autoCenter: True
GV.antialias: True
GV.respectDSC: True
GV.ignoreEOF: True
GV.confirmPrint: True
GV.reverseScrolling: False
GV.scrollingEyeGuide: True
GV.autoResize: True
GV.maximumWidth: screen-20
GV.maximumHeight: screen-44
GV.minimumWidth: 400
GV.minimumHeight: 430
GV.confirmQuit: 1
GV.watchFile: False
GV.watchFileFrequency: 1000
GV.showTitle: True
GV.miscMenuEntries: redisplay \n\
# update \n\
stop \n\
line \n\
toggle_current \n\
toggle_even \n\
toggle_odd \n\
unmark \n\
line \n\
print_all \n\
print_marked \n\
save_all \n\
save_marked
GV.scale: 0
GV.scaleBase: 1
GV.scales: Natural size, 1.000, screen \n\
Pixel based, 1.000, pixel \n\
0.100, 0.100 \n\
0.125, 0.125 \n\
0.250, 0.250 \n\
0.500, 0.500 \n\
0.707, 0.707 \n\
1.000, 1.000 \n\
1.414, 1.414 \n\
2.000, 2.000 \n\
4.000, 4.000 \n\
8.000, 8.000 \n\
10.00, 10.00
GV.medias: Letter, 612 792 \n\
# LetterSmall, 612 792 \n\
Legal, 612 1008 \n\
Statement, 396 612 \n\
Tabloid, 792 1224 \n\
Ledger, 1224 792 \n\
Folio, 612 936 \n\
Quarto, 610 780 \n\
# 7x9, 504 648 \n\
# 9x11, 648 792 \n\
# 9x12, 648 864 \n\
# 10x13, 720 936 \n\
10x14, 720 1008 \n\
Executive, 540 720 \n\
# A0, 2384 3370 \n\
# A1, 1684 2384 \n\
# A2, 1191 1684 \n\
A3, 842 1191 \n\
A4, 595 842 \n\
# A4Small, 595 842 \n\
A5, 420 595 \n\
# A6, 297 420 \n\
# A7, 210 297 \n\
# A8, 148 210 \n\
# A9, 105 148 \n\
# A10, 73 105 \n\
# B0, 2920 4127 \n\
# B1, 2064 2920 \n\
# B2, 1460 2064 \n\
# B3, 1032 1460 \n\
B4, 729 1032 \n\
B5, 516 729 \n\
# B6, 363 516 \n\
# B7, 258 363 \n\
# B8, 181 258 \n\
# B9, 127 181 \n\
# B10, 91 127 \n\
# ISOB0, 2835 4008 \n\
# ISOB1, 2004 2835 \n\
# ISOB2, 1417 2004 \n\
# ISOB3, 1001 1417 \n\
# ISOB4, 709 1001 \n\
# ISOB5, 499 709 \n\
# ISOB6, 354 499 \n\
# ISOB7, 249 354 \n\
# ISOB8, 176 249 \n\
# ISOB9, 125 176 \n\
# ISOB10, 88 125 \n\
# C0, 2599 3676 \n\
# C1, 1837 2599 \n\
# C2, 1298 1837 \n\
# C3, 918 1296 \n\
# C4, 649 918 \n\
# C5, 459 649 \n\
# C6, 323 459 \n\
# C7, 230 323 \n\
# DL, 312 624
GV.magMenu: 2, 2 \n\
4, 4 \n\
8, 8 \n\
16, 16 \n\
32, 32 \n\
64, 64

!##### Ghostview Widget

GV*Ghostview.background: white
GV*Ghostview.foreground: black

!########## gv_intern_res.dat (generated by makefile)

GV.gsInterpreter: gs
GV.gsCmdScanPDF: gs -dNODISPLAY -dQUIET -sPDFname=%s -sDSCname=%s pdf2dsc.ps -c quit
GV.gsCmdConvPDF: gs -dNODISPLAY -dQUIET -dNOPAUSE -sPSFile=%s %s -c quit
GV.gsX11Device: -sDEVICE=x11
GV.gsX11AlphaDevice: -dNOPLATFONTS -sDEVICE=x11alpha
GV.gsSafer: True
GV.gsQuiet: True
GV.gsArguments:
GV.uncompressCommand: gzip -d -c %s > %s
GV.printCommand: lpr

!########## gv_make_res.dat (generated by makefile)

GV.scratchDir: ~/
GV.defaultSaveDir: ~/
GV.fallbackPageMedia: letter
GV.useBackingPixmap: True
GV*dirs: Home\n\
Tmp\n\

/usr/doc\n\
/usr/local/doc
GV*filter: no .*
GV*filters: None\n\
*.*ps* *.pdf* no .*\n\
*.*ps* no .*\n\
*.pdf* no .*\n\
no .*

設定說明

□ antialias

是否使用 antialias 功能 (True/False)。

□ autoCenter

是否使用自動置中功能 (True/False)。

□ autoResize

是否依照目前文件的頁面大小來調整視窗 (True/False)。

□ confirmPrint

列印時是否需要額外的確認 (True/False)。

□ confirmQuit

離開時是否要確認 (0/1/2)。預設值是 1 表示文件內容有變更時 (例如轉換格式) 才確認,0 表示永遠做不確認,2 表示每次離開時都做確認。

□ scrollingEyeGuide

利用鍵盤捲動文件時是否提示上一頁的部份,使用這個參數,在捲動文件時才能分辨的出那些內容是上一頁的舊內容 (True/False)。

□ ignoreEOF

是否忽略 EOF,當 gv 遇到結束的註解時,並不表示檔案的結束,可能文件中間來雜了 EOF,設定 ignoreEOF=True 時才能完全閱讀這樣的文件 (True/False)。

□ respectDSC

是否要使用 DSC (document structuring convention)。如果不使用 DSC,gv 就不會檢查文件的結構,並且直接將整個檔案傳給 ghostscript (True/False)。在 respectDSC=False 時,閱讀文件時不會有頁數顯示,而且無法在文件裡移動。

□ swapLandscape

landscape 與 seacape 的義意是否要互相交換 (True/False)。

□ scratchDir

設定一個暫存目錄。

□ defaultSaveDir

設定一個預設的存檔目錄。

□ useBackingPixmap

False 表示由 X Server 負責暫存顯示過的內容。True 則是由 gv 以 pixmap 方式暫存顯示過的內容。

□ watchFile

是否要自動檢查文件的改變 (True/False)。

□ watchFileFrequency

設定檢查文件的時間間隔,單位為 milliseconds,這個值必須大於 500 (milliseconds)。當 WathFile 為 True 時這個設定才有效。

□ printCommand

設定列印文件的指令,%s 巨集可用在這個指令的參數上,表示要列印的文件檔名。

□ gsInterpreter

啟動 ghostscript interpreter 的命令。

□ gsCmdScanPDF

由 PDF 格式的檔案中讀取 DSC 的命令。

□ gsCmdConvPDF

將 PDF 的格式轉換成 PostScript 的命令。

□ gsX11Device

啟動 X11 的命令。

□ gsX11AlphaDevice

當 antialiasing 啟動時,執行 X11 的命令。

□ gsSafer

確認 ghostscript 是否應該以 -dSAFER 的參數啟動。

□ gsQuiet

確認 ghostscript 是否應該以 -dQUIET 的參數啟動。

□ gsArguments

設定要傳給 ghostscript 的參數。

□ dirs

設定在目錄列表時可以選擇的目錄。

□ filter

設定 gv 的目錄列表方式,語法:

<filespecs> [no <filespecs>]

例如:

GV*filter: *.ps *.pdf no .*

表示只列出 *.ps 與 *.pdf 的檔案,但不列出 "." 開頭的檔案 (隱藏檔)。

□ filters

設定 Fliters 選單中可用的目錄列表方式。

□ miscMenuEntries

設定在文件上按滑鼠右鍵的彈跳視窗內容(update/redisplay/toggle_current/toggle_even/toggle_odd/unmark/stop/print_all/print_marked/save_all/save_marked/line)。

□ showTitle

是否在 title 上顯示目前所閱讀的文件名稱。

□ maximumWidth, maximumHeight

設定主視窗的最小寬度與高度,必須是正整數,最大當然是螢幕的解析度設定。

□ minimumWidth, minimumHeight

設定主視窗的最小寬度與高度,必須是大於 200 的正整數。

□ scale

設定放大倍數。

□ scaleBase

設定預設的放大倍數,必須為正整數。

□ scales

設定在 Scale 選單中的可用的閱讀放大倍數。

□ orientation

設定預設的文件顯示位置 (portrait/landscape/seascape/upside-down/automatic)。automatic 表示由 DSC 取得。

□ fallbackOrientation

設定自動偵測失敗時的預設紙張大小,value 有 portrait/landscape/seascape/upside-down。

□ medias

設定紙張大小,在 gv 的 Media 選單中可以選擇,如果是以 "!" 或 "#" 開始,表示不列入 Media 的選單中,但仍可以被自動偵測並使用。

□ pagemedia

設定紙張大小,value 為在 paper-sizes 中的設定。value 為 automatic 的話,gv 會試著由 DSC 自動偵測大小。

□ fallbackPageMedia

設定紙張大小,value 為在 paper-sizes 中的設定。當自動偵測失敗時就使用這裡設定的大小。

gv 的操作

底下只是基本常用的按鍵,其它 gv 的操作熱鍵請參考 man gv。

□ O 開啟新檔案
□ Q 離開 gv
□ shift-ctrl-P 列印目檔的文件
□ ctrl-L 重新顯示目前這一頁
□ . 重新顯示目前這一頁

□ V 把目前文件置中
□ Home 跳到第一頁
□ End 跳到最後一頁

□ shift-up 把文件往上捲,或移動 -1 頁
□ shift-left 把文件往左移,或移動 -1 頁
□ shift-down 把文件往下捲,或移動 1 頁
□ shift-right 把文件往右移,或移動 1 頁

□ shift-up 移動 -1 頁
□ shift-down 移動 1 頁

□ c-Enter 移動 -1 頁
□ s-Enter 移動 -1 頁

□ Enter 移動 1 頁
□ B 移動 -1 頁
□ F 移動 1 頁

□ ctrl-left 移動 -5 頁
□ ctrl-right 移動 5 頁
□Insert 移動 -5 頁
□ Delete 移動 5 頁

October 24, 2006

ReiserFS 日誌式檔案系統

自 kernel 2.4.1 開始,Linux 已經支援一種稱為 ReiserFS 的日誌式檔案系統。日誌式檔案系統可以提供更安全的檔案保護機制,特別是可以運用在伺服器或是商業環境的應用上。

目前有 4 種較廣為人知的日誌式檔案系統:

□ XFS

□ JFS

□ ext3 / ext4

□ ReiserFS

其中 JFS 是由 IBM 所發展,有興趣的讀者可以參考 IBM 的說明:

http://www-128.ibm.com/developerworks/linux/library/l-jfs.html

另外 XFS 是由 SGI 所發展。我們選擇目前較受觀迎的 ReiserFS 來做介紹。

ReiserFS 的特點

ReiserFS 官方網站:http://www.namesys.com/

日誌式檔案系統被認為相當適合應用在大型的商業伺服器環境中。在這類的環境裡,資料完整性相當的重要。

日誌式檔案系統有著資料庫管理系統 (DBMS) 的交易機制 (Transaction) 特性,一連串的動作如果中間發生錯誤而中斷,資料可以被還原成原來的狀態,可確保資料不會因為未完成,而發生資料不完整的情形。

日誌式檔案會在分割區記錄使用資訊,檔案的寫入動作會先被記錄到記錄檔裡,進行寫入動作時如果中途發生中斷 (例如當機),而重新啟動電腦時,日誌式的檔案系統會根據記錄檔將先前未完成的動作做回覆 (roll back),因此可以保證資料不會因為寫入時發生的中斷,而產生不完整的資料。

安裝 ReiserFS V4

ReiserFS 目前搭載於 kernel 2.4 的是 V3 版,搭載於 kernel 2.6 的是 V4 版。Kernel 的 patch、設定與安裝可參考:

http://www.namesys.com/install_v4.html

另外,也需要用到 reiser4progs 工具程式,下載位置:

ftp://ftp.namesys.com/pub/reiser4progs/libaal-1.0.5.tar.gz
ftp://ftp.namesys.com/pub/reiser4progs/reiser4progs-1.0.5.tar.gz

要製作 reiser4 的分割區的話只要使用 mkfs.reiser4 工具即可:

linux# mkfs.reiser4 /dev/hda5 (範例)

要 mount reiserfs 分割區時,必須加上 -t reiser4 的參數:

linux# mount -t reiser4 /dev/hda5 /home2

如果要對 reiserfs 分割區做檢查,只要使用 fsck.reiser4 指令即可。

Jollen 的 Linux 核心分享包,#2: 《講義1~5》

process_sched_intro_01.JPG

講義第1頁到第5頁的說明。

課前說明

作業系統(operating system)理論的教材書,與 process 和 scheduling(排程)相關的主題都是最先被討論的議題。因此,對於 Linux kernel 原始碼的研究,我們也從 process 與 scheduling 有關的部份開始講起。

process_sched_intro_02.JPG

Process 是執行中的程式,因此「程式如何被執行」是第一個重點,這個部份的觀念當然也包含「程式如何由儲存裝置載入」。緊接著的是,「程式載入記憶體後的佈局(layout)」,這是第二個要研究的重點。當程式被載到記憶體後,作業系統的 scheduler(排程器)便負責排程的工作與執行本文切換(context switch),這是第三個所要討論的重點。

因此,我們將會研究 Linux kernel 的 3 個「process and scheduling」議題:

1. Shell 如何載入執行檔(ELF executables)至記憶體。
2. Process 的 memory 資枓結構。
3. Linux scheduling 與 x86 context switch。

在開始進入主題前,我們先來了解一下 Linux kernel 的開機流程與 scheduler 初始化的關係。然後我們會接著討論「Process Creation」,並一併說明「 Shell 如何載入執行檔(ELF executables)至記憶體」。

編譯 Kernel 2.6 的注意事項

process_sched_intro_03.JPG

Kernel 2.6 的編譯必須使用 gcc 3.2 版以上,這張講義的 code 位於 init/main.c,由這段 code 也能知道,在編譯時期(compile time)就會做 gcc 版本的檢查。

Operating System Entry Point

init/main.c:start_kernel() 是「 architecture-independent booting process」的起點(entry point),到這裡表示 kernel 的開機已經進入作業系統核心的部份(OS booting),並且完成了機器平臺(architectural)的初始化與設定工作。

process_sched_intro_04.JPG

用一句簡單的話來解釋:我們已經脫離 arch/ 目錄啦!start_kernel() 也被解釋為作業系統(operating system、linux kernel)的進入點。

Initialization Sequence

main.c 裡的 start_kernel() 函數實作中,我們能看到一大串的「initialization」函數呼叫。這些初始化函數的呼叫是有順序關係的,因此是「initialization sequence」。

在整個初始化程序中,與 scheduler 有關的初始化函數說明如下。

Scheduler Initialization Sequence

process_sched_intro_05.JPG

我們先來說明一下這 3 個初始化函數的主要目的,再深入討論其內部實作:

1. sched_init():初始化排程器,包含:初始化 run queue、初始化 “idle thread”。
2. pidhash_init():初始化 “PID” 的 hash table。
3. fork_init():計算 kernel 能 “fork” 的最大 process 數量。

Keywords

operating system, process, scheduling, Linux kernel, scheduler, context switch, ELF, process creation, run queue, idle thread, PID,

跟上我們的腳步:請先行閱讀以下的文章,再看這篇日記!

October 25, 2006

kernel 2.6 的 battery class 驅動程式

"class driver" 是 kernel 2.6 driver model 的新觀念,從系統管理面的角度來看,就是 /sysfs。現在 kernel 2.6 已經出現專門針對電池電源管理的驅動程式了:battery class。這是一個有別於以往對於電源管理的實作,雖然 "battery class" 仍只是一個初步實作的驅動程式,但未來 "battery" 與 "AC powe" 在 Linux 驅動程式新觀念底下,將會是一個獨立的 "device"。

新的 battery class 實作中,我們也看到了 OLPC(百元美金電腦)專用的電池驅動程式。程式碼目前可由 kernel 的 git 下載,並可追磫此討論串:http://forum.jollen.org/index.php?showtopic=6899

October 26, 2006

什麼是 "asmlinkage"?

有網友來信問到,kernel 裡的 system call 實作函數中(C 函數),為什麼每一個函數原型宣告的前面都有一個 "asmlinkage" 的字串?例如:

asmlinkage long sys_nice(int increment)

"asmlinkage" 是在 i386 system call 實作中相當重要的一個 gcc 標籤(tag)。

當 system call handler 要呼叫相對應的 system call routine 時,便將一般用途暫存器的值 push 到 stack 裡,因此 system call routine 就要由 stack 來讀取 system call handler 傳遞的參數。這就是 asmlinkage 標籤的用意。

system call handler 是 assembly code,system call routine(例如:sys_nice)是 C code,當 assembly code 呼叫 C function,並且是以 stack 方式傳參數(parameter)時,在 C function 的 prototype 前面就要加上 "asmlinkage"。

加上 "asmlinkage" 後,C function 就會由 stack 取參數,而不是從 register 取參數(可能發生在程式碼最佳化後)。

更進一步的說明...

80x86 的 assembly 有 2 種傳遞參數的方法:

1. register method
2. stack method

Register method 大多使用一般用途(general-purpose)暫存器來傳遞參數,這種方法的好處是簡單且快速。另外一種傳遞參數的做法是使用 stack(堆疊),assembly code 的模式如下:

push number1
push number2
push number3
call sum

在 'sum' procedure 裡取值的方法,最簡單的做法是:

pop ax
pop ax
pop bx
pop cx

Stack Top 是放 IP,我們傳給 sum procedure 的參數由 stack 的後一個 entry 開始讀取。

其它有關 asmlinkage

1. asmlinkage 是一個定義
2. "asmlinkage" 被定義在 /usr/include/linux/linkage.h
3. 如果您看了 linkage.h,會發現 "__attribute__" 這個語法,這是 gcc 用來定義 function attribute 的語法。

October 27, 2006

關於 gcc 的 __attribute__ 用法

gcc 提供一種「定義函數屬性(attribute)」的語法,也就是前一篇日記我們所提到的 __attribute__ 標籤。__attribute__ 用來讓我們定義函數的行為,以便告訴 gcc 在編譯時期對此函數做一些特殊的處理或檢查動作。

asmlinkage 的例子來說,asmlinkage 的定義是(/usr/include/linux/linkage.h):

#if defined __i386__
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
#elif defined __ia64__
#define asmlinkage CPP_ASMLINKAGE __attribute__((syscall_linkage))
#else
#define asmlinkage CPP_ASMLINKAGE
#endif

由此可知,以 sys_nice() 的原型宣告來說,以下的二行程式碼是等價的:

asmlinkage sys_nice(...);
__attribute__((regparm(0))) sys_nice();

"__attribute__" 寫在函數宣告之前或之後都可以(左括號前或右括號後),並接著使用一對「雙括號」來註明此函數的屬性。語法:

__attribute__((keywords)) functon_name(...);

屬性的關鍵字如下(節錄自 gcc 3.4.6 manual):

noreturn,noinline, always_inline, pure, const, nothrow, format, format_arg, no_instrument_function, section, constructor, destructor, used, unused, deprecated, weak, malloc,alias, warn_unused_result, nonnull.

regparm 的用法與用途

regparm 的語法是:regparm(number),regparm 屬性只在 Intel 386 平臺上有作用,用來指定最多可以有多少個("number" )參數(arguments)能以暫存器來傳遞,regparm(0) 表示參數都不能透過暫存器來傳遞,因此所有參數都會透過堆疊來傳遞。

更多關於__attribute__

又如,在 ARM 平臺上宣告 "__attribute((interrupt))" 表示此函數是一個 interrupt handler。

其它的屬性說明可參閱 gcc 的手冊。

__attribute__ 是重要的 gcc 用法,對系統程式(system software)的開發尤其重要,應仔細閱讀 gcc 手冊。

Also See

October 30, 2006

Kconfig 與 "-mregparm=num" 參數

gcc 在 i386 / x86_64 的 machine dependent 參數 (-m) 中,有 1 個參數與參數的傳遞相關的:-mregparm=num,這個參數的用途與先前提到的 "__attribute((regparm(?))__" 作用相同*2

-mregparm 用來指定有多少個 integer 的參數可以透過暫存器(register)來傳遞, 以下是 -mregparm 的 man(GCC(1)):

Intel 386 and AMD x86-64 Options
...
-mregparam
           Use a different function-calling convention where the first two
           arguments are passed in registers.

kernel 的編譯設定中(menuconfig),也提供一個選項來設定「暫存器參數的傳遞」。這個設定位於 menuconfig 的 「Processor type and features|Use register arguments (EXPERIMENTAL) (NEW)」,Jollen 所使用的 kernel 版本是 Linux v2.6.11 (for i386),如果您的 kernel 不是 i386 或是版本不同,您可能無法在這個地方找到此設定項。

Kconfig 與 -mregparam

以下是節錄自 arch/i386/Kconfig 的內容:

config REGPARM
        bool "Use register arguments (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        default n
        help
        Compile the kernel with -mregparm=3. This uses a different ABI
        and passes the first three arguments of a function call in registers.
        This will probably break binary only modules.

This feature is only enabled for gcc-3.0 and later - earlier compilers generate incorrect output with certain kernel constructs when -mregparm=3 is used.

當我們把 REGPARM 設定為 'y' 後,Makefile 裡的 CONFIG_REGPARM 值也會是 'y'。當 CONFIG_REGPARM=y 時,cflags-y 便加 "-mregparm=3" 的參數,請注意 Kernel 2.6.x 必須以 3.2.x 以上的 gcc 來編譯*1。相關的 Makefile 節錄如下(arch/i386/Makefile):

# -mregparm=3 works ok on gcc-3.0 and later
#
GCC_VERSION                     := $(call cc-version)
cflags-$(CONFIG_REGPARM)        += $(shell if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)

# Disable unit-at-a-time mode, it makes gcc use a lot more stack # due to the lack of sharing of stacklots. CFLAGS += $(call cc-option,-fno-unit-at-a-time)
CFLAGS += $(cflags-y)

最後,CFLAGS 的值會加上 '$(cflgs-y)',我們知道 CFLAGS 是 gcc 的編譯參數設定變數,所以當 gcc 在編譯 kernel 時,便會套用 "-mregparm=3" 的參數。

Also See

October 31, 2006

PowerPC 的無硬碟刀峰伺服器

一個有趣的應用。這是利用 IBM PowerPC 750GX 處理器,搭載 Tundra Tsi108 北橋,製作出無硬體的 server board,掛載(mount)在一個背板(backbone)後,就成為一台小型的分散式計算伺服器。以下是這台「diskless-blade server」的照片。

gx_108_1.jpg

gx_108_2.jpg

基本上這是一個 computation platform,因此需要軟體「分散式計算技術」的支援。不過不拿這個可怕的題目來討論,基本上 Linux 要有一個無硬碟的計算環境,最簡單的方法是「NFS」。

gx_108_3.jpg
(一台機器可安插 4 片 diskless server board,可做為小型的伺服器或計算平臺。)

NFS 果然是萬用解決方案,像是這種異質性平臺(host v.s. target、client v.s. server),利用 NFS 來掛載(mount)host(或server)端的 Linux distribution 到 target(或 client)端來做計算,是最簡單的方法。

唯一需要具備的能力是:

1. NFS 的設定:/etc/exports。
2. 製作 target 的 NFS bootstrap root filesystem。
3. 灌一套支援 target 端的 Linux distribution 在 host 端。

以下是這個「server board」的 block diagram。

gx_108_4.JPG

diskless-blade server 的幾個好處是:

1. 資料存放於 remote data server。
2. 將計算(computation)與資料儲存(storage)分開:separate computation from storage。
3. 計算端(computation)的損壞不影響資料安全性。
4. 提供較佳的備援。
5. 使用 Giga lan 互連(connectivity),佈署成本(deployment)較低(see the block diagram)。

至於軟體端的解決方案,我想大家應該也都猜得到,這片伺服器板是使用 U-Boot + Linux 2.6.x 做為解決方案。

Also See

在 Red Hat Linux 9 下安裝 bitbake 1.6 的注意事項

最近有朋友問到,在 Red Hat Linux 9 底下要如何安裝 bitbake 1.6。如果您是使用 Red Hat Linux 9(我們的課程學員),想要在 Red Hat Linux 9 底下安裝 bitbake 1.6 的話,需要注意以下事項(已實測成功):

1. Python 要更新至 2.3(rh9 提供的是 2.2),至於其它更新版本的 Python 經測試,則是不能使用的。我們測試過 Python 2.5,結果是無法運作。我們實測可運作的版本是 Python 2.3.5 ;另外請務必使用以下的 configure 設定:

# ./configure --enable-unicode=ucs4 --prefix=/usr

2. 安裝 Psyco(Python JIT Compiler):這是必要的,以快加 bitbake 建立套件的速度。我們測試的版本是 2006/10/23 的 snapshot,實測後可順利運作,不過更新一點的 snapshot 我想應該也不致於有太大問題。

3. 安裝 text2html library,我們實測的版本是 texi2html 1.64。

4. 安裝 xmlto,我們使用的版本是 xmlto 0.0.18。

以下是 bitbake 1.6 在我們的 Red Hat Linux 9 下運作的畫面。

bitbake.jpg


關於 October 2006

此頁面包含了在October 2006發表於Jollen's Blog的所有日記,它們從老到新列出。

前一個存檔 September 2006

後一個存檔 November 2006

更多信息可在 主索引 頁和 歸檔 頁看到。

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org