第七次执行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,貌似问题出在这里?
接着往下看吧~
文章评论(0条评论)
登录后参与讨论