2010年12月12日 星期日
2010年12月11日 星期六
Linux Kernel(13)- syscall
System Call在HW和user space提供一層抽象層,主要目的有:
- 為user space提供硬體抽象層。比如,讀取檔案時,不用管檔案所在的媒體類型與檔案儲存類型。
- System call能確保系統的安全與穩定。避免user space的無意或惡意的破壞。
除了exception和trap以外,System call是user space進入kernel space的唯一管道。
User space的programming主要是base on API(Application Programming Interface)並非system call,從programmer的觀點來看,關注的是API(如C library)而非system call。
System call的return type為long,主要是要相容64bit,return value通常代表失敗或成功,失敗時,error code當常寫入global variable “errno”。
典型的system call都以sys_開頭,如getpid()的system call為:
asmlinkage long sys_getpid(void) { return current->tgid; }
在Linux中(x86),將所有的system call存放在一個system call table中,透過system call number來所引(index)要執行的system call,儘管每個platform所implement的system call table和system call number都不同,但是原理都是相同的,首先會將system call number存放在某個特定的CPU register(X86放在eax),並將system call的參數也存放置其他的register(最多5個參數,x86依序為ebx、ecx、edx、esi和edi),接著透過int 0x80進入system call處理程序,透過system call number(eax)在system call table中找到相對應的system call,並且執行該system call,因為參數存放是先就定義好了,所以就可以在registers(x86依序為ebx、ecx、edx、esi和edi)中依序讀出要處理的參數,超過五個參數就會用structure來傳遞,而ioctl這個不定參數的system call是傳遞pointer的方式來存取,ioctl是一個不好的例子,因為定義不是很明確,system call最好是能定義明確。
新增system call “brook()”到kernel 2.6.32的步驟(x86)
- 新增一筆system call entry到sys_call_table中arch/x86/kernel/syscall_table_32.s。 直接在最後面加入”.long sys_brook”
- 定義brook的system call number,arch/x86/include/asm/unistd_32.h,並將NR_syscalls做遞增。
- 定義system call的原型,include/linux/syscalls.h。
- 加入至system call table中,arch/x86/kernel/syscall_table_32.S。
- 撰寫system call的內容。 建立一個新的資料夾名為”brook_syscall”,並將這個資料夾加入Makefile的core-y+=中。 brook_syscall/Makefile
- 撰寫Application測試system call 這邊我們撰寫一個類似C library這層的功能"brook_app/brook.h"
#define __NR_brook 337 #define __NR_syscalls 338
asmlinkage long sys_brook(int n, unsigned long arg);
.long sys_brook;
obj-y := brook.o
brook_syscall/brook.c
#include <linux/kernel.h> #include <linux/syscalls.h> #include <linux/uaccess.h> SYSCALL_DEFINE2(brook, int, n, unsigned long, arg) { int __user *p = (int __user *) arg; int i, x, sum = 0, err = 0; printk("n=%d, ", n); for (i = 0; i < n; i++) { err = get_user(x, p + i); sum += x; if (err) { return err; } printk("[%d]=%d, ", i, x); } return sum; }
頂層的Makefile要將brook_syscall加入core-y中
ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ brook_syscall/
#include <linux/unistd.h> #include#define __NR_brook 337 int brook(int n, ...) { int ret; va_list ap; va_start(ap, n); ret = syscall(__NR_brook, n, ap); va_end(ap); return ret; }
application呼叫brook(),再由brook()轉call我們的system call "sys_brook()"
#include <stdio.h> #include "brook.h" int main(int argc, char *argv[]) { return printf("%d\n", brook(3, 3, 2, 1)); }
Kernel Version:2.6.32
參考資料:
- Linux Kernel Development 2nd, Novell Press
- http://pradeepkumar.org/2010/01/implementing-a-new-system-call-in-kernel-version-2-6-32.html
- Professional Linux Kernel Architecture, Wiley Publishing
標籤:
Linux - kernel
config automatically switches from 32-bit to 64-bit for x86
今天我用我的NB去make config,卻發現config會自動的切成64bit的,如果想要編成32bit,就執行linux32 make menuconfig即可。
參考資料:
http://kerneltrap.org/mailarchive/linux-kernel/2010/6/6/4579953/thread
標籤:
Linux - kernel
訂閱:
文章 (Atom)
熱門文章
-
轉自 http://www.wretch.cc/blog/redsonoma/14021073 基本概念: 1> tty(終端設備的統稱): tty一詞源於Teletypes,或者teletypewriters,原來指的是電傳打字機,是通過串行線用打印機鍵盤通過閱...
-
Work queue提供一個interface,讓使用者輕易的建立kernel thread並且將work綁在這個kernel thread上面,如下圖[1]所示。 由於work queue是建立一個kernel thread來執行,所以是在process context...
-
(V)將介紹file operations中的ioctl。ioctl的prototype為: int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); ...
-
這兩天電腦的word忽然都不能存檔,即便是另存新檔也不行,最後都只能放棄修改檔案,即便重新安裝過或者更新成2007也都不能存檔,最後就乖乖的google一下,原來是暫存的資料夾不存在,按照以下方式就可以解決了。 資料來源: word 2003不能存檔問題 編輯機碼的(reg...
-
System Call在HW和user space提供一層抽象層,主要目的有: 為user space提供硬體抽象層。比如,讀取檔案時,不用管檔案所在的媒體類型與檔案儲存類型。 System call能確保系統的安全與穩定。避免user space的無意或惡意的破壞。 ...
-
在kernel中建立thread可以使用kthread_create(),建立一個task,然後在調用wake_up_process(task)讓task真正的運行,如果要kill一個kthread可以使用kthread_stop()。 在kernel中,將kthread_cr...
-
Linux module練習手札I紀錄如何撰寫一個簡單的module,並且編輯它,以及load和unload一個module。 write a module #include <linux/init.h> #include <linux/module.h...
-
幾乎任何使用 TCP,UDP或UNIX-domain socket的動作都可以用nc來達成,常見的功能如。 simple TCP proxies shell-script based HTTP clients and servers network daemon testi...
-
很多人心中都有過一個問題 What is the difference between Platform driver and normal device driver? ,簡單的來說Platform devices就non-discoverable,也就是device本身沒辦法...
-
組成元件 要能正確顯示資料,必須包含資料倉儲(Store),資料欄位的定義(ColumnModel)。 首先我們先定義資料欄位: var cm = new Ext.grid.ColumnModel({ {header: 'Name', dataIndex...