2.6.21相比2.4.18内核机制变更
本人正在把2.4.18的網關,防火墻,等公司的代碼從2.4.18移植到2.6.18linux內核上去.本日志會不斷更新,希望能讓同在進行2.4到2.6內核移植
的朋友們一些幫助.
????????????????IPMAC部分改動
1.?2.4內核:
?????????Save_flags();保存標志
?????????cli();關閉中斷
?????????Restore_flags();還原標志打開中斷.
???在2.6內核中由:
??????????local_irq_save(flags);
??????????local_irq_restore(flags);
取代。功能完全一樣.
要使用save_flags功能需要刪除CONFIG_SMP宏
在/include/linux/autoconf.h?2125行定義.
2.?修改后的nf_hook_ops結構體
static?struct?nf_hook_ops?ipmac_rcv_ops=?{
????????{NULL,?NULL},
????????my_ipmac_rcv,
????????NULL,?/2.4.18沒有這個元素,2.6.21此參數原型為:struct?module?*owner;*、
????????PF_INET,
????????NF_IP_PRE_ROUTING,
????????SE_PRI_PRERT_IPMAC_BIND
};
?
3.
?
2.4?內核下,缺省情況時模塊中的非靜態全局變量及函數在模塊加載后會輸出到內核
空間。2.6?內核下,缺省情況時模塊中的非靜態全局變量及函數在模塊加載后不會輸出到內
核空間,需要顯式調用宏EXPORT_SYMBOL才能輸出。所以在2.6?內核的模塊下,EXPORT_NO_SYMBOLS宏的調用沒有意義,是空操作。在同時支持2.4與2.6內核的設備
?
驅動中,可以通過以下代碼段來輸出模塊的內核符號
EXPORT_NO_SYMBOLS在2.6.21內核中沒有這個東西了.因為沒有必要存在了,已近刪除.
?
.
4.
(int)?*buf_p?=?IPMAC_ADD
這種類型的代碼編譯報錯了.是無法賦值的,提示左值無法賦值.
全部改為:*((int*)buf_p)?=?IPMAC_ADD此種類型
還有函數原型不帶參數聲明會帶警告,我都加了void
如下:int?get_index()改為int?get_index(void);
一些聲明了沒有初始化就使用的變量也給了警告我也都初始化了.
比如flags;
????????????PF(包過濾)改動部分
1.
???2.4內核中,模塊自身通過?MOD_INC_USE_COUNT,?MOD_DEC_USE_COUNT宏來管理自己被使用的計數。
???2.6內核提供了更健壯、靈活的模塊計數管理接口?try_module_get(&module),?module_put(&module)取代2.4中的模塊使用計數管理宏;模塊的使用計數不必由自身管理,而且在管理模塊使用計數時考慮到?SMP與PREEMPT機制的影響。
???int?try_module_get(struct?module?*module);?用于增加模塊使用計數;若返回為0,表示調用失敗,希望使用的模塊沒有被加載或正在被卸載中。
???void?module_put(struct?module?*module);?減少模塊使用計數。
???try_module_get與module_put?的引入與使用與2.6內核下的設備模型密切相關。模塊是用來管理硬件設備的,2.6內核為不同類型的設備定義了struct?module?*owner?域,用來指向管理此設備的模塊。如字符設備的定義:
struct?cdev
{
????struct?kobject?kobj;
????struct?module?*owner;
????struct?file_operations?*ops;
????struct?list_head?list;
????dev_t?dev;
????unsigned?int?count;
};
????從設備使用的角度出發,當需要打開、開始使用某個設備時,使用?try_module_get(dev->owner)去增加管理此設備的?owner模塊的使用計數;當關閉、不再使用此設備時,使用module_put(dev->owner)減少對管理此設備的owner模塊的使用?計數。這樣,當設備在使用時,管理此設備的模塊就不能被卸載;只有設備不再使用時模塊才能被卸載。
???2.6內核下,對于為具體設備寫驅動的開發人員而言,基本無需使用?try_module_get與module_put,因為此時開發人員所寫的驅動通常為支持某具體設備的owner模塊,對此設備owner模塊的計數管理由內核里更底層的代碼如總線驅動或是此類設備共用的核心模塊來實現,從而簡化了設備驅動開發。
?
?
?
4.
??
2.4?.18內核?:skb_linearize(skb,?GFP_ATOMIC)
2.6.21?內核?:?skb_linearize(skb)??
?
????????????skb_is_nonlinear函數用于測試一個緩沖區是否是分片的,而skb_linearize可以把分片組合成一個單一的緩沖區。組合分片涉及到數據拷貝,它將嚴重影響系統性能。
?
5.
?
????EXPORT_SYMBOL_NOVERS???2.6內核中已近沒有這個宏.我只知道EXPORT_SYMBOL是內核模塊向其它的模塊倒出可用的函數,
2.6內核中只有EXPORT_SYMBOL這個宏,而且用的很多.
我把代碼里的
EXPORT_SYMBOL_NOVERS全部改為EXPORT_SYMBOL了.
6.
?2.6內核中沒有.for_each_task
替換為如下宏:
#define?for_each_process(p)?\
for?(p?=?&init_task?;?(p?=?next_task(p))?!=?&init_task?;?)
在2.6.21內核中定義的.
2.
2.6內核?:Struct?sk_buff??*ip_defrag(struct?sk_buff?*skb,u32?user);
這個函數的第二個參數是2.6內核增加的,目的好像是是說明sk_buff數據包的來源.
第二個參數的全部可取值如下,此結構在內核中被定義.
enum?ip_defrag_users
{
IP_DEFRAG_LOCAL_DELIVER,(sk_buff代表的數據包是本機ip地址發送出去的,)
IP_DEFRAG_CALL_RA_CHAIN,(在ip_call_ra_chain函數中被調用,sk_buff來源參數被設置為這個,說明這個數據包是遍歷那個什么鏈表找到的?)
IP_DEFRAG_CONNTRACK_IN,(當hook節點的值為NF_IP_PRE_ROUTING時,參數為這個值,不是為下面的值)
IP_DEFRAG_CONNTRACK_OUT,
IP_DEFRAG_VS_IN,(hook節點值為NF_IP_LOCAL_IN時,參數為這個,不是參數為NF_IP_LOCAL_FWD)
IP_DEFRAG_VS_OUT,(在ip_vs_out和ip_vs_out_icmp里被調用,sk_buff來源參數被設置為IP_DEFRAG_VS_OUT)
IP_DEFRAG_VS_FWD
};
我查找了下.內核中對這5個參數的用法.對參數意思的總結如上.
3.
2.4內核中,通過內核監聽的套接口返回套接口結構的方法:
Struct?sock?sk2;
?sk2?=?tcp_listening_hash[i]已近行不通.
2.6內核中?要返回監聽端口需要;?tcp_hashinfo.listening_hash[i].first
但是返回的不是struct?sock?而是?struct?hlist_node結構體.這個結構體里除了下一個這個結構的指針什么也沒.內核中維護監聽的套接口,是一個哈希表,每個哈希元素又是一個鏈表.
所以2.4內核中想要通過返回的sock結構直接取出源目的的ip以及端口在2.6內核中已近無法做到.而且2.6內核中的sock結構也沒有地址端口這些信息.
想要通過監聽列表獲得監聽的套接口的地址端口信息必須通過,inet_sock結構.這個結構的第一個元素為strock?sock,它封裝了sock結構,如下
struct?inet_sock?{
/*?sk?and?pinet6?has?to?be?the?first?two?members?of?inet_sock?*/
struct?sock sk;
#if?defined(CONFIG_IPV6)?||?defined(CONFIG_IPV6_MODULE)
struct?ipv6_pinfo *pinet6;
#endif
/*?Socket?demultiplex?comparisons?on?incoming?packets.?*/
__be32 daddr;
__be32 rcv_saddr;
__be16 dport;
__u16 num;
__be32 saddr;
__s16 uc_ttl;
__u16 cmsg_flags;
struct?ip_options *opt;
__be16 sport;
__u16 id;
__u8 tos;
__u8 mc_ttl;
__u8 pmtudisc;
__u8 recverr:1,
is_icsk:1,
freebind:1,
hdrincl:1,
mc_loop:1;
int mc_index;
__be32 mc_addr;
struct?ip_mc_socklist *mc_list;
struct?{
unsigned?int flags;
unsigned?int fragsize;
struct?ip_options *opt;
struct?rtable *rt;
int length;?/*?Total?length?of?all?frames?*/
__be32 addr;
struct?flowi fl;
}?cork;
};
但是想用這個結構體加進頭文件也用不了.必須要這樣:
#undef?_INET_SOCK_H
#include?<net/inet_sock.h>
才可以使用,具體見這個頭文件里的宏開關.
想要通過返回的hlist_node指針找到這個套接口的inet_sock結構只能這樣:
Struct?hlist_node?list;
Struct?inet_sock?sk2;
...
.....
list?=?tcp_hashinfo.listening_hash[i].first;?
sk2?=??container_of(list,struct?inet_sock,sk.sk_node);
(編譯是過了...沒測試過.不保證%100對...)
?
轉載于:https://blog.51cto.com/3592063/667775
總結
以上是生活随笔為你收集整理的2.6.21相比2.4.18内核机制变更的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用的fileupload组件实现的大文件
- 下一篇: QQ在线咨询插件