marvell pxa2128 uboot/linux kernel fast ethernet development documentary No.2
2013-01-07 17:24
525 查看
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 int netboot_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; else copy_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); else show_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; #endifNow 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 void DhcpHandler(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_PREFIX if (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); #endif if (strlen(bp->bp_file) > 0 && !BootFile[0]) // If BootFile has no data, then copy copy_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 remotecapture 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! | |
---|---|
tcpdump is not part of the Wireshark distribution. You can get it from: http://www.tcpdump.org for various platforms. |
相关文章推荐
- marvell pxa2128 uboot/linux kernel fast ethernet development documentary
- HOWTO do Linux kernel development
- Linux kernel bootsect
- linux : android 命令 fastboot
- zz HOWTO do Linux kernel development
- ARM Linux Kernel Boot Requirements
- linux-boot-arch_x86_kernel_head_32.S
- Linux Kernel Development 笔记(六)中断以及中断处理
- Linux Kernel development (2)
- Linux Kernel Development (6)
- Linux Kernel Development有关内存管理
- Linux Kernel Development 3rd Edition 读书笔记(1)
- HOWTO do Linux kernel development
- Linux Kernel Boot CMDLINE Processing
- linux kernel development 3rd
- 《Linux Kernel Development》读书笔记PDF下载(2012.5.7最后更新)
- usb to ethernet adapter (moshi) work in linux kernel
- Linux kernel boot
- howto do linux kernel development---take3
- linux kernel boot arguments