嵌入式netconsole源码分析3 1几个重要的数据结构_第1页
嵌入式netconsole源码分析3 1几个重要的数据结构_第2页
嵌入式netconsole源码分析3 1几个重要的数据结构_第3页
嵌入式netconsole源码分析3 1几个重要的数据结构_第4页
嵌入式netconsole源码分析3 1几个重要的数据结构_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

By ·-22. -22.1主机的配 22.2被主机的配 -22.3实例测 -33. Ntonol-43.1几个重要的数据结构·-43.1.1structconsole-43.1.2structnetpoll·······························-53.1.3·····························-5-3.1.4····························-6-3.2实现分析·--3.2.1Netconsole初始化·······························-7-3.2.2具体运行实现··--网络的方式传送到另一台主机上。这样,就可以实现某台机子的kernelpanic信息这里使用的是netcat的方式进行监视的。安装好netcat后,执行s命令:#netcat-l-p3000030000块的依赖,以及在加载时必须配置相关的端口,IPs执行命令如下:#modprobenetconsolenetconsole=6666@25/eth7,30000@20/00:0C:29:E2:87:E8–30000@20/00:0C:29:E2:87:E8:三个位段分别是,远端端口,远端IP地址及远端机子的MAC地址。也就是我们在2.1节中指定的端口30000,以及其IP地址和MAC world模块,看看我们的printk信息是怎样被发送到主机上去的。1 #include#include#include6staticint{return11static {15 47$(RM)*.o*.mod.c*.ko##insmodnetconsole:networkloggingstartedoWorldnetconsole:networkloggingstartedoWorldGoodbye核的地址等。下面,我们开始来分析内核源码的netconsole的实现。Theinterfaceforaconsole,oranyotherdevicethatwantstoconsolemessages(printerIfaconsoledriverismarkedCON_BOOTthenitwillbeauto-whenthefirstrealconsoleis Thisisforearly-printk#define #defineCON_CONSDEV (2)/*Lastonthecommandline*/#defineCON_ENABLED #define #define (16)/*Safetocallwhencpuisofflinestruct{charvoid(*write)(structconsole*,constchar*,unsigned);int(*read)(structconsole*,char*,unsigned);structtty_driver*(*device)(structconsole*,int*);void(*unblank)(void);int(*setup)(structconsole*,char*); intcflag; console构,并实现其信息捕捉函数,即write函数。structnetpoll{structnet_device*dev;指向实际的网卡chardev_name[16],*name;//名字void*rx_hook)(structnetpoll*,intchar*,int钩子函数,这里并没有用到void(*drop)(structsk_buff*skb);//函数netconsole实现的一个关键数据结构。net_device成员指向了实际的网卡,我们正是通dmesg信息,因此就必须通过实际的网卡来发送数据。实际上,这个structnet_device{Thisisthefirstfieldofthe"visible"partofthis(i.e.asseenbyusersinthe"Space.c" Itisthethe /*devicenamehashchain*/structhlist_node #ifdefCONFIG_NETPOLL#ifdef (*poll_controller)(structnet_device*dev);/*bridgestuffstruct #ifdef/*thiswillgetinitializedateachinterfacetypeinitroutine*/structdivert_blk /*class/net/nameentry*/structclass_deviceclass_dev;/*spaceforoptionalstatisticsandwirelesssysfsgroups*/structattribute_group net_device结构包含了一个网络设备相关的所有信息,这里并没有全部列出其成员,其中用粉红色标记出来的,正是和netpoll相关的结构。从这里我们可以看到,如果要支持netconsolenetpollnetpollCONFIG_NETPOLL和CONFIG_NET_POLL_CONTROLLER这两个选项。structnetpoll_info{;//inttries;//如果发送失败,指定了发送信息的次数intrx_flags;spinlock_tstructnetpoll*rx_np;/*netpollthatregisteredanrx_hook*/structsk_buff_headarp_tx;/*listofarprequeststoreplyto*/staticcharconfig[256];//定义模块加载时指定参数选项的bufmodule_param_string(netconsoleconfig,256,0定义模块参数 consolestructconsole。因此,我们/*netconsolemoduleinitialization*/staticintinit_netconsole(void){/*Theconfigisthemoduleparameter,whichcontainsthecaptureoptions);printk("netconsole:notconfigured,aborting\n");return0;}/*Setupthenetpollcaptureoperations//指定了netpollreturn-/*registernetconsolethatcangettheprintkinfo*/register_console(&netconsole);//netconsoleprintk(KERN_INFO"netconsole:networkloggingstarted\n");return0;}/*Initializetheconsolecapture...*/staticstructconsolenetconsole={.name=.flags=CON_ENABLED|staticintconfiguredstaticintoption_setup(char{/*parsetheconsolecaptureoptions*/configured=!netpoll_parse_options(&np,opt);return1;}staticstructnetpollnp=//.remote_mac={0xff,0xff,0xff,0xff,0xff,0xff},//默认的机MAC地址,实际上intnetpoll_setup(structnetpoll{structnet_device*ndev=NULL;structin_device*in_dev;unsignedlongflags;if(np->dev_name)/*findthenetworkinterfacecardndev=dev_get_by_name(np->dev_name);if(!ndev){printk(KERN_ERR"%s:%sdoesn'texist,aborting.\n",np->name,np->dev_name);return-}np->devndev;npnpinfo=kmalloc(sizeof(*npinfo),GFP_KERNEL);if(!npinfo)gotonpinfo->rx_flags=npinfo->poll_owner=-1;//暂时无npinfo->triesMAX_RETRIES设定如果发送失败的话,重复的最大次数}npinfo=ndev-if(!ndev->poll_controller){//netdevpoll_controller,否则将不能支持printk(KERN_ERR"%s:%sdoesn'tsupportpolling,aborting.\n",np->name,np->dev_name);goto}ifnetif_running(ndev检查网卡是否启动unsignedlongatmost,atleast;printk(KERN_INFO"%s:device%snotupyet,forcingit\n",np->name,np->dev_name);if(dev_change_flags(ndev,ndev->flags|IFF_UP)<{printk(KERN_ERR"%s:failedtoopen%s\n",np->name,np->dev_name);gotorelease;}atleast=jiffies+HZ/10;atmost=jiffies+while(!netif_carrier_ok(ndev)){{"%s:timeoutwaitingforcarrier\n",}}/*Ifcarrierappearstocomeupinstantly,wetrustitandpausesothatwedon'tpumpallqueuedconsolemessagesintotheif(time_before(jiffies,{printk(KERN_NOTICE"%s:carrierdetect"untrustworthy,waiting4seconds\n",}}/*initializethelocalmac,thatwhyweneednotsetthelocalmacfortheoptions这里要进行本地mac地址的初始化。if(is_zero_ether_addr(np->local_mac)&&ndev->dev_addr)memcpy(np->local_mac,ndev->dev_addr,6);in_dev if(!in_dev||!in_dev-{printk(KERN_ERR"%s:noIPaddressfor%s,aborting\n",np->name,np->dev_name);goto}np->local_ip=ntohl(in_dev->ifa_list->ifa_local);printk(KERN_INFO"%s:localIP%d.%d.%d.%d\n",np->name,HIPQUAD(np->local_ip));}if(np->rx_hook)spin_lock_irqsave(&npinfo->rx_lock,flags);npinfo->rx_flags|=NETPOLL_RX_ENABLED;npinfo->rx_np=np;spin_unlock_irqrestore(&npinfo->rx_lock,flags);}/*filluptheskbqueue*//*lastthingtodoislinkittothenetdevicestructure*/ndev->npinfo=npinfo;/*avoidracingwithNAPIreadingnpinfo*/returnif(!ndev->npinfo) np->dev=NULL;return-1;}netconsolewrite函数的初始化,正是这个函数实现了对终端信息的捕捉。下面,我们就来分析一下write_msg()staticvoidwrite_msg(structconsole*con,constchar*msg,unsignedint{intfrag,left;unsignedlongflags;iffor(left=len;left;)/*thetransport msgshouldNOTlargerthanMAX_PRINT_CHUNK*/frag=min(left,MAX_PRINT_CHUNK);netpoll_send_udp(&np,msg,frag);/*sendthemsg*/msg+=frag;left-=}}voidnetpoll_send_udp(structnetpoll*np,constchar*msg,intlen){inttotal_len,eth_len,ip_len,udp_len;structsk_buff*skb;structudphdr*udph;structiphdr*iph;structethhdr*eth;udp_len=len+ip_len=eth_len=udp_len+total_len=eth_len+ETH_HLEN+skb=find_skb(np,total_len,total_len-len);if(!skb)memcpy(skb->data,msg,len);skb->len+=len;udph=(structudphdr*)skb_push(skb,sizeof(*udph));udph->source=htons(np->local_port);udph->dest=htons(np->remote_port);udph->len=htons(udp_len);udph->check=iph=(structiphdr*)skb_push(skb,/*iph->version=4;iph->ihl=5;*/put_unaligned(0x45,(unsignedchar*)iph); =0; =0; = =0;put_unaligned(htonl(np->local_ip),&(iph->saddr));put_unaligned(htonl(np->remote_ip),&(iph->daddr)); =ip_fast_csum((unsignedchar*)iph,iph-eth=(structethhdr*)skb_push(skb,eth->h_proto=htons(ETH_P_IP);memcpy(eth->h_dest,np->remote_mac,6);skb->dev=np->dev;}这个函数看起来并不复杂,主要是对一些控制信息的设置,最后调用了来发送数据。接下来看看netpoll_send_skp()是怎样实现的:staticvoidnetpoll_send_skb(structnetpoll*np,structsk_buff*skb){intif(!np||!np->dev||!netif_running(np->dev)){ }npinfo=np->dev-/*avoidrecursion/*forourowncpu我们

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论