Running TCP/IP Stack in Linux Print

 

With uClinux running on the i.MX RT1170, you get the full Linux TCP/IP stack (kernel version 4.5.0). Userspace POSIX APIs are provided by the uClibc library. Key user-space networking tools and utilities are available from the multi-call busybox. Additional tools and packages, such as for instance the SSH dropbear server, can be built specifically for uClinux. All in all, you have the powerful Linux TCP/IP stack at your disposal.

There is a full-functioning Ethernet device driver available in the kernel tree for the i.MX RT1170. The device driver is linux/drivers/net/ethernet/freescale/fec.c configured in the kernel using the CONFIG_FEC build time option in Device Drivers -> Network device support -> Ethernet driver support -> Freescale devices -> FEC ethernet controller (of ColdFire and some i.MX CPUs).

For the run-time configuration of the kernel, Ethernet is enabled in rootfs.dts.IMXRT117X_NXPEVK in projects/rootfs as follows:

&fec1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec1>, <&pinctrl_fec1_lpsr>; status = "okay"; assigned-clocks = <&clks IMXRT1170_CLK_ROOT_ENET1>; assigned-clock-parents = <&clks IMXRT1170_CLK_PLL1_DIV2>; assigned-clock-rates = <50000000>; fsl,ref-clk-dir = <&gpr 0x10 1 1>; phy-mode = "rmii"; phy-handle = <&ethphy0>; phy-reset-duration = <1>; phy-reset-gpios = <&gpio12 12 GPIO_ACTIVE_LOW>; clocks = <&clks IMXRT1170_CLK_ROOT_BUS>, <&clks IMXRT1170_CLK_ROOT_BUS>, <&clks IMXRT1170_CLK_ENET1>; clock-names = "ipg", "ahb", "enet_clk_ref"; mdio { #address-cells = <1>; #size-cells = <0>; ethphy0: ethernet-phy@0 { reg = <2>; clocks = <&clks IMXRT1170_CLK_ENET1>; clock-names = "rmii-ref"; }; }; };

This will register a platform device for the i.MX RT1170 Ethernet controller with the Ethernet driver.

The Linux project provided by Emcraft in the distribution (refer to projects/rootfs) and installed on each shipping module and kit includes the TCP/IP stack and various network related capabilities. The following snapshot shows the full Linux bootsrap sequence from power-on to the Linux shell:

U-Boot SPL 2023.04 (Sep 01 2023 - 17:34:47 +0000) Trying to boot from MMC1 U-Boot 2023.04 (Sep 01 2023 - 17:34:47 +0000) Model: NXP imxrt1170-evk board DRAM: 960 KiB (effective 64.9 MiB) Core: 72 devices, 15 uclasses, devicetree: separate MMC: FSL_SDHC: 0 Loading Environment from MMC... OK In: serial@4007c000 Out: serial@4007c000 Err: serial@4007c000 Net: eth0: ethernet@40424000 Hit any key to stop autoboot: 0 8489874 bytes read in 756 ms (10.7 MiB/s) ## Booting kernel from Legacy Image at 80007fc0 ... Image Name: Linux-6.1.22 Image Type: ARM Linux Multi-File Image (uncompressed) Data Size: 8489810 Bytes = 8.1 MiB Load Address: 80008000 Entry Point: 80008001 Contents: Image 0: 8480224 Bytes = 8.1 MiB Image 1: 9574 Bytes = 9.3 KiB Verifying Checksum ... OK ## Flattened Device Tree from multi component Image at 80007FC0 Booting using the fdt at 0x8081e5ec Working FDT set to 8081e5ec Loading Multi-File Image Loading Device Tree to 2032a000, end 2032f565 ... OK Working FDT set to 2032a000 Starting kernel ... Booting Linux on physical CPU 0x0 Linux version 6.1.22 (sasha@workbench.emcraft.com) (arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824 (release), GNU ld (GNU Arm Embedded Toolchain 10.3-2021.10) 2.36.1.20210621) #2 Fri Sep 1 14:20:49 UTC 2023 CPU: ARMv7-M [411fc272] revision 2 (ARMv7M), cr=00000000 CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache OF: fdt: Machine model: NXP IMXRT1170 EVK board Reserved memory: created DMA memory pool at 0x83f00000, size 1 MiB OF: reserved mem: initialized node dmapool@83f00000, compatible id shared-dma-pool Zone ranges: Normal [mem 0x0000000080000000-0x0000000083ffffff] Movable zone start for each node Early memory node ranges node 0: [mem 0x0000000080000000-0x0000000083efffff] node 0: [mem 0x0000000083f00000-0x0000000083ffffff] Initmem setup node 0 [mem 0x0000000080000000-0x0000000083ffffff] Built 1 zonelists, mobility grouping on. Total pages: 16256 Kernel command line: ip=192.168.88.89:192.168.88.170:192.168.88.1:255. 255.255.0::eth0:off Unknown kernel command line parameters "ip=192.168.88.89:192.168.88.170: 192.168.88.1:255.255.255.0::eth0:off", will be passed to user space. Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear) Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear) mem auto-init: stack:off, heap alloc:off, heap free:off Memory: 55504K/65536K available (3423K kernel code, 185K rwdata, 908K rodata, 3556K init, 95K bss, 10032K reserved, 0K cma-reserved) NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16 Switching to timer-based delay loop, resolution 41ns sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns clocksource: mxc_timer1: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000) pid_max: default: 4096 minimum: 301 Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) devtmpfs: initialized DMA: default coherent area is set clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns futex hash table entries: 16 (order: -5, 192 bytes, linear) pinctrl core: initialized pinctrl subsystem NET: Registered PF_NETLINK/PF_ROUTE protocol family imxrt1170-pinctrl 400e8000.iomuxc: initialized IMX pinctrl driver imxrt1170-pinctrl 40c08000.iomuxc_lpsr: initialized IMX pinctrl driver imxrt1170-pinctrl 40c94000.iomuxc_snvs: initialized IMX pinctrl driver SCSI subsystem initialized usbcore: registered new interface driver usbfs usbcore: registered new interface driver hub usbcore: registered new device driver usb pps_core: LinuxPPS API ver. 1 registered pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it> PTP clock support registered Bluetooth: Core ver 2.22 NET: Registered PF_BLUETOOTH protocol family Bluetooth: HCI device and connection manager initialized Bluetooth: HCI socket layer initialized Bluetooth: L2CAP socket layer initialized Bluetooth: SCO socket layer initialized clocksource: Switched to clocksource mxc_timer1 NET: Registered PF_INET protocol family IP idents hash table entries: 2048 (order: 2, 16384 bytes, linear) tcp_listen_portaddr_hash hash table entries: 1024 (order: 0, 4096 bytes, linear) Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear) TCP established hash table entries: 1024 (order: 0, 4096 bytes, linear) TCP bind hash table entries: 1024 (order: 1, 8192 bytes, linear) TCP: Hash tables configured (established 1024 bind 1024) UDP hash table entries: 256 (order: 0, 4096 bytes, linear) UDP-Lite hash table entries: 256 (order: 0, 4096 bytes, linear) NET: Registered PF_UNIX/PF_LOCAL protocol family RPC: Registered named UNIX socket transport module. RPC: Registered udp transport module. RPC: Registered tcp transport module. RPC: Registered tcp NFSv4.1 backchannel transport module. Bus freq driver module loaded Initialise system trusted keyrings workingset: timestamp_bits=30 max_order=14 bucket_order=0 fuse: init (API version 7.37) Key type asymmetric registered Asymmetric key parser 'x509' registered Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251) io scheduler mq-deadline registered io scheduler kyber registered 4007c000.serial: ttyLP0 at MMIO 0x4007c010 (irq = 447, base_baud = 1500000) is a FSL_LPUART fsl-lpuart 4007c000.serial: Serial: Console lpuart rounded baud ratefrom 187500 to 115200 printk: console [ttyLP0] enabled PPP generic driver version 2.4.2 PPP BSD Compression module registered PPP Deflate Compression module registered usbcore: registered new interface driver rt2800usb usbcore: registered new interface driver cdc_acm cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters usbcore: registered new interface driver uas usbcore: registered new interface driver usb-storage i2c_dev: i2c /dev entries driver usbcore: registered new interface driver btusb sdhci: Secure Digital Host Controller Interface driver sdhci: Copyright(c) Pierre Ossman sdhci-pltfm: SDHCI platform and OF driver helper usbcore: registered new interface driver usbhid usbhid: USB HID core driver NET: Registered PF_PACKET protocol family mmc0 bounce up to 128 segments into one, max segment size 65536 bytes Bluetooth: RFCOMM TTY layer initialized Bluetooth: RFCOMM socket layer initialized Bluetooth: RFCOMM ver 1.11 ARMv7-M VFP coprocessor found VFP: Double precision floating points are supported Loading compiled-in X.509 certificates mmc0: SDHCI controller on 40418000.usdhc [40418000.usdhc] using DMA input: gpio-keys as /devices/platform/gpio-keys/input/input0 cfg80211: Loading compiled-in X.509 certificates for regulatory database cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7' platform regulatory.0: Direct firmware load for regulatory.db failed with error -2 cfg80211: failed to load regulatory.db Freeing unused kernel image (initmem) memory: 3556K This architecture does not have kernel memory protection. Run /init as init process [72] Jan 01 00:00:01 Running in background / # mmc0: host does not support reading read-only switch, assuming write-enable mmc0: new high speed SDHC card at address 59b4 mmcblk0: mmc0:59b4 USD 7.39 GiB mmcblk0: p1 Micrel KSZ8081 or KSZ8091 40424000.ethernet-1:02: attached PHY driver (mii_bus:phy_addr=40424000.ethernet-1:02, irq=POLL) fec 40424000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off / #

Let's test the TCP/IP stack on the i.MX RT1170.

From the development host validate that the i.MX RT1170 is visible using ping:

$ ping 192.168.88.89 -c 5
PING 192.168.88.89 (192.168.88.89) 56(84) bytes of data.
64 bytes from 192.168.88.89: icmp_seq=1 ttl=64 time=8.99 ms
64 bytes from 192.168.88.89: icmp_seq=2 ttl=64 time=1.93 ms
64 bytes from 192.168.88.89: icmp_seq=3 ttl=64 time=11.9 ms
64 bytes from 192.168.88.89: icmp_seq=4 ttl=64 time=1.75 ms
64 bytes from 192.168.88.89: icmp_seq=5 ttl=64 time=2.07 ms

--- 192.168.88.89 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 405ms
rtt min/avg/max/mdev = 1.746/5.323/11.877/4.272 ms

ping the development host from the i.MX RT1170:

/ # ping 192.168.88.170 -c 5
PING 192.168.88.170 (192.168.88.170): 56 data bytes
64 bytes from 192.168.88.170: seq=0 ttl=64 time=8.999 ms
64 bytes from 192.168.88.170: seq=1 ttl=64 time=3.367 ms
64 bytes from 192.168.88.170: seq=2 ttl=64 time=3.020 ms
64 bytes from 192.168.88.170: seq=3 ttl=64 time=2.845 ms
64 bytes from 192.168.88.170: seq=4 ttl=64 time=3.012 ms

--- 192.168.88.170 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 2.845/4.248/8.999 ms

On the target, start the telnetd daemon to allow connections to the i.MX RT1170:

/ # ps | grep telnetd 99 root 848 S telnetd 101 root 848 S grep telnetd / # / #

Connect to the target from the development host using telnet. The target is configured to accept the 123 password for root.

$ telnet 192.168.88.89 Trying 192.168.88.89... Connected to 192.168.88.89. Escape character is '^]'. (none) login: root Password: / # ls bin hello.ko lib proc sys var dev httpd linuxrc root tmp etc init mnt sbin usr / # exit Connection closed by foreign host. $

The dropbear SSH daemon starts automatically on the target. Verify that dropbear allows secure connections to the target:

/ # ps | grep dropbear
72 root 728 S dropbear -R
99 root 864 S grep dropbear
/ #

Connect to the target from the development host using ssh. The first connection takes several seconds to establish as the i.MX RT1170 runs computation-extensive key calculations. Again, enter 123 on the password prompt:

$ ssh root@192.168.88.89
The authenticity of host '192.168.88.89 (192.168.88.89)' can't be established.
ED25519 key fingerprint is SHA256:i2ePwYaIvztXXdWDoDXrOWhdYMB87xX9V5T1pZEIxGM.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.88.89' (ED25519) to the list of known hosts.
root@192.168.88.89's password:
/ # ls
bin hello.ko lib proc sys var
dev httpd linuxrc root tmp
etc init mnt sbin usr
/ # exit Connection to 192.168.88.89 closed by remote host.
Connection to 192.168.88.89 closed.
$

On the target, enable access to the Internet by configuring a default gateway. Note also that the system makes use of the public name server provided by Google:

/ # route add default gw 192.168.88.1 / # cat /etc/resolv.conf # This configuration makes use of the Google public DNS server. # If you would like to use something else, replace with the IP # of your DNS server nameserver 8.8.8.8 / #

Use ntpd to synchronize the time on the target with the time provided by a public server:

/ # date
Thu Jan 1 00:09:27 UTC 1970
/ # ntpd -p 0.fedora.pool.ntp.org
/ # sleep 5

/ # date
Mon Aug 21 07:13:18 UTC 2023

Use wget to download a file from a remote server:

/ # wget ftp://ftp.gnu.org/README
Connecting to ftp.gnu.org (209.51.188.20:21)
saving to 'README'
README 100% |********************************| 2748 0:00:00 ETA
'README' saved
/ # cat README
This is ftp.gnu.org, the FTP server of the the GNU project.
...

Mount a directory exported by a development host over NFS:

/ # mount -o nolock,rsize=1024 192.168.1.99:/srv/nfs /mnt/nfs / # ls /mnt/nfs/ SimpleClass linux-dp test / # cp /bin/busybox /mnt/nfs / # cp /mnt/nfs/busybox /tmp / # md5sum /bin/busybox /tmp/busybox bb39cf3470150200a35c41bd6f78ef92 /bin/busybox bb39cf3470150200a35c41bd6f78ef92 /tmp/busybox