linux panic 构造_Linux Wireless架构总结
1、無線網絡驅動(ath9k_htc)
ath9k_htc是一個基于USB接口的SoftMAC無線網絡適配器。為了其驅動能正常工作,首先必須調用usb_register來注冊驅動定義的usb_driver,以借助USB Core的力量來處理與USB協議相關的事件。其代碼如下:
staticstructusb_driver?ath9k_hif_usb_driver?=?{
.name?=?KBUILD_MODNAME,
.probe?=?ath9k_hif_usb_probe,
.disconnect?=?ath9k_hif_usb_disconnect,
#ifdef?CONFIG_PM
.suspend?=?ath9k_hif_usb_suspend,
.resume?=?ath9k_hif_usb_resume,
.reset_resume?=?ath9k_hif_usb_resume,
#endif
.id_table?=?ath9k_hif_usb_ids,
.soft_unbind?=?1,
};
2. 關鍵數據結構
1) struct ieee80211_hw: 它包含802.11 PHY的配置和硬件信息
2.1 各層間關鍵數據接口
3、USB無線適配器枚舉過程
當此基于USB接口的無線網絡適配器被枚舉時,ath9k_hif_usb_probe將被調用。其調用流程如下圖所示:
3.1 struct ieee80211_ops 實例 ath9k_htc_ops(驅動實現)
ath9k_htc_ops: mac80211通過這些回調函數回調driver的處理函數。ath9k_htc為了接受mac80211的管理,它必須首先向mac80211注冊,以申明自己的存在,從而可以接受mac80211的調用。
structieee80211_ops?ath9k_htc_ops?=?{
.tx?????????????????=?ath9k_htc_tx,??//?發送mac80211要求發送的幀
.start??????????????=?ath9k_htc_start,?//?第一個被attach到此硬件的net_device被enable之前被調用,之后,可以接收幀數據
.stop???????????????=?ath9k_htc_stop,??//?最后一個被attach到此硬件的net_device被disable之后被調用,之后,不可以接收幀數據
.add_interface??????=?ath9k_htc_add_interface,?//?當一個被attach到此硬件的net_device被enable時被調用
.remove_interface???=?ath9k_htc_remove_interface,?//?通知driver一個接口將要going?down
.config?????????????=?ath9k_htc_config,???????????//?mac802.11調用它修改硬件配置
.configure_filter???=?ath9k_htc_configure_filter,?//?配置設備的接收過濾器
.sta_add????????????=?ath9k_htc_sta_add,
.sta_remove?????????=?ath9k_htc_sta_remove,
.conf_tx????????????=?ath9k_htc_conf_tx,
.bss_info_changed???=?ath9k_htc_bss_info_changed,
.set_key????????????=?ath9k_htc_set_key,
.get_tsf????????????=?ath9k_htc_get_tsf,
.set_tsf????????????=?ath9k_htc_set_tsf,
.reset_tsf??????????=?ath9k_htc_reset_tsf,
.ampdu_action???????=?ath9k_htc_ampdu_action,
.sw_scan_start??????=?ath9k_htc_sw_scan_start,
.sw_scan_complete???=?ath9k_htc_sw_scan_complete,
.set_rts_threshold??=?ath9k_htc_set_rts_threshold,
.rfkill_poll????????=?ath9k_htc_rfkill_poll_state,
.set_coverage_class?=?ath9k_htc_set_coverage_class,
.set_bitrate_mask???=?ath9k_htc_set_bitrate_mask,
};
3.2 struct cfg80211_ops 實例 mac80211_config_ops(mac80211實現)
cfg80211_ops定義了無線配置的操作,在它的增加虛擬接口(ieee80211_add_iface)中,它將創建并注冊net_device。在mac80211中,其定義如下所示:
structcfg80211_ops?mac80211_config_ops?=?{
.add_virtual_intf?=?ieee80211_add_iface,?//使用給定的名字創建一個"虛擬接口",在wiphy的命名空間中創建net_device并返回
.del_virtual_intf?=?ieee80211_del_iface,?//刪除由ifindex指定的"虛擬接口"
.change_virtual_intf?=?ieee80211_change_iface,
.add_key?=?ieee80211_add_key,
.del_key?=?ieee80211_del_key,
.get_key?=?ieee80211_get_key,
.set_default_key?=?ieee80211_config_default_key,
.set_default_mgmt_key?=?ieee80211_config_default_mgmt_key,
.add_beacon?=?ieee80211_add_beacon,
.set_beacon?=?ieee80211_set_beacon,
.del_beacon?=?ieee80211_del_beacon,
.add_station?=?ieee80211_add_station,
.del_station?=?ieee80211_del_station,
.change_station?=?ieee80211_change_station,
.get_station?=?ieee80211_get_station,
.dump_station?=?ieee80211_dump_station,
.dump_survey?=?ieee80211_dump_survey,
#ifdef?CONFIG_MAC80211_MESH
.add_mpath?=?ieee80211_add_mpath,
.del_mpath?=?ieee80211_del_mpath,
.change_mpath?=?ieee80211_change_mpath,
.get_mpath?=?ieee80211_get_mpath,
.dump_mpath?=?ieee80211_dump_mpath,
.update_mesh_config?=?ieee80211_update_mesh_config,
.get_mesh_config?=?ieee80211_get_mesh_config,
.join_mesh?=?ieee80211_join_mesh,
.leave_mesh?=?ieee80211_leave_mesh,
#endif
.change_bss?=?ieee80211_change_bss,
.set_txq_params?=?ieee80211_set_txq_params,
.set_channel?=?ieee80211_set_channel,
.suspend?=?ieee80211_suspend,
.resume?=?ieee80211_resume,
.scan?=?ieee80211_scan,
.sched_scan_start?=?ieee80211_sched_scan_start,
.sched_scan_stop?=?ieee80211_sched_scan_stop,
.auth?=?ieee80211_auth,
.assoc?=?ieee80211_assoc,
.deauth?=?ieee80211_deauth,
.disassoc?=?ieee80211_disassoc,
.join_ibss?=?ieee80211_join_ibss,
.leave_ibss?=?ieee80211_leave_ibss,
.set_wiphy_params?=?ieee80211_set_wiphy_params,
.set_tx_power?=?ieee80211_set_tx_power,
.get_tx_power?=?ieee80211_get_tx_power,
.set_wds_peer?=?ieee80211_set_wds_peer,
.rfkill_poll?=?ieee80211_rfkill_poll,
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
.set_power_mgmt?=?ieee80211_set_power_mgmt,
.set_bitrate_mask?=?ieee80211_set_bitrate_mask,
.remain_on_channel?=?ieee80211_remain_on_channel,
.cancel_remain_on_channel?=?ieee80211_cancel_remain_on_channel,
.mgmt_tx?=?ieee80211_mgmt_tx,
.mgmt_tx_cancel_wait?=?ieee80211_mgmt_tx_cancel_wait,
.set_cqm_rssi_config?=?ieee80211_set_cqm_rssi_config,
.mgmt_frame_register?=?ieee80211_mgmt_frame_register,
.set_antenna?=?ieee80211_set_antenna,
.get_antenna?=?ieee80211_get_antenna,
.set_ringparam?=?ieee80211_set_ringparam,
.get_ringparam?=?ieee80211_get_ringparam,
}
3.3 struct iw_handler_def ?實例 cfg80211_wext_handler(wireless實現)
cfg80211_wext_handler實現了wext要求的ioctl操作,將通過net_device->wireless_handlers->standard[ioctl cmd- SIOCIWFIRST]來進行調用。在net/wireless/wext-compat.c中的定義如下所示:
taticconstiw_handler?cfg80211_handlers[]?=?{
[IW_IOCTL_IDX(SIOCGIWNAME)]?=?(iw_handler)?cfg80211_wext_giwname,
[IW_IOCTL_IDX(SIOCSIWFREQ)]?=?(iw_handler)?cfg80211_wext_siwfreq,
[IW_IOCTL_IDX(SIOCGIWFREQ)]?=?(iw_handler)?cfg80211_wext_giwfreq,
[IW_IOCTL_IDX(SIOCSIWMODE)]?=?(iw_handler)?cfg80211_wext_siwmode,
[IW_IOCTL_IDX(SIOCGIWMODE)]?=?(iw_handler)?cfg80211_wext_giwmode,
[IW_IOCTL_IDX(SIOCGIWRANGE)]????=?(iw_handler)?cfg80211_wext_giwrange,
[IW_IOCTL_IDX(SIOCSIWAP)]???=?(iw_handler)?cfg80211_wext_siwap,
[IW_IOCTL_IDX(SIOCGIWAP)]???=?(iw_handler)?cfg80211_wext_giwap,
[IW_IOCTL_IDX(SIOCSIWMLME)]?=?(iw_handler)?cfg80211_wext_siwmlme,
[IW_IOCTL_IDX(SIOCSIWSCAN)]?=?(iw_handler)?cfg80211_wext_siwscan,
[IW_IOCTL_IDX(SIOCGIWSCAN)]?=?(iw_handler)?cfg80211_wext_giwscan,
[IW_IOCTL_IDX(SIOCSIWESSID)]????=?(iw_handler)?cfg80211_wext_siwessid,
[IW_IOCTL_IDX(SIOCGIWESSID)]????=?(iw_handler)?cfg80211_wext_giwessid,
[IW_IOCTL_IDX(SIOCSIWRATE)]?=?(iw_handler)?cfg80211_wext_siwrate,
[IW_IOCTL_IDX(SIOCGIWRATE)]?=?(iw_handler)?cfg80211_wext_giwrate,
[IW_IOCTL_IDX(SIOCSIWRTS)]??=?(iw_handler)?cfg80211_wext_siwrts,
[IW_IOCTL_IDX(SIOCGIWRTS)]??=?(iw_handler)?cfg80211_wext_giwrts,
[IW_IOCTL_IDX(SIOCSIWFRAG)]?=?(iw_handler)?cfg80211_wext_siwfrag,
[IW_IOCTL_IDX(SIOCGIWFRAG)]?=?(iw_handler)?cfg80211_wext_giwfrag,
[IW_IOCTL_IDX(SIOCSIWTXPOW)]????=?(iw_handler)?cfg80211_wext_siwtxpower,
[IW_IOCTL_IDX(SIOCGIWTXPOW)]????=?(iw_handler)?cfg80211_wext_giwtxpower,
[IW_IOCTL_IDX(SIOCSIWRETRY)]????=?(iw_handler)?cfg80211_wext_siwretry,
[IW_IOCTL_IDX(SIOCGIWRETRY)]????=?(iw_handler)?cfg80211_wext_giwretry,
[IW_IOCTL_IDX(SIOCSIWENCODE)]???=?(iw_handler)?cfg80211_wext_siwencode,
[IW_IOCTL_IDX(SIOCGIWENCODE)]???=?(iw_handler)?cfg80211_wext_giwencode,
[IW_IOCTL_IDX(SIOCSIWPOWER)]????=?(iw_handler)?cfg80211_wext_siwpower,
[IW_IOCTL_IDX(SIOCGIWPOWER)]????=?(iw_handler)?cfg80211_wext_giwpower,
[IW_IOCTL_IDX(SIOCSIWGENIE)]????=?(iw_handler)?cfg80211_wext_siwgenie,
[IW_IOCTL_IDX(SIOCSIWAUTH)]?=?(iw_handler)?cfg80211_wext_siwauth,
[IW_IOCTL_IDX(SIOCGIWAUTH)]?=?(iw_handler)?cfg80211_wext_giwauth,
[IW_IOCTL_IDX(SIOCSIWENCODEEXT)]=?(iw_handler)?cfg80211_wext_siwencodeext,
[IW_IOCTL_IDX(SIOCSIWPMKSA)]????=?(iw_handler)?cfg80211_wext_siwpmksa,
[IW_IOCTL_IDX(SIOCSIWPRIV)]?=?(iw_handler)cfg80211_wext_setpriv
};
conststructiw_handler_def?cfg80211_wext_handler?=?{
.num_standard???????=?ARRAY_SIZE(cfg80211_handlers),
.standard???????=?cfg80211_handlers,
.get_wireless_stats?=?cfg80211_wireless_stats,
4、創建并注冊net_device
當執行mac80211_config_ops-> ieee80211_add_iface時,它將創建net_device和對應的ieee80211_sub_if_data, 然后主要做了以下幾件事:
1) 把net_device對應的名字增加到/sys/class/net/目錄下
2) 把新創建的net_device插入到init_net->dev_base_head中
3) 通知上層協議,有一個新的net_device出現了,大家可以使用它了
4) 把新創建的ieee80211_sub_if_data增加到ieee80211_local的interfaces列表中
其流程如下圖所示:
mac80211中定義的net_device_ops ieee80211_dataif_ops,以下這些方法,都有一個struct net_device參數。其具體定義如下:
staticconststructnet_device_ops?ieee80211_dataif_ops?=?{
.ndo_open???????=?ieee80211_open,??????????????//?net_device變換到?UP?時被調用
.ndo_stop???????=?ieee80211_stop,??????????????//?net_device變換到?Down?時被調用
.ndo_uninit?????=?ieee80211_teardown_sdata,????//?取消注冊或注冊失敗時調用
.ndo_start_xmit?????=?ieee80211_subif_start_xmit,??//?需要發送包時被調用
.ndo_set_multicast_list?=?ieee80211_set_multicast_list,//?多播地址列表變化時被調用
.ndo_change_mtu?????=?ieee80211_change_mtu,????????//?當用戶想改變一個設備的MTU時被調用
.ndo_set_mac_address????=?ieee80211_change_mac,????????//?mac地址需要改變時被調用
.ndo_select_queue???=?ieee80211_netdev_select_queue,?//當net_device支持多個發送隊列時,用來決定使用哪個隊列
};
mac80211中初始化net_device->netdev_ops:
staticvoidieee80211_if_setup(structnet_device?*dev)
{
ether_setup(dev);
dev->priv_flags?&=?~IFF_TX_SKB_SHARING;
dev->netdev_ops?=?&ieee80211_dataif_ops;
dev->destructor?=?free_netdev;
}
5. 數據接收(Data RX)流程
數據接收流程如下圖所示:
IP層與TCP/UDP層接口定義如下:
staticconststructnet_protocol?tcp_protocol?=?{
.handler?=??tcp_v4_rcv,
.err_handler?=??tcp_v4_err,
.gso_send_check?=?tcp_v4_gso_send_check,
.gso_segment?=??tcp_tso_segment,
.gro_receive?=??tcp4_gro_receive,
.gro_complete?=?tcp4_gro_complete,
.no_policy?=????1,
.netns_ok?=?1,
};
staticconststructnet_protocol?udp_protocol?=?{
.handler?=??udp_rcv,
.err_handler?=??udp_err,
.gso_send_check?=?udp4_ufo_send_check,
.gso_segment?=?udp4_ufo_fragment,
.no_policy?=????1,
.netns_ok?=?1,
};
staticconststructnet_protocol?icmp_protocol?=?{
.handler?=??icmp_rcv,
.err_handler?=??ping_err,
.no_policy?=????1,
.netns_ok?=?1,
};
IP層與net/core層接口定義如下
staticstructpacket_type?ip_packet_type?__read_mostly?=?{
.type?=?cpu_to_be16(ETH_P_IP),
.func?=?ip_rcv,
.gso_send_check?=?inet_gso_send_check,
.gso_segment?=?inet_gso_segment,
.gro_receive?=?inet_gro_receive,
.gro_complete?=?inet_gro_complete,
};
6、數據發送(Data TX)流珵
數據發送流程如下圖所示:
上半部分涉及到的相關代碼如下所示(以上流程主要通過dump_stack獲取):
net/socket.c
net/ipv4/af_net.c
net/ipv4/tcp.c
net/ipv4/tcp_output.c
net/ipv4/ip_output.c
net/core/neighbour.c
net/core/dev.c
7、INET初始化
INET為Linux?OS實現了TCP/IP協議集,它使用BSD Socket接口作為與User通訊的方式。其初始化代碼如下所示:
代碼位于:net/ipv4/af_inet.c
staticint__init?inet_init(void)
{
structsk_buff?*dummy_skb;
structinet_protosw?*q;
structlist_head?*r;
intrc?=?-EINVAL;
BUILD_BUG_ON(sizeof(structinet_skb_parm)?>sizeof(dummy_skb->cb));
sysctl_local_reserved_ports?=?kzalloc(65536?/?8,?GFP_KERNEL);
if(!sysctl_local_reserved_ports)
gotoout;
rc?=?proto_register(&tcp_prot,?1);
if(rc)
gotoout_free_reserved_ports;
rc?=?proto_register(&udp_prot,?1);
if(rc)
gotoout_unregister_tcp_proto;
rc?=?proto_register(&raw_prot,?1);
if(rc)
gotoout_unregister_udp_proto;
rc?=?proto_register(&ping_prot,?1);
if(rc)
gotoout_unregister_raw_proto;
/*
*??Tell?SOCKET?that?we?are?alive...
*/
(void)sock_register(&inet_family_ops);
#ifdef?CONFIG_SYSCTL
ip_static_sysctl_init();
#endif
/*
*??Add?all?the?base?protocols.
*/
if(inet_add_protocol(&icmp_protocol,?IPPROTO_ICMP)
printk(KERN_CRIT?"inet_init:?Cannot?add?ICMP?protocol\n");
if(inet_add_protocol(&udp_protocol,?IPPROTO_UDP)
printk(KERN_CRIT?"inet_init:?Cannot?add?UDP?protocol\n");
if(inet_add_protocol(&tcp_protocol,?IPPROTO_TCP)
printk(KERN_CRIT?"inet_init:?Cannot?add?TCP?protocol\n");
#ifdef?CONFIG_IP_MULTICAST
if(inet_add_protocol(&igmp_protocol,?IPPROTO_IGMP)
printk(KERN_CRIT?"inet_init:?Cannot?add?IGMP?protocol\n");
#endif
/*?Register?the?socket-side?information?for?inet_create.?*/
for(r?=?&inetsw[0];?r
INIT_LIST_HEAD(r);
for(q?=?inetsw_array;?q
inet_register_protosw(q);
/*
*??Set?the?ARP?module?up
*/
arp_init();
/*
*??Set?the?IP?module?up
*/
ip_init();
tcp_v4_init();
/*?Setup?TCP?slab?cache?for?open?requests.?*/
tcp_init();
/*?Setup?UDP?memory?threshold?*/
udp_init();
/*?Add?UDP-Lite?(RFC?3828)?*/
udplite4_register();
ping_init();
/*
*??Set?the?ICMP?layer?up
*/
if(icmp_init()
panic("Failed?to?create?the?ICMP?control?socket.\n");
/*
*??Initialise?the?multicast?router
*/
#if?defined(CONFIG_IP_MROUTE)
if(ip_mr_init())
printk(KERN_CRIT?"inet_init:?Cannot?init?ipv4?mroute\n");
#endif
/*
*??Initialise?per-cpu?ipv4?mibs
*/
if(init_ipv4_mibs())
printk(KERN_CRIT?"inet_init:?Cannot?init?ipv4?mibs\n");
ipv4_proc_init();
ipfrag_init();
dev_add_pack(&ip_packet_type);
rc?=?0;
out:
returnrc;
out_unregister_raw_proto:
proto_unregister(&raw_prot);
out_unregister_udp_proto:
proto_unregister(&udp_prot);
out_unregister_tcp_proto:
proto_unregister(&tcp_prot);
out_free_reserved_ports:
kfree(sysctl_local_reserved_ports);
gotoout;
}
總結
以上是生活随笔為你收集整理的linux panic 构造_Linux Wireless架构总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: workbeach约束简称_AnsysW
- 下一篇: 英特尔至强 W3400 系列工作站处理器