原创 为AM335x移植Linux内核主线代码(38)调试Ethernet之三

2015-2-13 20:46 1726 18 18 分类: MCU/ 嵌入式 文集: Linux Kernel的DTS

第七次执行inet_ioctl函数:

[   29.778770] ================================> inet_ioctl SSSS               
[   29.784913] ====> ioctl_num = 7 cmd = 0x8914                                
[   29.789386] ====> delay 2s.                                                 
[   31.781801] ====> GIFADDR/SIFADDR ......                                    
[   31.785935] ====> devinet_ioctl SSSS                                        
[   31.789682] ====> ifr.ifr_name = eth0                                       
[   31.793543] ====> switch (cmd) 1                                            
[   31.796931] ====> in_dev is true.                                           
[   31.800401] ====> ifa is false.                                             
[   31.803713] ====> switch (cmd) 2                                            
[   31.807183] ====> dev_change_flags SSSS                                     
[   31.811198] ====> dev->flags = 0x1002, flags = 0x1043                       
[   31.816509] ----> __dev_change_flags SSSS                                   
[   31.820706] ----> dev_flags = 0x1002                                        
[   31.824470] ----> dev_flags = 0x1002                                        
[   31.828210] ----> dev_set_rx_mode IIII                                      
[   31.832502] ====> __dev_set_rx_mode SSSS                                    
[   31.836662] ====> no IFF_UP                                                 
[   31.839603] ----> IFF_UP = 0x1 old_flags = 0x1002                           
[   31.844556] 1111 __dev_open start                                           
[   31.848028] 1111 netif_device_present IIII                                  
[   31.852314] 1111 netpoll_poll_disable IIII                                  
[   31.856625] 1111 call_netdevice_notifiers IIII                              
[   31.861287] 1111 notifier_to_errno IIII                                     
[   31.865326] 1111 set_bit __LINK_STATE_START                                 
[   31.869797] 1111 ops->ndo_validate_addr IIII                                
[   31.874290] 20 cd 39 e2 03 96 1111 ops->ndo_open IIII                       
[   31.879634] ==> cpsw_ndo_open SSSS                                          
[   31.883219] ==> netif_carrier_off IIII                                      
[   31.887345] ==> pm_runtime_get_sync IIII                                    
[   31.891505] net eth0: initializing cpsw version 1.12 (0)                    
[   31.897111] ==> cpsw_init_host_port IIII                                    
[   31.901218] ========> cpsw_init_host_port SSSS                              
[   31.905893] ========> soft reset cpsw (notice it's not resetting phy)       
[   31.912661] ========> cpsw_ale_start IIII                                   
[   31.916860] ========> cpsw_ale_start start                                  
[   31.921162] ========> notice here is for am335x register                    
[   31.926747] ========> cpsw_ale_start over                                   
[   31.930947] ========> dual_emac = 0                                         
[   31.936317] ========> cpsw_init_host_port EEEE                              
[   31.940969] ==> for each slave cpsw_slave_open IIII                         
[   31.946099] ========> cpsw_slave_open SSSS                                  
[   31.950386] ========> soft_reset_slave                                      
[   31.954341] ========> phy_connect IIII                                      
[   31.958356] ========> phy_connect start                                     
[   31.962369] ========> search for list of PHY devices on the mdio bus        
[   31.969083] net eth0: phy found : id is : 0x8201                            
[   31.974113] =======> cpsw_slave_open EEEE                                   
[   31.978316] ========> cpsw_slave_open SSSS                                  
[   31.982634] ========> soft_reset_slave                                      
[   31.986565] ========> phy_connect IIII                                      
[   31.990581] ========> phy_connect start                                     
[   31.994618] ========> search for list of PHY devices on the mdio bus        
[   32.001276] libphy: PHY  not found                                          
[   32.004868] net eth0: phy  not found on slave 1                             
[   32.009611] =======> cpsw_slave_open EEEE                                   
[   32.013832] ==> cpsw_add_default_vlan IIII                                  
[   32.018970] ==> cpdma_control_set IIII                                      
[   32.024069] ==> cpsw_info submitted 64 rx descriptors                       
[   32.029364] ==> cpts_register IIII                                          
[   32.032978] ==> enable interrupt pacing if configured                       
[   32.038268] ==> napi_enable / cpdma_ctlr_start / cpsw_inir_enable           
[   32.044726] ==> cpsw_get_slave_priv IIII                                    
[   32.048834] ==> open_stat                                                   
[   32.051665] ==> cpsw_ndo_open EEEE                                          
[   32.055251] 1111 netpoll_poll_enable IIII                                   
[   32.059449] 2222 __dev_open middle                                          
[   32.063032] 2222 dev_set_rx_mode IIII                                       
[   32.066868] ====> __dev_set_rx_mode SSSS                                    
[   32.070973] ====> no IFF_UNICAST_FLT                                        
[   32.074734] ====> ops->ndp_set_rx_mode(dev) IIII                            
[   32.079568] ========> cpsw_ndo_set_rx_mode SSSS                             
[   32.085180] ========> cpsw_ndo_set_rx_mode EEEE                             
[   32.089973] 3333 __dev_open over                                            
[   32.093381] ----> __dev_change_flags EEEE                                   
[   32.097581] ----> __dev_notify_flags SSSS                                   
[   32.101872] ====> __dev_set_rx_mode SSSS                                    
[   32.106010] ====> no IFF_UNICAST_FLT                                        
[   32.109754] ====> ops->ndp_set_rx_mode(dev) IIII                            
[   32.114607] ========> cpsw_ndo_set_rx_mode SSSS                             
[   32.120196] ====> mc_empty                                                  
[   32.123989] ========> cpsw_ndo_set_rx_mode EEEE                             
[   32.128747] ----> __dev_notify_flags EEEE                                   
[   32.132968] ====> changes = 0x1                                             
[   32.136257] ====> dev_change_flags EEEE                                     
[   32.140275] ====> devinet_ioctl EEEE ret = 0                                
[   32.144767] =========================> inet_ioctl EEEEEEEEEEEEEE

首先下面这个函数被调用:
int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);

它的cmd参数为SIOCSIFFLAGS,这样就会由switch分支跳转到下面这个函数执行:
int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg);

它的arg参数是用户空间的struct ifreq结构体地址,存放了网卡的基本信息,ifr.ifr_name包含在此结构体中,它的名字是“eth0”。知道了网卡的名字,就能够装载它的network module了。所以下面这个函数会被执行:
dev_load(net, ifr.ifr_name);

上面这个函数执行完之后,会进入第一个switch分支,cmd的值为SIOCSIFFLAGS,因此在第一个switch分支里面,会执行:
ns_capable(net->user_ns, CAP_NET_ADMIN);

这个函数用来判断if the current task has the given superior capability currently available for use,如果有的话则返回真,否则返回假。如果返回假的话则跳出devinet_ioctl,这里返回了真,因此会继续往下执行第二个switch分支,在此分支中跳转到下面这个函数去执行:
int dev_change_flags(struct net_device *dev, unsigned int flags);

此时的flags正是之前ifr.ifr_flags的内容,而ifr.ifr_name一起由copy_from_user函数获得。由于此时IFF_UP还无效,因此先执行__dev_open使其有效,在__dev_open中,由于此时ops->ndo_*函数们已经被赋值了,就是drivers/net/ethernet/ti/cpsw.c中的cpsw_netdev_ops,因此之后会执行两个函数:
ops->ndo_validate_addr(dev);
ops->ndo_open(dev);

ndo_validate_addr函数用来检查mac地址是否有效,这里的地址是20 cd 39 e2 03 96,是eth0的网卡地址,需要注意的是它不是以字符形式存储,而是以十六进制数存储的,因此共7个字节。而在ndo_open函数中,根据MDIO的寄存器找到了PHY设备,也就是这里的slave0对应的0x8201。同时也可以知道,由于找不到slave1,它并没有被设置为dule_emac模式。

当__dev_open函数执行完之后,又会返回dev_change_flags函数,继续往下执行;
当dev_change_flags函数执行完之后,又会返回devinet_ioctl函数,继续往下执行;
当devinet_ioctl函数执行完之后,又会返回inet_ioctl函数,直到结束。

第八次执行inet_ioctl函数:

[   32.174413] ================================> inet_ioctl SSSS               
[   32.180470] ====> ioctl_num = 8 cmd = 0x8916                                
[   32.185024] ====> delay 2s.                                                 
[   34.178198] ====> GIFADDR/SIFADDR ......                                    
[   34.182322] ====> devinet_ioctl SSSS                                        
[   34.186095] ====> ifr.ifr_name = eth0                                       
[   34.189934] ====> switch (cmd) 1                                            
[   34.194866] ====> in_dev is true.                                           
[   34.198414] ====> ifa is false.                                             
[   34.201734] ====> switch (cmd) 2                                            
[   34.205335] ====> dev->name = eth0                                          
[   34.208899] ====> ifa_address = 0xe800a8c0                                  
[   34.213230] ====> no IFF_POINTOPOINT                                        
[   34.217363] ====> devinet_ioctl EEEE ret = 0                                
[   34.221839] =========================> inet_ioctl EEEEEEEEEEEEEE

0x8916被定义为宏SIOCSIFADDR,ifa_address = 0xe800a8c0,换成通用的IPV4地址是192.168.0.232。
好吧,其实这个地址是不对的,因为现在路由器的地址是192.168.1.1,所以如果被分配了地址也应该是192.168.1.x,貌似问题出在这里?

接着往下看吧~

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
18
关闭 站长推荐上一条 /3 下一条