Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ass:labs-2025:03:tasks:02 [2025/08/06 11:56]
florin.stancu created
ass:labs-2025:03:tasks:02 [2026/07/16 11:35] (current)
florin.stancu
Line 1: Line 1:
 ==== 02. Enabling networking on iMX93 ==== ==== 02. Enabling networking on iMX93 ====
  
-Notice that the FRDM-iMX93 has two Ethernet ports.+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''​.
  
-But if you boot your previous Buildroot distro ​and try to see the available network: ''​ip link show'',​ notice ​that they are missing.+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.
  
-TODO+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 ''#​ifdef''​s. 
 +  * 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. 
 + 
 +<spoiler Hint #1> 
 +This line from **dmesg** tells us why the Network Interface Controller (NIC) remains unavailable. 
 + 
 +<​code>​ 
 +[   ​12.004678] platform 42890000.ethernet:​ deferred probe pending: platform: wait for supplier /​soc@0/​efuse@47510000/​mac-address@4ec 
 +</​code>​ 
 +</​spoiler>​ 
 + 
 +<spoiler 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). 
 +</​spoiler>​ 
 + 
 +<spoiler 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 [[https://​gist.github.com/​aallan/​b4bb86db86079509e6159810ae9bd3e4|some vendor]]. 
 +</​spoiler>​ 
 + 
 +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: 
 + 
 +<code bash> 
 +# 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/​* 
 +</​code>​ 
 + 
 +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: 
 +<​code>​ 
 +# it's recommended to supply the whole cmdline value: 
 +setenv bootargs "​console=ttyLP0,​115200 earlycon,​115200 root=/​dev/​mmcblk0p2 rootwait clk_ignore_unused"​ 
 +</​code>​ 
 + 
 +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.1754470595.txt.gz · Last modified: 2025/08/06 11:56 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