marvell pxa2128 uboot/linux kernel fast ethernet development documentary No.2

来源:互联网 发布:淘宝网怎么买罂粟种子 编辑:程序博客网 时间:2024/06/06 21:25

1. uboot dhcp's issue analysis

Issue the following command:
# dhcp 0x1100000 serverip:uImage
Error Log:
Marvell>> dhcp 0x1100000 10.66.130.110:uImage
pxa2128-eth Waiting for PHY auto negotiation to complete. done
pxa2128-eth: link up, 100 Mb/s, full duplex
BOOTP broadcast 1
DHCP client bound to address 10.66.130.251
Using pxa2128-eth device
TFTP from server 10.66.130.4; our IP address is 10.66.130.251
Filename 'pxelinux.0'.
Load address: 0x1100000
Loading: #
done
Bytes transferred = 14146 (3742 hex)
Automatic boot of image at addr 0x01100000 ...
Wrong Image Format for dhcp command
ERROR: can't get kernel image!

The image name is changed from uImage topxelinux.0. And the TFTP serverip 10.66.130.4 actually is a DHCP serverip. So TFTP downloads image unsuccessfully! Let's track the code.

1). dhcp command implementation
#if defined(CONFIG_CMD_DHCP)int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){return netboot_common(DHCP, cmdtp, argc, argv);}U_BOOT_CMD(dhcp,3,1,do_dhcp,"boot image via network using DHCP/TFTP protocol","[loadAddress] [[hostIPaddr:]bootfilename]");#endif
static intnetboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[]){char *s;char *end;int   rcode = 0;int   size;ulong addr;/* pre-set load_addr */if ((s = getenv("loadaddr")) != NULL) {load_addr = simple_strtoul(s, NULL, 16);}switch (argc) {case 1:break;case 2:/* * Only one arg - accept two forms: * Just load address, or just boot file name. The latter * form must be written in a format which can not be * mis-interpreted as a valid number. */addr = simple_strtoul(argv[1], &end, 16);if (end == (argv[1] + strlen(argv[1])))load_addr = addr;elsecopy_filename(BootFile, argv[1], sizeof(BootFile));break;case 3:load_addr = simple_strtoul(argv[1], NULL, 16);  // argc is 3. so this is point.copy_filename (BootFile, argv[2], sizeof(BootFile));break;default:show_boot_progress (-80);return cmd_usage(cmdtp);}show_boot_progress (80);if ((size = NetLoop(proto)) < 0) {   // This function is important!show_boot_progress (-81);return 1;}show_boot_progress (81);/* NetLoop ok, update environment */netboot_update_env();   // update the env related to net device./* done if no file was loaded (no errors though) */if (size == 0) {show_boot_progress (-82);return 0;}/* flush cache */flush_cache(load_addr, size);show_boot_progress(82);rcode = bootm_maybe_autostart(cmdtp, argv[0]);if (rcode < 0)show_boot_progress (-83);elseshow_boot_progress (84);return rcode;}

Coming into NetLoop, we focus on DHCP:(net.c)
#if defined(CONFIG_CMD_DHCP)case DHCP:BootpTry = 0;NetOurIP = 0;DhcpRequest();/* Basically same as BOOTP */break;#endif
Now we come into bootp.c, and the function would send out DHCP request using broadcast.
When the DHCP request is done, the function DhcpHandler would be called.
/* *Handle DHCP received packets. */static voidDhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,    unsigned len){Bootp_t *bp = (Bootp_t *)pkt;debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",src, dest, len, dhcp_state);if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */return;debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",src, dest, len, dhcp_state);switch (dhcp_state) {case SELECTING:/* * Wait an appropriate time for any potential DHCPOFFER packets * to arrive.  Then select one, and generate DHCPREQUEST response. * If filename is in format we recognize, assume it is a valid * OFFER from a server we want. */debug("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file);#ifdef CONFIG_SYS_BOOTFILE_PREFIXif (strncmp(bp->bp_file,    CONFIG_SYS_BOOTFILE_PREFIX,    strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0 ) {#endif/* CONFIG_SYS_BOOTFILE_PREFIX */debug("TRANSITIONING TO REQUESTING STATE\n");dhcp_state = REQUESTING;if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);NetSetTimeout(TIMEOUT, BootpTimeout);DhcpSendRequestPkt(bp);#ifdef CONFIG_SYS_BOOTFILE_PREFIX}#endif/* CONFIG_SYS_BOOTFILE_PREFIX */return;break;case REQUESTING:debug("DHCP State: REQUESTING\n");if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) {if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);BootpCopyNetParams(bp); /* Store net params from reply */dhcp_state = BOUND;printf ("DHCP client bound to address %pI4\n", &NetOurIP);auto_load();return;}break;case BOUND:/* DHCP client bound to address */break;default:puts ("DHCP: INVALID STATE\n");break;}}
The function BootpCopyNetParams would handle bootfile and serverip, sometimes issue would be happened here!
So the function should be modified, as follow:
/* * Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet */static void BootpCopyNetParams(Bootp_t *bp){IPaddr_t tmp_ip;NetCopyIP(&NetOurIP, &bp->bp_yiaddr);#if !defined(CONFIG_BOOTP_SERVERIP)NetCopyIP(&tmp_ip, &bp->bp_siaddr);if (tmp_ip != 0)NetCopyIP(&NetServerIP, &bp->bp_siaddr);memcpy (NetServerEther, ((Ethernet_t *)NetRxPacket)->et_src, 6);#endifif (strlen(bp->bp_file) > 0 && !BootFile[0]) // If BootFile has no data, then copycopy_filename (BootFile, bp->bp_file, sizeof(BootFile));debug("Bootfile: %s\n", BootFile);/* Propagate to environment: * don't delete exising entry when BOOTP / DHCP reply does * not contain a new value */if (*BootFile) {setenv ("bootfile", BootFile);}}

Then make tftp serverip as serverip, not dhcp server ip!

2. Capturing with tcpdump for viewing with Wireshark

D.3. tcpdump: Capturing with tcpdump for viewing with Wireshark

There are occasions when you want to capture packets using tcpdump rather than wireshark, especially when you want to do a remote capture and do not want the network load associated with running Wireshark remotely (not to mention all the X traffic polluting your capture).

However, the default tcpdump parameters result in a capture file where each packet is truncated, because most versions of tcpdump, will, by default, only capture the first 68 or 96 bytes of each packet.

To ensure that you capture complete packets, use the following command:

tcpdump -i <interface> -s 65535 -w <some-file>      

You will have to specify the correct interface and the name of a file to save into. In addition, you will have to terminate the capture with ^C when you believe you have captured enough packets.

[Note]Note!

tcpdump is not part of the Wireshark distribution. You can get it from: http://www.tcpdump.org for various platforms.




原创粉丝点击