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
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.
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
}
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
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>>
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;
}
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;
}
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.
To be sure everything works fine reboot your machine.# 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"
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
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