啟動參數
在前面的很多例子中,我們不得不硬性的將一些東西寫如內核模塊,例如在 /proc 中的文件名或設備的主設備號,因此我們可以對它 ioctl。 這和 Unix及 Linux的編寫用戶可以定制的靈活的程序精神是相矛盾的。
在程序或內核模塊能開始工作之前告訴它一些需要的東西的辦法是通過命令行參數。在內核模塊的情況下,我們不能得到 argc 和 argv -- 代替的,我們得到更好的東西。我們可以在內核模塊中定義全局變量並且 insmod將為我們填充它們。
在這個內核模塊中,我們定義了兩個: str1 和 str2。你所需要做的全部就是編譯那個內核模塊然後用insmod str1=xxx str2=yyy運行它。當init_module 被調用,str1 將指向字符串‘xxx’, str2 將指向‘yyy’。
在 2.0 版中對這些參數6.1沒有類型檢查。如果str1 或 str2 的第一個字符是數字,內核將用整數值填充變量而不是字符串指針。如果是在實際的情形下你需要檢查這個。
另一方面,在 2.2 版中你用宏 MACRO_PARM 告訴 insmod 你期待一個參數,它的名字和類型 。這解決了類型的問題並且允許內核模塊接收以數字開始的字符串。
范例 param.c
/* param.c * * 在模塊被安裝時接收命令行參數 */ /* Copyright (C) 1998-99 by Ori Pomerantz */ /* 必要頭文件 */ /* 標准頭文件 */ #include /* 內核工作 */ #include /* 明確指定是模塊 */ /* 處理 CONFIG_MODVERSIONS */ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include #endif #include /* 我需要 NULL */ /* 在 2.2.3 版/usr/include/linux/version.h 包含這個宏 * 但 2.0.35版不包括-因此加入以備需要 */ #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif /* Emmanuel Papirakis: * * 現在(2.2版),在宏裡參數名現在被處理。內核不能像它好象已經作過的那樣解決符號名。 * * 為了向模塊傳送參數,你不得不使用 include/linux/modules.h (第 176 行)裡面定義的一個宏。 * 宏需要兩個參數。參數名和它的類型。類型是用雙引號引住的一個字母。例如: * "i" 將為整數, "s" 將為字符串。 */ char *str1, *str2; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) MODULE_PARM(str1, "s"); MODULE_PARM(str2, "s"); #endif /* 初始化模塊--顯示參數 */ int init_module() { if (str1 == NULL || str2 == NULL) { printk("Next time, do insmod param str1="); printk("str2=\n"); } else printk("Strings:%s and %s\n", str1, str2); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) printk("If you try to insmod this module twice,"); printk("(without rmmod'ing\n"); printk("it first), you might get the wrong"); printk("error message:\n"); printk("'symbol for parameters str1 not found'.\n"); #endif return 0; } /* 清除 */ void cleanup_module() { }