Skip to content

Fix the Thumb-2 register shifts and NetworkInterface on Meadow.OS - #6

Merged
NevynUK merged 4 commits into
MergeManagedCodefrom
Phase6
Oct 15, 2026
Merged

NevynUK merged 4 commits into
MergeManagedCodefrom
Phase6

Conversation

@NevynUK

@NevynUK NevynUK commented Oct 15, 2026

Copy link
Copy Markdown

Summary

Meadow.Core reported the WiFi adapter's IP address, mask and gateway as 255.255.255.255. Four runtime commits fix the runtime side; the Meadow.OS espcp side is on Meadow.OS Phase6.

  1. Fix the Thumb-2 register-controlled ASR and ROR encodings. arm_asr_register() and arm_ror_register() were copied from the EOR helper.
    • When rd == rm they swapped the operands.
    • Otherwise they emitted EOR or ORN instead of a shift.
    • Every JIT-compiled int >> variable could be wrong: PrefixLengthToSubnetMask() turned a /24 into 135.135.135.0.
  2. Read the name servers from /meadow0/dns.conf. Meadow.OS has no /etc. The /etc/resolv.conf read threw DirectoryNotFoundException, so GetAllNetworkInterfaces() returned nothing.
  3. Report the interface type and MAC address on NuttX.
    • The type comes from espcp's MEADOW_IFF_WIFI flag (bit 14).
    • The loopback device is recognised by name.
    • The MAC comes from ifa_data.
    • This replaces Legacy Meadow's NuttxNetworkInterface.
  4. Report the gateway on NuttX. With no /proc/net/route, the Linux code asks SystemNative_EnumerateGatewayAddressesForInterface(). On NuttX that returns meadow_os_get_gateway_address(). Over WiFi the OS answers 0.0.0.0 for now (Meadow.OS When generating MSIs, use heat.exe "-ag", not "-gg" to make component GUIDs more stable dotnet/runtime#703).

Test

On a Meadow F7 (CCM, ProjectLab v3), OS and runtime 2.999.50.9:

  • JIT probe: the masks are 255.255.255.0 (before the fix, 135.135.135.0) and the shifts are 128..1 (before, all zeros).
  • NetworkInterface: wlan0, Wireless80211, Up, MAC 4C7525D52860, 192.168.1.76/24, gateway 0.0.0.0, and the DNS servers from dns.conf.
  • Meadow.Core: IpAddress is 192.168.1.76 and SubnetMask is 255.255.255.0.
  • Network test suite: 10/10, including 50/50 repeated HTTP.
  • GC stress as a Meadow app: pass 2 runs out of memory in large-objects. It does the same with the old encoder (runtime rebuilt from scratch without commit 1), so this is not a regression; it will be followed up separately.

🤖 Generated with Claude Code

NevynUK and others added 4 commits October 15, 2026 18:46
arm_asr_register() and arm_ror_register() were copied from the EOR
helper.  When rd == rm they emitted the 16-bit ASRS/RORS with the
operands swapped (rd = rm >> rn), and otherwise the 32-bit data
processing (shifted register) encoding with opcode 4 or 6, which is
rn EOR rm or rn ORN rm, not a shift.

The JIT uses ARM_SAR_REG for every int >> variable, so code such as
0x80 >> (bit % 8) gave wrong results once registers were allocated
that way: PrefixLengthToSubnetMask() turned a /24 into
135.135.135.0, and a loop printing 0x80 >> (bit % 8) printed zeros.

Use the 16-bit form only when rd == rn, and the 32-bit
register-controlled shift (type ASR or ROR) otherwise, as
arm_lsl_reg() and arm_lsr_reg() already do.  ROR by register is not
used by the JIT at present; it is fixed because it had the same
defect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NetworkInterface.GetAllNetworkInterfaces() reads /etc/resolv.conf for
the DNS suffix and addresses.  Meadow.OS has no /etc, so the read
threw DirectoryNotFoundException in
LinuxNetworkInterfaceSystemProperties, which catches only
FileNotFoundException and UnauthorizedAccessException, and no
interface was returned (Meadow.Core then reported the IP address as
255.255.255.255).

The NuttX DNS client already reads /meadow0/dns.conf
(CONFIG_NETDB_RESOLVCONF_PATH), which uses the resolv.conf format and
is written by the OS at boot, so point EtcResolvConfFile, used by
every reader, at it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NuttX getifaddrs() returns no AF_PACKET or AF_LINK entries, so
SystemNative_GetNetworkInterfaces() left every interface as
NetworkInterfaceType.Unknown with no physical address.  Meadow.Core
looks for a Wireless80211 interface, so the WiFi adapter's IP address,
mask and gateway were reported as 255.255.255.255.

On NuttX, take the hardware address from ifa_data (the SIOCGIFHWADDR
struct sockaddr) and the type from the interface flags: Meadow.OS's
ESP32 driver (espcp) marks its interface with MEADOW_IFF_WIFI (bit 14,
which NuttX <net/if.h> leaves free), the loopback device is
recognised by name because NuttX does not set IFF_LOOPBACK on it, and
anything else is Ethernet.  This replaces the IFF_WIFI handling of
Legacy Meadow's NuttxNetworkInterface.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Linux NetworkInformation reads gateways only from /proc/net/route,
which NuttX does not have, so GatewayAddresses was always empty.

When there is no route file, LinuxIPInterfaceProperties now asks
SystemNative_EnumerateGatewayAddressesForInterface(), as the BSD code
does.  On NuttX that returns the gateway of Meadow.OS's active
interface from meadow_os_get_gateway_address(), the call Legacy
Meadow's NuttxIPInterfaceProperties used.  The OS answer is passed on
as it is; over WiFi the OS does not yet learn the DHCP gateway and
answers 0.0.0.0 (Meadow.OS issue dotnet#703).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@NevynUK
NevynUK merged commit 3000068 into MergeManagedCode Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant