Message ID | 20230505102529.1254445-1-maxim.uvarov@linaro.org |
---|---|
Headers | show |
Series | LWIP stack integration | expand |
Hi Maxim, On Fri, 5 May 2023 at 04:50, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > Greetings, > > This RFC patchset is an attempt to try to use an already existing IP network stack inside U-boot. > U-Boot recently got basic TCP/IP support, implementing wget, but in order to get a full IP stack > with new features (e.g ipv6), it would be preferable to use an established embedded ip library, > instead of rewriting the code from scratch. > > For this experiment LWIP network stack was selected: > https://savannah.nongnu.org/git/?group=lwip > > LWIP main features include: > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > - APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API > - Extended features: IP forwarding over multiple network interfaces, TCP congestion control, > RTT estimation and fast recovery/fast retransmit > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, > mDNS responder, MQTT client, TFTP server. > > This RFC work is a demo to enable lwIP (lightweight IP) which is a widely used open-source > TCP/IP stack designed for embedded systems for U-boot. That will allow using already > written network applications for microcontrollers. > > lwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. > Which should be compatible with u-boot. > > In the current RFC I tried to use minimal changes to better see how LWIP code can be embedded into > U-boot. Patches implement ping and wget commands work. Both commands are currently copy pasting and > reusing lwIP examples. Whether we want to add the final application in U-Boot or lwIP is up to > discussion, but the current approach was the easiest one for an RFC. > > Looking for your comments, > Best regards, > Maxim. > > Maxim Uvarov (5): > add lwip-external submodule > lib/lwip: compile-in core files > add doc/README.lwip > add doc/README.lwip.size > lwip: implement wget command from http_client.c example > > .gitignore | 5 + > .gitmodules | 3 + > doc/README.lwip | 90 +++++ > doc/README.lwip.size | 291 +++++++++++++++ > include/net.h | 2 +- > lib/Kconfig | 2 + > lib/Makefile | 2 + > lib/lwip/Kconfig | 12 + > lib/lwip/Makefile | 86 +++++ > lib/lwip/apps/http/lwip-wget.c | 67 ++++ > lib/lwip/apps/http/rmstatic.patch | 47 +++ > lib/lwip/apps/ping/lwip_ping.c | 33 ++ > lib/lwip/apps/ping/lwip_ping.h | 19 + > lib/lwip/apps/ping/ping.h | 0 > lib/lwip/apps/ping/rmstatic.patch | 32 ++ > lib/lwip/cmd-lwip.c | 129 +++++++ > lib/lwip/lwip-external | 1 + > lib/lwip/lwipopts.h | 484 +++++++++++++++++++++++++ > lib/lwip/port/if.c | 256 +++++++++++++ > lib/lwip/port/include/arch/cc.h | 41 +++ > lib/lwip/port/include/arch/sys_arch.h | 78 ++++ > lib/lwip/port/include/arch/u-sockets.h | 26 ++ > lib/lwip/port/include/limits.h | 0 > lib/lwip/port/sys-arch.c | 7 + > net/eth-uclass.c | 4 +- > net/net.c | 14 + > 26 files changed, 1729 insertions(+), 2 deletions(-) > create mode 100644 .gitmodules > create mode 100644 doc/README.lwip > create mode 100644 doc/README.lwip.size > create mode 100644 lib/lwip/Kconfig > create mode 100644 lib/lwip/Makefile > create mode 100644 lib/lwip/apps/http/lwip-wget.c > create mode 100644 lib/lwip/apps/http/rmstatic.patch > create mode 100644 lib/lwip/apps/ping/lwip_ping.c > create mode 100644 lib/lwip/apps/ping/lwip_ping.h > create mode 100644 lib/lwip/apps/ping/ping.h > create mode 100644 lib/lwip/apps/ping/rmstatic.patch > create mode 100644 lib/lwip/cmd-lwip.c > create mode 160000 lib/lwip/lwip-external > create mode 100644 lib/lwip/lwipopts.h > create mode 100644 lib/lwip/port/if.c > create mode 100644 lib/lwip/port/include/arch/cc.h > create mode 100644 lib/lwip/port/include/arch/sys_arch.h > create mode 100644 lib/lwip/port/include/arch/u-sockets.h > create mode 100644 lib/lwip/port/include/limits.h > create mode 100644 lib/lwip/port/sys-arch.c > > -- > 2.30.2 > I don't know much about lwip but I certainly think we should be open to changing the network stack, if it is better. Regards, Simon
On Mon, 8 May 2023 at 17:23, Simon Glass <sjg@chromium.org> wrote: > > Hi Maxim, > > On Fri, 5 May 2023 at 04:50, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > > > Greetings, > > > > This RFC patchset is an attempt to try to use an already existing IP network stack inside U-boot. > > U-Boot recently got basic TCP/IP support, implementing wget, but in order to get a full IP stack > > with new features (e.g ipv6), it would be preferable to use an established embedded ip library, > > instead of rewriting the code from scratch. > > > > For this experiment LWIP network stack was selected: > > https://savannah.nongnu.org/git/?group=lwip > > > > LWIP main features include: > > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE > > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), > > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > > - APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API > > - Extended features: IP forwarding over multiple network interfaces, TCP congestion control, > > RTT estimation and fast recovery/fast retransmit > > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, > > mDNS responder, MQTT client, TFTP server. > > > > This RFC work is a demo to enable lwIP (lightweight IP) which is a widely used open-source > > TCP/IP stack designed for embedded systems for U-boot. That will allow using already > > written network applications for microcontrollers. > > > > lwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. > > Which should be compatible with u-boot. > > > > In the current RFC I tried to use minimal changes to better see how LWIP code can be embedded into > > U-boot. Patches implement ping and wget commands work. Both commands are currently copy pasting and > > reusing lwIP examples. Whether we want to add the final application in U-Boot or lwIP is up to > > discussion, but the current approach was the easiest one for an RFC. > > > > Looking for your comments, > > Best regards, > > Maxim. > > > > Maxim Uvarov (5): > > add lwip-external submodule > > lib/lwip: compile-in core files > > add doc/README.lwip > > add doc/README.lwip.size > > lwip: implement wget command from http_client.c example > > > > .gitignore | 5 + > > .gitmodules | 3 + > > doc/README.lwip | 90 +++++ > > doc/README.lwip.size | 291 +++++++++++++++ > > include/net.h | 2 +- > > lib/Kconfig | 2 + > > lib/Makefile | 2 + > > lib/lwip/Kconfig | 12 + > > lib/lwip/Makefile | 86 +++++ > > lib/lwip/apps/http/lwip-wget.c | 67 ++++ > > lib/lwip/apps/http/rmstatic.patch | 47 +++ > > lib/lwip/apps/ping/lwip_ping.c | 33 ++ > > lib/lwip/apps/ping/lwip_ping.h | 19 + > > lib/lwip/apps/ping/ping.h | 0 > > lib/lwip/apps/ping/rmstatic.patch | 32 ++ > > lib/lwip/cmd-lwip.c | 129 +++++++ > > lib/lwip/lwip-external | 1 + > > lib/lwip/lwipopts.h | 484 +++++++++++++++++++++++++ > > lib/lwip/port/if.c | 256 +++++++++++++ > > lib/lwip/port/include/arch/cc.h | 41 +++ > > lib/lwip/port/include/arch/sys_arch.h | 78 ++++ > > lib/lwip/port/include/arch/u-sockets.h | 26 ++ > > lib/lwip/port/include/limits.h | 0 > > lib/lwip/port/sys-arch.c | 7 + > > net/eth-uclass.c | 4 +- > > net/net.c | 14 + > > 26 files changed, 1729 insertions(+), 2 deletions(-) > > create mode 100644 .gitmodules > > create mode 100644 doc/README.lwip > > create mode 100644 doc/README.lwip.size > > create mode 100644 lib/lwip/Kconfig > > create mode 100644 lib/lwip/Makefile > > create mode 100644 lib/lwip/apps/http/lwip-wget.c > > create mode 100644 lib/lwip/apps/http/rmstatic.patch > > create mode 100644 lib/lwip/apps/ping/lwip_ping.c > > create mode 100644 lib/lwip/apps/ping/lwip_ping.h > > create mode 100644 lib/lwip/apps/ping/ping.h > > create mode 100644 lib/lwip/apps/ping/rmstatic.patch > > create mode 100644 lib/lwip/cmd-lwip.c > > create mode 160000 lib/lwip/lwip-external > > create mode 100644 lib/lwip/lwipopts.h > > create mode 100644 lib/lwip/port/if.c > > create mode 100644 lib/lwip/port/include/arch/cc.h > > create mode 100644 lib/lwip/port/include/arch/sys_arch.h > > create mode 100644 lib/lwip/port/include/arch/u-sockets.h > > create mode 100644 lib/lwip/port/include/limits.h > > create mode 100644 lib/lwip/port/sys-arch.c > > > > -- > > 2.30.2 > > > > I don't know much about lwip but I certainly think we should be open > to changing the network stack, if it is better. > > Regards, > Simon lwip is commonly used for non linux micro controllers which should have a wide community and a bunch of examples for applications. So it's closer to resources which we have inside u-boot. I don't strictly vote for lwip, it can be any IP stack which already exists. But not implement an IP stack inside u-boot. lwip looks reasonable. So if the RFC idea is accepted I can work on real patches. Best regards, Maxim.
On Fri, May 05, 2023 at 10:25:24AM +0000, Maxim Uvarov wrote: > Greetings, > > This RFC patchset is an attempt to try to use an already existing IP network stack inside U-boot. > U-Boot recently got basic TCP/IP support, implementing wget, but in order to get a full IP stack > with new features (e.g ipv6), it would be preferable to use an established embedded ip library, > instead of rewriting the code from scratch. > > For this experiment LWIP network stack was selected: > https://savannah.nongnu.org/git/?group=lwip > > LWIP main features include: > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > - APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API > - Extended features: IP forwarding over multiple network interfaces, TCP congestion control, > RTT estimation and fast recovery/fast retransmit > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, > mDNS responder, MQTT client, TFTP server. > > This RFC work is a demo to enable lwIP (lightweight IP) which is a widely used open-source > TCP/IP stack designed for embedded systems for U-boot. That will allow using already > written network applications for microcontrollers. > > lwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. > Which should be compatible with u-boot. > > In the current RFC I tried to use minimal changes to better see how LWIP code can be embedded into > U-boot. Patches implement ping and wget commands work. Both commands are currently copy pasting and > reusing lwIP examples. Whether we want to add the final application in U-Boot or lwIP is up to > discussion, but the current approach was the easiest one for an RFC. I'm honestly not sure this is the most useful way of doing an RFC. The long term goal would be that we replace our existing net/ with lwIP, yes? So what I'd see as more valuable is what it looks like to limit yourself to either sandbox or some QEMU target, disable the current network stack, and instead use lwIP to support just cmd/net.c so that the scope of the conversion is visible. Then the size comparison you do should be between platform + net + cmd/net.c (and the rest of networking turned off) and platform + lwip + cmd/net.c converted.
On Thu, 11 May 2023 at 09:52, Tom Rini <trini@konsulko.com> wrote: > On Fri, May 05, 2023 at 10:25:24AM +0000, Maxim Uvarov wrote: > > > Greetings, > > > > This RFC patchset is an attempt to try to use an already existing IP > network stack inside U-boot. > > U-Boot recently got basic TCP/IP support, implementing wget, but in > order to get a full IP stack > > with new features (e.g ipv6), it would be preferable to use an > established embedded ip library, > > instead of rewriting the code from scratch. > > > > For this experiment LWIP network stack was selected: > > https://savannah.nongnu.org/git/?group=lwip > > > > LWIP main features include: > > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE > > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA > (Zeroconf), > > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > > - APIs: specialized APIs for enhanced performance, optional > Berkeley-alike socket API > > - Extended features: IP forwarding over multiple network interfaces, TCP > congestion control, > > RTT estimation and fast recovery/fast retransmit > > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, > NetBIOS nameserver, > > mDNS responder, MQTT client, TFTP server. > > > > This RFC work is a demo to enable lwIP (lightweight IP) which is a > widely used open-source > > TCP/IP stack designed for embedded systems for U-boot. That will allow > using already > > written network applications for microcontrollers. > > > > lwIP is licensed under a BSD-style license: > http://lwip.wikia.com/wiki/License. > > Which should be compatible with u-boot. > > > > In the current RFC I tried to use minimal changes to better see how LWIP > code can be embedded into > > U-boot. Patches implement ping and wget commands work. Both commands are > currently copy pasting and > > reusing lwIP examples. Whether we want to add the final application in > U-Boot or lwIP is up to > > discussion, but the current approach was the easiest one for an RFC. > > I'm honestly not sure this is the most useful way of doing an RFC. The > long term goal would be that we replace our existing net/ with lwIP, > yes? So what I'd see as more valuable is what it looks like to limit > yourself to either sandbox or some QEMU target, disable the current > network stack, and instead use lwIP to support just cmd/net.c so that > the scope of the conversion is visible. Then the size comparison you do > should be between platform + net + cmd/net.c (and the rest of networking > turned off) and platform + lwip + cmd/net.c converted. > > -- > Tom > Is there any acceptance criteria for size? If we say that additing lwip will add about 48kb and removing current code will also release some kbs. How size is critical here or it's just numbers good to know? BR, Maxim.
On Mon, May 15, 2023 at 11:25:58AM -0400, Maxim Uvarov wrote: > On Thu, 11 May 2023 at 09:52, Tom Rini <trini@konsulko.com> wrote: > > > On Fri, May 05, 2023 at 10:25:24AM +0000, Maxim Uvarov wrote: > > > > > Greetings, > > > > > > This RFC patchset is an attempt to try to use an already existing IP > > network stack inside U-boot. > > > U-Boot recently got basic TCP/IP support, implementing wget, but in > > order to get a full IP stack > > > with new features (e.g ipv6), it would be preferable to use an > > established embedded ip library, > > > instead of rewriting the code from scratch. > > > > > > For this experiment LWIP network stack was selected: > > > https://savannah.nongnu.org/git/?group=lwip > > > > > > LWIP main features include: > > > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE > > > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA > > (Zeroconf), > > > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > > > - APIs: specialized APIs for enhanced performance, optional > > Berkeley-alike socket API > > > - Extended features: IP forwarding over multiple network interfaces, TCP > > congestion control, > > > RTT estimation and fast recovery/fast retransmit > > > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, > > NetBIOS nameserver, > > > mDNS responder, MQTT client, TFTP server. > > > > > > This RFC work is a demo to enable lwIP (lightweight IP) which is a > > widely used open-source > > > TCP/IP stack designed for embedded systems for U-boot. That will allow > > using already > > > written network applications for microcontrollers. > > > > > > lwIP is licensed under a BSD-style license: > > http://lwip.wikia.com/wiki/License. > > > Which should be compatible with u-boot. > > > > > > In the current RFC I tried to use minimal changes to better see how LWIP > > code can be embedded into > > > U-boot. Patches implement ping and wget commands work. Both commands are > > currently copy pasting and > > > reusing lwIP examples. Whether we want to add the final application in > > U-Boot or lwIP is up to > > > discussion, but the current approach was the easiest one for an RFC. > > > > I'm honestly not sure this is the most useful way of doing an RFC. The > > long term goal would be that we replace our existing net/ with lwIP, > > yes? So what I'd see as more valuable is what it looks like to limit > > yourself to either sandbox or some QEMU target, disable the current > > network stack, and instead use lwIP to support just cmd/net.c so that > > the scope of the conversion is visible. Then the size comparison you do > > should be between platform + net + cmd/net.c (and the rest of networking > > turned off) and platform + lwip + cmd/net.c converted. > > > > -- > > Tom > > > > Is there any acceptance criteria for size? If we say that additing lwip > will add about 48kb and removing current code will also release some kbs. > How size is critical here or it's just numbers good to know? Well, the text portion of a current sandbox build (with LTO off, so adding up sizes is easier to do quickly) net/ is 46kB. But that includes v6 and fastboot and so on. So, it's a matter of discussion. If replacing the network stack but maintaining the same level of functionality causes us to grow by single digit kilobytes, we can maybe justify it due to easier to maintain. If it's smaller, that's great and an argument in favor of it. But if we're growing everything by tens of kilobytes, that's a lot harder to justify but maybe shows we need to work with upstream as perhaps some things need to be more configurable, or otherwise something to investigate.
Hi Tom, Apologies for being late to the party > On Thu, May 11, 2023 at 09:52:04AM -0400, Tom Rini wrote: > On Fri, May 05, 2023 at 10:25:24AM +0000, Maxim Uvarov wrote: > > > Greetings, > > > > This RFC patchset is an attempt to try to use an already existing IP network stack inside U-boot. > > U-Boot recently got basic TCP/IP support, implementing wget, but in order to get a full IP stack > > with new features (e.g ipv6), it would be preferable to use an established embedded ip library, > > instead of rewriting the code from scratch. > > > > For this experiment LWIP network stack was selected: > > https://savannah.nongnu.org/git/?group=lwip > > > > LWIP main features include: > > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE > > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), > > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > > - APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API > > - Extended features: IP forwarding over multiple network interfaces, TCP congestion control, > > RTT estimation and fast recovery/fast retransmit > > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, > > mDNS responder, MQTT client, TFTP server. > > > > This RFC work is a demo to enable lwIP (lightweight IP) which is a widely used open-source > > TCP/IP stack designed for embedded systems for U-boot. That will allow using already > > written network applications for microcontrollers. > > > > lwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. > > Which should be compatible with u-boot. > > > > In the current RFC I tried to use minimal changes to better see how LWIP code can be embedded into > > U-boot. Patches implement ping and wget commands work. Both commands are currently copy pasting and > > reusing lwIP examples. Whether we want to add the final application in U-Boot or lwIP is up to > > discussion, but the current approach was the easiest one for an RFC. > > I'm honestly not sure this is the most useful way of doing an RFC. The > long term goal would be that we replace our existing net/ with lwIP, > yes? So what I'd see as more valuable is what it looks like to limit > yourself to either sandbox or some QEMU target, disable the current > network stack, and instead use lwIP to support just cmd/net.c so that > the scope of the conversion is visible. Then the size comparison you do > should be between platform + net + cmd/net.c (and the rest of networking > turned off) and platform + lwip + cmd/net.c converted. This might be a bit too much imho. How about replacing the TCP stack which is new an under heavy devel as well. If we do that we could replace lwip with the version Maxim proposes and check the difference between U-boot + homegrown TCP + wget U-Boot + LWIP (for tcp only) + new wget That would give us an idea before trying to replace the UDP portion which is way bigger Regards /Ilias > > -- > Tom
On Fri, May 19, 2023 at 04:17:06PM +0300, Ilias Apalodimas wrote: > Hi Tom, > > Apologies for being late to the party > > > On Thu, May 11, 2023 at 09:52:04AM -0400, Tom Rini wrote: > > On Fri, May 05, 2023 at 10:25:24AM +0000, Maxim Uvarov wrote: > > > > > Greetings, > > > > > > This RFC patchset is an attempt to try to use an already existing IP network stack inside U-boot. > > > U-Boot recently got basic TCP/IP support, implementing wget, but in order to get a full IP stack > > > with new features (e.g ipv6), it would be preferable to use an established embedded ip library, > > > instead of rewriting the code from scratch. > > > > > > For this experiment LWIP network stack was selected: > > > https://savannah.nongnu.org/git/?group=lwip > > > > > > LWIP main features include: > > > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE > > > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), > > > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > > > - APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API > > > - Extended features: IP forwarding over multiple network interfaces, TCP congestion control, > > > RTT estimation and fast recovery/fast retransmit > > > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, > > > mDNS responder, MQTT client, TFTP server. > > > > > > This RFC work is a demo to enable lwIP (lightweight IP) which is a widely used open-source > > > TCP/IP stack designed for embedded systems for U-boot. That will allow using already > > > written network applications for microcontrollers. > > > > > > lwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. > > > Which should be compatible with u-boot. > > > > > > In the current RFC I tried to use minimal changes to better see how LWIP code can be embedded into > > > U-boot. Patches implement ping and wget commands work. Both commands are currently copy pasting and > > > reusing lwIP examples. Whether we want to add the final application in U-Boot or lwIP is up to > > > discussion, but the current approach was the easiest one for an RFC. > > > > I'm honestly not sure this is the most useful way of doing an RFC. The > > long term goal would be that we replace our existing net/ with lwIP, > > yes? So what I'd see as more valuable is what it looks like to limit > > yourself to either sandbox or some QEMU target, disable the current > > network stack, and instead use lwIP to support just cmd/net.c so that > > the scope of the conversion is visible. Then the size comparison you do > > should be between platform + net + cmd/net.c (and the rest of networking > > turned off) and platform + lwip + cmd/net.c converted. > > This might be a bit too much imho. How about replacing the TCP stack which > is new an under heavy devel as well. If we do that we could replace lwip > with the version Maxim proposes and check the difference between > U-boot + homegrown TCP + wget > U-Boot + LWIP (for tcp only) + new wget > > That would give us an idea before trying to replace the UDP portion which > is way bigger I guess we can try that as a starting point and see what things look like. My gut feeling however is that's not going to look like a win.
My measurements for binary after LTO looks like: U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % 870728 | 915000 | 912560 | 41832 | 4.8 BR, Maxim. On Fri, 19 May 2023 at 09:52, Tom Rini <trini@konsulko.com> wrote: > On Fri, May 19, 2023 at 04:17:06PM +0300, Ilias Apalodimas wrote: > > Hi Tom, > > > > Apologies for being late to the party > > > > > On Thu, May 11, 2023 at 09:52:04AM -0400, Tom Rini wrote: > > > On Fri, May 05, 2023 at 10:25:24AM +0000, Maxim Uvarov wrote: > > > > > > > Greetings, > > > > > > > > This RFC patchset is an attempt to try to use an already existing IP > network stack inside U-boot. > > > > U-Boot recently got basic TCP/IP support, implementing wget, but in > order to get a full IP stack > > > > with new features (e.g ipv6), it would be preferable to use an > established embedded ip library, > > > > instead of rewriting the code from scratch. > > > > > > > > For this experiment LWIP network stack was selected: > > > > https://savannah.nongnu.org/git/?group=lwip > > > > > > > > LWIP main features include: > > > > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, > PPPoE > > > > - DHCP client, DNS client (incl. mDNS hostname resolver), > AutoIP/APIPA (Zeroconf), > > > > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) > > > > - APIs: specialized APIs for enhanced performance, optional > Berkeley-alike socket API > > > > - Extended features: IP forwarding over multiple network interfaces, > TCP congestion control, > > > > RTT estimation and fast recovery/fast retransmit > > > > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, > ping, NetBIOS nameserver, > > > > mDNS responder, MQTT client, TFTP server. > > > > > > > > This RFC work is a demo to enable lwIP (lightweight IP) which is a > widely used open-source > > > > TCP/IP stack designed for embedded systems for U-boot. That will > allow using already > > > > written network applications for microcontrollers. > > > > > > > > lwIP is licensed under a BSD-style license: > http://lwip.wikia.com/wiki/License. > > > > Which should be compatible with u-boot. > > > > > > > > In the current RFC I tried to use minimal changes to better see how > LWIP code can be embedded into > > > > U-boot. Patches implement ping and wget commands work. Both commands > are currently copy pasting and > > > > reusing lwIP examples. Whether we want to add the final application > in U-Boot or lwIP is up to > > > > discussion, but the current approach was the easiest one for an RFC. > > > > > > I'm honestly not sure this is the most useful way of doing an RFC. The > > > long term goal would be that we replace our existing net/ with lwIP, > > > yes? So what I'd see as more valuable is what it looks like to limit > > > yourself to either sandbox or some QEMU target, disable the current > > > network stack, and instead use lwIP to support just cmd/net.c so that > > > the scope of the conversion is visible. Then the size comparison you > do > > > should be between platform + net + cmd/net.c (and the rest of > networking > > > turned off) and platform + lwip + cmd/net.c converted. > > > > This might be a bit too much imho. How about replacing the TCP stack > which > > is new an under heavy devel as well. If we do that we could replace lwip > > with the version Maxim proposes and check the difference between > > U-boot + homegrown TCP + wget > > U-Boot + LWIP (for tcp only) + new wget > > > > That would give us an idea before trying to replace the UDP portion which > > is way bigger > > I guess we can try that as a starting point and see what things look > like. My gut feeling however is that's not going to look like a win. > > -- > Tom >
Hi Maxim On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > My measurements for binary after LTO looks like: > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > 870728 | 915000 | 912560 | 41832 | 4.8 I think you'll need to analyze that a bit more. First of all I don't think the '+ping' tab is useful. What is is trying to achieve? - How was LWIP compiled? - Was ipv6 supported? - Can we strip it down even further? In general please give as much information as you can with what we gain in functionality from LWIP with those extra bytes of code. Thanks /Ilias > BR, > Maxim. > > On Fri, 19 May 2023 at 09:52, Tom Rini <trini@konsulko.com> wrote: >> >> On Fri, May 19, 2023 at 04:17:06PM +0300, Ilias Apalodimas wrote: >> > Hi Tom, >> > >> > Apologies for being late to the party >> > >> > > On Thu, May 11, 2023 at 09:52:04AM -0400, Tom Rini wrote: >> > > On Fri, May 05, 2023 at 10:25:24AM +0000, Maxim Uvarov wrote: >> > > >> > > > Greetings, >> > > > >> > > > This RFC patchset is an attempt to try to use an already existing IP network stack inside U-boot. >> > > > U-Boot recently got basic TCP/IP support, implementing wget, but in order to get a full IP stack >> > > > with new features (e.g ipv6), it would be preferable to use an established embedded ip library, >> > > > instead of rewriting the code from scratch. >> > > > >> > > > For this experiment LWIP network stack was selected: >> > > > https://savannah.nongnu.org/git/?group=lwip >> > > > >> > > > LWIP main features include: >> > > > - Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE >> > > > - DHCP client, DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), >> > > > SNMP agent (v1, v2c, v3, private MIB support & MIB compiler) >> > > > - APIs: specialized APIs for enhanced performance, optional Berkeley-alike socket API >> > > > - Extended features: IP forwarding over multiple network interfaces, TCP congestion control, >> > > > RTT estimation and fast recovery/fast retransmit >> > > > - Addon applications: HTTP(S) server, SNTP client, SMTP(S) client, ping, NetBIOS nameserver, >> > > > mDNS responder, MQTT client, TFTP server. >> > > > >> > > > This RFC work is a demo to enable lwIP (lightweight IP) which is a widely used open-source >> > > > TCP/IP stack designed for embedded systems for U-boot. That will allow using already >> > > > written network applications for microcontrollers. >> > > > >> > > > lwIP is licensed under a BSD-style license: http://lwip.wikia.com/wiki/License. >> > > > Which should be compatible with u-boot. >> > > > >> > > > In the current RFC I tried to use minimal changes to better see how LWIP code can be embedded into >> > > > U-boot. Patches implement ping and wget commands work. Both commands are currently copy pasting and >> > > > reusing lwIP examples. Whether we want to add the final application in U-Boot or lwIP is up to >> > > > discussion, but the current approach was the easiest one for an RFC. >> > > >> > > I'm honestly not sure this is the most useful way of doing an RFC. The >> > > long term goal would be that we replace our existing net/ with lwIP, >> > > yes? So what I'd see as more valuable is what it looks like to limit >> > > yourself to either sandbox or some QEMU target, disable the current >> > > network stack, and instead use lwIP to support just cmd/net.c so that >> > > the scope of the conversion is visible. Then the size comparison you do >> > > should be between platform + net + cmd/net.c (and the rest of networking >> > > turned off) and platform + lwip + cmd/net.c converted. >> > >> > This might be a bit too much imho. How about replacing the TCP stack which >> > is new an under heavy devel as well. If we do that we could replace lwip >> > with the version Maxim proposes and check the difference between >> > U-boot + homegrown TCP + wget >> > U-Boot + LWIP (for tcp only) + new wget >> > >> > That would give us an idea before trying to replace the UDP portion which >> > is way bigger >> >> I guess we can try that as a starting point and see what things look >> like. My gut feeling however is that's not going to look like a win. >> >> -- >> Tom
On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > Hi Maxim > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > > > My measurements for binary after LTO looks like: > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > > 870728 | 915000 | 912560 | 41832 | 4.8 > > > I think you'll need to analyze that a bit more. First of all I don't > think the '+ping' tab is useful. What is is trying to achieve? > - How was LWIP compiled? > - Was ipv6 supported? > - Can we strip it down even further? > > In general please give as much information as you can with what we > gain in functionality from LWIP with those extra bytes of code. And please make sure to disable the previous support, my guess fro that much growth is that you didn't.
On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > > Hi Maxim > > > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> > wrote: > > > > > > My measurements for binary after LTO looks like: > > > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > > > 870728 | 915000 | 912560 | > 41832 | 4.8 > > > > > > I think you'll need to analyze that a bit more. First of all I don't > > think the '+ping' tab is useful. What is is trying to achieve? > To show the difference of extra bytes if we add a ping app on top. > > - How was LWIP compiled? > It has a really huge configuration. I tried to turn off everything off everything what can impact on size but still make http app work: #define LWIP_HAVE_LOOPIF 0 #define LWIP_NETCONN 0 #define LWIP_SOCKET 0 #define SO_REUSE 0 #define LWIP_STATS 0 #define PPP_SUPPORT 0 Disabling loopback: #define LWIP_NETIF_LOOPBACK 0 can lower to 912288 bytes. And it's the same compilation option (optimization for size) as the main u-boot. I will do more experiments, but I think the goal is not to turn off everything. > > - Was ipv6 supported? > No. I.e. when I sent results it was enabled on the compilation stage but not used. I just checked that size remains the same if IPv6 is not even compiled. > > - Can we strip it down even further? > > > There is always room for optimization. I think I tried to turn off everything that is configurable with defines. I can play with disable IP reassembly and things like that or figure out which functions have more size and if it's possible to exclude them. > > In general please give as much information as you can with what we > > gain in functionality from LWIP with those extra bytes of code. > > The main idea is to reuse a maintainable IP stack outside of U-boot. LWIP can give a nice separation between IP stack code and network application code. I.e. application should not take care about any TCP details (SYN, ACK, retransmission, reassembly etc) and should open connection and use functions similar to recv() and send() to transfer data. Data means application data, no network packets. And LWIP allows us to do that. Because LWIP has an API similar to sockets, it has to be very easy to port a linux application to LWIP. Then you can test it with a tap device. Then copy sources to U-boot, add a small integration layer (cmd command to call), compile and use. So my suggestion was: - do not maintain new network stack code in the current U-boot. Use lwip sources as an external project. All bugs related to network stack go to lwip project first, then sync with U-boot. - maintain network apps code* or -- inside U-boot. Write our own code for application and maintain it inside U-boot. -- inside LWIP. Add examples to LWIP which are suitable for both U-boot and LWIP. * Let's define a U-boot network application as a cmd command. It might be ping, wget (http or https download), telnet, arp dns etc.. Let's consider the real use case, like HTTPS download client. We need to enable TLS connection, validate certificates, then do http download. Looking at the current code of wget command it's quite difficult to implement this due to the application having some protol level things. On the other side we can find embedTLS examples to do https download on sockets. If LWIP socket API is ported then the only thing you need to do is change socket() -> lwip_socket(), recv()->lwip_recv(), send()->lwip_send() and etc, even function names are similar. If LWIP socket API is not supported, then use callback API for recv() and send(), which are also easy. So yes we add extra bytes, but that will allow us to write more complex apps, use standard debug tools, use applications with very minimal integration changes, use help from the LWIP community to fix protocol bugs, etc.. Bunch of things already implemented there: - ipv6 - dhcp - snmp - igmp - dns - tcp and udp and raw. - loopback - netconn - socket - stats - ppp (I just followed configurable defines). And please make sure to disable the previous support, my guess fro that > much growth is that you didn't. > # CONFIG_PROT_TCP is not set # CONFIG_PROT_UDP is not set # CONFIG_UDP_CHECKSUM is not set # CONFIG_UDP_FUNCTION_FASTBOOT is not set # CONFIG_CMD_WGET is not set BR, Maxim. > > -- > Tom >
On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > > > On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > > > Hi Maxim > > > > > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> > > wrote: > > > > > > > > My measurements for binary after LTO looks like: > > > > > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > > > > 870728 | 915000 | 912560 | > > 41832 | 4.8 > > > > > > > > > I think you'll need to analyze that a bit more. First of all I don't > > > think the '+ping' tab is useful. What is is trying to achieve? > > > > To show the difference of extra bytes if we add a ping app on top. > > > > > - How was LWIP compiled? > > > > It has a really huge configuration. I tried to turn off everything off > everything what can impact on size but still make http app work: > #define LWIP_HAVE_LOOPIF 0 > #define LWIP_NETCONN 0 > #define LWIP_SOCKET 0 > #define SO_REUSE 0 > #define LWIP_STATS 0 > #define PPP_SUPPORT 0 > > Disabling loopback: > #define LWIP_NETIF_LOOPBACK 0 > can lower to 912288 bytes. > > And it's the same compilation option (optimization for size) as the main > u-boot. I will do more experiments, but I think the goal is not to turn off > everything. > > > > > - Was ipv6 supported? > > > > No. I.e. when I sent results it was enabled on the compilation stage but > not used. I just checked that size remains the same if IPv6 is not even > compiled. > > > > > - Can we strip it down even further? > > > > > > > There is always room for optimization. I think I tried to turn off > everything that is configurable with defines. I can play with disable IP > reassembly and things like that or figure out which functions have more > size and if it's possible to exclude them. > > > > > In general please give as much information as you can with what we > > > gain in functionality from LWIP with those extra bytes of code. > > > > > The main idea is to reuse a maintainable IP stack outside of U-boot. LWIP > can give a nice separation between IP stack code and network application > code. I.e. application should not take care about any TCP details (SYN, > ACK, retransmission, reassembly etc) and should open connection and use > functions similar to recv() and send() to transfer data. Data means > application data, no network packets. And LWIP allows > us to do that. > Because LWIP has an API similar to sockets, it has to be very easy to port > a linux application to LWIP. Then you can test it with a tap device. Then > copy sources to U-boot, add a small integration layer (cmd command to > call), compile and use. > > So my suggestion was: > - do not maintain new network stack code in the current U-boot. Use lwip > sources as an external project. All bugs related to network stack go to > lwip project first, then sync with U-boot. > - maintain network apps code* or > -- inside U-boot. Write our own code for application and maintain it > inside U-boot. > -- inside LWIP. Add examples to LWIP which are suitable for both U-boot > and LWIP. > > * Let's define a U-boot network application as a cmd command. It might be > ping, wget (http or https download), telnet, arp dns etc.. > > Let's consider the real use case, like HTTPS download client. We need to > enable TLS connection, validate certificates, then do http download. > Looking at the current code of wget command it's quite difficult to > implement this due to the application having some protol level things. On > the other side we can find embedTLS examples to do https download on > sockets. If LWIP socket API is ported then the only thing you need to do is > change socket() -> lwip_socket(), recv()->lwip_recv(), send()->lwip_send() > and etc, even function names are similar. If LWIP socket API is not > supported, then use callback API for recv() and send(), which are also > easy. > > So yes we add extra bytes, but that will allow us to write more complex > apps, use standard debug tools, use applications with very minimal > integration changes, use help from the LWIP community to fix protocol bugs, > etc.. > Bunch of things already implemented there: > - ipv6 > - dhcp > - snmp > - igmp > - dns > - tcp and udp and raw. > - loopback > - netconn > - socket > - stats > - ppp > (I just followed configurable defines). > > > And please make sure to disable the previous support, my guess fro that > > much growth is that you didn't. > > > > # CONFIG_PROT_TCP is not set > # CONFIG_PROT_UDP is not set > # CONFIG_UDP_CHECKSUM is not set > # CONFIG_UDP_FUNCTION_FASTBOOT is not set > # CONFIG_CMD_WGET is not set I think you need to step back and figure out a better way to measure the size change and growth. I am not interested in a path that long term means two networking stacks in U-Boot. I am not interested in massively growing the overall binary size for every platform. Given how much larger just TCP support is, that's strongly implying a huge growth for the older use cases too. But I also suspect given the overall reputation that LWIP enjoys, there's something amiss here.
On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > > On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > > > > > On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > > > > Hi Maxim > > > > > > > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> > > > wrote: > > > > > > > > > > My measurements for binary after LTO looks like: > > > > > > > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > > > > > 870728 | 915000 | 912560 | > > > 41832 | 4.8 > > > > > > > > > > > > I think you'll need to analyze that a bit more. First of all I don't > > > > think the '+ping' tab is useful. What is is trying to achieve? > > > > > > > To show the difference of extra bytes if we add a ping app on top. > > > > > > > > - How was LWIP compiled? > > > > > > > It has a really huge configuration. I tried to turn off everything off > > everything what can impact on size but still make http app work: > > #define LWIP_HAVE_LOOPIF 0 > > #define LWIP_NETCONN 0 > > #define LWIP_SOCKET 0 > > #define SO_REUSE 0 > > #define LWIP_STATS 0 > > #define PPP_SUPPORT 0 > > > > Disabling loopback: > > #define LWIP_NETIF_LOOPBACK 0 > > can lower to 912288 bytes. > > > > And it's the same compilation option (optimization for size) as the main > > u-boot. I will do more experiments, but I think the goal is not to turn > off > > everything. > > > > > > > > - Was ipv6 supported? > > > > > > > No. I.e. when I sent results it was enabled on the compilation stage but > > not used. I just checked that size remains the same if IPv6 is not even > > compiled. > > > > > > > > - Can we strip it down even further? > > > > > > > > > > > There is always room for optimization. I think I tried to turn off > > everything that is configurable with defines. I can play with disable IP > > reassembly and things like that or figure out which functions have more > > size and if it's possible to exclude them. > > > > > > > > In general please give as much information as you can with what we > > > > gain in functionality from LWIP with those extra bytes of code. > > > > > > > > The main idea is to reuse a maintainable IP stack outside of U-boot. > LWIP > > can give a nice separation between IP stack code and network application > > code. I.e. application should not take care about any TCP details (SYN, > > ACK, retransmission, reassembly etc) and should open connection and use > > functions similar to recv() and send() to transfer data. Data means > > application data, no network packets. And LWIP allows > > us to do that. > > Because LWIP has an API similar to sockets, it has to be very easy to > port > > a linux application to LWIP. Then you can test it with a tap device. Then > > copy sources to U-boot, add a small integration layer (cmd command to > > call), compile and use. > > > > So my suggestion was: > > - do not maintain new network stack code in the current U-boot. Use lwip > > sources as an external project. All bugs related to network stack go to > > lwip project first, then sync with U-boot. > > - maintain network apps code* or > > -- inside U-boot. Write our own code for application and maintain it > > inside U-boot. > > -- inside LWIP. Add examples to LWIP which are suitable for both > U-boot > > and LWIP. > > > > * Let's define a U-boot network application as a cmd command. It might be > > ping, wget (http or https download), telnet, arp dns etc.. > > > > Let's consider the real use case, like HTTPS download client. We need to > > enable TLS connection, validate certificates, then do http download. > > Looking at the current code of wget command it's quite difficult to > > implement this due to the application having some protol level things. On > > the other side we can find embedTLS examples to do https download on > > sockets. If LWIP socket API is ported then the only thing you need to do > is > > change socket() -> lwip_socket(), recv()->lwip_recv(), > send()->lwip_send() > > and etc, even function names are similar. If LWIP socket API is not > > supported, then use callback API for recv() and send(), which are also > > easy. > > > > So yes we add extra bytes, but that will allow us to write more complex > > apps, use standard debug tools, use applications with very minimal > > integration changes, use help from the LWIP community to fix protocol > bugs, > > etc.. > > Bunch of things already implemented there: > > - ipv6 > > - dhcp > > - snmp > > - igmp > > - dns > > - tcp and udp and raw. > > - loopback > > - netconn > > - socket > > - stats > > - ppp > > (I just followed configurable defines). > > > > > > And please make sure to disable the previous support, my guess fro that > > > much growth is that you didn't. > > > > > > > # CONFIG_PROT_TCP is not set > > # CONFIG_PROT_UDP is not set > > # CONFIG_UDP_CHECKSUM is not set > > # CONFIG_UDP_FUNCTION_FASTBOOT is not set > > # CONFIG_CMD_WGET is not set > > I think you need to step back and figure out a better way to measure the > size change and growth. > > I am not interested in a path that long term means two networking stacks > in U-Boot. > > I am not interested in massively growing the overall binary size for > every platform. Given how much larger just TCP support is, that's > strongly implying a huge growth for the older use cases too. > > But I also suspect given the overall reputation that LWIP enjoys, > there's something amiss here. > > -- > Tom > +cc lwip-devel@ mailing list, maybe they have something to add. My measurements say that the current U-boot IP stack + wget command adds an additional 9 Kbytes. The minimal configuration of LWIP with wget command is 30 Kbytes. (compiled out all asserts, debugs, not used protocols etc.). And the most bigger functions are tcp in/out itself: * These functions are generally called in the order (ip_input() ->) * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). +tcp_input - 4364 +4364 https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n118 +tcp_receive - 3444 +3444 https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n1154 +tcp_write - 2192 +2192 https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n393 +ip4_reass - 2096 +2096 https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/ipv4/ip4_frag.c#n503 +tcp_output - 1616 +1616 https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n1241 If we transfer current net commands to lwip then we can decrease the size, because of functions reuse. And if we turn on all features in lwip it will be about 50 Kbytes. BR, Maxim.
Hi Maxim, Tom, On 24.05.2023 16:05, Maxim Uvarov wrote: > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > >> On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: >>> On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: >>> >>>> On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: >>>>> Hi Maxim >>>>> >>>>> On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> >>>> wrote: >>>>>> >>>>>> My measurements for binary after LTO looks like: >>>>>> >>>>>> U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % >>>>>> 870728 | 915000 | 912560 | >>>> 41832 | 4.8 >>>>> >>>>> >>>>> I think you'll need to analyze that a bit more. First of all I don't >>>>> think the '+ping' tab is useful. What is is trying to achieve? >>>> >>> >>> To show the difference of extra bytes if we add a ping app on top. >>> >>> >>>>> - How was LWIP compiled? >>>> >>> >>> It has a really huge configuration. I tried to turn off everything off >>> everything what can impact on size but still make http app work: >>> #define LWIP_HAVE_LOOPIF 0 >>> #define LWIP_NETCONN 0 >>> #define LWIP_SOCKET 0 >>> #define SO_REUSE 0 >>> #define LWIP_STATS 0 >>> #define PPP_SUPPORT 0 >>> >>> Disabling loopback: >>> #define LWIP_NETIF_LOOPBACK 0 >>> can lower to 912288 bytes. >>> >>> And it's the same compilation option (optimization for size) as the main >>> u-boot. I will do more experiments, but I think the goal is not to turn >> off >>> everything. >>> >>> >>>>> - Was ipv6 supported? >>>> >>> >>> No. I.e. when I sent results it was enabled on the compilation stage but >>> not used. I just checked that size remains the same if IPv6 is not even >>> compiled. >>> >>> >>>>> - Can we strip it down even further? >>>>> >>>> >>> >>> There is always room for optimization. I think I tried to turn off >>> everything that is configurable with defines. I can play with disable IP >>> reassembly and things like that or figure out which functions have more >>> size and if it's possible to exclude them. >>> >>> >>>>> In general please give as much information as you can with what we >>>>> gain in functionality from LWIP with those extra bytes of code. >>>> >>>> >>> The main idea is to reuse a maintainable IP stack outside of U-boot. >> LWIP >>> can give a nice separation between IP stack code and network application >>> code. I.e. application should not take care about any TCP details (SYN, >>> ACK, retransmission, reassembly etc) and should open connection and use >>> functions similar to recv() and send() to transfer data. Data means >>> application data, no network packets. And LWIP allows >>> us to do that. >>> Because LWIP has an API similar to sockets, it has to be very easy to >> port >>> a linux application to LWIP. Then you can test it with a tap device. Then >>> copy sources to U-boot, add a small integration layer (cmd command to >>> call), compile and use. >>> >>> So my suggestion was: >>> - do not maintain new network stack code in the current U-boot. Use lwip >>> sources as an external project. All bugs related to network stack go to >>> lwip project first, then sync with U-boot. >>> - maintain network apps code* or >>> -- inside U-boot. Write our own code for application and maintain it >>> inside U-boot. >>> -- inside LWIP. Add examples to LWIP which are suitable for both >> U-boot >>> and LWIP. >>> >>> * Let's define a U-boot network application as a cmd command. It might be >>> ping, wget (http or https download), telnet, arp dns etc.. >>> >>> Let's consider the real use case, like HTTPS download client. We need to >>> enable TLS connection, validate certificates, then do http download. >>> Looking at the current code of wget command it's quite difficult to >>> implement this due to the application having some protol level things. On >>> the other side we can find embedTLS examples to do https download on >>> sockets. If LWIP socket API is ported then the only thing you need to do >> is >>> change socket() -> lwip_socket(), recv()->lwip_recv(), >> send()->lwip_send() >>> and etc, even function names are similar. If LWIP socket API is not >>> supported, then use callback API for recv() and send(), which are also >>> easy. >>> >>> So yes we add extra bytes, but that will allow us to write more complex >>> apps, use standard debug tools, use applications with very minimal >>> integration changes, use help from the LWIP community to fix protocol >> bugs, >>> etc.. >>> Bunch of things already implemented there: >>> - ipv6 >>> - dhcp >>> - snmp >>> - igmp >>> - dns >>> - tcp and udp and raw. >>> - loopback >>> - netconn >>> - socket >>> - stats >>> - ppp >>> (I just followed configurable defines). >>> >>> >>> And please make sure to disable the previous support, my guess fro that >>>> much growth is that you didn't. >>>> >>> >>> # CONFIG_PROT_TCP is not set >>> # CONFIG_PROT_UDP is not set >>> # CONFIG_UDP_CHECKSUM is not set >>> # CONFIG_UDP_FUNCTION_FASTBOOT is not set >>> # CONFIG_CMD_WGET is not set >> >> I think you need to step back and figure out a better way to measure the >> size change and growth. >> >> I am not interested in a path that long term means two networking stacks >> in U-Boot. >> >> I am not interested in massively growing the overall binary size for >> every platform. Given how much larger just TCP support is, that's >> strongly implying a huge growth for the older use cases too. >> >> But I also suspect given the overall reputation that LWIP enjoys, >> there's something amiss here. >> >> -- >> Tom >> > > +cc lwip-devel@ mailing list, maybe they have something to add. I do think using lwIP instead of "inventing yet another IP stack" is a good idea! However, in terms of code size, lwIP will lose against what's in U-Boot at present. And this is only natural, as lwIP is a "full-size" stack supporting multiple concurrently running applications while the current IP stack in U-Boot is rather "crippled" down to just what the implementor needed at the time of writing. One example of this is that (if I remember correctly), U-Boot only has one single network packet buffer, while lwIP has support for multiple buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track of that development in U-Boot about 3 years ago), we're comparing "we have implemented everything we need so that it just kind of works" to "we can easily add a HTTPS client to download something over the internet just by enabling more compile options". Also, when comparing lwIP to U-Boot TCP code size, keep in mind that U-Boot TCP (at least that of some years ago) is far from complete when compared to lwIP! lwIP is meant to be highly configurable and we're always open to add yet more options to leave out more code when it's not needed. However, I think there are some design decisions that will make lwIP larger than the current IP stack in U-Boot. To me, that's a natural result of having a "generic code" approach vs "developed to our needs". However, while DHCP + BOOTP and even a simple network console was rather easy to implement, I would not recommend implementing your own HTTPS download but rather using the existing lwIP + apps for that. In the end, I cannot take the decision from you. In my opinion, lwIP would be the better decision in terms of future work load and compatibility, but in the short run, it *will* lead to bigger binaries at least in some setups. And I do know from my past that it sometimes has been a pain to try and stuff a new U-Boot release into the existing space of flash or RAM, so that's not an easy decision. If you do take the lwIP approach however, let us know if we can help! Regards, Simon > > My measurements say that the current U-boot IP stack + wget command adds an > additional 9 Kbytes. > The minimal configuration of LWIP with wget command is 30 Kbytes. > (compiled out all asserts, debugs, not used protocols etc.). > > And the most bigger functions are tcp in/out itself: > * These functions are generally called in the order (ip_input() ->) > * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). > > +tcp_input - 4364 +4364 > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n118 > +tcp_receive - 3444 +3444 > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n1154 > +tcp_write - 2192 +2192 > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n393 > +ip4_reass - 2096 +2096 > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/ipv4/ip4_frag.c#n503 > +tcp_output - 1616 +1616 > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n1241 > > If we transfer current net commands to lwip then we can decrease the size, > because of functions reuse. > And if we turn on all features in lwip it will be about 50 Kbytes. > > BR, > Maxim. > > > _______________________________________________ > lwip-devel mailing list > lwip-devel@nongnu.org > https://lists.nongnu.org/mailman/listinfo/lwip-devel
Greetings, I implemented the tftp client (that was quick due to lwip has example app for tftp), and did some more measurements. I uploaded patches here if somebody want to do his own measurements: https://github.com/muvarov/uboot-lwip measure 1: 976K - total (total means lwip with all 3 commands ping, tftp, wget) 971K - total - tftp (total, but disable/minus tftp) 965K - total - tftp - wget (disable tftp and wget) 963K - total - tftp - wget - ping (disable tftp, wget, ping) 931K - no lwip result 1: lwip tftp (+ udp protocol) protocol 976-971k = 5kb result 2: lwip ping command 965- 963 = 2kb result 3: lwip wget command 971- 965 = 6kb result 4: lwip core stack with apps 976 - 931 = 45kb measure 2: 890K - no CONFIG_NET_CMD 930K - + lwip tftp only 937K - + full lwip (ping wget tftp) result 1: 937-890=47kb ( lwip + all 3 commands) result 2: 937-930=7kb (ping and lwip command) measure 3: 904K - no lwip, CMD_NET_TFTP=y 900K - no lwip, CMD_NET_TFTP=n result 1: original u-boot tftp command 904-900=4kb 890K - no lwip, CMD_NET=n result 2: 900-890=10k original u-boot net/IP stack. My findings for all that measurements and lwip configuration: 1. The original u-boot net stack (packet process and up layers) is 10k vs lwip 40k (the very minimal settings were 30k). 2. Network applications size is about the same 4kb for tftp original command 5kb for lwip. 3. It's quite easy to reuse LWIP examples to implement the same functionality for the U-boot. 4. I still think that there are other criterias which might have more priority than size (bug free code, code reuse, development speed, compatible API to posix and etc). BR, Maxim. On Thu, 25 May 2023 at 02:18, Simon Goldschmidt <goldsimon@gmx.de> wrote: > Hi Maxim, Tom, > > On 24.05.2023 16:05, Maxim Uvarov wrote: > > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > > > >> On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > >>> On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > >>> > >>>> On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > >>>>> Hi Maxim > >>>>> > >>>>> On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> > >>>> wrote: > >>>>>> > >>>>>> My measurements for binary after LTO looks like: > >>>>>> > >>>>>> U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > >>>>>> 870728 | 915000 | 912560 | > >>>> 41832 | 4.8 > >>>>> > >>>>> > >>>>> I think you'll need to analyze that a bit more. First of all I don't > >>>>> think the '+ping' tab is useful. What is is trying to achieve? > >>>> > >>> > >>> To show the difference of extra bytes if we add a ping app on top. > >>> > >>> > >>>>> - How was LWIP compiled? > >>>> > >>> > >>> It has a really huge configuration. I tried to turn off everything off > >>> everything what can impact on size but still make http app work: > >>> #define LWIP_HAVE_LOOPIF 0 > >>> #define LWIP_NETCONN 0 > >>> #define LWIP_SOCKET 0 > >>> #define SO_REUSE 0 > >>> #define LWIP_STATS 0 > >>> #define PPP_SUPPORT 0 > >>> > >>> Disabling loopback: > >>> #define LWIP_NETIF_LOOPBACK 0 > >>> can lower to 912288 bytes. > >>> > >>> And it's the same compilation option (optimization for size) as the > main > >>> u-boot. I will do more experiments, but I think the goal is not to turn > >> off > >>> everything. > >>> > >>> > >>>>> - Was ipv6 supported? > >>>> > >>> > >>> No. I.e. when I sent results it was enabled on the compilation stage > but > >>> not used. I just checked that size remains the same if IPv6 is not even > >>> compiled. > >>> > >>> > >>>>> - Can we strip it down even further? > >>>>> > >>>> > >>> > >>> There is always room for optimization. I think I tried to turn off > >>> everything that is configurable with defines. I can play with disable > IP > >>> reassembly and things like that or figure out which functions have more > >>> size and if it's possible to exclude them. > >>> > >>> > >>>>> In general please give as much information as you can with what we > >>>>> gain in functionality from LWIP with those extra bytes of code. > >>>> > >>>> > >>> The main idea is to reuse a maintainable IP stack outside of U-boot. > >> LWIP > >>> can give a nice separation between IP stack code and network > application > >>> code. I.e. application should not take care about any TCP details > (SYN, > >>> ACK, retransmission, reassembly etc) and should open connection and use > >>> functions similar to recv() and send() to transfer data. Data means > >>> application data, no network packets. And LWIP allows > >>> us to do that. > >>> Because LWIP has an API similar to sockets, it has to be very easy to > >> port > >>> a linux application to LWIP. Then you can test it with a tap device. > Then > >>> copy sources to U-boot, add a small integration layer (cmd command to > >>> call), compile and use. > >>> > >>> So my suggestion was: > >>> - do not maintain new network stack code in the current U-boot. Use > lwip > >>> sources as an external project. All bugs related to network stack go > to > >>> lwip project first, then sync with U-boot. > >>> - maintain network apps code* or > >>> -- inside U-boot. Write our own code for application and maintain it > >>> inside U-boot. > >>> -- inside LWIP. Add examples to LWIP which are suitable for both > >> U-boot > >>> and LWIP. > >>> > >>> * Let's define a U-boot network application as a cmd command. It might > be > >>> ping, wget (http or https download), telnet, arp dns etc.. > >>> > >>> Let's consider the real use case, like HTTPS download client. We need > to > >>> enable TLS connection, validate certificates, then do http download. > >>> Looking at the current code of wget command it's quite difficult to > >>> implement this due to the application having some protol level things. > On > >>> the other side we can find embedTLS examples to do https download on > >>> sockets. If LWIP socket API is ported then the only thing you need to > do > >> is > >>> change socket() -> lwip_socket(), recv()->lwip_recv(), > >> send()->lwip_send() > >>> and etc, even function names are similar. If LWIP socket API is not > >>> supported, then use callback API for recv() and send(), which are also > >>> easy. > >>> > >>> So yes we add extra bytes, but that will allow us to write more complex > >>> apps, use standard debug tools, use applications with very minimal > >>> integration changes, use help from the LWIP community to fix protocol > >> bugs, > >>> etc.. > >>> Bunch of things already implemented there: > >>> - ipv6 > >>> - dhcp > >>> - snmp > >>> - igmp > >>> - dns > >>> - tcp and udp and raw. > >>> - loopback > >>> - netconn > >>> - socket > >>> - stats > >>> - ppp > >>> (I just followed configurable defines). > >>> > >>> > >>> And please make sure to disable the previous support, my guess fro that > >>>> much growth is that you didn't. > >>>> > >>> > >>> # CONFIG_PROT_TCP is not set > >>> # CONFIG_PROT_UDP is not set > >>> # CONFIG_UDP_CHECKSUM is not set > >>> # CONFIG_UDP_FUNCTION_FASTBOOT is not set > >>> # CONFIG_CMD_WGET is not set > >> > >> I think you need to step back and figure out a better way to measure the > >> size change and growth. > >> > >> I am not interested in a path that long term means two networking stacks > >> in U-Boot. > >> > >> I am not interested in massively growing the overall binary size for > >> every platform. Given how much larger just TCP support is, that's > >> strongly implying a huge growth for the older use cases too. > >> > >> But I also suspect given the overall reputation that LWIP enjoys, > >> there's something amiss here. > >> > >> -- > >> Tom > >> > > > > +cc lwip-devel@ mailing list, maybe they have something to add. > > I do think using lwIP instead of "inventing yet another IP stack" is a > good idea! However, in terms of code size, lwIP will lose against what's > in U-Boot at present. And this is only natural, as lwIP is a "full-size" > stack supporting multiple concurrently running applications while the > current IP stack in U-Boot is rather "crippled" down to just what the > implementor needed at the time of writing. > > One example of this is that (if I remember correctly), U-Boot only has > one single network packet buffer, while lwIP has support for multiple > buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track > of that development in U-Boot about 3 years ago), we're comparing "we > have implemented everything we need so that it just kind of works" to > "we can easily add a HTTPS client to download something over the > internet just by enabling more compile options". > > Also, when comparing lwIP to U-Boot TCP code size, keep in mind that > U-Boot TCP (at least that of some years ago) is far from complete when > compared to lwIP! > > lwIP is meant to be highly configurable and we're always open to add yet > more options to leave out more code when it's not needed. However, I > think there are some design decisions that will make lwIP larger than > the current IP stack in U-Boot. To me, that's a natural result of having > a "generic code" approach vs "developed to our needs". However, while > DHCP + BOOTP and even a simple network console was rather easy to > implement, I would not recommend implementing your own HTTPS download > but rather using the existing lwIP + apps for that. > > In the end, I cannot take the decision from you. In my opinion, lwIP > would be the better decision in terms of future work load and > compatibility, but in the short run, it *will* lead to bigger binaries > at least in some setups. And I do know from my past that it sometimes > has been a pain to try and stuff a new U-Boot release into the existing > space of flash or RAM, so that's not an easy decision. > > If you do take the lwIP approach however, let us know if we can help! > > Regards, > Simon > > > > > My measurements say that the current U-boot IP stack + wget command adds > an > > additional 9 Kbytes. > > The minimal configuration of LWIP with wget command is 30 Kbytes. > > (compiled out all asserts, debugs, not used protocols etc.). > > > > And the most bigger functions are tcp in/out itself: > > * These functions are generally called in the order (ip_input() ->) > > * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). > > > > +tcp_input - 4364 +4364 > > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n118 > > +tcp_receive - 3444 +3444 > > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n1154 > > +tcp_write - 2192 +2192 > > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n393 > > +ip4_reass - 2096 +2096 > > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/ipv4/ip4_frag.c#n503 > > +tcp_output - 1616 +1616 > > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n1241 > > > > If we transfer current net commands to lwip then we can decrease the > size, > > because of functions reuse. > > And if we turn on all features in lwip it will be about 50 Kbytes. > > > > BR, > > Maxim. > > > > > > _______________________________________________ > > lwip-devel mailing list > > lwip-devel@nongnu.org > > https://lists.nongnu.org/mailman/listinfo/lwip-devel >
Hi Maxim, On Tue, 6 Jun 2023 at 17:33, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > Greetings, > > I implemented the tftp client (that was quick due to lwip has example app for tftp), and did some more measurements. > I uploaded patches here if somebody want to do his own measurements: > https://github.com/muvarov/uboot-lwip > > measure 1: > 976K - total (total means lwip with all 3 commands ping, tftp, wget) > 971K - total - tftp (total, but disable/minus tftp) > 965K - total - tftp - wget (disable tftp and wget) > 963K - total - tftp - wget - ping (disable tftp, wget, ping) > 931K - no lwip > > result 1: lwip tftp (+ udp protocol) protocol 976-971k = 5kb > result 2: lwip ping command 965- 963 = 2kb > result 3: lwip wget command 971- 965 = 6kb > result 4: lwip core stack with apps 976 - 931 = 45kb So tftp = 5kb, wget = 6kb ping =2kb and lwip = 32kb > > measure 2: > 890K - no CONFIG_NET_CMD > 930K - + lwip tftp only > 937K - + full lwip (ping wget tftp) > > result 1: 937-890=47kb ( lwip + all 3 commands) > result 2: 937-930=7kb (ping and lwip command) I am not sure I understand this measurement. How is this different from measurement 1 where the entire binary was 976K? > > measure 3: > 904K - no lwip, CMD_NET_TFTP=y > 900K - no lwip, CMD_NET_TFTP=n > result 1: original u-boot tftp command 904-900=4kb > 890K - no lwip, CMD_NET=n > result 2: 900-890=10k original u-boot net/IP stack. > > My findings for all that measurements and lwip configuration: > 1. The original u-boot net stack (packet process and up layers) is 10k vs lwip 40k (the very minimal settings were 30k). > 2. Network applications size is about the same 4kb for tftp original command 5kb for lwip. > 3. It's quite easy to reuse LWIP examples to implement the same functionality for the U-boot. > 4. I still think that there are other criterias which might have more priority than size (bug free code, code reuse, development speed, compatible API to posix and etc). Yes, there are other criteria and certainly having a complete network stack might be worth it in many cases, but we need to keep in mind 30kb might be a lot for some systems. I personally think this is decent and we can optimize lwip more in the future. Tom, Simon, how about adding lwip as 'experimental' and making it depend on !CMD_NET or something similar? Thanks /Ilias > > BR, > Maxim. > > On Thu, 25 May 2023 at 02:18, Simon Goldschmidt <goldsimon@gmx.de> wrote: >> >> Hi Maxim, Tom, >> >> On 24.05.2023 16:05, Maxim Uvarov wrote: >> > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: >> > >> >> On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: >> >>> On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: >> >>> >> >>>> On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: >> >>>>> Hi Maxim >> >>>>> >> >>>>> On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> >> >>>> wrote: >> >>>>>> >> >>>>>> My measurements for binary after LTO looks like: >> >>>>>> >> >>>>>> U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % >> >>>>>> 870728 | 915000 | 912560 | >> >>>> 41832 | 4.8 >> >>>>> >> >>>>> >> >>>>> I think you'll need to analyze that a bit more. First of all I don't >> >>>>> think the '+ping' tab is useful. What is is trying to achieve? >> >>>> >> >>> >> >>> To show the difference of extra bytes if we add a ping app on top. >> >>> >> >>> >> >>>>> - How was LWIP compiled? >> >>>> >> >>> >> >>> It has a really huge configuration. I tried to turn off everything off >> >>> everything what can impact on size but still make http app work: >> >>> #define LWIP_HAVE_LOOPIF 0 >> >>> #define LWIP_NETCONN 0 >> >>> #define LWIP_SOCKET 0 >> >>> #define SO_REUSE 0 >> >>> #define LWIP_STATS 0 >> >>> #define PPP_SUPPORT 0 >> >>> >> >>> Disabling loopback: >> >>> #define LWIP_NETIF_LOOPBACK 0 >> >>> can lower to 912288 bytes. >> >>> >> >>> And it's the same compilation option (optimization for size) as the main >> >>> u-boot. I will do more experiments, but I think the goal is not to turn >> >> off >> >>> everything. >> >>> >> >>> >> >>>>> - Was ipv6 supported? >> >>>> >> >>> >> >>> No. I.e. when I sent results it was enabled on the compilation stage but >> >>> not used. I just checked that size remains the same if IPv6 is not even >> >>> compiled. >> >>> >> >>> >> >>>>> - Can we strip it down even further? >> >>>>> >> >>>> >> >>> >> >>> There is always room for optimization. I think I tried to turn off >> >>> everything that is configurable with defines. I can play with disable IP >> >>> reassembly and things like that or figure out which functions have more >> >>> size and if it's possible to exclude them. >> >>> >> >>> >> >>>>> In general please give as much information as you can with what we >> >>>>> gain in functionality from LWIP with those extra bytes of code. >> >>>> >> >>>> >> >>> The main idea is to reuse a maintainable IP stack outside of U-boot. >> >> LWIP >> >>> can give a nice separation between IP stack code and network application >> >>> code. I.e. application should not take care about any TCP details (SYN, >> >>> ACK, retransmission, reassembly etc) and should open connection and use >> >>> functions similar to recv() and send() to transfer data. Data means >> >>> application data, no network packets. And LWIP allows >> >>> us to do that. >> >>> Because LWIP has an API similar to sockets, it has to be very easy to >> >> port >> >>> a linux application to LWIP. Then you can test it with a tap device. Then >> >>> copy sources to U-boot, add a small integration layer (cmd command to >> >>> call), compile and use. >> >>> >> >>> So my suggestion was: >> >>> - do not maintain new network stack code in the current U-boot. Use lwip >> >>> sources as an external project. All bugs related to network stack go to >> >>> lwip project first, then sync with U-boot. >> >>> - maintain network apps code* or >> >>> -- inside U-boot. Write our own code for application and maintain it >> >>> inside U-boot. >> >>> -- inside LWIP. Add examples to LWIP which are suitable for both >> >> U-boot >> >>> and LWIP. >> >>> >> >>> * Let's define a U-boot network application as a cmd command. It might be >> >>> ping, wget (http or https download), telnet, arp dns etc.. >> >>> >> >>> Let's consider the real use case, like HTTPS download client. We need to >> >>> enable TLS connection, validate certificates, then do http download. >> >>> Looking at the current code of wget command it's quite difficult to >> >>> implement this due to the application having some protol level things. On >> >>> the other side we can find embedTLS examples to do https download on >> >>> sockets. If LWIP socket API is ported then the only thing you need to do >> >> is >> >>> change socket() -> lwip_socket(), recv()->lwip_recv(), >> >> send()->lwip_send() >> >>> and etc, even function names are similar. If LWIP socket API is not >> >>> supported, then use callback API for recv() and send(), which are also >> >>> easy. >> >>> >> >>> So yes we add extra bytes, but that will allow us to write more complex >> >>> apps, use standard debug tools, use applications with very minimal >> >>> integration changes, use help from the LWIP community to fix protocol >> >> bugs, >> >>> etc.. >> >>> Bunch of things already implemented there: >> >>> - ipv6 >> >>> - dhcp >> >>> - snmp >> >>> - igmp >> >>> - dns >> >>> - tcp and udp and raw. >> >>> - loopback >> >>> - netconn >> >>> - socket >> >>> - stats >> >>> - ppp >> >>> (I just followed configurable defines). >> >>> >> >>> >> >>> And please make sure to disable the previous support, my guess fro that >> >>>> much growth is that you didn't. >> >>>> >> >>> >> >>> # CONFIG_PROT_TCP is not set >> >>> # CONFIG_PROT_UDP is not set >> >>> # CONFIG_UDP_CHECKSUM is not set >> >>> # CONFIG_UDP_FUNCTION_FASTBOOT is not set >> >>> # CONFIG_CMD_WGET is not set >> >> >> >> I think you need to step back and figure out a better way to measure the >> >> size change and growth. >> >> >> >> I am not interested in a path that long term means two networking stacks >> >> in U-Boot. >> >> >> >> I am not interested in massively growing the overall binary size for >> >> every platform. Given how much larger just TCP support is, that's >> >> strongly implying a huge growth for the older use cases too. >> >> >> >> But I also suspect given the overall reputation that LWIP enjoys, >> >> there's something amiss here. >> >> >> >> -- >> >> Tom >> >> >> > >> > +cc lwip-devel@ mailing list, maybe they have something to add. >> >> I do think using lwIP instead of "inventing yet another IP stack" is a >> good idea! However, in terms of code size, lwIP will lose against what's >> in U-Boot at present. And this is only natural, as lwIP is a "full-size" >> stack supporting multiple concurrently running applications while the >> current IP stack in U-Boot is rather "crippled" down to just what the >> implementor needed at the time of writing. >> >> One example of this is that (if I remember correctly), U-Boot only has >> one single network packet buffer, while lwIP has support for multiple >> buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track >> of that development in U-Boot about 3 years ago), we're comparing "we >> have implemented everything we need so that it just kind of works" to >> "we can easily add a HTTPS client to download something over the >> internet just by enabling more compile options". >> >> Also, when comparing lwIP to U-Boot TCP code size, keep in mind that >> U-Boot TCP (at least that of some years ago) is far from complete when >> compared to lwIP! >> >> lwIP is meant to be highly configurable and we're always open to add yet >> more options to leave out more code when it's not needed. However, I >> think there are some design decisions that will make lwIP larger than >> the current IP stack in U-Boot. To me, that's a natural result of having >> a "generic code" approach vs "developed to our needs". However, while >> DHCP + BOOTP and even a simple network console was rather easy to >> implement, I would not recommend implementing your own HTTPS download >> but rather using the existing lwIP + apps for that. >> >> In the end, I cannot take the decision from you. In my opinion, lwIP >> would be the better decision in terms of future work load and >> compatibility, but in the short run, it *will* lead to bigger binaries >> at least in some setups. And I do know from my past that it sometimes >> has been a pain to try and stuff a new U-Boot release into the existing >> space of flash or RAM, so that's not an easy decision. >> >> If you do take the lwIP approach however, let us know if we can help! >> >> Regards, >> Simon >> >> > >> > My measurements say that the current U-boot IP stack + wget command adds an >> > additional 9 Kbytes. >> > The minimal configuration of LWIP with wget command is 30 Kbytes. >> > (compiled out all asserts, debugs, not used protocols etc.). >> > >> > And the most bigger functions are tcp in/out itself: >> > * These functions are generally called in the order (ip_input() ->) >> > * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). >> > >> > +tcp_input - 4364 +4364 >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n118 >> > +tcp_receive - 3444 +3444 >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n1154 >> > +tcp_write - 2192 +2192 >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n393 >> > +ip4_reass - 2096 +2096 >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/ipv4/ip4_frag.c#n503 >> > +tcp_output - 1616 +1616 >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n1241 >> > >> > If we transfer current net commands to lwip then we can decrease the size, >> > because of functions reuse. >> > And if we turn on all features in lwip it will be about 50 Kbytes. >> > >> > BR, >> > Maxim. >> > >> > >> > _______________________________________________ >> > lwip-devel mailing list >> > lwip-devel@nongnu.org >> > https://lists.nongnu.org/mailman/listinfo/lwip-devel
On Wed, 7 Jun 2023 at 15:47, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > Hi Maxim, > > On Tue, 6 Jun 2023 at 17:33, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > > > Greetings, > > > > I implemented the tftp client (that was quick due to lwip has example > app for tftp), and did some more measurements. > > I uploaded patches here if somebody want to do his own measurements: > > https://github.com/muvarov/uboot-lwip > > > > measure 1: > > 976K - total (total means lwip with all 3 commands ping, tftp, wget) > > 971K - total - tftp (total, but disable/minus tftp) > > 965K - total - tftp - wget (disable tftp and wget) > > 963K - total - tftp - wget - ping (disable tftp, wget, ping) > > 931K - no lwip > > > > result 1: lwip tftp (+ udp protocol) protocol 976-971k = 5kb > > result 2: lwip ping command 965- 963 = 2kb > > result 3: lwip wget command 971- 965 = 6kb > > result 4: lwip core stack with apps 976 - 931 = 45kb > > So tftp = 5kb, wget = 6kb ping =2kb and lwip = 32kb > > tftp also compiles in the UDP stack. So if there will be one more UDP application, then this size will be lower. > > > > measure 2: > > 890K - no CONFIG_NET_CMD > > 930K - + lwip tftp only > > 937K - + full lwip (ping wget tftp) > > > > result 1: 937-890=47kb ( lwip + all 3 commands) > > result 2: 937-930=7kb (ping and lwip command) > > I am not sure I understand this measurement. How is this different > from measurement 1 where the entire binary was 976K? > > This is when NET_CMD is off and LWIP is off also. First measurement had NET_CMD=y. (moved numbers to separate changes due to u-boot can not just enable only tfpt command due to a compilation error and had to fix it.). > > > measure 3: > > 904K - no lwip, CMD_NET_TFTP=y > > 900K - no lwip, CMD_NET_TFTP=n > > result 1: original u-boot tftp command 904-900=4kb > > 890K - no lwip, CMD_NET=n > > result 2: 900-890=10k original u-boot net/IP stack. > > > > My findings for all that measurements and lwip configuration: > > 1. The original u-boot net stack (packet process and up layers) is 10k > vs lwip 40k (the very minimal settings were 30k). > > 2. Network applications size is about the same 4kb for tftp original > command 5kb for lwip. > > 3. It's quite easy to reuse LWIP examples to implement the same > functionality for the U-boot. > > 4. I still think that there are other criterias which might have more > priority than size (bug free code, code reuse, development speed, > compatible API to posix and etc). > > Yes, there are other criteria and certainly having a complete network > stack might be worth it in many cases, but we need to keep in mind > 30kb might be a lot for some systems. > > I personally think this is decent and we can optimize lwip more in the > future. Tom, Simon, how about adding lwip as 'experimental' and > making it depend on !CMD_NET or something similar? > > Thanks > /Ilias > > > > BR, > > Maxim. > > > > On Thu, 25 May 2023 at 02:18, Simon Goldschmidt <goldsimon@gmx.de> > wrote: > >> > >> Hi Maxim, Tom, > >> > >> On 24.05.2023 16:05, Maxim Uvarov wrote: > >> > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > >> > > >> >> On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > >> >>> On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > >> >>> > >> >>>> On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > >> >>>>> Hi Maxim > >> >>>>> > >> >>>>> On Mon, 22 May 2023 at 12:01, Maxim Uvarov < > maxim.uvarov@linaro.org> > >> >>>> wrote: > >> >>>>>> > >> >>>>>> My measurements for binary after LTO looks like: > >> >>>>>> > >> >>>>>> U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > >> >>>>>> 870728 | 915000 | 912560 > | > >> >>>> 41832 | 4.8 > >> >>>>> > >> >>>>> > >> >>>>> I think you'll need to analyze that a bit more. First of all I > don't > >> >>>>> think the '+ping' tab is useful. What is is trying to achieve? > >> >>>> > >> >>> > >> >>> To show the difference of extra bytes if we add a ping app on top. > >> >>> > >> >>> > >> >>>>> - How was LWIP compiled? > >> >>>> > >> >>> > >> >>> It has a really huge configuration. I tried to turn off everything > off > >> >>> everything what can impact on size but still make http app work: > >> >>> #define LWIP_HAVE_LOOPIF 0 > >> >>> #define LWIP_NETCONN 0 > >> >>> #define LWIP_SOCKET 0 > >> >>> #define SO_REUSE 0 > >> >>> #define LWIP_STATS 0 > >> >>> #define PPP_SUPPORT 0 > >> >>> > >> >>> Disabling loopback: > >> >>> #define LWIP_NETIF_LOOPBACK 0 > >> >>> can lower to 912288 bytes. > >> >>> > >> >>> And it's the same compilation option (optimization for size) as the > main > >> >>> u-boot. I will do more experiments, but I think the goal is not to > turn > >> >> off > >> >>> everything. > >> >>> > >> >>> > >> >>>>> - Was ipv6 supported? > >> >>>> > >> >>> > >> >>> No. I.e. when I sent results it was enabled on the compilation > stage but > >> >>> not used. I just checked that size remains the same if IPv6 is not > even > >> >>> compiled. > >> >>> > >> >>> > >> >>>>> - Can we strip it down even further? > >> >>>>> > >> >>>> > >> >>> > >> >>> There is always room for optimization. I think I tried to turn off > >> >>> everything that is configurable with defines. I can play with > disable IP > >> >>> reassembly and things like that or figure out which functions have > more > >> >>> size and if it's possible to exclude them. > >> >>> > >> >>> > >> >>>>> In general please give as much information as you can with what > we > >> >>>>> gain in functionality from LWIP with those extra bytes of code. > >> >>>> > >> >>>> > >> >>> The main idea is to reuse a maintainable IP stack outside of U-boot. > >> >> LWIP > >> >>> can give a nice separation between IP stack code and network > application > >> >>> code. I.e. application should not take care about any TCP details > (SYN, > >> >>> ACK, retransmission, reassembly etc) and should open connection and > use > >> >>> functions similar to recv() and send() to transfer data. Data means > >> >>> application data, no network packets. And LWIP allows > >> >>> us to do that. > >> >>> Because LWIP has an API similar to sockets, it has to be very easy > to > >> >> port > >> >>> a linux application to LWIP. Then you can test it with a tap > device. Then > >> >>> copy sources to U-boot, add a small integration layer (cmd command > to > >> >>> call), compile and use. > >> >>> > >> >>> So my suggestion was: > >> >>> - do not maintain new network stack code in the current U-boot. > Use lwip > >> >>> sources as an external project. All bugs related to network stack > go to > >> >>> lwip project first, then sync with U-boot. > >> >>> - maintain network apps code* or > >> >>> -- inside U-boot. Write our own code for application and > maintain it > >> >>> inside U-boot. > >> >>> -- inside LWIP. Add examples to LWIP which are suitable for both > >> >> U-boot > >> >>> and LWIP. > >> >>> > >> >>> * Let's define a U-boot network application as a cmd command. It > might be > >> >>> ping, wget (http or https download), telnet, arp dns etc.. > >> >>> > >> >>> Let's consider the real use case, like HTTPS download client. We > need to > >> >>> enable TLS connection, validate certificates, then do http download. > >> >>> Looking at the current code of wget command it's quite difficult to > >> >>> implement this due to the application having some protol level > things. On > >> >>> the other side we can find embedTLS examples to do https download on > >> >>> sockets. If LWIP socket API is ported then the only thing you need > to do > >> >> is > >> >>> change socket() -> lwip_socket(), recv()->lwip_recv(), > >> >> send()->lwip_send() > >> >>> and etc, even function names are similar. If LWIP socket API is not > >> >>> supported, then use callback API for recv() and send(), which are > also > >> >>> easy. > >> >>> > >> >>> So yes we add extra bytes, but that will allow us to write more > complex > >> >>> apps, use standard debug tools, use applications with very minimal > >> >>> integration changes, use help from the LWIP community to fix > protocol > >> >> bugs, > >> >>> etc.. > >> >>> Bunch of things already implemented there: > >> >>> - ipv6 > >> >>> - dhcp > >> >>> - snmp > >> >>> - igmp > >> >>> - dns > >> >>> - tcp and udp and raw. > >> >>> - loopback > >> >>> - netconn > >> >>> - socket > >> >>> - stats > >> >>> - ppp > >> >>> (I just followed configurable defines). > >> >>> > >> >>> > >> >>> And please make sure to disable the previous support, my guess fro > that > >> >>>> much growth is that you didn't. > >> >>>> > >> >>> > >> >>> # CONFIG_PROT_TCP is not set > >> >>> # CONFIG_PROT_UDP is not set > >> >>> # CONFIG_UDP_CHECKSUM is not set > >> >>> # CONFIG_UDP_FUNCTION_FASTBOOT is not set > >> >>> # CONFIG_CMD_WGET is not set > >> >> > >> >> I think you need to step back and figure out a better way to measure > the > >> >> size change and growth. > >> >> > >> >> I am not interested in a path that long term means two networking > stacks > >> >> in U-Boot. > >> >> > >> >> I am not interested in massively growing the overall binary size for > >> >> every platform. Given how much larger just TCP support is, that's > >> >> strongly implying a huge growth for the older use cases too. > >> >> > >> >> But I also suspect given the overall reputation that LWIP enjoys, > >> >> there's something amiss here. > >> >> > >> >> -- > >> >> Tom > >> >> > >> > > >> > +cc lwip-devel@ mailing list, maybe they have something to add. > >> > >> I do think using lwIP instead of "inventing yet another IP stack" is a > >> good idea! However, in terms of code size, lwIP will lose against what's > >> in U-Boot at present. And this is only natural, as lwIP is a "full-size" > >> stack supporting multiple concurrently running applications while the > >> current IP stack in U-Boot is rather "crippled" down to just what the > >> implementor needed at the time of writing. > >> > >> One example of this is that (if I remember correctly), U-Boot only has > >> one single network packet buffer, while lwIP has support for multiple > >> buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track > >> of that development in U-Boot about 3 years ago), we're comparing "we > >> have implemented everything we need so that it just kind of works" to > >> "we can easily add a HTTPS client to download something over the > >> internet just by enabling more compile options". > >> > >> Also, when comparing lwIP to U-Boot TCP code size, keep in mind that > >> U-Boot TCP (at least that of some years ago) is far from complete when > >> compared to lwIP! > >> > >> lwIP is meant to be highly configurable and we're always open to add yet > >> more options to leave out more code when it's not needed. However, I > >> think there are some design decisions that will make lwIP larger than > >> the current IP stack in U-Boot. To me, that's a natural result of having > >> a "generic code" approach vs "developed to our needs". However, while > >> DHCP + BOOTP and even a simple network console was rather easy to > >> implement, I would not recommend implementing your own HTTPS download > >> but rather using the existing lwIP + apps for that. > >> > >> In the end, I cannot take the decision from you. In my opinion, lwIP > >> would be the better decision in terms of future work load and > >> compatibility, but in the short run, it *will* lead to bigger binaries > >> at least in some setups. And I do know from my past that it sometimes > >> has been a pain to try and stuff a new U-Boot release into the existing > >> space of flash or RAM, so that's not an easy decision. > >> > >> If you do take the lwIP approach however, let us know if we can help! > >> > >> Regards, > >> Simon > >> > >> > > >> > My measurements say that the current U-boot IP stack + wget command > adds an > >> > additional 9 Kbytes. > >> > The minimal configuration of LWIP with wget command is 30 Kbytes. > >> > (compiled out all asserts, debugs, not used protocols etc.). > >> > > >> > And the most bigger functions are tcp in/out itself: > >> > * These functions are generally called in the order (ip_input() ->) > >> > * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). > >> > > >> > +tcp_input - 4364 +4364 > >> > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n118 > >> > +tcp_receive - 3444 +3444 > >> > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n1154 > >> > +tcp_write - 2192 +2192 > >> > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n393 > >> > +ip4_reass - 2096 +2096 > >> > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/ipv4/ip4_frag.c#n503 > >> > +tcp_output - 1616 +1616 > >> > > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n1241 > >> > > >> > If we transfer current net commands to lwip then we can decrease the > size, > >> > because of functions reuse. > >> > And if we turn on all features in lwip it will be about 50 Kbytes. > >> > > >> > BR, > >> > Maxim. > >> > > >> > > >> > _______________________________________________ > >> > lwip-devel mailing list > >> > lwip-devel@nongnu.org > >> > https://lists.nongnu.org/mailman/listinfo/lwip-devel >
On Wed, May 24, 2023 at 10:18:13PM +0200, Simon Goldschmidt wrote: > Hi Maxim, Tom, > > On 24.05.2023 16:05, Maxim Uvarov wrote: > > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > > > > > On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > > > > On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > > On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > > > > > > Hi Maxim > > > > > > > > > > > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> > > > > > wrote: > > > > > > > > > > > > > > My measurements for binary after LTO looks like: > > > > > > > > > > > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > > > > > > > 870728 | 915000 | 912560 | > > > > > 41832 | 4.8 > > > > > > > > > > > > > > > > > > I think you'll need to analyze that a bit more. First of all I don't > > > > > > think the '+ping' tab is useful. What is is trying to achieve? > > > > > > > > > > > > > To show the difference of extra bytes if we add a ping app on top. > > > > > > > > > > > > > > - How was LWIP compiled? > > > > > > > > > > > > > It has a really huge configuration. I tried to turn off everything off > > > > everything what can impact on size but still make http app work: > > > > #define LWIP_HAVE_LOOPIF 0 > > > > #define LWIP_NETCONN 0 > > > > #define LWIP_SOCKET 0 > > > > #define SO_REUSE 0 > > > > #define LWIP_STATS 0 > > > > #define PPP_SUPPORT 0 > > > > > > > > Disabling loopback: > > > > #define LWIP_NETIF_LOOPBACK 0 > > > > can lower to 912288 bytes. > > > > > > > > And it's the same compilation option (optimization for size) as the main > > > > u-boot. I will do more experiments, but I think the goal is not to turn > > > off > > > > everything. > > > > > > > > > > > > > > - Was ipv6 supported? > > > > > > > > > > > > > No. I.e. when I sent results it was enabled on the compilation stage but > > > > not used. I just checked that size remains the same if IPv6 is not even > > > > compiled. > > > > > > > > > > > > > > - Can we strip it down even further? > > > > > > > > > > > > > > > > > > > There is always room for optimization. I think I tried to turn off > > > > everything that is configurable with defines. I can play with disable IP > > > > reassembly and things like that or figure out which functions have more > > > > size and if it's possible to exclude them. > > > > > > > > > > > > > > In general please give as much information as you can with what we > > > > > > gain in functionality from LWIP with those extra bytes of code. > > > > > > > > > > > > > > The main idea is to reuse a maintainable IP stack outside of U-boot. > > > LWIP > > > > can give a nice separation between IP stack code and network application > > > > code. I.e. application should not take care about any TCP details (SYN, > > > > ACK, retransmission, reassembly etc) and should open connection and use > > > > functions similar to recv() and send() to transfer data. Data means > > > > application data, no network packets. And LWIP allows > > > > us to do that. > > > > Because LWIP has an API similar to sockets, it has to be very easy to > > > port > > > > a linux application to LWIP. Then you can test it with a tap device. Then > > > > copy sources to U-boot, add a small integration layer (cmd command to > > > > call), compile and use. > > > > > > > > So my suggestion was: > > > > - do not maintain new network stack code in the current U-boot. Use lwip > > > > sources as an external project. All bugs related to network stack go to > > > > lwip project first, then sync with U-boot. > > > > - maintain network apps code* or > > > > -- inside U-boot. Write our own code for application and maintain it > > > > inside U-boot. > > > > -- inside LWIP. Add examples to LWIP which are suitable for both > > > U-boot > > > > and LWIP. > > > > > > > > * Let's define a U-boot network application as a cmd command. It might be > > > > ping, wget (http or https download), telnet, arp dns etc.. > > > > > > > > Let's consider the real use case, like HTTPS download client. We need to > > > > enable TLS connection, validate certificates, then do http download. > > > > Looking at the current code of wget command it's quite difficult to > > > > implement this due to the application having some protol level things. On > > > > the other side we can find embedTLS examples to do https download on > > > > sockets. If LWIP socket API is ported then the only thing you need to do > > > is > > > > change socket() -> lwip_socket(), recv()->lwip_recv(), > > > send()->lwip_send() > > > > and etc, even function names are similar. If LWIP socket API is not > > > > supported, then use callback API for recv() and send(), which are also > > > > easy. > > > > > > > > So yes we add extra bytes, but that will allow us to write more complex > > > > apps, use standard debug tools, use applications with very minimal > > > > integration changes, use help from the LWIP community to fix protocol > > > bugs, > > > > etc.. > > > > Bunch of things already implemented there: > > > > - ipv6 > > > > - dhcp > > > > - snmp > > > > - igmp > > > > - dns > > > > - tcp and udp and raw. > > > > - loopback > > > > - netconn > > > > - socket > > > > - stats > > > > - ppp > > > > (I just followed configurable defines). > > > > > > > > > > > > And please make sure to disable the previous support, my guess fro that > > > > > much growth is that you didn't. > > > > > > > > > > > > > # CONFIG_PROT_TCP is not set > > > > # CONFIG_PROT_UDP is not set > > > > # CONFIG_UDP_CHECKSUM is not set > > > > # CONFIG_UDP_FUNCTION_FASTBOOT is not set > > > > # CONFIG_CMD_WGET is not set > > > > > > I think you need to step back and figure out a better way to measure the > > > size change and growth. > > > > > > I am not interested in a path that long term means two networking stacks > > > in U-Boot. > > > > > > I am not interested in massively growing the overall binary size for > > > every platform. Given how much larger just TCP support is, that's > > > strongly implying a huge growth for the older use cases too. > > > > > > But I also suspect given the overall reputation that LWIP enjoys, > > > there's something amiss here. > > > > > > -- > > > Tom > > > > > > > +cc lwip-devel@ mailing list, maybe they have something to add. > > I do think using lwIP instead of "inventing yet another IP stack" is a > good idea! However, in terms of code size, lwIP will lose against what's > in U-Boot at present. And this is only natural, as lwIP is a "full-size" > stack supporting multiple concurrently running applications while the > current IP stack in U-Boot is rather "crippled" down to just what the > implementor needed at the time of writing. > > One example of this is that (if I remember correctly), U-Boot only has > one single network packet buffer, while lwIP has support for multiple > buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track > of that development in U-Boot about 3 years ago), we're comparing "we > have implemented everything we need so that it just kind of works" to > "we can easily add a HTTPS client to download something over the > internet just by enabling more compile options". > > Also, when comparing lwIP to U-Boot TCP code size, keep in mind that > U-Boot TCP (at least that of some years ago) is far from complete when > compared to lwIP! > > lwIP is meant to be highly configurable and we're always open to add yet > more options to leave out more code when it's not needed. However, I > think there are some design decisions that will make lwIP larger than > the current IP stack in U-Boot. To me, that's a natural result of having > a "generic code" approach vs "developed to our needs". However, while > DHCP + BOOTP and even a simple network console was rather easy to > implement, I would not recommend implementing your own HTTPS download > but rather using the existing lwIP + apps for that. > > In the end, I cannot take the decision from you. In my opinion, lwIP > would be the better decision in terms of future work load and > compatibility, but in the short run, it *will* lead to bigger binaries > at least in some setups. And I do know from my past that it sometimes > has been a pain to try and stuff a new U-Boot release into the existing > space of flash or RAM, so that's not an easy decision. > > If you do take the lwIP approach however, let us know if we can help! Given Maxim's more recent experiments, I'm sure we can come up with something that works overall. There's hopefully a place or two U-Boot people can help introduce a tunable or two to lwIP to bring some sizes down. But I think it's overall looking to be the right direction.
Ilias asked to make more clear results to compare the original stack and LWIP stack. So the difference between the current U-boot stack and the LWIP stack with 3 network commands is: a) 18Kb - ls -lh size b) 15Kb - bloat-o-meter script total line report. BOM=linux/scripts/bloat-o-meter (script) 1. 893K - U-boot CMD_NET=n 2. 928K - U-boot CMD_NET=y TFTP=y PING=y WGET=y BOM 1-2: Total: Before=692286, After=722283, chg +4.33% 3. 940K - U-boot CMD_NET=n, LWIP_TFTP=y LWIP_PING=y LWIP_PING=y BOM 1-3: Total: Before=692286, After=738425, chg +6.66% BOM 2-3: add/remove: 287/203 grow/shrink: 3/11 up/down: 43459/-27317 (16142) Function old new delta tcp_input - 3588 +3588 tcp_receive - 2884 +2884 ip4_reass - 1760 +1760 tcp_output - 1400 +1400 tcp_write - 1300 +1300 tcp_slowtmr - 1172 +1172 httpc_tcp_recv - 1044 +1044 tftp_recv - 888 +888 ip4_input - 700 +700 ip4_frag - 632 +632 icmp_input - 604 +604 udp_input - 596 +596 etharp_input - 512 +512 tcp_split_unsent_seg - 500 +500 ip4addr_aton - 492 +492 tcp_alloc - 484 +484 ip4_output_if_src - 476 +476 tcp_close_shutdown - 448 +448 etharp_query - 436 +436 httpc_init_connection_common.constprop - 416 +416 udp_sendto_if_src - 408 +408 etharp_output - 404 +404 arp_table - 400 +400 tcp_connect - 396 +396 pbuf_alloc - 376 +376 etharp_find_entry - 372 +372 tcp_abandon - 368 +368 tcp_zero_window_probe - 356 +356 raw_sendto_if_src - 328 +328 pbuf_copy_partial_pbuf - 328 +328 ip_reass_free_complete_datagram - 328 +328 tcp_create_segment - 300 +300 raw_input - 292 +292 uboot_lwip_init - 284 +284 ethernet_input - 284 +284 etharp_raw - 284 +284 tcp_output_alloc_header_common.constprop - 280 +280 cmds - 280 +280 udp_bind - 276 +276 tcp_oos_insert_segment - 276 +276 ip_reass_remove_oldest_datagram - 272 +272 icmp_send_response - 268 +268 netif_add - 260 +260 ping_send - 244 +244 tcp_rexmit - 232 +232 tcp_parseopt - 220 +220 tcp_free_acked_segments.constprop - 220 +220 send_request - 220 +220 inet_chksum_pseudo - 216 +216 ip4addr_ntoa_r - 212 +212 do_lwip_ping - 212 +212 tcp_enqueue_flags - 208 +208 etharp_output_to_arp_index - 208 +208 netif_set_addr - 204 +204 tcp_fasttmr - 200 +200 tcp_rexmit_rto_prepare - 196 +196 tcp_process_refused_data - 196 +196 send_data - 196 +196 lwip_wget - 192 +192 ethernet_output - 192 +192 ping_recv - 188 +188 pbuf_memcmp - 184 +184 pbuf_copy_partial - 184 +184 httpc_free_state - 180 +180 tcp_send_fin - 172 +172 httpc_recv - 168 +168 tcp_output_control_segment_netif - 164 +164 send_error.isra - 164 +164 do_ops - 164 +164 raw_sendto - 160 +160 pbuf_realloc - 160 +160 pbuf_free - 160 +160 do_lwip_wget - 160 +160 do_lwip_tftp - 160 +160 tftp_init_common - 156 +156 tcp_rst_netif - 152 +152 udp_sendto - 144 +144 tftp_tmr - 144 +144 tcp_rst - 144 +144 uboot_lwip_if_init - 140 +140 tcp_pcb_remove - 140 +140 tcp_pbuf_prealloc - 140 +140 sys_timeout_abs - 140 +140 lwip_tftp - 140 +140 netif_do_set_ipaddr.isra - 136 +136 ip4_route - 136 +136 tcp_netif_ip_addr_changed - 132 +132 resend_data.isra - 132 +132 inet_chksum_pbuf - 132 +132 tcp_output_control_segment - 128 +128 pbuf_memfind - 128 +128 lwip_standard_chksum - 128 +128 tcp_rexmit_fast - 124 +124 tcp_new_port - 124 +124 tcp_close_shutdown_fin - 124 +124 pbuf_add_header_impl - 124 +124 tcp_send_empty_ack - 120 +120 httpc_create_request_string.constprop.isra - 120 +120 tftp_get - 116 +116 tcp_recved - 116 +116 tcp_pcb_purge - 116 +116 tftp_write - 112 +112 pbuf_free_header - 112 +112 httpc_tcp_connected - 112 +112 tftp_error - 108 +108 send_ack.isra - 108 +108 low_level_input.constprop - 108 +108 tcp_input_delayed_close - 104 +104 close_handle - 100 +100 sys_untimeout - 96 +96 memp_pools - 96 +96 tcp_keepalive - 92 +92 ip4_addr_isbroadcast_u32 - 92 +92 init_packet - 92 +92 tcp_kill_state - 88 +88 raw_new - 88 +88 ping_raw_init - 88 +88 lwip_ping_init - 88 +88 udp_sendto_if - 84 +84 tcp_update_rcv_ann_wnd - 84 +84 tcp_recv_null - 84 +84 pbuf_remove_header - 84 +84 pbuf_alloc_reference - 84 +84 udp_remove - 80 +80 tcp_get_next_optbyte - 80 +80 pbuf_alloced_custom - 80 +80 ip4_input_accept - 80 +80 httpc_close - 80 +80 etharp_free_entry - 80 +80 uboot_lwip_poll - 76 +76 tcpip_tcp_timer - 76 +76 udp_netif_ip_addr_changed - 72 +72 uboot_netif - 72 +72 tcp_output_alloc_header.constprop - 72 +72 raw_netif_ip_addr_changed - 72 +72 tcpip_try_callback - 68 +68 tcp_timer_needed - 68 +68 tcp_seg_copy - 68 +68 tcp_netif_ip_addr_changed_pcblist - 68 +68 ping_timeout - 68 +68 ethernetif_input - 68 +68 udp_new - 64 +64 pbuf_try_get_at - 64 +64 sys_timeout - 60 +60 pbuf_clone - 60 +60 tcp_seg_free - 56 +56 pbuf_cat - 56 +56 netif_get_by_index - 56 +56 low_level_output - 56 +56 _u_boot_list_2_cmd_2_lwipinfo - 56 +56 _u_boot_list_2_cmd_2_lwip - 56 +56 tftp_state 4 56 +52 tcp_tmr - 52 +52 tcp_rexmit_rto - 52 +52 tcp_segs_free - 48 +48 tcp_eff_send_mss_netif - 48 +48 pbuf_skip_const - 48 +48 ipfrag_free_pbuf_custom - 48 +48 httpc_tcp_poll - 48 +48 tcp_free_ooseq - 44 +44 tcp_close - 44 +44 pbuf_free_ooseq_callback - 44 +44 netif_issue_reports - 44 +44 ip_reass_dequeue_datagram - 44 +44 httpc_get_internal_addr - 44 +44 tftp_read - 40 +40 tftp - 40 +40 ip_data - 40 +40 etharp_request - 40 +40 do_lwip_info - 40 +40 ulwip_timeout_handler - 36 +36 raw_bind - 36 +36 memp_malloc - 36 +36 ip4_output_if - 36 +36 tcp_pcb_lists - 32 +32 pbuf_header_force - 32 +32 pbuf_clen - 32 +32 netif_set_up - 32 +32 netif_set_link_up - 32 +32 inseg - 32 +32 inet_chksum - 32 +32 tcp_next_iss - 28 +28 pbuf_get_at - 28 +28 httpc_tcp_err - 28 +28 do_lwip_init - 28 +28 tcp_rexmit_rto_commit - 24 +24 sys_now - 24 +24 settings - 24 +24 pbuf_copy - 24 +24 pbuf_chain - 24 +24 memp_free - 24 +24 __func__ 1243 1266 +23 ulwip_exit - 20 +20 tcp_trigger_input_pcb_close - 20 +20 tcp_poll - 20 +20 ping_send_now - 20 +20 pbuf_ref - 20 +20 str - 16 +16 ip4addr_ntoa - 16 +16 daddr - 16 +16 tcp_backoff - 13 +13 ulwip_loop_set - 12 +12 ulwip_in_loop - 12 +12 ulwip_enabled - 12 +12 ulwip_app_get_err - 12 +12 udp_recv - 12 +12 tftp_init_client - 12 +12 tcp_sent - 12 +12 tcp_recv - 12 +12 tcp_free - 12 +12 tcp_err - 12 +12 tcp_arg - 12 +12 net_process_received_packet 800 812 +12 icmp_time_exceeded - 12 +12 icmp_dest_unreach - 12 +12 udp_pcbs - 8 +8 tftp_open - 8 +8 tftp_close - 8 +8 tcphdr_opt2 - 8 +8 tcphdr - 8 +8 tcp_tw_pcbs - 8 +8 tcp_new - 8 +8 tcp_listen_pcbs - 8 +8 tcp_input_pcb - 8 +8 tcp_bound_pcbs - 8 +8 tcp_active_pcbs - 8 +8 tcp_abort - 8 +8 recv_data - 8 +8 reassdatagrams - 8 +8 raw_recv - 8 +8 raw_pcbs - 8 +8 ping_target - 8 +8 ping_pcb - 8 +8 pbuf_add_header - 8 +8 next_timeout - 8 +8 netif_null_output_ip4 - 8 +8 netif_list - 8 +8 netif_default - 8 +8 lwip_htons - 8 +8 lwip_htonl - 8 +8 httpc_tcp_sent - 8 +8 tcp_persist_backoff - 7 +7 ethzero - 6 +6 ethbroadcast - 6 +6 ulwip_app_err - 4 +4 udp_new_ip_type - 4 +4 uboot_net_use_lwip - 4 +4 tcpip_tcp_timer_active - 4 +4 tcp_ticks - 4 +4 seqno - 4 +4 mem_trim - 4 +4 mem_malloc - 4 +4 mem_free - 4 +4 loop_lwip - 4 +4 iss - 4 +4 ip_target - 4 +4 ip_chksum_pseudo - 4 +4 ip_addr_any - 4 +4 httpc_init_connection - 4 +4 ackno - 4 +4 udp_port - 2 +2 tcplen - 2 +2 tcphdr_optlen - 2 +2 tcphdr_opt1len - 2 +2 tcp_port - 2 +2 tcp_optidx - 2 +2 recv_acked - 2 +2 ping_seq_num - 2 +2 memp_UDP_PCB - 2 +2 memp_TCP_SEG - 2 +2 memp_TCP_PCB_LISTEN - 2 +2 memp_TCP_PCB - 2 +2 memp_TCPIP_MSG_INPKT - 2 +2 memp_TCPIP_MSG_API - 2 +2 memp_SYS_TIMEOUT - 2 +2 memp_REASSDATA - 2 +2 memp_RAW_PCB - 2 +2 memp_PBUF_POOL - 2 +2 memp_PBUF - 2 +2 memp_FRAG_PBUF - 2 +2 ip_reass_pbufcount - 2 +2 ip_id - 2 +2 tcp_timer_ctr - 1 +1 tcp_timer - 1 +1 tcp_active_pcbs_changed - 1 +1 recv_flags - 1 +1 pbuf_free_ooseq_pending - 1 +1 netif_num - 1 +1 flags - 1 +1 etharp_cached_entry - 1 +1 supported_nfs_versions 1 - -1 retry_action 1 - -1 net_boot_file_name_explicit 1 - -1 dhcp_option_overload 1 - -1 tftp_windowsize 2 - -2 tftp_window_size_option 2 - -2 tftp_next_ack 2 - -2 tftp_last_nack 2 - -2 tftp_block_size_option 2 - -2 tftp_block_size 2 - -2 ping_seq_number 2 - -2 last_op 2 - -2 env_flags_vartype_rep 7 5 -2 linefeed 3 - -3 wget_timeout_count 4 - -4 wget_loop_state 4 - -4 web_server_ip 4 - -4 timeout_count_max 4 - -4 timeout_count 4 - -4 tftp_timeout_count_max 4 - -4 tftp_remote_port 4 - -4 tftp_remote_ip 4 - -4 tftp_our_port 4 - -4 saved_tftp_block_size_option 4 - -4 retry_tcp_seq_num 4 - -4 retry_tcp_ack_num 4 - -4 retry_len 4 - -4 pkt_q_idx 4 - -4 packets 4 - -4 our_port 4 - -4 nfs_timeout_count 4 - -4 nfs_state 4 - -4 nfs_server_port 4 - -4 nfs_server_mount_port 4 - -4 nfs_server_ip 4 - -4 nfs_our_port 4 - -4 nfs_offset 4 - -4 nfs_len 4 - -4 nfs_download_state 4 - -4 net_ping_ip 4 - -4 net_dns_server 4 - -4 net_boot_file_expected_size_in_blocks 4 - -4 last_reg_lo 4 - -4 last_reg_hi 4 - -4 last_mask 4 - -4 last_data 4 - -4 last_addr_lo 4 - -4 last_addr_hi 4 - -4 initial_data_seq_num 4 - -4 http_ok 4 - -4 fs_mounted 4 - -4 filefh3_length 4 - -4 eth_common_init 4 - -4 dummy_handler 8 4 -4 dhcp_state 4 - -4 dhcp_server_ip 4 - -4 dhcp_leasetime 4 - -4 current_wget_state 4 - -4 bootp_try 4 - -4 bootp_num_ids 4 - -4 http_eom 5 - -5 bootfile1 5 - -5 timeout_ms 8 - -8 time_taken_max 8 - -8 time_start 16 8 -8 tftp_prev_block 8 - -8 tftp_load_size 8 - -8 tftp_load_addr 8 - -8 tftp_cur_block 8 - -8 tftp_block_wrap_offset 8 - -8 tftp_block_wrap 8 - -8 rpc_id 8 - -8 nfs_path 8 - -8 nfs_filename 8 - -8 miiphy_is_1000base_x 8 - -8 init_sequence_r 264 256 -8 image_url 8 - -8 distro_pxe_check 8 - -8 current_mii 8 - -8 content_length 8 - -8 bootp_timeout 8 - -8 bootp_start 8 - -8 tcp_get_tcp_state 12 - -12 do_wget 12 - -12 do_tftpb 12 - -12 do_nfs 12 - -12 do_dhcp 12 - -12 do_bootp 12 - -12 default_filename 13 - -13 bootfile3 14 - -14 content_len 15 - -15 reg_2_desc_tbl 16 - -16 pkt_q 16 - -16 mii_devs 16 - -16 bootp_ids 16 - -16 miiphy_get_current_dev 20 - -20 tcp_set_tcp_handler 24 - -24 pxe_default_paths 24 - -24 net_set_udp_handler 24 - -24 net_check_prereq 256 232 -24 miiphy_init 28 - -28 ping_timeout_handler 32 - -32 net_nis_domain 32 - -32 net_hostname 32 - -32 distro_bootmeth_pxe_ids 32 - -32 dirfh 32 - -32 initr_net 36 - -36 distro_bootmeth_pxe_bind 36 - -36 ip_to_string 40 - -40 distro_bootmeth_pxe_ops 40 - -40 net_send_udp_packet 44 - -44 label_boot 1944 1900 -44 env_flags_validate 632 588 -44 reg_3_desc_tbl 48 - -48 do_get_tftp 56 - -56 cmd_net 56 - -56 _u_boot_list_2_cmd_2_wget 56 - -56 _u_boot_list_2_cmd_2_tftpboot 56 - -56 _u_boot_list_2_cmd_2_pxe 56 - -56 _u_boot_list_2_cmd_2_ping 56 - -56 _u_boot_list_2_cmd_2_nfs 56 - -56 _u_boot_list_2_cmd_2_net 56 - -56 _u_boot_list_2_cmd_2_mii 56 - -56 _u_boot_list_2_cmd_2_dhcp 56 - -56 _u_boot_list_2_cmd_2_bootp 56 - -56 net_loop 652 592 -60 net_eth_hdr_size 60 - -60 bootp_reset 60 - -60 net_root_path 64 - -64 filefh 64 - -64 do_bootvx 816 748 -68 miiphy_set_current_dev 72 - -72 basename 72 - -72 pxe_get_file_size 76 - -76 copy_filename 76 - -76 distro_pxe_getfile 80 - -80 tftp_init_load_addr 92 - -92 miiphy_read 92 - -92 extract_range 92 - -92 miiphy_write 96 - -96 miiphy_get_active_dev 96 - -96 distro_pxe_read_file 96 - -96 wget_fail 104 - -104 skip_num 104 - -104 miiphy_get_dev_by_name 104 - -104 dump_field 104 - -104 do_bdinfo 432 328 -104 bootp_timeout_handler 104 - -104 nfs_timeout_handler 108 - -108 cmd_pxe_sub 112 - -112 nfs_umountall_req 120 - -120 _u_boot_list_2_driver_2_bootmeth_pxe 120 - -120 do_ping 124 - -124 tftp_filename 128 - -128 reg_9_desc_tbl 128 - -128 reg_10_desc_tbl 128 - -128 distro_pxe_boot 128 - -128 tftp_timeout_handler 132 - -132 do_pxe 132 - -132 nfs_umountall_reply 136 - -136 lmb_get_free_size 136 - -136 format_mac_pxe 136 - -136 miiphy_listdev 144 - -144 efi_net_set_dhcp_ack 144 - -144 wget_timeout_handler 148 - -148 nfs_mount_reply 148 - -148 dhcp_packet_process_options 148 - -148 eth_validate_ethaddr_str 152 - -152 do_pxe_get 156 - -156 reg_0_desc_tbl 160 - -160 net_parse_bootfile 160 - -160 miiphy_info 160 - -160 get_pxelinux_path 160 - -160 do_net 164 - -164 net_auto_load 172 - -172 do_net_list 176 - -176 rpc_lookup_reply 180 - -180 nfs_readlink_req 184 - -184 nfs_mount_req 188 - -188 reg_5_desc_tbl 192 - -192 reg_4_desc_tbl 192 - -192 miiphy_speed 200 - -200 miiphy_duplex 200 - -200 nfs_read_req 224 - -224 do_pxe_boot 248 - -248 reg_1_desc_tbl 256 - -256 mii_reg_desc_tbl 256 - -256 nfs_send 260 - -260 wget_start 268 - -268 ping_start 276 - -276 nfs_lookup_reply 280 - -280 rpc_req 300 - -300 eth_initialize 300 - -300 distro_pxe_read_bootflow 300 - -300 nfs_readlink_reply 328 - -328 nfs_lookup_req 328 - -328 ping_receive 332 - -332 pxe_get 376 - -376 nfs_read_reply 396 - -396 wget_send_stored 444 - -444 nfs_start 468 - -468 dhcp_process_options 508 - -508 tftp_send 560 - -560 nfs_handler 580 - -580 bootp_request 612 - -612 dhcp_extended 616 - -616 netboot_common 632 - -632 default_environment 4444 3800 -644 tftp_start 912 - -912 dhcp_handler 1000 - -1000 wget_handler 1092 - -1092 tftp_handler 1304 - -1304 nfs_path_buff 2048 - -2048 do_mii 2124 - -2124 Total: Before=722283, After=738425, chg +2.23% On Thu, 8 Jun 2023 at 02:07, Tom Rini <trini@konsulko.com> wrote: > On Wed, May 24, 2023 at 10:18:13PM +0200, Simon Goldschmidt wrote: > > Hi Maxim, Tom, > > > > On 24.05.2023 16:05, Maxim Uvarov wrote: > > > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > > > > > > > On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > > > > > On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > > > > > > > > > > > On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > > > > > > > Hi Maxim > > > > > > > > > > > > > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov < > maxim.uvarov@linaro.org> > > > > > > wrote: > > > > > > > > > > > > > > > > My measurements for binary after LTO looks like: > > > > > > > > > > > > > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| > diff % > > > > > > > > 870728 | 915000 | 912560 > | > > > > > > 41832 | 4.8 > > > > > > > > > > > > > > > > > > > > > I think you'll need to analyze that a bit more. First of all > I don't > > > > > > > think the '+ping' tab is useful. What is is trying to achieve? > > > > > > > > > > > > > > > > To show the difference of extra bytes if we add a ping app on top. > > > > > > > > > > > > > > > > > - How was LWIP compiled? > > > > > > > > > > > > > > > > It has a really huge configuration. I tried to turn off everything > off > > > > > everything what can impact on size but still make http app work: > > > > > #define LWIP_HAVE_LOOPIF 0 > > > > > #define LWIP_NETCONN 0 > > > > > #define LWIP_SOCKET 0 > > > > > #define SO_REUSE 0 > > > > > #define LWIP_STATS 0 > > > > > #define PPP_SUPPORT 0 > > > > > > > > > > Disabling loopback: > > > > > #define LWIP_NETIF_LOOPBACK 0 > > > > > can lower to 912288 bytes. > > > > > > > > > > And it's the same compilation option (optimization for size) as > the main > > > > > u-boot. I will do more experiments, but I think the goal is not to > turn > > > > off > > > > > everything. > > > > > > > > > > > > > > > > > - Was ipv6 supported? > > > > > > > > > > > > > > > > No. I.e. when I sent results it was enabled on the compilation > stage but > > > > > not used. I just checked that size remains the same if IPv6 is not > even > > > > > compiled. > > > > > > > > > > > > > > > > > - Can we strip it down even further? > > > > > > > > > > > > > > > > > > > > > > > There is always room for optimization. I think I tried to turn off > > > > > everything that is configurable with defines. I can play with > disable IP > > > > > reassembly and things like that or figure out which functions have > more > > > > > size and if it's possible to exclude them. > > > > > > > > > > > > > > > > > In general please give as much information as you can with > what we > > > > > > > gain in functionality from LWIP with those extra bytes of code. > > > > > > > > > > > > > > > > > The main idea is to reuse a maintainable IP stack outside of > U-boot. > > > > LWIP > > > > > can give a nice separation between IP stack code and network > application > > > > > code. I.e. application should not take care about any TCP > details (SYN, > > > > > ACK, retransmission, reassembly etc) and should open connection > and use > > > > > functions similar to recv() and send() to transfer data. Data means > > > > > application data, no network packets. And LWIP allows > > > > > us to do that. > > > > > Because LWIP has an API similar to sockets, it has to be very easy > to > > > > port > > > > > a linux application to LWIP. Then you can test it with a tap > device. Then > > > > > copy sources to U-boot, add a small integration layer (cmd command > to > > > > > call), compile and use. > > > > > > > > > > So my suggestion was: > > > > > - do not maintain new network stack code in the current U-boot. > Use lwip > > > > > sources as an external project. All bugs related to network stack > go to > > > > > lwip project first, then sync with U-boot. > > > > > - maintain network apps code* or > > > > > -- inside U-boot. Write our own code for application and > maintain it > > > > > inside U-boot. > > > > > -- inside LWIP. Add examples to LWIP which are suitable for both > > > > U-boot > > > > > and LWIP. > > > > > > > > > > * Let's define a U-boot network application as a cmd command. It > might be > > > > > ping, wget (http or https download), telnet, arp dns etc.. > > > > > > > > > > Let's consider the real use case, like HTTPS download client. We > need to > > > > > enable TLS connection, validate certificates, then do http > download. > > > > > Looking at the current code of wget command it's quite difficult to > > > > > implement this due to the application having some protol level > things. On > > > > > the other side we can find embedTLS examples to do https download > on > > > > > sockets. If LWIP socket API is ported then the only thing you need > to do > > > > is > > > > > change socket() -> lwip_socket(), recv()->lwip_recv(), > > > > send()->lwip_send() > > > > > and etc, even function names are similar. If LWIP socket API is not > > > > > supported, then use callback API for recv() and send(), which are > also > > > > > easy. > > > > > > > > > > So yes we add extra bytes, but that will allow us to write more > complex > > > > > apps, use standard debug tools, use applications with very minimal > > > > > integration changes, use help from the LWIP community to fix > protocol > > > > bugs, > > > > > etc.. > > > > > Bunch of things already implemented there: > > > > > - ipv6 > > > > > - dhcp > > > > > - snmp > > > > > - igmp > > > > > - dns > > > > > - tcp and udp and raw. > > > > > - loopback > > > > > - netconn > > > > > - socket > > > > > - stats > > > > > - ppp > > > > > (I just followed configurable defines). > > > > > > > > > > > > > > > And please make sure to disable the previous support, my guess fro > that > > > > > > much growth is that you didn't. > > > > > > > > > > > > > > > > # CONFIG_PROT_TCP is not set > > > > > # CONFIG_PROT_UDP is not set > > > > > # CONFIG_UDP_CHECKSUM is not set > > > > > # CONFIG_UDP_FUNCTION_FASTBOOT is not set > > > > > # CONFIG_CMD_WGET is not set > > > > > > > > I think you need to step back and figure out a better way to measure > the > > > > size change and growth. > > > > > > > > I am not interested in a path that long term means two networking > stacks > > > > in U-Boot. > > > > > > > > I am not interested in massively growing the overall binary size for > > > > every platform. Given how much larger just TCP support is, that's > > > > strongly implying a huge growth for the older use cases too. > > > > > > > > But I also suspect given the overall reputation that LWIP enjoys, > > > > there's something amiss here. > > > > > > > > -- > > > > Tom > > > > > > > > > > +cc lwip-devel@ mailing list, maybe they have something to add. > > > > I do think using lwIP instead of "inventing yet another IP stack" is a > > good idea! However, in terms of code size, lwIP will lose against what's > > in U-Boot at present. And this is only natural, as lwIP is a "full-size" > > stack supporting multiple concurrently running applications while the > > current IP stack in U-Boot is rather "crippled" down to just what the > > implementor needed at the time of writing. > > > > One example of this is that (if I remember correctly), U-Boot only has > > one single network packet buffer, while lwIP has support for multiple > > buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track > > of that development in U-Boot about 3 years ago), we're comparing "we > > have implemented everything we need so that it just kind of works" to > > "we can easily add a HTTPS client to download something over the > > internet just by enabling more compile options". > > > > Also, when comparing lwIP to U-Boot TCP code size, keep in mind that > > U-Boot TCP (at least that of some years ago) is far from complete when > > compared to lwIP! > > > > lwIP is meant to be highly configurable and we're always open to add yet > > more options to leave out more code when it's not needed. However, I > > think there are some design decisions that will make lwIP larger than > > the current IP stack in U-Boot. To me, that's a natural result of having > > a "generic code" approach vs "developed to our needs". However, while > > DHCP + BOOTP and even a simple network console was rather easy to > > implement, I would not recommend implementing your own HTTPS download > > but rather using the existing lwIP + apps for that. > > > > In the end, I cannot take the decision from you. In my opinion, lwIP > > would be the better decision in terms of future work load and > > compatibility, but in the short run, it *will* lead to bigger binaries > > at least in some setups. And I do know from my past that it sometimes > > has been a pain to try and stuff a new U-Boot release into the existing > > space of flash or RAM, so that's not an easy decision. > > > > If you do take the lwIP approach however, let us know if we can help! > > Given Maxim's more recent experiments, I'm sure we can come up with > something that works overall. There's hopefully a place or two U-Boot > people can help introduce a tunable or two to lwIP to bring some sizes > down. But I think it's overall looking to be the right direction. > > -- > Tom >
Thanks Maxim, On Thu, 8 Jun 2023 at 13:14, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > Ilias asked to make more clear results to compare the original stack and LWIP stack. So the difference between the current U-boot stack and the LWIP stack with 3 network commands is: > a) 18Kb - ls -lh size > b) 15Kb - bloat-o-meter script total line report. > > BOM=linux/scripts/bloat-o-meter (script) > > 1. 893K - U-boot CMD_NET=n > 2. 928K - U-boot CMD_NET=y TFTP=y PING=y WGET=y > BOM 1-2: Total: Before=692286, After=722283, chg +4.33% > 3. 940K - U-boot CMD_NET=n, LWIP_TFTP=y LWIP_PING=y LWIP_PING=y > BOM 1-3: Total: Before=692286, After=738425, chg +6.66% That's much more readable! I discussed this with Tom over IRC and the size difference is certainly a reasonable trade-off for the extra functionality. Can you tidy up the series and include DHCP and PXE done through LWIP? Thanks /Ilias > > BOM 2-3: > > add/remove: 287/203 grow/shrink: 3/11 up/down: 43459/-27317 (16142) > Function old new delta > tcp_input - 3588 +3588 > tcp_receive - 2884 +2884 > ip4_reass - 1760 +1760 > tcp_output - 1400 +1400 > tcp_write - 1300 +1300 > tcp_slowtmr - 1172 +1172 > httpc_tcp_recv - 1044 +1044 > tftp_recv - 888 +888 > ip4_input - 700 +700 > ip4_frag - 632 +632 > icmp_input - 604 +604 > udp_input - 596 +596 > etharp_input - 512 +512 > tcp_split_unsent_seg - 500 +500 > ip4addr_aton - 492 +492 > tcp_alloc - 484 +484 > ip4_output_if_src - 476 +476 > tcp_close_shutdown - 448 +448 > etharp_query - 436 +436 > httpc_init_connection_common.constprop - 416 +416 > udp_sendto_if_src - 408 +408 > etharp_output - 404 +404 > arp_table - 400 +400 > tcp_connect - 396 +396 > pbuf_alloc - 376 +376 > etharp_find_entry - 372 +372 > tcp_abandon - 368 +368 > tcp_zero_window_probe - 356 +356 > raw_sendto_if_src - 328 +328 > pbuf_copy_partial_pbuf - 328 +328 > ip_reass_free_complete_datagram - 328 +328 > tcp_create_segment - 300 +300 > raw_input - 292 +292 > uboot_lwip_init - 284 +284 > ethernet_input - 284 +284 > etharp_raw - 284 +284 > tcp_output_alloc_header_common.constprop - 280 +280 > cmds - 280 +280 > udp_bind - 276 +276 > tcp_oos_insert_segment - 276 +276 > ip_reass_remove_oldest_datagram - 272 +272 > icmp_send_response - 268 +268 > netif_add - 260 +260 > ping_send - 244 +244 > tcp_rexmit - 232 +232 > tcp_parseopt - 220 +220 > tcp_free_acked_segments.constprop - 220 +220 > send_request - 220 +220 > inet_chksum_pseudo - 216 +216 > ip4addr_ntoa_r - 212 +212 > do_lwip_ping - 212 +212 > tcp_enqueue_flags - 208 +208 > etharp_output_to_arp_index - 208 +208 > netif_set_addr - 204 +204 > tcp_fasttmr - 200 +200 > tcp_rexmit_rto_prepare - 196 +196 > tcp_process_refused_data - 196 +196 > send_data - 196 +196 > lwip_wget - 192 +192 > ethernet_output - 192 +192 > ping_recv - 188 +188 > pbuf_memcmp - 184 +184 > pbuf_copy_partial - 184 +184 > httpc_free_state - 180 +180 > tcp_send_fin - 172 +172 > httpc_recv - 168 +168 > tcp_output_control_segment_netif - 164 +164 > send_error.isra - 164 +164 > do_ops - 164 +164 > raw_sendto - 160 +160 > pbuf_realloc - 160 +160 > pbuf_free - 160 +160 > do_lwip_wget - 160 +160 > do_lwip_tftp - 160 +160 > tftp_init_common - 156 +156 > tcp_rst_netif - 152 +152 > udp_sendto - 144 +144 > tftp_tmr - 144 +144 > tcp_rst - 144 +144 > uboot_lwip_if_init - 140 +140 > tcp_pcb_remove - 140 +140 > tcp_pbuf_prealloc - 140 +140 > sys_timeout_abs - 140 +140 > lwip_tftp - 140 +140 > netif_do_set_ipaddr.isra - 136 +136 > ip4_route - 136 +136 > tcp_netif_ip_addr_changed - 132 +132 > resend_data.isra - 132 +132 > inet_chksum_pbuf - 132 +132 > tcp_output_control_segment - 128 +128 > pbuf_memfind - 128 +128 > lwip_standard_chksum - 128 +128 > tcp_rexmit_fast - 124 +124 > tcp_new_port - 124 +124 > tcp_close_shutdown_fin - 124 +124 > pbuf_add_header_impl - 124 +124 > tcp_send_empty_ack - 120 +120 > httpc_create_request_string.constprop.isra - 120 +120 > tftp_get - 116 +116 > tcp_recved - 116 +116 > tcp_pcb_purge - 116 +116 > tftp_write - 112 +112 > pbuf_free_header - 112 +112 > httpc_tcp_connected - 112 +112 > tftp_error - 108 +108 > send_ack.isra - 108 +108 > low_level_input.constprop - 108 +108 > tcp_input_delayed_close - 104 +104 > close_handle - 100 +100 > sys_untimeout - 96 +96 > memp_pools - 96 +96 > tcp_keepalive - 92 +92 > ip4_addr_isbroadcast_u32 - 92 +92 > init_packet - 92 +92 > tcp_kill_state - 88 +88 > raw_new - 88 +88 > ping_raw_init - 88 +88 > lwip_ping_init - 88 +88 > udp_sendto_if - 84 +84 > tcp_update_rcv_ann_wnd - 84 +84 > tcp_recv_null - 84 +84 > pbuf_remove_header - 84 +84 > pbuf_alloc_reference - 84 +84 > udp_remove - 80 +80 > tcp_get_next_optbyte - 80 +80 > pbuf_alloced_custom - 80 +80 > ip4_input_accept - 80 +80 > httpc_close - 80 +80 > etharp_free_entry - 80 +80 > uboot_lwip_poll - 76 +76 > tcpip_tcp_timer - 76 +76 > udp_netif_ip_addr_changed - 72 +72 > uboot_netif - 72 +72 > tcp_output_alloc_header.constprop - 72 +72 > raw_netif_ip_addr_changed - 72 +72 > tcpip_try_callback - 68 +68 > tcp_timer_needed - 68 +68 > tcp_seg_copy - 68 +68 > tcp_netif_ip_addr_changed_pcblist - 68 +68 > ping_timeout - 68 +68 > ethernetif_input - 68 +68 > udp_new - 64 +64 > pbuf_try_get_at - 64 +64 > sys_timeout - 60 +60 > pbuf_clone - 60 +60 > tcp_seg_free - 56 +56 > pbuf_cat - 56 +56 > netif_get_by_index - 56 +56 > low_level_output - 56 +56 > _u_boot_list_2_cmd_2_lwipinfo - 56 +56 > _u_boot_list_2_cmd_2_lwip - 56 +56 > tftp_state 4 56 +52 > tcp_tmr - 52 +52 > tcp_rexmit_rto - 52 +52 > tcp_segs_free - 48 +48 > tcp_eff_send_mss_netif - 48 +48 > pbuf_skip_const - 48 +48 > ipfrag_free_pbuf_custom - 48 +48 > httpc_tcp_poll - 48 +48 > tcp_free_ooseq - 44 +44 > tcp_close - 44 +44 > pbuf_free_ooseq_callback - 44 +44 > netif_issue_reports - 44 +44 > ip_reass_dequeue_datagram - 44 +44 > httpc_get_internal_addr - 44 +44 > tftp_read - 40 +40 > tftp - 40 +40 > ip_data - 40 +40 > etharp_request - 40 +40 > do_lwip_info - 40 +40 > ulwip_timeout_handler - 36 +36 > raw_bind - 36 +36 > memp_malloc - 36 +36 > ip4_output_if - 36 +36 > tcp_pcb_lists - 32 +32 > pbuf_header_force - 32 +32 > pbuf_clen - 32 +32 > netif_set_up - 32 +32 > netif_set_link_up - 32 +32 > inseg - 32 +32 > inet_chksum - 32 +32 > tcp_next_iss - 28 +28 > pbuf_get_at - 28 +28 > httpc_tcp_err - 28 +28 > do_lwip_init - 28 +28 > tcp_rexmit_rto_commit - 24 +24 > sys_now - 24 +24 > settings - 24 +24 > pbuf_copy - 24 +24 > pbuf_chain - 24 +24 > memp_free - 24 +24 > __func__ 1243 1266 +23 > ulwip_exit - 20 +20 > tcp_trigger_input_pcb_close - 20 +20 > tcp_poll - 20 +20 > ping_send_now - 20 +20 > pbuf_ref - 20 +20 > str - 16 +16 > ip4addr_ntoa - 16 +16 > daddr - 16 +16 > tcp_backoff - 13 +13 > ulwip_loop_set - 12 +12 > ulwip_in_loop - 12 +12 > ulwip_enabled - 12 +12 > ulwip_app_get_err - 12 +12 > udp_recv - 12 +12 > tftp_init_client - 12 +12 > tcp_sent - 12 +12 > tcp_recv - 12 +12 > tcp_free - 12 +12 > tcp_err - 12 +12 > tcp_arg - 12 +12 > net_process_received_packet 800 812 +12 > icmp_time_exceeded - 12 +12 > icmp_dest_unreach - 12 +12 > udp_pcbs - 8 +8 > tftp_open - 8 +8 > tftp_close - 8 +8 > tcphdr_opt2 - 8 +8 > tcphdr - 8 +8 > tcp_tw_pcbs - 8 +8 > tcp_new - 8 +8 > tcp_listen_pcbs - 8 +8 > tcp_input_pcb - 8 +8 > tcp_bound_pcbs - 8 +8 > tcp_active_pcbs - 8 +8 > tcp_abort - 8 +8 > recv_data - 8 +8 > reassdatagrams - 8 +8 > raw_recv - 8 +8 > raw_pcbs - 8 +8 > ping_target - 8 +8 > ping_pcb - 8 +8 > pbuf_add_header - 8 +8 > next_timeout - 8 +8 > netif_null_output_ip4 - 8 +8 > netif_list - 8 +8 > netif_default - 8 +8 > lwip_htons - 8 +8 > lwip_htonl - 8 +8 > httpc_tcp_sent - 8 +8 > tcp_persist_backoff - 7 +7 > ethzero - 6 +6 > ethbroadcast - 6 +6 > ulwip_app_err - 4 +4 > udp_new_ip_type - 4 +4 > uboot_net_use_lwip - 4 +4 > tcpip_tcp_timer_active - 4 +4 > tcp_ticks - 4 +4 > seqno - 4 +4 > mem_trim - 4 +4 > mem_malloc - 4 +4 > mem_free - 4 +4 > loop_lwip - 4 +4 > iss - 4 +4 > ip_target - 4 +4 > ip_chksum_pseudo - 4 +4 > ip_addr_any - 4 +4 > httpc_init_connection - 4 +4 > ackno - 4 +4 > udp_port - 2 +2 > tcplen - 2 +2 > tcphdr_optlen - 2 +2 > tcphdr_opt1len - 2 +2 > tcp_port - 2 +2 > tcp_optidx - 2 +2 > recv_acked - 2 +2 > ping_seq_num - 2 +2 > memp_UDP_PCB - 2 +2 > memp_TCP_SEG - 2 +2 > memp_TCP_PCB_LISTEN - 2 +2 > memp_TCP_PCB - 2 +2 > memp_TCPIP_MSG_INPKT - 2 +2 > memp_TCPIP_MSG_API - 2 +2 > memp_SYS_TIMEOUT - 2 +2 > memp_REASSDATA - 2 +2 > memp_RAW_PCB - 2 +2 > memp_PBUF_POOL - 2 +2 > memp_PBUF - 2 +2 > memp_FRAG_PBUF - 2 +2 > ip_reass_pbufcount - 2 +2 > ip_id - 2 +2 > tcp_timer_ctr - 1 +1 > tcp_timer - 1 +1 > tcp_active_pcbs_changed - 1 +1 > recv_flags - 1 +1 > pbuf_free_ooseq_pending - 1 +1 > netif_num - 1 +1 > flags - 1 +1 > etharp_cached_entry - 1 +1 > supported_nfs_versions 1 - -1 > retry_action 1 - -1 > net_boot_file_name_explicit 1 - -1 > dhcp_option_overload 1 - -1 > tftp_windowsize 2 - -2 > tftp_window_size_option 2 - -2 > tftp_next_ack 2 - -2 > tftp_last_nack 2 - -2 > tftp_block_size_option 2 - -2 > tftp_block_size 2 - -2 > ping_seq_number 2 - -2 > last_op 2 - -2 > env_flags_vartype_rep 7 5 -2 > linefeed 3 - -3 > wget_timeout_count 4 - -4 > wget_loop_state 4 - -4 > web_server_ip 4 - -4 > timeout_count_max 4 - -4 > timeout_count 4 - -4 > tftp_timeout_count_max 4 - -4 > tftp_remote_port 4 - -4 > tftp_remote_ip 4 - -4 > tftp_our_port 4 - -4 > saved_tftp_block_size_option 4 - -4 > retry_tcp_seq_num 4 - -4 > retry_tcp_ack_num 4 - -4 > retry_len 4 - -4 > pkt_q_idx 4 - -4 > packets 4 - -4 > our_port 4 - -4 > nfs_timeout_count 4 - -4 > nfs_state 4 - -4 > nfs_server_port 4 - -4 > nfs_server_mount_port 4 - -4 > nfs_server_ip 4 - -4 > nfs_our_port 4 - -4 > nfs_offset 4 - -4 > nfs_len 4 - -4 > nfs_download_state 4 - -4 > net_ping_ip 4 - -4 > net_dns_server 4 - -4 > net_boot_file_expected_size_in_blocks 4 - -4 > last_reg_lo 4 - -4 > last_reg_hi 4 - -4 > last_mask 4 - -4 > last_data 4 - -4 > last_addr_lo 4 - -4 > last_addr_hi 4 - -4 > initial_data_seq_num 4 - -4 > http_ok 4 - -4 > fs_mounted 4 - -4 > filefh3_length 4 - -4 > eth_common_init 4 - -4 > dummy_handler 8 4 -4 > dhcp_state 4 - -4 > dhcp_server_ip 4 - -4 > dhcp_leasetime 4 - -4 > current_wget_state 4 - -4 > bootp_try 4 - -4 > bootp_num_ids 4 - -4 > http_eom 5 - -5 > bootfile1 5 - -5 > timeout_ms 8 - -8 > time_taken_max 8 - -8 > time_start 16 8 -8 > tftp_prev_block 8 - -8 > tftp_load_size 8 - -8 > tftp_load_addr 8 - -8 > tftp_cur_block 8 - -8 > tftp_block_wrap_offset 8 - -8 > tftp_block_wrap 8 - -8 > rpc_id 8 - -8 > nfs_path 8 - -8 > nfs_filename 8 - -8 > miiphy_is_1000base_x 8 - -8 > init_sequence_r 264 256 -8 > image_url 8 - -8 > distro_pxe_check 8 - -8 > current_mii 8 - -8 > content_length 8 - -8 > bootp_timeout 8 - -8 > bootp_start 8 - -8 > tcp_get_tcp_state 12 - -12 > do_wget 12 - -12 > do_tftpb 12 - -12 > do_nfs 12 - -12 > do_dhcp 12 - -12 > do_bootp 12 - -12 > default_filename 13 - -13 > bootfile3 14 - -14 > content_len 15 - -15 > reg_2_desc_tbl 16 - -16 > pkt_q 16 - -16 > mii_devs 16 - -16 > bootp_ids 16 - -16 > miiphy_get_current_dev 20 - -20 > tcp_set_tcp_handler 24 - -24 > pxe_default_paths 24 - -24 > net_set_udp_handler 24 - -24 > net_check_prereq 256 232 -24 > miiphy_init 28 - -28 > ping_timeout_handler 32 - -32 > net_nis_domain 32 - -32 > net_hostname 32 - -32 > distro_bootmeth_pxe_ids 32 - -32 > dirfh 32 - -32 > initr_net 36 - -36 > distro_bootmeth_pxe_bind 36 - -36 > ip_to_string 40 - -40 > distro_bootmeth_pxe_ops 40 - -40 > net_send_udp_packet 44 - -44 > label_boot 1944 1900 -44 > env_flags_validate 632 588 -44 > reg_3_desc_tbl 48 - -48 > do_get_tftp 56 - -56 > cmd_net 56 - -56 > _u_boot_list_2_cmd_2_wget 56 - -56 > _u_boot_list_2_cmd_2_tftpboot 56 - -56 > _u_boot_list_2_cmd_2_pxe 56 - -56 > _u_boot_list_2_cmd_2_ping 56 - -56 > _u_boot_list_2_cmd_2_nfs 56 - -56 > _u_boot_list_2_cmd_2_net 56 - -56 > _u_boot_list_2_cmd_2_mii 56 - -56 > _u_boot_list_2_cmd_2_dhcp 56 - -56 > _u_boot_list_2_cmd_2_bootp 56 - -56 > net_loop 652 592 -60 > net_eth_hdr_size 60 - -60 > bootp_reset 60 - -60 > net_root_path 64 - -64 > filefh 64 - -64 > do_bootvx 816 748 -68 > miiphy_set_current_dev 72 - -72 > basename 72 - -72 > pxe_get_file_size 76 - -76 > copy_filename 76 - -76 > distro_pxe_getfile 80 - -80 > tftp_init_load_addr 92 - -92 > miiphy_read 92 - -92 > extract_range 92 - -92 > miiphy_write 96 - -96 > miiphy_get_active_dev 96 - -96 > distro_pxe_read_file 96 - -96 > wget_fail 104 - -104 > skip_num 104 - -104 > miiphy_get_dev_by_name 104 - -104 > dump_field 104 - -104 > do_bdinfo 432 328 -104 > bootp_timeout_handler 104 - -104 > nfs_timeout_handler 108 - -108 > cmd_pxe_sub 112 - -112 > nfs_umountall_req 120 - -120 > _u_boot_list_2_driver_2_bootmeth_pxe 120 - -120 > do_ping 124 - -124 > tftp_filename 128 - -128 > reg_9_desc_tbl 128 - -128 > reg_10_desc_tbl 128 - -128 > distro_pxe_boot 128 - -128 > tftp_timeout_handler 132 - -132 > do_pxe 132 - -132 > nfs_umountall_reply 136 - -136 > lmb_get_free_size 136 - -136 > format_mac_pxe 136 - -136 > miiphy_listdev 144 - -144 > efi_net_set_dhcp_ack 144 - -144 > wget_timeout_handler 148 - -148 > nfs_mount_reply 148 - -148 > dhcp_packet_process_options 148 - -148 > eth_validate_ethaddr_str 152 - -152 > do_pxe_get 156 - -156 > reg_0_desc_tbl 160 - -160 > net_parse_bootfile 160 - -160 > miiphy_info 160 - -160 > get_pxelinux_path 160 - -160 > do_net 164 - -164 > net_auto_load 172 - -172 > do_net_list 176 - -176 > rpc_lookup_reply 180 - -180 > nfs_readlink_req 184 - -184 > nfs_mount_req 188 - -188 > reg_5_desc_tbl 192 - -192 > reg_4_desc_tbl 192 - -192 > miiphy_speed 200 - -200 > miiphy_duplex 200 - -200 > nfs_read_req 224 - -224 > do_pxe_boot 248 - -248 > reg_1_desc_tbl 256 - -256 > mii_reg_desc_tbl 256 - -256 > nfs_send 260 - -260 > wget_start 268 - -268 > ping_start 276 - -276 > nfs_lookup_reply 280 - -280 > rpc_req 300 - -300 > eth_initialize 300 - -300 > distro_pxe_read_bootflow 300 - -300 > nfs_readlink_reply 328 - -328 > nfs_lookup_req 328 - -328 > ping_receive 332 - -332 > pxe_get 376 - -376 > nfs_read_reply 396 - -396 > wget_send_stored 444 - -444 > nfs_start 468 - -468 > dhcp_process_options 508 - -508 > tftp_send 560 - -560 > nfs_handler 580 - -580 > bootp_request 612 - -612 > dhcp_extended 616 - -616 > netboot_common 632 - -632 > default_environment 4444 3800 -644 > tftp_start 912 - -912 > dhcp_handler 1000 - -1000 > wget_handler 1092 - -1092 > tftp_handler 1304 - -1304 > nfs_path_buff 2048 - -2048 > do_mii 2124 - -2124 > Total: Before=722283, After=738425, chg +2.23% > > > > On Thu, 8 Jun 2023 at 02:07, Tom Rini <trini@konsulko.com> wrote: >> >> On Wed, May 24, 2023 at 10:18:13PM +0200, Simon Goldschmidt wrote: >> > Hi Maxim, Tom, >> > >> > On 24.05.2023 16:05, Maxim Uvarov wrote: >> > > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: >> > > >> > > > On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: >> > > > > On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: >> > > > > >> > > > > > On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: >> > > > > > > Hi Maxim >> > > > > > > >> > > > > > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> >> > > > > > wrote: >> > > > > > > > >> > > > > > > > My measurements for binary after LTO looks like: >> > > > > > > > >> > > > > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % >> > > > > > > > 870728 | 915000 | 912560 | >> > > > > > 41832 | 4.8 >> > > > > > > >> > > > > > > >> > > > > > > I think you'll need to analyze that a bit more. First of all I don't >> > > > > > > think the '+ping' tab is useful. What is is trying to achieve? >> > > > > > >> > > > > >> > > > > To show the difference of extra bytes if we add a ping app on top. >> > > > > >> > > > > >> > > > > > > - How was LWIP compiled? >> > > > > > >> > > > > >> > > > > It has a really huge configuration. I tried to turn off everything off >> > > > > everything what can impact on size but still make http app work: >> > > > > #define LWIP_HAVE_LOOPIF 0 >> > > > > #define LWIP_NETCONN 0 >> > > > > #define LWIP_SOCKET 0 >> > > > > #define SO_REUSE 0 >> > > > > #define LWIP_STATS 0 >> > > > > #define PPP_SUPPORT 0 >> > > > > >> > > > > Disabling loopback: >> > > > > #define LWIP_NETIF_LOOPBACK 0 >> > > > > can lower to 912288 bytes. >> > > > > >> > > > > And it's the same compilation option (optimization for size) as the main >> > > > > u-boot. I will do more experiments, but I think the goal is not to turn >> > > > off >> > > > > everything. >> > > > > >> > > > > >> > > > > > > - Was ipv6 supported? >> > > > > > >> > > > > >> > > > > No. I.e. when I sent results it was enabled on the compilation stage but >> > > > > not used. I just checked that size remains the same if IPv6 is not even >> > > > > compiled. >> > > > > >> > > > > >> > > > > > > - Can we strip it down even further? >> > > > > > > >> > > > > > >> > > > > >> > > > > There is always room for optimization. I think I tried to turn off >> > > > > everything that is configurable with defines. I can play with disable IP >> > > > > reassembly and things like that or figure out which functions have more >> > > > > size and if it's possible to exclude them. >> > > > > >> > > > > >> > > > > > > In general please give as much information as you can with what we >> > > > > > > gain in functionality from LWIP with those extra bytes of code. >> > > > > > >> > > > > > >> > > > > The main idea is to reuse a maintainable IP stack outside of U-boot. >> > > > LWIP >> > > > > can give a nice separation between IP stack code and network application >> > > > > code. I.e. application should not take care about any TCP details (SYN, >> > > > > ACK, retransmission, reassembly etc) and should open connection and use >> > > > > functions similar to recv() and send() to transfer data. Data means >> > > > > application data, no network packets. And LWIP allows >> > > > > us to do that. >> > > > > Because LWIP has an API similar to sockets, it has to be very easy to >> > > > port >> > > > > a linux application to LWIP. Then you can test it with a tap device. Then >> > > > > copy sources to U-boot, add a small integration layer (cmd command to >> > > > > call), compile and use. >> > > > > >> > > > > So my suggestion was: >> > > > > - do not maintain new network stack code in the current U-boot. Use lwip >> > > > > sources as an external project. All bugs related to network stack go to >> > > > > lwip project first, then sync with U-boot. >> > > > > - maintain network apps code* or >> > > > > -- inside U-boot. Write our own code for application and maintain it >> > > > > inside U-boot. >> > > > > -- inside LWIP. Add examples to LWIP which are suitable for both >> > > > U-boot >> > > > > and LWIP. >> > > > > >> > > > > * Let's define a U-boot network application as a cmd command. It might be >> > > > > ping, wget (http or https download), telnet, arp dns etc.. >> > > > > >> > > > > Let's consider the real use case, like HTTPS download client. We need to >> > > > > enable TLS connection, validate certificates, then do http download. >> > > > > Looking at the current code of wget command it's quite difficult to >> > > > > implement this due to the application having some protol level things. On >> > > > > the other side we can find embedTLS examples to do https download on >> > > > > sockets. If LWIP socket API is ported then the only thing you need to do >> > > > is >> > > > > change socket() -> lwip_socket(), recv()->lwip_recv(), >> > > > send()->lwip_send() >> > > > > and etc, even function names are similar. If LWIP socket API is not >> > > > > supported, then use callback API for recv() and send(), which are also >> > > > > easy. >> > > > > >> > > > > So yes we add extra bytes, but that will allow us to write more complex >> > > > > apps, use standard debug tools, use applications with very minimal >> > > > > integration changes, use help from the LWIP community to fix protocol >> > > > bugs, >> > > > > etc.. >> > > > > Bunch of things already implemented there: >> > > > > - ipv6 >> > > > > - dhcp >> > > > > - snmp >> > > > > - igmp >> > > > > - dns >> > > > > - tcp and udp and raw. >> > > > > - loopback >> > > > > - netconn >> > > > > - socket >> > > > > - stats >> > > > > - ppp >> > > > > (I just followed configurable defines). >> > > > > >> > > > > >> > > > > And please make sure to disable the previous support, my guess fro that >> > > > > > much growth is that you didn't. >> > > > > > >> > > > > >> > > > > # CONFIG_PROT_TCP is not set >> > > > > # CONFIG_PROT_UDP is not set >> > > > > # CONFIG_UDP_CHECKSUM is not set >> > > > > # CONFIG_UDP_FUNCTION_FASTBOOT is not set >> > > > > # CONFIG_CMD_WGET is not set >> > > > >> > > > I think you need to step back and figure out a better way to measure the >> > > > size change and growth. >> > > > >> > > > I am not interested in a path that long term means two networking stacks >> > > > in U-Boot. >> > > > >> > > > I am not interested in massively growing the overall binary size for >> > > > every platform. Given how much larger just TCP support is, that's >> > > > strongly implying a huge growth for the older use cases too. >> > > > >> > > > But I also suspect given the overall reputation that LWIP enjoys, >> > > > there's something amiss here. >> > > > >> > > > -- >> > > > Tom >> > > > >> > > >> > > +cc lwip-devel@ mailing list, maybe they have something to add. >> > >> > I do think using lwIP instead of "inventing yet another IP stack" is a >> > good idea! However, in terms of code size, lwIP will lose against what's >> > in U-Boot at present. And this is only natural, as lwIP is a "full-size" >> > stack supporting multiple concurrently running applications while the >> > current IP stack in U-Boot is rather "crippled" down to just what the >> > implementor needed at the time of writing. >> > >> > One example of this is that (if I remember correctly), U-Boot only has >> > one single network packet buffer, while lwIP has support for multiple >> > buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track >> > of that development in U-Boot about 3 years ago), we're comparing "we >> > have implemented everything we need so that it just kind of works" to >> > "we can easily add a HTTPS client to download something over the >> > internet just by enabling more compile options". >> > >> > Also, when comparing lwIP to U-Boot TCP code size, keep in mind that >> > U-Boot TCP (at least that of some years ago) is far from complete when >> > compared to lwIP! >> > >> > lwIP is meant to be highly configurable and we're always open to add yet >> > more options to leave out more code when it's not needed. However, I >> > think there are some design decisions that will make lwIP larger than >> > the current IP stack in U-Boot. To me, that's a natural result of having >> > a "generic code" approach vs "developed to our needs". However, while >> > DHCP + BOOTP and even a simple network console was rather easy to >> > implement, I would not recommend implementing your own HTTPS download >> > but rather using the existing lwIP + apps for that. >> > >> > In the end, I cannot take the decision from you. In my opinion, lwIP >> > would be the better decision in terms of future work load and >> > compatibility, but in the short run, it *will* lead to bigger binaries >> > at least in some setups. And I do know from my past that it sometimes >> > has been a pain to try and stuff a new U-Boot release into the existing >> > space of flash or RAM, so that's not an easy decision. >> > >> > If you do take the lwIP approach however, let us know if we can help! >> >> Given Maxim's more recent experiments, I'm sure we can come up with >> something that works overall. There's hopefully a place or two U-Boot >> people can help introduce a tunable or two to lwIP to bring some sizes >> down. But I think it's overall looking to be the right direction. >> >> -- >> Tom
On Thu, Jun 8, 2023 at 6:56 PM Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > Thanks Maxim, > > On Thu, 8 Jun 2023 at 13:14, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > > > Ilias asked to make more clear results to compare the original stack and LWIP stack. So the difference between the current U-boot stack and the LWIP stack with 3 network commands is: > > a) 18Kb - ls -lh size > > b) 15Kb - bloat-o-meter script total line report. > > > > BOM=linux/scripts/bloat-o-meter (script) > > > > 1. 893K - U-boot CMD_NET=n > > 2. 928K - U-boot CMD_NET=y TFTP=y PING=y WGET=y > > BOM 1-2: Total: Before=692286, After=722283, chg +4.33% > > 3. 940K - U-boot CMD_NET=n, LWIP_TFTP=y LWIP_PING=y LWIP_PING=y > > BOM 1-3: Total: Before=692286, After=738425, chg +6.66% > > That's much more readable! I discussed this with Tom over IRC and the > size difference is certainly a reasonable trade-off for the extra > functionality. Yes, this looks great! I'm also sure with a closer look there could be further optimisations here in time as well. I feel having a widely used IP stack that's also widely audited is a big win here, it will also provide things like HTTP, DNS and IPv6 without having to reinvent the wheel. > Can you tidy up the series and include DHCP and PXE done through LWIP? I'll look forward to this. > Thanks > /Ilias > > > > BOM 2-3: > > > > add/remove: 287/203 grow/shrink: 3/11 up/down: 43459/-27317 (16142) > > Function old new delta > > tcp_input - 3588 +3588 > > tcp_receive - 2884 +2884 > > ip4_reass - 1760 +1760 > > tcp_output - 1400 +1400 > > tcp_write - 1300 +1300 > > tcp_slowtmr - 1172 +1172 > > httpc_tcp_recv - 1044 +1044 > > tftp_recv - 888 +888 > > ip4_input - 700 +700 > > ip4_frag - 632 +632 > > icmp_input - 604 +604 > > udp_input - 596 +596 > > etharp_input - 512 +512 > > tcp_split_unsent_seg - 500 +500 > > ip4addr_aton - 492 +492 > > tcp_alloc - 484 +484 > > ip4_output_if_src - 476 +476 > > tcp_close_shutdown - 448 +448 > > etharp_query - 436 +436 > > httpc_init_connection_common.constprop - 416 +416 > > udp_sendto_if_src - 408 +408 > > etharp_output - 404 +404 > > arp_table - 400 +400 > > tcp_connect - 396 +396 > > pbuf_alloc - 376 +376 > > etharp_find_entry - 372 +372 > > tcp_abandon - 368 +368 > > tcp_zero_window_probe - 356 +356 > > raw_sendto_if_src - 328 +328 > > pbuf_copy_partial_pbuf - 328 +328 > > ip_reass_free_complete_datagram - 328 +328 > > tcp_create_segment - 300 +300 > > raw_input - 292 +292 > > uboot_lwip_init - 284 +284 > > ethernet_input - 284 +284 > > etharp_raw - 284 +284 > > tcp_output_alloc_header_common.constprop - 280 +280 > > cmds - 280 +280 > > udp_bind - 276 +276 > > tcp_oos_insert_segment - 276 +276 > > ip_reass_remove_oldest_datagram - 272 +272 > > icmp_send_response - 268 +268 > > netif_add - 260 +260 > > ping_send - 244 +244 > > tcp_rexmit - 232 +232 > > tcp_parseopt - 220 +220 > > tcp_free_acked_segments.constprop - 220 +220 > > send_request - 220 +220 > > inet_chksum_pseudo - 216 +216 > > ip4addr_ntoa_r - 212 +212 > > do_lwip_ping - 212 +212 > > tcp_enqueue_flags - 208 +208 > > etharp_output_to_arp_index - 208 +208 > > netif_set_addr - 204 +204 > > tcp_fasttmr - 200 +200 > > tcp_rexmit_rto_prepare - 196 +196 > > tcp_process_refused_data - 196 +196 > > send_data - 196 +196 > > lwip_wget - 192 +192 > > ethernet_output - 192 +192 > > ping_recv - 188 +188 > > pbuf_memcmp - 184 +184 > > pbuf_copy_partial - 184 +184 > > httpc_free_state - 180 +180 > > tcp_send_fin - 172 +172 > > httpc_recv - 168 +168 > > tcp_output_control_segment_netif - 164 +164 > > send_error.isra - 164 +164 > > do_ops - 164 +164 > > raw_sendto - 160 +160 > > pbuf_realloc - 160 +160 > > pbuf_free - 160 +160 > > do_lwip_wget - 160 +160 > > do_lwip_tftp - 160 +160 > > tftp_init_common - 156 +156 > > tcp_rst_netif - 152 +152 > > udp_sendto - 144 +144 > > tftp_tmr - 144 +144 > > tcp_rst - 144 +144 > > uboot_lwip_if_init - 140 +140 > > tcp_pcb_remove - 140 +140 > > tcp_pbuf_prealloc - 140 +140 > > sys_timeout_abs - 140 +140 > > lwip_tftp - 140 +140 > > netif_do_set_ipaddr.isra - 136 +136 > > ip4_route - 136 +136 > > tcp_netif_ip_addr_changed - 132 +132 > > resend_data.isra - 132 +132 > > inet_chksum_pbuf - 132 +132 > > tcp_output_control_segment - 128 +128 > > pbuf_memfind - 128 +128 > > lwip_standard_chksum - 128 +128 > > tcp_rexmit_fast - 124 +124 > > tcp_new_port - 124 +124 > > tcp_close_shutdown_fin - 124 +124 > > pbuf_add_header_impl - 124 +124 > > tcp_send_empty_ack - 120 +120 > > httpc_create_request_string.constprop.isra - 120 +120 > > tftp_get - 116 +116 > > tcp_recved - 116 +116 > > tcp_pcb_purge - 116 +116 > > tftp_write - 112 +112 > > pbuf_free_header - 112 +112 > > httpc_tcp_connected - 112 +112 > > tftp_error - 108 +108 > > send_ack.isra - 108 +108 > > low_level_input.constprop - 108 +108 > > tcp_input_delayed_close - 104 +104 > > close_handle - 100 +100 > > sys_untimeout - 96 +96 > > memp_pools - 96 +96 > > tcp_keepalive - 92 +92 > > ip4_addr_isbroadcast_u32 - 92 +92 > > init_packet - 92 +92 > > tcp_kill_state - 88 +88 > > raw_new - 88 +88 > > ping_raw_init - 88 +88 > > lwip_ping_init - 88 +88 > > udp_sendto_if - 84 +84 > > tcp_update_rcv_ann_wnd - 84 +84 > > tcp_recv_null - 84 +84 > > pbuf_remove_header - 84 +84 > > pbuf_alloc_reference - 84 +84 > > udp_remove - 80 +80 > > tcp_get_next_optbyte - 80 +80 > > pbuf_alloced_custom - 80 +80 > > ip4_input_accept - 80 +80 > > httpc_close - 80 +80 > > etharp_free_entry - 80 +80 > > uboot_lwip_poll - 76 +76 > > tcpip_tcp_timer - 76 +76 > > udp_netif_ip_addr_changed - 72 +72 > > uboot_netif - 72 +72 > > tcp_output_alloc_header.constprop - 72 +72 > > raw_netif_ip_addr_changed - 72 +72 > > tcpip_try_callback - 68 +68 > > tcp_timer_needed - 68 +68 > > tcp_seg_copy - 68 +68 > > tcp_netif_ip_addr_changed_pcblist - 68 +68 > > ping_timeout - 68 +68 > > ethernetif_input - 68 +68 > > udp_new - 64 +64 > > pbuf_try_get_at - 64 +64 > > sys_timeout - 60 +60 > > pbuf_clone - 60 +60 > > tcp_seg_free - 56 +56 > > pbuf_cat - 56 +56 > > netif_get_by_index - 56 +56 > > low_level_output - 56 +56 > > _u_boot_list_2_cmd_2_lwipinfo - 56 +56 > > _u_boot_list_2_cmd_2_lwip - 56 +56 > > tftp_state 4 56 +52 > > tcp_tmr - 52 +52 > > tcp_rexmit_rto - 52 +52 > > tcp_segs_free - 48 +48 > > tcp_eff_send_mss_netif - 48 +48 > > pbuf_skip_const - 48 +48 > > ipfrag_free_pbuf_custom - 48 +48 > > httpc_tcp_poll - 48 +48 > > tcp_free_ooseq - 44 +44 > > tcp_close - 44 +44 > > pbuf_free_ooseq_callback - 44 +44 > > netif_issue_reports - 44 +44 > > ip_reass_dequeue_datagram - 44 +44 > > httpc_get_internal_addr - 44 +44 > > tftp_read - 40 +40 > > tftp - 40 +40 > > ip_data - 40 +40 > > etharp_request - 40 +40 > > do_lwip_info - 40 +40 > > ulwip_timeout_handler - 36 +36 > > raw_bind - 36 +36 > > memp_malloc - 36 +36 > > ip4_output_if - 36 +36 > > tcp_pcb_lists - 32 +32 > > pbuf_header_force - 32 +32 > > pbuf_clen - 32 +32 > > netif_set_up - 32 +32 > > netif_set_link_up - 32 +32 > > inseg - 32 +32 > > inet_chksum - 32 +32 > > tcp_next_iss - 28 +28 > > pbuf_get_at - 28 +28 > > httpc_tcp_err - 28 +28 > > do_lwip_init - 28 +28 > > tcp_rexmit_rto_commit - 24 +24 > > sys_now - 24 +24 > > settings - 24 +24 > > pbuf_copy - 24 +24 > > pbuf_chain - 24 +24 > > memp_free - 24 +24 > > __func__ 1243 1266 +23 > > ulwip_exit - 20 +20 > > tcp_trigger_input_pcb_close - 20 +20 > > tcp_poll - 20 +20 > > ping_send_now - 20 +20 > > pbuf_ref - 20 +20 > > str - 16 +16 > > ip4addr_ntoa - 16 +16 > > daddr - 16 +16 > > tcp_backoff - 13 +13 > > ulwip_loop_set - 12 +12 > > ulwip_in_loop - 12 +12 > > ulwip_enabled - 12 +12 > > ulwip_app_get_err - 12 +12 > > udp_recv - 12 +12 > > tftp_init_client - 12 +12 > > tcp_sent - 12 +12 > > tcp_recv - 12 +12 > > tcp_free - 12 +12 > > tcp_err - 12 +12 > > tcp_arg - 12 +12 > > net_process_received_packet 800 812 +12 > > icmp_time_exceeded - 12 +12 > > icmp_dest_unreach - 12 +12 > > udp_pcbs - 8 +8 > > tftp_open - 8 +8 > > tftp_close - 8 +8 > > tcphdr_opt2 - 8 +8 > > tcphdr - 8 +8 > > tcp_tw_pcbs - 8 +8 > > tcp_new - 8 +8 > > tcp_listen_pcbs - 8 +8 > > tcp_input_pcb - 8 +8 > > tcp_bound_pcbs - 8 +8 > > tcp_active_pcbs - 8 +8 > > tcp_abort - 8 +8 > > recv_data - 8 +8 > > reassdatagrams - 8 +8 > > raw_recv - 8 +8 > > raw_pcbs - 8 +8 > > ping_target - 8 +8 > > ping_pcb - 8 +8 > > pbuf_add_header - 8 +8 > > next_timeout - 8 +8 > > netif_null_output_ip4 - 8 +8 > > netif_list - 8 +8 > > netif_default - 8 +8 > > lwip_htons - 8 +8 > > lwip_htonl - 8 +8 > > httpc_tcp_sent - 8 +8 > > tcp_persist_backoff - 7 +7 > > ethzero - 6 +6 > > ethbroadcast - 6 +6 > > ulwip_app_err - 4 +4 > > udp_new_ip_type - 4 +4 > > uboot_net_use_lwip - 4 +4 > > tcpip_tcp_timer_active - 4 +4 > > tcp_ticks - 4 +4 > > seqno - 4 +4 > > mem_trim - 4 +4 > > mem_malloc - 4 +4 > > mem_free - 4 +4 > > loop_lwip - 4 +4 > > iss - 4 +4 > > ip_target - 4 +4 > > ip_chksum_pseudo - 4 +4 > > ip_addr_any - 4 +4 > > httpc_init_connection - 4 +4 > > ackno - 4 +4 > > udp_port - 2 +2 > > tcplen - 2 +2 > > tcphdr_optlen - 2 +2 > > tcphdr_opt1len - 2 +2 > > tcp_port - 2 +2 > > tcp_optidx - 2 +2 > > recv_acked - 2 +2 > > ping_seq_num - 2 +2 > > memp_UDP_PCB - 2 +2 > > memp_TCP_SEG - 2 +2 > > memp_TCP_PCB_LISTEN - 2 +2 > > memp_TCP_PCB - 2 +2 > > memp_TCPIP_MSG_INPKT - 2 +2 > > memp_TCPIP_MSG_API - 2 +2 > > memp_SYS_TIMEOUT - 2 +2 > > memp_REASSDATA - 2 +2 > > memp_RAW_PCB - 2 +2 > > memp_PBUF_POOL - 2 +2 > > memp_PBUF - 2 +2 > > memp_FRAG_PBUF - 2 +2 > > ip_reass_pbufcount - 2 +2 > > ip_id - 2 +2 > > tcp_timer_ctr - 1 +1 > > tcp_timer - 1 +1 > > tcp_active_pcbs_changed - 1 +1 > > recv_flags - 1 +1 > > pbuf_free_ooseq_pending - 1 +1 > > netif_num - 1 +1 > > flags - 1 +1 > > etharp_cached_entry - 1 +1 > > supported_nfs_versions 1 - -1 > > retry_action 1 - -1 > > net_boot_file_name_explicit 1 - -1 > > dhcp_option_overload 1 - -1 > > tftp_windowsize 2 - -2 > > tftp_window_size_option 2 - -2 > > tftp_next_ack 2 - -2 > > tftp_last_nack 2 - -2 > > tftp_block_size_option 2 - -2 > > tftp_block_size 2 - -2 > > ping_seq_number 2 - -2 > > last_op 2 - -2 > > env_flags_vartype_rep 7 5 -2 > > linefeed 3 - -3 > > wget_timeout_count 4 - -4 > > wget_loop_state 4 - -4 > > web_server_ip 4 - -4 > > timeout_count_max 4 - -4 > > timeout_count 4 - -4 > > tftp_timeout_count_max 4 - -4 > > tftp_remote_port 4 - -4 > > tftp_remote_ip 4 - -4 > > tftp_our_port 4 - -4 > > saved_tftp_block_size_option 4 - -4 > > retry_tcp_seq_num 4 - -4 > > retry_tcp_ack_num 4 - -4 > > retry_len 4 - -4 > > pkt_q_idx 4 - -4 > > packets 4 - -4 > > our_port 4 - -4 > > nfs_timeout_count 4 - -4 > > nfs_state 4 - -4 > > nfs_server_port 4 - -4 > > nfs_server_mount_port 4 - -4 > > nfs_server_ip 4 - -4 > > nfs_our_port 4 - -4 > > nfs_offset 4 - -4 > > nfs_len 4 - -4 > > nfs_download_state 4 - -4 > > net_ping_ip 4 - -4 > > net_dns_server 4 - -4 > > net_boot_file_expected_size_in_blocks 4 - -4 > > last_reg_lo 4 - -4 > > last_reg_hi 4 - -4 > > last_mask 4 - -4 > > last_data 4 - -4 > > last_addr_lo 4 - -4 > > last_addr_hi 4 - -4 > > initial_data_seq_num 4 - -4 > > http_ok 4 - -4 > > fs_mounted 4 - -4 > > filefh3_length 4 - -4 > > eth_common_init 4 - -4 > > dummy_handler 8 4 -4 > > dhcp_state 4 - -4 > > dhcp_server_ip 4 - -4 > > dhcp_leasetime 4 - -4 > > current_wget_state 4 - -4 > > bootp_try 4 - -4 > > bootp_num_ids 4 - -4 > > http_eom 5 - -5 > > bootfile1 5 - -5 > > timeout_ms 8 - -8 > > time_taken_max 8 - -8 > > time_start 16 8 -8 > > tftp_prev_block 8 - -8 > > tftp_load_size 8 - -8 > > tftp_load_addr 8 - -8 > > tftp_cur_block 8 - -8 > > tftp_block_wrap_offset 8 - -8 > > tftp_block_wrap 8 - -8 > > rpc_id 8 - -8 > > nfs_path 8 - -8 > > nfs_filename 8 - -8 > > miiphy_is_1000base_x 8 - -8 > > init_sequence_r 264 256 -8 > > image_url 8 - -8 > > distro_pxe_check 8 - -8 > > current_mii 8 - -8 > > content_length 8 - -8 > > bootp_timeout 8 - -8 > > bootp_start 8 - -8 > > tcp_get_tcp_state 12 - -12 > > do_wget 12 - -12 > > do_tftpb 12 - -12 > > do_nfs 12 - -12 > > do_dhcp 12 - -12 > > do_bootp 12 - -12 > > default_filename 13 - -13 > > bootfile3 14 - -14 > > content_len 15 - -15 > > reg_2_desc_tbl 16 - -16 > > pkt_q 16 - -16 > > mii_devs 16 - -16 > > bootp_ids 16 - -16 > > miiphy_get_current_dev 20 - -20 > > tcp_set_tcp_handler 24 - -24 > > pxe_default_paths 24 - -24 > > net_set_udp_handler 24 - -24 > > net_check_prereq 256 232 -24 > > miiphy_init 28 - -28 > > ping_timeout_handler 32 - -32 > > net_nis_domain 32 - -32 > > net_hostname 32 - -32 > > distro_bootmeth_pxe_ids 32 - -32 > > dirfh 32 - -32 > > initr_net 36 - -36 > > distro_bootmeth_pxe_bind 36 - -36 > > ip_to_string 40 - -40 > > distro_bootmeth_pxe_ops 40 - -40 > > net_send_udp_packet 44 - -44 > > label_boot 1944 1900 -44 > > env_flags_validate 632 588 -44 > > reg_3_desc_tbl 48 - -48 > > do_get_tftp 56 - -56 > > cmd_net 56 - -56 > > _u_boot_list_2_cmd_2_wget 56 - -56 > > _u_boot_list_2_cmd_2_tftpboot 56 - -56 > > _u_boot_list_2_cmd_2_pxe 56 - -56 > > _u_boot_list_2_cmd_2_ping 56 - -56 > > _u_boot_list_2_cmd_2_nfs 56 - -56 > > _u_boot_list_2_cmd_2_net 56 - -56 > > _u_boot_list_2_cmd_2_mii 56 - -56 > > _u_boot_list_2_cmd_2_dhcp 56 - -56 > > _u_boot_list_2_cmd_2_bootp 56 - -56 > > net_loop 652 592 -60 > > net_eth_hdr_size 60 - -60 > > bootp_reset 60 - -60 > > net_root_path 64 - -64 > > filefh 64 - -64 > > do_bootvx 816 748 -68 > > miiphy_set_current_dev 72 - -72 > > basename 72 - -72 > > pxe_get_file_size 76 - -76 > > copy_filename 76 - -76 > > distro_pxe_getfile 80 - -80 > > tftp_init_load_addr 92 - -92 > > miiphy_read 92 - -92 > > extract_range 92 - -92 > > miiphy_write 96 - -96 > > miiphy_get_active_dev 96 - -96 > > distro_pxe_read_file 96 - -96 > > wget_fail 104 - -104 > > skip_num 104 - -104 > > miiphy_get_dev_by_name 104 - -104 > > dump_field 104 - -104 > > do_bdinfo 432 328 -104 > > bootp_timeout_handler 104 - -104 > > nfs_timeout_handler 108 - -108 > > cmd_pxe_sub 112 - -112 > > nfs_umountall_req 120 - -120 > > _u_boot_list_2_driver_2_bootmeth_pxe 120 - -120 > > do_ping 124 - -124 > > tftp_filename 128 - -128 > > reg_9_desc_tbl 128 - -128 > > reg_10_desc_tbl 128 - -128 > > distro_pxe_boot 128 - -128 > > tftp_timeout_handler 132 - -132 > > do_pxe 132 - -132 > > nfs_umountall_reply 136 - -136 > > lmb_get_free_size 136 - -136 > > format_mac_pxe 136 - -136 > > miiphy_listdev 144 - -144 > > efi_net_set_dhcp_ack 144 - -144 > > wget_timeout_handler 148 - -148 > > nfs_mount_reply 148 - -148 > > dhcp_packet_process_options 148 - -148 > > eth_validate_ethaddr_str 152 - -152 > > do_pxe_get 156 - -156 > > reg_0_desc_tbl 160 - -160 > > net_parse_bootfile 160 - -160 > > miiphy_info 160 - -160 > > get_pxelinux_path 160 - -160 > > do_net 164 - -164 > > net_auto_load 172 - -172 > > do_net_list 176 - -176 > > rpc_lookup_reply 180 - -180 > > nfs_readlink_req 184 - -184 > > nfs_mount_req 188 - -188 > > reg_5_desc_tbl 192 - -192 > > reg_4_desc_tbl 192 - -192 > > miiphy_speed 200 - -200 > > miiphy_duplex 200 - -200 > > nfs_read_req 224 - -224 > > do_pxe_boot 248 - -248 > > reg_1_desc_tbl 256 - -256 > > mii_reg_desc_tbl 256 - -256 > > nfs_send 260 - -260 > > wget_start 268 - -268 > > ping_start 276 - -276 > > nfs_lookup_reply 280 - -280 > > rpc_req 300 - -300 > > eth_initialize 300 - -300 > > distro_pxe_read_bootflow 300 - -300 > > nfs_readlink_reply 328 - -328 > > nfs_lookup_req 328 - -328 > > ping_receive 332 - -332 > > pxe_get 376 - -376 > > nfs_read_reply 396 - -396 > > wget_send_stored 444 - -444 > > nfs_start 468 - -468 > > dhcp_process_options 508 - -508 > > tftp_send 560 - -560 > > nfs_handler 580 - -580 > > bootp_request 612 - -612 > > dhcp_extended 616 - -616 > > netboot_common 632 - -632 > > default_environment 4444 3800 -644 > > tftp_start 912 - -912 > > dhcp_handler 1000 - -1000 > > wget_handler 1092 - -1092 > > tftp_handler 1304 - -1304 > > nfs_path_buff 2048 - -2048 > > do_mii 2124 - -2124 > > Total: Before=722283, After=738425, chg +2.23% > > > > > > > > On Thu, 8 Jun 2023 at 02:07, Tom Rini <trini@konsulko.com> wrote: > >> > >> On Wed, May 24, 2023 at 10:18:13PM +0200, Simon Goldschmidt wrote: > >> > Hi Maxim, Tom, > >> > > >> > On 24.05.2023 16:05, Maxim Uvarov wrote: > >> > > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > >> > > > >> > > > On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > >> > > > > On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > >> > > > > > >> > > > > > On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > >> > > > > > > Hi Maxim > >> > > > > > > > >> > > > > > > On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> > >> > > > > > wrote: > >> > > > > > > > > >> > > > > > > > My measurements for binary after LTO looks like: > >> > > > > > > > > >> > > > > > > > U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > >> > > > > > > > 870728 | 915000 | 912560 | > >> > > > > > 41832 | 4.8 > >> > > > > > > > >> > > > > > > > >> > > > > > > I think you'll need to analyze that a bit more. First of all I don't > >> > > > > > > think the '+ping' tab is useful. What is is trying to achieve? > >> > > > > > > >> > > > > > >> > > > > To show the difference of extra bytes if we add a ping app on top. > >> > > > > > >> > > > > > >> > > > > > > - How was LWIP compiled? > >> > > > > > > >> > > > > > >> > > > > It has a really huge configuration. I tried to turn off everything off > >> > > > > everything what can impact on size but still make http app work: > >> > > > > #define LWIP_HAVE_LOOPIF 0 > >> > > > > #define LWIP_NETCONN 0 > >> > > > > #define LWIP_SOCKET 0 > >> > > > > #define SO_REUSE 0 > >> > > > > #define LWIP_STATS 0 > >> > > > > #define PPP_SUPPORT 0 > >> > > > > > >> > > > > Disabling loopback: > >> > > > > #define LWIP_NETIF_LOOPBACK 0 > >> > > > > can lower to 912288 bytes. > >> > > > > > >> > > > > And it's the same compilation option (optimization for size) as the main > >> > > > > u-boot. I will do more experiments, but I think the goal is not to turn > >> > > > off > >> > > > > everything. > >> > > > > > >> > > > > > >> > > > > > > - Was ipv6 supported? > >> > > > > > > >> > > > > > >> > > > > No. I.e. when I sent results it was enabled on the compilation stage but > >> > > > > not used. I just checked that size remains the same if IPv6 is not even > >> > > > > compiled. > >> > > > > > >> > > > > > >> > > > > > > - Can we strip it down even further? > >> > > > > > > > >> > > > > > > >> > > > > > >> > > > > There is always room for optimization. I think I tried to turn off > >> > > > > everything that is configurable with defines. I can play with disable IP > >> > > > > reassembly and things like that or figure out which functions have more > >> > > > > size and if it's possible to exclude them. > >> > > > > > >> > > > > > >> > > > > > > In general please give as much information as you can with what we > >> > > > > > > gain in functionality from LWIP with those extra bytes of code. > >> > > > > > > >> > > > > > > >> > > > > The main idea is to reuse a maintainable IP stack outside of U-boot. > >> > > > LWIP > >> > > > > can give a nice separation between IP stack code and network application > >> > > > > code. I.e. application should not take care about any TCP details (SYN, > >> > > > > ACK, retransmission, reassembly etc) and should open connection and use > >> > > > > functions similar to recv() and send() to transfer data. Data means > >> > > > > application data, no network packets. And LWIP allows > >> > > > > us to do that. > >> > > > > Because LWIP has an API similar to sockets, it has to be very easy to > >> > > > port > >> > > > > a linux application to LWIP. Then you can test it with a tap device. Then > >> > > > > copy sources to U-boot, add a small integration layer (cmd command to > >> > > > > call), compile and use. > >> > > > > > >> > > > > So my suggestion was: > >> > > > > - do not maintain new network stack code in the current U-boot. Use lwip > >> > > > > sources as an external project. All bugs related to network stack go to > >> > > > > lwip project first, then sync with U-boot. > >> > > > > - maintain network apps code* or > >> > > > > -- inside U-boot. Write our own code for application and maintain it > >> > > > > inside U-boot. > >> > > > > -- inside LWIP. Add examples to LWIP which are suitable for both > >> > > > U-boot > >> > > > > and LWIP. > >> > > > > > >> > > > > * Let's define a U-boot network application as a cmd command. It might be > >> > > > > ping, wget (http or https download), telnet, arp dns etc.. > >> > > > > > >> > > > > Let's consider the real use case, like HTTPS download client. We need to > >> > > > > enable TLS connection, validate certificates, then do http download. > >> > > > > Looking at the current code of wget command it's quite difficult to > >> > > > > implement this due to the application having some protol level things. On > >> > > > > the other side we can find embedTLS examples to do https download on > >> > > > > sockets. If LWIP socket API is ported then the only thing you need to do > >> > > > is > >> > > > > change socket() -> lwip_socket(), recv()->lwip_recv(), > >> > > > send()->lwip_send() > >> > > > > and etc, even function names are similar. If LWIP socket API is not > >> > > > > supported, then use callback API for recv() and send(), which are also > >> > > > > easy. > >> > > > > > >> > > > > So yes we add extra bytes, but that will allow us to write more complex > >> > > > > apps, use standard debug tools, use applications with very minimal > >> > > > > integration changes, use help from the LWIP community to fix protocol > >> > > > bugs, > >> > > > > etc.. > >> > > > > Bunch of things already implemented there: > >> > > > > - ipv6 > >> > > > > - dhcp > >> > > > > - snmp > >> > > > > - igmp > >> > > > > - dns > >> > > > > - tcp and udp and raw. > >> > > > > - loopback > >> > > > > - netconn > >> > > > > - socket > >> > > > > - stats > >> > > > > - ppp > >> > > > > (I just followed configurable defines). > >> > > > > > >> > > > > > >> > > > > And please make sure to disable the previous support, my guess fro that > >> > > > > > much growth is that you didn't. > >> > > > > > > >> > > > > > >> > > > > # CONFIG_PROT_TCP is not set > >> > > > > # CONFIG_PROT_UDP is not set > >> > > > > # CONFIG_UDP_CHECKSUM is not set > >> > > > > # CONFIG_UDP_FUNCTION_FASTBOOT is not set > >> > > > > # CONFIG_CMD_WGET is not set > >> > > > > >> > > > I think you need to step back and figure out a better way to measure the > >> > > > size change and growth. > >> > > > > >> > > > I am not interested in a path that long term means two networking stacks > >> > > > in U-Boot. > >> > > > > >> > > > I am not interested in massively growing the overall binary size for > >> > > > every platform. Given how much larger just TCP support is, that's > >> > > > strongly implying a huge growth for the older use cases too. > >> > > > > >> > > > But I also suspect given the overall reputation that LWIP enjoys, > >> > > > there's something amiss here. > >> > > > > >> > > > -- > >> > > > Tom > >> > > > > >> > > > >> > > +cc lwip-devel@ mailing list, maybe they have something to add. > >> > > >> > I do think using lwIP instead of "inventing yet another IP stack" is a > >> > good idea! However, in terms of code size, lwIP will lose against what's > >> > in U-Boot at present. And this is only natural, as lwIP is a "full-size" > >> > stack supporting multiple concurrently running applications while the > >> > current IP stack in U-Boot is rather "crippled" down to just what the > >> > implementor needed at the time of writing. > >> > > >> > One example of this is that (if I remember correctly), U-Boot only has > >> > one single network packet buffer, while lwIP has support for multiple > >> > buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track > >> > of that development in U-Boot about 3 years ago), we're comparing "we > >> > have implemented everything we need so that it just kind of works" to > >> > "we can easily add a HTTPS client to download something over the > >> > internet just by enabling more compile options". > >> > > >> > Also, when comparing lwIP to U-Boot TCP code size, keep in mind that > >> > U-Boot TCP (at least that of some years ago) is far from complete when > >> > compared to lwIP! > >> > > >> > lwIP is meant to be highly configurable and we're always open to add yet > >> > more options to leave out more code when it's not needed. However, I > >> > think there are some design decisions that will make lwIP larger than > >> > the current IP stack in U-Boot. To me, that's a natural result of having > >> > a "generic code" approach vs "developed to our needs". However, while > >> > DHCP + BOOTP and even a simple network console was rather easy to > >> > implement, I would not recommend implementing your own HTTPS download > >> > but rather using the existing lwIP + apps for that. > >> > > >> > In the end, I cannot take the decision from you. In my opinion, lwIP > >> > would be the better decision in terms of future work load and > >> > compatibility, but in the short run, it *will* lead to bigger binaries > >> > at least in some setups. And I do know from my past that it sometimes > >> > has been a pain to try and stuff a new U-Boot release into the existing > >> > space of flash or RAM, so that's not an easy decision. > >> > > >> > If you do take the lwIP approach however, let us know if we can help! > >> > >> Given Maxim's more recent experiments, I'm sure we can come up with > >> something that works overall. There's hopefully a place or two U-Boot > >> people can help introduce a tunable or two to lwIP to bring some sizes > >> down. But I think it's overall looking to be the right direction. > >> > >> -- > >> Tom
Hi, On Wed, 7 Jun 2023 at 10:47, Ilias Apalodimas <ilias.apalodimas@linaro.org> wrote: > > Hi Maxim, > > On Tue, 6 Jun 2023 at 17:33, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > > > Greetings, > > > > I implemented the tftp client (that was quick due to lwip has example app for tftp), and did some more measurements. > > I uploaded patches here if somebody want to do his own measurements: > > https://github.com/muvarov/uboot-lwip > > > > measure 1: > > 976K - total (total means lwip with all 3 commands ping, tftp, wget) > > 971K - total - tftp (total, but disable/minus tftp) > > 965K - total - tftp - wget (disable tftp and wget) > > 963K - total - tftp - wget - ping (disable tftp, wget, ping) > > 931K - no lwip > > > > result 1: lwip tftp (+ udp protocol) protocol 976-971k = 5kb > > result 2: lwip ping command 965- 963 = 2kb > > result 3: lwip wget command 971- 965 = 6kb > > result 4: lwip core stack with apps 976 - 931 = 45kb > > So tftp = 5kb, wget = 6kb ping =2kb and lwip = 32kb > > > > > measure 2: > > 890K - no CONFIG_NET_CMD > > 930K - + lwip tftp only > > 937K - + full lwip (ping wget tftp) > > > > result 1: 937-890=47kb ( lwip + all 3 commands) > > result 2: 937-930=7kb (ping and lwip command) > > I am not sure I understand this measurement. How is this different > from measurement 1 where the entire binary was 976K? > > > > > measure 3: > > 904K - no lwip, CMD_NET_TFTP=y > > 900K - no lwip, CMD_NET_TFTP=n > > result 1: original u-boot tftp command 904-900=4kb > > 890K - no lwip, CMD_NET=n > > result 2: 900-890=10k original u-boot net/IP stack. > > > > My findings for all that measurements and lwip configuration: > > 1. The original u-boot net stack (packet process and up layers) is 10k vs lwip 40k (the very minimal settings were 30k). > > 2. Network applications size is about the same 4kb for tftp original command 5kb for lwip. > > 3. It's quite easy to reuse LWIP examples to implement the same functionality for the U-boot. > > 4. I still think that there are other criterias which might have more priority than size (bug free code, code reuse, development speed, compatible API to posix and etc). > > Yes, there are other criteria and certainly having a complete network > stack might be worth it in many cases, but we need to keep in mind > 30kb might be a lot for some systems. > > I personally think this is decent and we can optimize lwip more in the > future. Tom, Simon, how about adding lwip as 'experimental' and > making it depend on !CMD_NET or something similar? That seems OK to me, but we don't really want two network stacks, so we'd need to set an expectation that we would move to lwip. I wonder why it is so large? I saw mention of it supporting multiple buffers and perhaps having a fuller implementation of the protocols. But it makes U-Boot's stack seem super-slim in comparison. I wonder if lwip could support just a single buffer and reduced functionality in other areas? Regards, Simon > > Thanks > /Ilias > > > > BR, > > Maxim. > > > > On Thu, 25 May 2023 at 02:18, Simon Goldschmidt <goldsimon@gmx.de> wrote: > >> > >> Hi Maxim, Tom, > >> > >> On 24.05.2023 16:05, Maxim Uvarov wrote: > >> > On Tue, 23 May 2023 at 03:23, Tom Rini <trini@konsulko.com> wrote: > >> > > >> >> On Mon, May 22, 2023 at 12:40:49PM -0400, Maxim Uvarov wrote: > >> >>> On Mon, 22 May 2023 at 10:20, Tom Rini <trini@konsulko.com> wrote: > >> >>> > >> >>>> On Mon, May 22, 2023 at 04:33:57PM +0300, Ilias Apalodimas wrote: > >> >>>>> Hi Maxim > >> >>>>> > >> >>>>> On Mon, 22 May 2023 at 12:01, Maxim Uvarov <maxim.uvarov@linaro.org> > >> >>>> wrote: > >> >>>>>> > >> >>>>>> My measurements for binary after LTO looks like: > >> >>>>>> > >> >>>>>> U-boot WGET | LWIP WGET + ping | LWIP WGET| diff bytes| diff % > >> >>>>>> 870728 | 915000 | 912560 | > >> >>>> 41832 | 4.8 > >> >>>>> > >> >>>>> > >> >>>>> I think you'll need to analyze that a bit more. First of all I don't > >> >>>>> think the '+ping' tab is useful. What is is trying to achieve? > >> >>>> > >> >>> > >> >>> To show the difference of extra bytes if we add a ping app on top. > >> >>> > >> >>> > >> >>>>> - How was LWIP compiled? > >> >>>> > >> >>> > >> >>> It has a really huge configuration. I tried to turn off everything off > >> >>> everything what can impact on size but still make http app work: > >> >>> #define LWIP_HAVE_LOOPIF 0 > >> >>> #define LWIP_NETCONN 0 > >> >>> #define LWIP_SOCKET 0 > >> >>> #define SO_REUSE 0 > >> >>> #define LWIP_STATS 0 > >> >>> #define PPP_SUPPORT 0 > >> >>> > >> >>> Disabling loopback: > >> >>> #define LWIP_NETIF_LOOPBACK 0 > >> >>> can lower to 912288 bytes. > >> >>> > >> >>> And it's the same compilation option (optimization for size) as the main > >> >>> u-boot. I will do more experiments, but I think the goal is not to turn > >> >> off > >> >>> everything. > >> >>> > >> >>> > >> >>>>> - Was ipv6 supported? > >> >>>> > >> >>> > >> >>> No. I.e. when I sent results it was enabled on the compilation stage but > >> >>> not used. I just checked that size remains the same if IPv6 is not even > >> >>> compiled. > >> >>> > >> >>> > >> >>>>> - Can we strip it down even further? > >> >>>>> > >> >>>> > >> >>> > >> >>> There is always room for optimization. I think I tried to turn off > >> >>> everything that is configurable with defines. I can play with disable IP > >> >>> reassembly and things like that or figure out which functions have more > >> >>> size and if it's possible to exclude them. > >> >>> > >> >>> > >> >>>>> In general please give as much information as you can with what we > >> >>>>> gain in functionality from LWIP with those extra bytes of code. > >> >>>> > >> >>>> > >> >>> The main idea is to reuse a maintainable IP stack outside of U-boot. > >> >> LWIP > >> >>> can give a nice separation between IP stack code and network application > >> >>> code. I.e. application should not take care about any TCP details (SYN, > >> >>> ACK, retransmission, reassembly etc) and should open connection and use > >> >>> functions similar to recv() and send() to transfer data. Data means > >> >>> application data, no network packets. And LWIP allows > >> >>> us to do that. > >> >>> Because LWIP has an API similar to sockets, it has to be very easy to > >> >> port > >> >>> a linux application to LWIP. Then you can test it with a tap device. Then > >> >>> copy sources to U-boot, add a small integration layer (cmd command to > >> >>> call), compile and use. > >> >>> > >> >>> So my suggestion was: > >> >>> - do not maintain new network stack code in the current U-boot. Use lwip > >> >>> sources as an external project. All bugs related to network stack go to > >> >>> lwip project first, then sync with U-boot. > >> >>> - maintain network apps code* or > >> >>> -- inside U-boot. Write our own code for application and maintain it > >> >>> inside U-boot. > >> >>> -- inside LWIP. Add examples to LWIP which are suitable for both > >> >> U-boot > >> >>> and LWIP. > >> >>> > >> >>> * Let's define a U-boot network application as a cmd command. It might be > >> >>> ping, wget (http or https download), telnet, arp dns etc.. > >> >>> > >> >>> Let's consider the real use case, like HTTPS download client. We need to > >> >>> enable TLS connection, validate certificates, then do http download. > >> >>> Looking at the current code of wget command it's quite difficult to > >> >>> implement this due to the application having some protol level things. On > >> >>> the other side we can find embedTLS examples to do https download on > >> >>> sockets. If LWIP socket API is ported then the only thing you need to do > >> >> is > >> >>> change socket() -> lwip_socket(), recv()->lwip_recv(), > >> >> send()->lwip_send() > >> >>> and etc, even function names are similar. If LWIP socket API is not > >> >>> supported, then use callback API for recv() and send(), which are also > >> >>> easy. > >> >>> > >> >>> So yes we add extra bytes, but that will allow us to write more complex > >> >>> apps, use standard debug tools, use applications with very minimal > >> >>> integration changes, use help from the LWIP community to fix protocol > >> >> bugs, > >> >>> etc.. > >> >>> Bunch of things already implemented there: > >> >>> - ipv6 > >> >>> - dhcp > >> >>> - snmp > >> >>> - igmp > >> >>> - dns > >> >>> - tcp and udp and raw. > >> >>> - loopback > >> >>> - netconn > >> >>> - socket > >> >>> - stats > >> >>> - ppp > >> >>> (I just followed configurable defines). > >> >>> > >> >>> > >> >>> And please make sure to disable the previous support, my guess fro that > >> >>>> much growth is that you didn't. > >> >>>> > >> >>> > >> >>> # CONFIG_PROT_TCP is not set > >> >>> # CONFIG_PROT_UDP is not set > >> >>> # CONFIG_UDP_CHECKSUM is not set > >> >>> # CONFIG_UDP_FUNCTION_FASTBOOT is not set > >> >>> # CONFIG_CMD_WGET is not set > >> >> > >> >> I think you need to step back and figure out a better way to measure the > >> >> size change and growth. > >> >> > >> >> I am not interested in a path that long term means two networking stacks > >> >> in U-Boot. > >> >> > >> >> I am not interested in massively growing the overall binary size for > >> >> every platform. Given how much larger just TCP support is, that's > >> >> strongly implying a huge growth for the older use cases too. > >> >> > >> >> But I also suspect given the overall reputation that LWIP enjoys, > >> >> there's something amiss here. > >> >> > >> >> -- > >> >> Tom > >> >> > >> > > >> > +cc lwip-devel@ mailing list, maybe they have something to add. > >> > >> I do think using lwIP instead of "inventing yet another IP stack" is a > >> good idea! However, in terms of code size, lwIP will lose against what's > >> in U-Boot at present. And this is only natural, as lwIP is a "full-size" > >> stack supporting multiple concurrently running applications while the > >> current IP stack in U-Boot is rather "crippled" down to just what the > >> implementor needed at the time of writing. > >> > >> One example of this is that (if I remember correctly), U-Boot only has > >> one single network packet buffer, while lwIP has support for multiple > >> buffers. When speaking of TCP (forgive me if I'm wrong, I've lost track > >> of that development in U-Boot about 3 years ago), we're comparing "we > >> have implemented everything we need so that it just kind of works" to > >> "we can easily add a HTTPS client to download something over the > >> internet just by enabling more compile options". > >> > >> Also, when comparing lwIP to U-Boot TCP code size, keep in mind that > >> U-Boot TCP (at least that of some years ago) is far from complete when > >> compared to lwIP! > >> > >> lwIP is meant to be highly configurable and we're always open to add yet > >> more options to leave out more code when it's not needed. However, I > >> think there are some design decisions that will make lwIP larger than > >> the current IP stack in U-Boot. To me, that's a natural result of having > >> a "generic code" approach vs "developed to our needs". However, while > >> DHCP + BOOTP and even a simple network console was rather easy to > >> implement, I would not recommend implementing your own HTTPS download > >> but rather using the existing lwIP + apps for that. > >> > >> In the end, I cannot take the decision from you. In my opinion, lwIP > >> would be the better decision in terms of future work load and > >> compatibility, but in the short run, it *will* lead to bigger binaries > >> at least in some setups. And I do know from my past that it sometimes > >> has been a pain to try and stuff a new U-Boot release into the existing > >> space of flash or RAM, so that's not an easy decision. > >> > >> If you do take the lwIP approach however, let us know if we can help! > >> > >> Regards, > >> Simon > >> > >> > > >> > My measurements say that the current U-boot IP stack + wget command adds an > >> > additional 9 Kbytes. > >> > The minimal configuration of LWIP with wget command is 30 Kbytes. > >> > (compiled out all asserts, debugs, not used protocols etc.). > >> > > >> > And the most bigger functions are tcp in/out itself: > >> > * These functions are generally called in the order (ip_input() ->) > >> > * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). > >> > > >> > +tcp_input - 4364 +4364 > >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n118 > >> > +tcp_receive - 3444 +3444 > >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_in.c#n1154 > >> > +tcp_write - 2192 +2192 > >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n393 > >> > +ip4_reass - 2096 +2096 > >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/ipv4/ip4_frag.c#n503 > >> > +tcp_output - 1616 +1616 > >> > https://git.savannah.nongnu.org/cgit/lwip.git/tree/src/core/tcp_out.c#n1241 > >> > > >> > If we transfer current net commands to lwip then we can decrease the size, > >> > because of functions reuse. > >> > And if we turn on all features in lwip it will be about 50 Kbytes. > >> > > >> > BR, > >> > Maxim. > >> > > >> > > >> > _______________________________________________ > >> > lwip-devel mailing list > >> > lwip-devel@nongnu.org > >> > https://lists.nongnu.org/mailman/listinfo/lwip-devel
On Sun, Jun 11, 2023 at 09:24:14AM +0100, Simon Glass wrote: > Hi, > > On Wed, 7 Jun 2023 at 10:47, Ilias Apalodimas > <ilias.apalodimas@linaro.org> wrote: > > > > Hi Maxim, > > > > On Tue, 6 Jun 2023 at 17:33, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > > > > > > Greetings, > > > > > > I implemented the tftp client (that was quick due to lwip has example app for tftp), and did some more measurements. > > > I uploaded patches here if somebody want to do his own measurements: > > > https://github.com/muvarov/uboot-lwip > > > > > > measure 1: > > > 976K - total (total means lwip with all 3 commands ping, tftp, wget) > > > 971K - total - tftp (total, but disable/minus tftp) > > > 965K - total - tftp - wget (disable tftp and wget) > > > 963K - total - tftp - wget - ping (disable tftp, wget, ping) > > > 931K - no lwip > > > > > > result 1: lwip tftp (+ udp protocol) protocol 976-971k = 5kb > > > result 2: lwip ping command 965- 963 = 2kb > > > result 3: lwip wget command 971- 965 = 6kb > > > result 4: lwip core stack with apps 976 - 931 = 45kb > > > > So tftp = 5kb, wget = 6kb ping =2kb and lwip = 32kb > > > > > > > > measure 2: > > > 890K - no CONFIG_NET_CMD > > > 930K - + lwip tftp only > > > 937K - + full lwip (ping wget tftp) > > > > > > result 1: 937-890=47kb ( lwip + all 3 commands) > > > result 2: 937-930=7kb (ping and lwip command) > > > > I am not sure I understand this measurement. How is this different > > from measurement 1 where the entire binary was 976K? > > > > > > > > measure 3: > > > 904K - no lwip, CMD_NET_TFTP=y > > > 900K - no lwip, CMD_NET_TFTP=n > > > result 1: original u-boot tftp command 904-900=4kb > > > 890K - no lwip, CMD_NET=n > > > result 2: 900-890=10k original u-boot net/IP stack. > > > > > > My findings for all that measurements and lwip configuration: > > > 1. The original u-boot net stack (packet process and up layers) is 10k vs lwip 40k (the very minimal settings were 30k). > > > 2. Network applications size is about the same 4kb for tftp original command 5kb for lwip. > > > 3. It's quite easy to reuse LWIP examples to implement the same functionality for the U-boot. > > > 4. I still think that there are other criterias which might have more priority than size (bug free code, code reuse, development speed, compatible API to posix and etc). > > > > Yes, there are other criteria and certainly having a complete network > > stack might be worth it in many cases, but we need to keep in mind > > 30kb might be a lot for some systems. > > > > I personally think this is decent and we can optimize lwip more in the > > future. Tom, Simon, how about adding lwip as 'experimental' and > > making it depend on !CMD_NET or something similar? > > That seems OK to me, but we don't really want two network stacks, so > we'd need to set an expectation that we would move to lwip. Yes, we'll need to move on to evaluating that once we can show and use lwip as a replacement for most cases. > I wonder why it is so large? I saw mention of it supporting multiple > buffers and perhaps having a fuller implementation of the protocols. > But it makes U-Boot's stack seem super-slim in comparison. I wonder if > lwip could support just a single buffer and reduced functionality in > other areas? Well, right. Seeing what space related tuneables we can introduce and/or further tune down will be of interest. But that will be easier to do once it's easier to try out lwip in U-Boot itself.