FreeBSD SNP 2.Server端--自我測試連線
2024-07-26 00:29:11
供稿:網友
發信人: hhuu(不知道愛我的是愛我的人), 信區: FreeBSD
標 題: FreeBSD kld簡介
發信站: BBS 水木清華站
上面的東西大致是daemonnews上的一片文章 by Andrew
在google上可以找到.
我覺得將的太羅索,還有一點小錯誤.改一改,放到這里來.
你要是感興趣的話,千萬去thc看看.
最后在強調一下
原文的作者是
Andrew Reiter
http://www.subterrain.net/~awr/KLD-Turorial/
就象linux下的lkm一樣,FreeBSD中有相應的東東.
如果我沒有搞錯的話,2.x系列中是叫lkm的.現在
還有系統的同志可以在/usr/share/example/lkm
中看到這些前輩的影子.
但是時代變遷,到了3.x系列之后,新的東西出現
了,就是所謂的kld.
這里摘錄的是關于FreeBSD的lkm和kld的比較:
1. LKM system used a userland linker to
push PRerelocated binary data into
the kernel.
2. KLD system does the relocation itself
in the kernel. LKMs had special data
structures that the lkm driver knew about
and used those to wire it into the kernel
3. LKMs were single purpose and were quite
difficult to change from LKM to actual
kernel code.
4. With KLDs, thins were made to be more
generic. A file could contain 0 or more
modules.
5. Each module is self-contianed and self-
initializing and registering.
6. KLDs and kernel code are compiled the
same.
7. It's possible to take a piece of the
kernel and easily make it a KLD without
much difficulty.
8. The dependncies and versioning are now
at the module level.
我們都知道kld有什么好處了,那么就開始作
一個吧. 標準的例子在/usr/share/example/kld.
btw: 3.x系列的還有lkm的目錄,有人愿意看嗎?
kld目錄中有兩個子目錄,對應了兩種主要的方法.
寫設備驅動(cdev)和增加系統調用(syscall).
我們還是從一般的情況開始吧.
所有的kld都會有一個類似的函數:
static int
load_handler (module_t mod, int what, void *arg)
{
int err=0;
switch(what) {
case MOD_LOAD:
........
break;
case MOD_UNLOAD:
.......
break;
default:
err=EINVAL;
break;
}
return (err);
}
大家都覺得很面善吧.看上去和init_module沒有太大
的區別.上面的函數格式格式可以在/usr/include/sys/module.h
中找到.
typedef int (*modeventhand_t)(module_t mod, int what, void *arg);
這個module_t mod是指向module結構的指針.從它可以牽出所有的
被載入的模塊.
int what是modeventtype_t的值之一.
MOD_LOAD:
MOD_UNLOAD:
MOD_SHUTDOWN: 上面兩個就不用說了.這個shutdown的意思
似乎是指機器shutdown時kld的行為.
所有的kld都需要注冊.所以就有了一個通用的宏:
DECLARE_MODULE( name, data, sub, order)
定義在/usr/include/sys/module.h
name: 就是kld的名字
data: 是個moduledata類型的東東.
sub: 在/usr/include/sys/kernel.h里定義的
sysinit_sub_id的值.
order:在/usr/include/sys/kernel.h里面的
sysinit_elem_order
看看就明白了,沒有什么大不了的.
(Declare_module還調用的sysinit......其實也不過是....
........... #%@^#&$^%*&$^)
考慮到我們寫module不過是為了設備驅動或者
增加系統調用罷了.所以就有了兩個常用的宏.
DEV_MODULE和SYSCALL_MODULE
分別在/usr/include/sys/conf.h和sys/sysent.h中
也就是對DECLARE_MODULE的簡單包裝.
回想我們在linux下編譯一個模塊時無非是
gcc -DMODULE -D__KERNEL__ -DLINUX -O3 -c ....
可是在FreeBSD下就不是這么好辦了.看看
前面說的那兩個例子編譯時出來的那么一
大堆,我就先嚇壞了.
感謝上帝,不是沒一個人都要搞得那么清楚才能
編譯kld的.我們的Makefle關鍵在于.include
只要包含了bsd.kmod.mk,我們自己要作的事就是
SRCS= 源文件名
KMOD= 目標模塊的名字
如果你是愛刨根問底的,請看/usr/share/mk
還是關于syscall的問題.
在sys/sysent.h中有定義
struct sysent {
int sy_narg;
sy_call_t *sy_call;
};
這分明是linux下面那個
sys_call_table么.
有區別的就是那個offset.
可以用offset=NO_SYSCALL來讓系統在載入的時候
自動選擇syscall number.
回顧一下,我們的任務是要有一個
load_xxx函數來處理load和unload的情況
要有我們自己的調用.
最后SYSCALL_MODULE來注冊.
如果是設備模塊的話.
我們需要一張表
/usr/include/sys/conf.h中定義的
struct cdevsw {.....}
然后的過程和上面幾乎一模一.....
就這樣吧.強力推薦
1 http://thc.pimmel.com/files/thc/bsdkern.html
2 /usr/share/example/kld/