Когда мы коннектимся к плате bbxm по ssh, каждый раз замечаем что ssh сервер спрашивает подтверждение на внесение ip адреса в постоянный список известных хостов. Это наводит на мысль, что после включения плата bbxm получает разный ip адрес по dhcp. И не стоит искать причину в том, что dhcp сервер не дает постоянную аренду ip адреса: такое поведение платы вызвано тем, что она не имеет постоянного mac адреса и каждый раз при загрузке ядра сетевой драйвер выбирает его случайным образом. Соответственно, каждый раз bbxm получает новый ip адрес.
Если такое поведение BeagleBoard XM вызывает дискомфорт, то можно сделать MAC адрес фиксированным. Сразу замечу, что бесполезно править сетевые настройки /etc/network/interfaces: это ничего не изменит. Задача решается патчем сетевого драйвера smsc95xx.c, который находится в дереве ядра по адресу drivers/net/usb (именно usb, потому что Ethernet в bbxm работает именно так!).
Будет разумно, если требуемое значение MAC адреса мы поместим в строку конфигурации, которую u-boot передает ядру. Чтобы не трогать настройки переменных окружения в самом u-boot, который на bbxm и не собирается сохранять их на SD карту, заведем в загрузочном разделе файл переменных окружения uEnv.txt, в котором и пропишем значение MAC адреса:
1 |
optargs="mem=114M ethaddr=00:02:03:aa:bb:cc" |
Значение mem=114M к нашему примеру отношения не имеет и просто показывает, как перечислить несколько параметров в командной строке. Загрузчик u-boot по умолчанию просматривает файл uEnv.txt, поэтому все что в этом файле будет передано как параметры ядру.
Патчи, которые я находил в инете, приходилось править. Вот рабочий патч для ядра 3.0.50:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
--- drivers/net/usb/smsc95xx.c 2015-04-18 11:30:15.561156357 +0300 +++ drivers/net/usb/smsc95xx.c 2015-04-18 15:21:09.409853866 +0300 @@ -63,6 +63,18 @@ module_param(turbo_mode, bool, 0644); MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); +static char *boot_ethaddr_mac = NULL; + +static int __init ethaddr_setup(char *str) +{ + boot_ethaddr_mac = str; + return 1; +} + +/* Read "ethaddr=xx:xx:xx:xx:xx:xx" boot command line parameter */ +__setup("ethaddr=", ethaddr_setup); + + static int smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data) { u32 *buf = kmalloc(4, GFP_KERNEL); @@ -602,8 +614,28 @@ static void smsc95xx_init_mac_address(struct usbnet *dev) { + int ret; /* try reading mac address from EEPROM */ - if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, + if (boot_ethaddr_mac) { + /* try to get MAC address from the boot CLI parameters first */ + printk("MAC ethaddr: %s\n", boot_ethaddr_mac); + ret = sscanf(boot_ethaddr_mac, "%02x:%02x:%02x:%02x:%02x:%02x", + (unsigned int *)&dev->net->dev_addr[0], + (unsigned int *)&dev->net->dev_addr[1], + (unsigned int *)&dev->net->dev_addr[2], + (unsigned int *)&dev->net->dev_addr[3], + (unsigned int *)&dev->net->dev_addr[4], + (unsigned int *)&dev->net->dev_addr[5]); + + if (ret > 0) { + /* CLI values are valid so use them */ + if (netif_msg_ifup(dev)) + netif_dbg(dev, ifup, dev->net, "MAC address read from command line\n"); + printk("MAC addr is valid\n"); + return; + } + } + else if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, dev->net->dev_addr) == 0) { if (is_valid_ether_addr(dev->net->dev_addr)) { /* eeprom values are valid so use them */ |
Патч добавляет функцию __setup(), которая принимает наш параметр командрой строки ethaddr из переменной окружения, которая задана в uEnv.txt. Дальше логика проста: исходный драйвер или находит MAC адрес в постоянной памяти, или задает его случайным образом. Мы добавляем дополнительное условие: если задан параметр ethaddr, то MAC адрес устанавливается значением этого параметра.
Строки printk() добавлены для отладки, в заключительной версии драйвера их можно удалить.
Ответить