marvell pxa2128 uboot/linux kernel fast ethernet development documentary

  • 1. uboot hang

Open debug information as follows:

U-Boot code: 00F00000 -> 00F3AA68  BSS: -> 00F80088
SoC:   ARMADA620 88AP2128-B1
Boot Core: MP1
Available Cores: MP1 MP2 
DRAM interleave size: 0x00040000
I2C:   ready
monitor len: 00080088
ramsize: 18000000
TLB table at: 17ff0000
Top of RAM usable for U-Boot at: 17ff0000
Reserving 512k for U-Boot at: 17f6f000
Reserving 1152k for malloc() at: 17e4f000
Reserving 80 Bytes for Board Info at: 17e4efb0
Reserving 120 Bytes for Global Data at: 17e4ef38
New Stack Pointer is: 17e4ef28
DRAM_BANKS[0]: 0x00000000, 0x40000000
RAM Configuration:
Bank #0: 00000000 1 GiB
Bank #1: 00000000 0 Bytes
Bank #2: 00000000 0 Bytes
Bank #3: 00000000 0 Bytes
Bank #4: 00000000 0 Bytes
Bank #5: 00000000 0 Bytes
Bank #6: 00000000 0 Bytes
Bank #7: 00000000 0 Bytes
relocation Offset is: 1706f000

Hang here. Seems that the text segment exceeds the boundary.

The related code is in the "board.c" file. The issue is caused by ntim not updated, and it can be solved by using the

marvell burning tool to generate ntim***.bin which would be burned to emmc.

There are two following things needed to remember:

1). make ****_config: where are these configuration files and soc informations?

$ ls uboot/arch/arm/include/asm/arch-armada620/
armada620.h  config.h  cpu.h  gpio.h  mfp.h  usb.h

After completing compilation, the above files would copy into the"include" directory in uboot's root dir.

$ ll uboot/include/asm/
total 1456
lrwxrwxrwx  1 yanghaibing yanghaibing      14 12月 20 09:31 arch -> arch-armada620/

$ ls include/asm/arch-armada620/
armada620.h  config.h  cpu.h  gpio.h  mfp.h  usb.h

$ ls uboot/arch/arm/cpu/armv7/armada620/
asm-offsets.s  cpu.c  dram.c  Makefile  smp_init.S  timer.c

$ ls uboot/arch/arm/cpu/armv7

start.S  u-boot.lds  cache_v7.c ...


2). where is board related configuration and soc informations?

$ ls uboot/include/configs/qseven.h

$ ls uboot/board/Marvell/qseven/

libqseven.o  Makefile  qseven.c  qseven.o

  • 2. using container_of macro needs to pay attention to some pointers which is in the structure or not, for example:

	priv->dev = malloc(sizeof(struct eth_device));
	if (!priv->dev)
		goto error7;
	PRINT(ETH_INIT_LOG, "Allocate memory successfully.");

	priv->mac_base = base_addr[0];
	priv->pmu_base = base_addr[1];
	priv->regs = &fe_mac_regs;

	dev = priv->dev;
compare:

	dev = malloc(sizeof(struct eth_device)); // "dev" is a local variable, "priv->dev" is a member variable in pxa2128_eth_priv.
	if (!dev)
		goto error7;
	PRINT(ETH_INIT_LOG, "Allocate memory successfully.");

	priv->mac_base = base_addr[0];
	priv->pmu_base = base_addr[1];
	priv->regs = &fe_mac_regs;

	priv->dev = dev;  // &dev is a local address, but &priv->dev is an address of the structure pxa2128_eth_priv.

    Actually, there are no difference. Tommorrow the issue would be continued.

container_of open up

({ \    // if the member variable is a pointer, the first argument musts take its address with "&"!!
	const typeof( ((struct pxa2128_eth_priv *)0)->dev ) *__mptr = (&ndev);	\   
	(struct pxa2128_eth_priv *)( (char *)__mptr - ((size_t) &((struct pxa2128_eth_priv *)0)->dev) );})

    Replace the container_of macro to the following function:

static inline void *netdev_priv(const struct eth_device *ndev)
{
	return ndev->priv;
}
    If the member is a pointer, container_of macro can't find the header. Because according to the symbol "&" to get the pointer address which is at other place, it can't get actual address in pxa2128_eth_priv structure.

  • 3. MAC controller needs to know phy device address, and this thing can be set by setting the MAC register 0x0. Then typically, the SMI unit continuously queries the PHY device for link status without the need for CPU intervention and the register Port Status(PSR)(offset 0x418) would display link status.

Table 1033:PHY Address (PAR)    Offset: 0x000
Bits Field Type / Description
             HW Rst 
31:15    Reserved     RSVD       Reserved
14:10    Phy_AD2     0x06 PHY  Device Address for Port 2
9:5        Phy_AD1    0x05 PHY  Device Address for Port 1
4:0        Phy_AD0    0x04 PHY  Device Address for Port 0

static void pxa2128_set_phyaddr(struct pxa2128_eth_priv *priv, int phy_addr)
{
	u32 reg_data;
	int addr_shift = 5 * priv->port_num;
	struct pxa2128_regs *reg = priv->regs;
	reg_data = rdl(priv, reg->PAR.addr);
	reg_data &= ~(0x1f << addr_shift);
	reg_data |= (phy_addr & 0x1f) << addr_shift;
	wrl(priv, reg->PAR.addr, reg_data); // MAC Register 0x0 and set bits 0-4
}

  • 4. FE dump mac and phy registers

pxa2128-eth: Dumping Ethernet MAC registers ...
offset 0x400:  pxa2128-eth: 0x00001080   0x00000000   0x10204838   0x00000000
offset 0x410:  pxa2128-eth: 0x00000000   0x00000000   0x0000000b   0x00000000
offset 0x420:  pxa2128-eth: 0x00218823   0x00000000   0x17e4fad0   0x00000000
offset 0x430:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x440:  pxa2128-eth: 0x000032fc   0x00000000   0x00800080   0x00000000
offset 0x450:  pxa2128-eth: 0x00000044   0x00000000   0x10002dcd   0x00000000
offset 0x460:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x470:  pxa2128-eth: 0x0000f0cc   0x00000000   0x00000000   0x00000000
offset 0x480:  pxa2128-eth: 0x17e53b00   0x00000000   0x00000000   0x00000000
offset 0x490:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x4a0:  pxa2128-eth: 0x17e53b00   0x00000000   0x00000000   0x00000000
offset 0x4b0:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x4c0:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x4d0:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x4e0:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x500:  pxa2128-eth: 0x000002c4   0x000000c0   0x00000005   0x00000003
offset 0x510:  pxa2128-eth: 0x000002c4   0x00000005   0x00000000   0x00000003
offset 0x520:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
offset 0x530:  pxa2128-eth: 0x00000000   0x00000000   0x00000005   0x00000000
offset 0x540:  pxa2128-eth: 0x00000003   0x00000000   0x00000000   0x00000000
offset 0x550:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000002
offset 0x560:  pxa2128-eth: 0x00000000   0x00000000   0x00000000   0x00000000
pxa2128-eth: Dumping Ethernet PHY registers ...
pxa2128-eth: offset 0xd4282a10 : 0x1b, 0x40000, 0x82f
offset 0x 0:  pxa2128-eth: 0x1100  0x78ed  0x0141  0x0e60  0x05e1
offset 0x 5:  pxa2128-eth: 0xc1e1  0x000f  0x2801  0x0000  0x0000
offset 0x a:  pxa2128-eth: 0x0000  0x0000  0x0000  0x0007  0x0000
offset 0x f:  pxa2128-eth: 0x0000  0x0138  0x7c00  0x0000  0x1c40
offset 0x14:  pxa2128-eth: 0x0000  0x0000  0x4458  0x4000  0x4245
offset 0x19:  pxa2128-eth: 0x0000  0x0000  0x0000  0x0c03  0x0009

  • 5. TFTP download uImage

Marvell>> dhcp 0x1100000 10.20.112.32:uImage
pxa2128-eth: link up, 100 Mb/s, full duplex
BOOTP broadcast 1
DHCP client bound to address 10.20.112.11
Using pxa2128-eth device
TFTP from server 10.20.112.32; our IP address is 10.20.112.11
Filename 'uImage'.
Load address: 0x1100000
Loading: #################################################################
                 #################################################################
                 #################################################################
                 #################################################################
                 #################################################################
                 #################################################################
                 #################################################################
                 #################################################################
                 #################################################################
                 #################################################################
                 ######
done
Bytes transferred = 3358164 (333dd4 hex)
Marvel>>

  • 6. Get mac address from eeprom

static int get_mac_from_eeprom(struct pxa2128_eth_priv *priv)
{
#define EEPROM_ADDR 0x50
#define EEPROM_MAC_OFFSET 0x64
        int err;
        char mac_addr[ETH_ALEN * 4] = {0};
        char *mac_env = "ethaddr";

        err = i2c_read(EEPROM_ADDR, EEPROM_MAC_OFFSET, 1, mac_addr, ETH_ALEN);
        if (err < 0)
                goto ERROR;
        err = str_reverse(mac_addr, ETH_ALEN);
        if (err < 0)
                goto ERROR;

        mac_addr[0] &= 0xfe; /* clear multicast bit */
        mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
        memcpy(priv->oldmac, mac_addr, ETH_ALEN);

    sprintf(&mac_addr[ETH_ALEN], "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0],
                mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
        setenv(mac_env, &mac_addr[ETH_ALEN]);

        return 0;
ERROR:
        PRINT(ETH_ERR, "Fail to get mac address from eeprom");
        return -1;
}

Write mac address to hash table

static int pxa2128_wirte_hwaddr(struct eth_device *dev)
{
        struct pxa2128_eth_priv *priv = netdev_priv(dev);

        if (!memcmp(priv->oldmac, dev->enetaddr, ETH_ALEN))
                return 0;

        if (!is_valid_ether_addr(dev->enetaddr))
                return -EINVAL;

        memcpy(priv->oldmac, dev->enetaddr, ETH_ALEN);
        update_hash_table_mac_address(priv, priv->oldmac, dev->enetaddr);

        return 0;
}

  • 7. Changing MAC leads that fe can't work

Because changing MAC address leads ubuntu modifies eth*. In my environment, the eth0 port number is changed to eth3.

If we need the port number revert to eth0, we could do the following changes:

CHANGE NETWORK DEVICE NAME FROM ETH3 BACK TO ETH0.

The file is the udev rule for network devices which is located here:

/etc/udev/rules.d/70-persistent-net.rules

Copy the new mac address to the line of your eth0 rule and delete eth3.

# net device ()
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:43:01:11:d
f", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"    // previous name is "eth3"

To be sure everything works fine reboot your machine.

then we can see:

Come into /proc/net

root@localhost:/proc/net# cat dev

Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  eth0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
 tunl0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
 mlan0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  uap0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  wfd0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0


Come into /sys/devices/platform/pxa168-eth/net

We can see that the directory named eth3 is changed to be eth0

Come into the directory: eth0

root@localhost:/sys/devices/platform/pxa168-eth/net# ls
eth0

root@localhost:/sys/devices/platform/pxa168-eth/net/eth0# ls
addr_assign_type  dev_id    flags      mtu           speed         uevent
addr_len          device    ifalias    netdev_group  statistics
address           dormant   ifindex    operstate     subsystem
broadcast         duplex    iflink     power         tx_queue_len
carrier           features  link_mode  queues        type

The card information can be seen. For example: get mac address

root@localhost:/sys/devices/platform/pxa168-eth/net/eth0# cat address 
00:50:43:01:11:df

  • 8. TFTP Server Setting (ubuntu)

---Step 1: Install software of tftp--- (My ubuntu's version is 12.04)

Boot up Ubuntu, open the terminal and issue the command:
# sudo apt-get install tftpd
# sudo apt-get install netkit-inetd


If the second above command's result is as follow:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
Package netkit-inetd is a virtual package provided by:
  inetutils-inetd 2:1.8-3
  openbsd-inetd 0.20080125-6Ubuntu1
You should explicitly select one to install.

E: Package 'netkit-inetd' has no installation candidate

If so, issue the following command 
# sudo apt-get install openbsd-inetd

---Step 2: Config tftp setting---

Modify the file of "/etc/inetd.conf" and add the following contents:
tftp        dgram    udp    wait    nobody    /usr/sbin/tcpd    /usr/sbin/in.tftpd /srv/tftp

"/srv/tftp" should be replaced to your own tftp home directory.

---Step 3: Restart tftp service---

Issue the following command

# sudo /etc/init.d/openbsd-inetd restart
The output should be as follow:
 * Restarting internet superserver inetd                                                                               [ OK ]


The tftp configuration is done.

  • 9. Ethernet Port Number is not "eth0" in user space (refer to No.7)

    All three numbering systems use the same format and differ only in the length of the identifier. Addresses can either be universally administered addresses or locally administered addresses. A universally administered address is uniquely assigned to a device by its manufacturer. The first three octets (in transmission order) identify the organization that issued the identifier and are known as the Organizationally Unique Identifier (OUI). The following three (MAC-48 and EUI-48) or five (EUI-64) octets are assigned by that organization in nearly any manner they please, subject to the constraint of uniqueness. The IEEE expects the MAC-48 space to be exhausted no sooner than the year 2100; EUI-64s are not expected to run out in the foreseeable future. A locally administered address is assigned to a device by a network administrator, overriding the burned-in address. Locally administered addresses do not contain OUIs.
    Universally administered and locally administered addresses are distinguished by setting the second-least-significant bit of the most significant byte of the address. This bit is also referred to as the U/L bit, short for Universal/Local, which identifies how the address is administered. If the bit is 0, the address is universally administered. If it is 1, the address is locally administered. In the example address 06-00-00-00-00-00 the most significant byte is 06 (hex), the binary form of which is 00000110, where the second-least-significant bit is 1. Therefore, it is a locally administered address. Consequently, this bit is 0 in all OUIs.

The interface name of a network device increases if the mac address of the physical or virtual network card changes. A common case is if you made a clone of a virtual machine for example via VMware or KVM or replaced a physical network card in a non virtualized server.

Remember if the mac address is set to a locally administered one, the interface name of the network device would not increase!

We have found a workaround that maps the network card to eth0 but first, a little background about how the adaptors are dynamically assigned.

Device mapping on some of our Linux machines are controlled by the file /etc/iftab.

On our Ubuntu test machine this file, /etc/iftab, is not present and the network devices assignment is controlled by files located in the /etc/udev/rules.d directory.

What's in Rules.d

This directory will contain two files with names the same as (or similar to) the following:

75-persistent-net-generator.rules
70-persistent-net.rules

The file, 75-persistent-net-generator.rules, contains rules for a script /lib/udev/write_net_rules that runs each time the machine boots up.

The second file, 70-persistent-net.rules, contains the names of the device files:

#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# USB device 0x0846:0x1040 (usb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0f:b5:fb:fc:e
0", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# USB device 0x0b95:0x1780 (usb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:b6:4d:c5:a
9", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# USB device 0x0b95:0x1780 (usb)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:b6:4d:c6:8
6", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"

# net device ()
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:50:43:01:11:d
f", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"

# net device ()
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="04:50:43:01:11:d
f", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth4"

It appears to us that each time the networking is reconfigured (for example, if one switches from a wireless adaptor to a wired adaptor) and then rebooted, this rule file gets updated and new network device names are assigned. On this particular machine, the most recent ethernet assignments had incremented to eth4.

root@localhost:/etc/udev/rules.d# ls /lib/udev/rules.d/
40-gnupg.rules                     70-udev-acl.rules
40-ia64.rules                      75-cd-aliases-generator.rules
40-ppc.rules                       75-net-description.rules
42-qemu-usb.rules                  75-persistent-net-generator.rules
50-firmware.rules                  75-probe_mtd.rules
50-udev-default.rules              75-tty-description.rules
60-cdrom_id.rules                  78-graphics-card.rules
60-persistent-alsa.rules           78-sound-card.rules
60-persistent-input.rules          80-drivers.rules
60-persistent-serial.rules         85-keyboard-configuration.rules
60-persistent-storage-tape.rules   90-alsa-restore.rules
60-persistent-storage.rules        90-alsa-ucm.rules
60-persistent-v4l.rules            95-keyboard-force-release.rules
61-accelerometer.rules             95-keymap.rules
64-xorg-xkb.rules                  95-udev-late.rules
66-xorg-synaptics-quirks.rules     97-bluetooth-hid2hci.rules
69-xserver-xorg-input-wacom.rules  README


 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(u-boot)