This is an old revision of the document!


02. Enabling networking on iMX93

Notice that the FRDM-iMX93 has two Ethernet ports. But if you boot your previous Buildroot distro and try to see the available network: ip link show.

In this task, you will have to debug the problem and try to fix it or at least find a workaround that lets you use your network interface.

Here are a few suggestions to get you started:

  • Investigate your kernel's Device Tree Blob (dtb) and search for the ethernet node
    • You can use the Device Tree Compiler tool dtc to convert between dtb and dts formats
    • dtc is compiled automatically with Linux and can be found at linux/scripts/dtc/dtc
    • Alternatively, it is packaged as dtc on Arch or device-tree-compiler on Ubuntu
  • Use dmesg to view the kernel's boot log and search for any relevant messages
    • grep -rn parts of any interesting message in the kernel's source to determine the context
    • If you've compiled the kernel already, you can run ./scripts/clang-tools/gen_compile_commands.py and it will generate a compile_commands.json file. This file can be used by your language server to allow you to *go to definition* or highlight code sections included in #ifdefs.
  • Try to identify the driver responsible for our network controller
    • Remember that on ARM, drivers are matched to devices based on their compatible string from the DTB
    • The driver must also have at least one of these strings written in its source files.

Hint #1

Hint #1

This line from dmesg tells us why the Network Interface Controller (NIC) remains unavailable.

[   12.004678] platform 42890000.ethernet: deferred probe pending: platform: wait for supplier /soc@0/efuse@47510000/mac-address@4ec

Hint #2

Hint #2

The driver can be found at linux/drivers/net/ethernet/freescale/fec_main.c.
There, the fec_get_mac() function will tell you how the driver gets the NIC's MAC address.
Try to provide it via another means, other than through the eFuse protected by the EdgeLink Enclave (that doesn't work).

Hint #3

Hint #3

In linux/net/ethernet/eth.c look at the comments of the fwnode_get_mac_address() function.
This will give you some alternatives for the nvmem-cells and nvmem-cell-names properties that block the driver initialization.
Try spoofing the MAC address of some vendor.

Once you are done, enable the iperf3, iproute2 and ethtool network packages in Buildroot and build them. The compilation should not take more than 1-2 minutes. Re-generate linux.itb and copy it to the board's eMMC.

Connect to a colleague's board with an Ethernet cable.
Use the ip command to add a static IP to your network interface (man ip-address).
Then, use the iperf3 tool to test the throughput and compare it to what ethtool advertises.
Why is it not a full 1Gbps?

Bonus: solving the actual cause of the problem

The steps above might seem a bit hackish… that's because they are a ugly HACK working around the real problem!

And the real problem is: since the kernel was compiled with external modules (and they take ~300MB), they were not included inside the initial ramdisk (obviously, since it's less than 80MB)!

Due to missing modules, the ethernet driver and its dependencies could not be properly initialized (actually, as we've debugged above, it's just missing its MAC address provider) and thus fails!

The real solution would be to install the buildroot-obtained rootfs (or any other method, tbh.), together with the external kernel modules (usually sitting inside /var/modules/7.x – your kernel version).

This can be easily done by using the kernel's built-in install target:

# enter linux kernel source directory
cd linux/
# create a target directory where external modules will be installed
mkdir -p "../linux-modules"
# install the modules 
make ARCH=arm64 INSTALL_MOD_PATH="../linux-overlay" modules modules_install
# explore it!
ls -l ../linux-modules/lib/modules/*

Next, you will want to add the linux-modules directory into your Buildroot filesystem. Fortunately, this is the easiest thing: enter buildroot's menuconfig, search for ROOTFS_OVERLAY configuration item and set it to the absolute path of your linux-modules created above. Do a make and voila! The rootfs archive will have a huge size (>~350MB), meaning we successfully added all available kernel modules.

There is one problem remaining, though: the rootfs won't fit anymore inside the uImage / small FAT32 partition… So change of plans: delete the initrd node from linux.its (together with its ramdisk configuration node property) and rebuild the uImage.

Next, on the second partition inside your disk image, you must unpack the rootfs.tar file outputted by buildroot. Simply use tar xf ./path/to/rootfs.tar -C /mnt/your-ext4-partition/ (check out the provided mk-disk-image.sh script!).

Still not finished: we need to add the following parameter to the kernel command line BEFORE booting Linux: root=/dev/mmcblk0p2. This can be done inside u-boot, e.g., by using the setenv command:

# it's recommended to supply the whole cmdline value:
setenv bootargs "console=ttyLP0,115200 earlycon,115200 root=/dev/mmcblk0p2 clk_ignore_unused"

Otherwise, the kernel will complain that it cannot find the root block device and panic. Check out the kernel boot log if you have any problems (it will also print its command line parameters it receives from the bootloader)!

If you successfully do all of this, you should see both eth interfaces: first one is 100Mbps, the second one is 1Gbps!

ass/labs-2025/03/tasks/02.1784116823.txt.gz · Last modified: 2026/07/15 15:00 by florin.stancu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0