Skip to content

Conversation

Ayush1325
Copy link
Member

Description

Enable Multifunction Composite Gadget for PocketBeagle 2. This allows ssh over USB with zero configuration by the user.

Currently, enabling ttyGS0 causes armbian-first-run to not work, so had to disable it. Will work on finding a solution for it.

setup-usbgadget-network-multi.sh uses setup-usbgadget-network.sh as a base but exposes a Multifunction Composite Gadget instead of just NCM.

How Has This Been Tested?

  • Tested on PocketBeagle 2 rev A0.

Checklist:

Please delete options that are not relevant.

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules

@Ayush1325 Ayush1325 requested review from Grippy98 and a team as code owners July 15, 2025 15:01
Copy link
Contributor

coderabbitai bot commented Jul 15, 2025

Walkthrough

Removed the ttyGS0 USB-gadget serial console from PocketBeagle2 kernel command line and from SERIALCON (leaving only ttyS2). Added two board-level post-tweak functions in config/boards/pocketbeagle2.conf: one to install USB-gadget networking assets and init/systemd files into the target filesystem, and one to enable services (temporarily enabling Armbian repo to install unudhcpd, enabling usbgadget-rndis.service, and adding a systemd override for static IP). Added packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh which creates and binds a USB gadget via configfs (ncm.usb0 network function), brings up usb0, and starts unudhcpd.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Needs review

Suggested reviewers

  • EvilOlaf
  • igorpecovnik
  • TheSnowfield

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title clearly identifies the board (pocketbeagle2) and the purpose of the change (enabling a better USB gadget) reflecting the main modifications to the configuration and scripting for USB gadget support. It succinctly conveys the primary intent without extraneous details. Users scanning history will understand that this update pertains to USB gadget improvements on the PocketBeagle2.
Description Check ✅ Passed The description clearly explains that the pull request enables the Linux Multifunction Composite Gadget on PocketBeagle2, details why ttyGS0 was disabled, and introduces a new setup script, matching the changes in the summary. It also includes testing information and a checklist of compliance steps which are relevant to the modifications. The level of detail is appropriate and stays on-topic with the code changes.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added size/medium PR with more then 50 and less then 250 lines 08 Milestone: Third quarter release Needs review Seeking for review Hardware Hardware related like kernel, U-Boot, ... BSP Board Support Packages labels Jul 15, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
config/boards/pocketbeagle2.conf (2)

13-16: Temporary removal of ttyGS0 - Track the underlying issue

The removal of ttyGS0 from both SERIALCON and SRC_CMDLINE is consistent with the PR objectives. Since this is a temporary workaround for the armbian-first-run failure, consider adding a TODO comment to track this issue.

Would you like me to create a tracking issue for investigating and resolving the ttyGS0/armbian-first-run conflict?


37-50: Improve service configuration reliability

The function correctly handles the Armbian repository manipulation and service configuration. Consider these improvements:

Use a heredoc for better readability and maintainability:

-	echo -e "[Service]\nEnvironment=\"unudhcpd_host_ip=192.168.7.2\"\nEnvironment=\"unudhcpd_client_ip=192.168.7.3\"" > "${SDCARD}"/etc/systemd/system/usbgadget-rndis.service.d/override.conf
+	cat > "${SDCARD}"/etc/systemd/system/usbgadget-rndis.service.d/override.conf <<-EOF
+	[Service]
+	Environment="unudhcpd_host_ip=192.168.7.2"
+	Environment="unudhcpd_client_ip=192.168.7.3"
+	EOF

Also consider adding error handling for the systemctl enable command.

packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1)

58-58: Fix typo in error message

-		echo "  Couldn't write configration name"
+		echo "  Couldn't write configuration name"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8155cc5 and 8d57c7a.

📒 Files selected for processing (2)
  • config/boards/pocketbeagle2.conf (1 hunks)
  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (2)
Learnt from: djurny
PR: armbian/build#8235
File: packages/bsp/mvebu/helios4/helios4-wol.service:0-0
Timestamp: 2025-05-29T01:52:21.381Z
Learning: When implementing systemd services that need to iterate over network interfaces, the pattern `/bin/ls -1 /sys/class/net/ | /bin/grep -E "^(eth|en[do])[0-9]+" | /bin/xargs -n1 -I{} /sbin/ethtool -s "{}" wol g` is more robust than using shell variables, as it avoids systemd variable resolution issues that can cause service failures.
Learnt from: EvilOlaf
PR: armbian/build#8298
File: extensions/https_proxy.sh:1-9
Timestamp: 2025-06-14T05:53:10.627Z
Learning: Armbian build framework extensions are NOT designed to run standalone but are called by the supervisor. The framework provides environment variables like USERPATCHES_PATH and SDCARD, and commands are executed with protection via run_host_command_logged and chroot_sdcard functions that use bash -e -o pipefail.
config/boards/pocketbeagle2.conf (10)
Learnt from: EvilOlaf
PR: armbian/build#0
File: :0-0
Timestamp: 2025-06-16T03:24:00.458Z
Learning: In Armbian board configuration files (.csc), the standard pattern is to have only one line as a comment describing the board hardware specifications. This single-line description typically includes the SoC model, core count, RAM options, and key features like connectivity options, storage interfaces, and special features.
Learnt from: EvilOlaf
PR: armbian/build#8330
File: config/sources/families/sun55iw3.conf:32-36
Timestamp: 2025-06-25T03:40:52.109Z
Learning: In Armbian build system configuration files like config/sources/families/*.conf, when KERNELSOURCE is not explicitly declared in a case branch, the system falls back to a default KERNELSOURCE value, so missing KERNELSOURCE declarations are not critical issues.
Learnt from: EvilOlaf
PR: armbian/build#8330
File: config/sources/families/sun55iw3.conf:32-36
Timestamp: 2025-06-25T03:42:09.086Z
Learning: In Armbian build system configuration files like config/sources/families/*.conf, KERNELSOURCE is explicitly declared when using unofficial or 3rd party kernel repositories (like the "dev" branch using https://github.com/apritzel/linux), but can be omitted when using the standard mainline kernel (like the "edge" branch) since it will fall back to the default mainline source.
Learnt from: Grippy98
PR: armbian/build#8152
File: lib/functions/configuration/interactive.sh:209-266
Timestamp: 2025-05-05T12:35:07.143Z
Learning: For the interactive kernel selection in Armbian, KERNEL_MAJOR_MINOR and KERNEL_DESCRIPTION are parsed from family.conf but deliberately not set as environment variables to avoid potential interference with other parts of the build system.
Learnt from: rpardini
PR: armbian/build#8044
File: patch/u-boot/v2025.04/cmd-fileenv-read-string-from-file-into-env.patch:76-86
Timestamp: 2025-03-31T22:20:48.475Z
Learning: For the Armbian build project, maintaining consistency with existing patches across U-Boot versions (such as between 2025.01 and 2025.04) is prioritized over refactoring individual patches for code improvements.
Learnt from: rpardini
PR: armbian/build#8044
File: patch/u-boot/v2025.04/cmd-fileenv-read-string-from-file-into-env.patch:73-75
Timestamp: 2025-03-31T22:20:41.849Z
Learning: When porting patches between U-Boot versions (like from 2025.01 to 2025.04), rpardini prefers to maintain patches as-is rather than introducing refactoring changes, even when potential improvements are identified. This approach prioritizes consistency and reduces the risk of introducing new issues.
Learnt from: EvilOlaf
PR: armbian/build#8298
File: extensions/https_proxy.sh:1-9
Timestamp: 2025-06-14T05:53:10.627Z
Learning: Armbian build framework extensions are NOT designed to run standalone but are called by the supervisor. The framework provides environment variables like USERPATCHES_PATH and SDCARD, and commands are executed with protection via run_host_command_logged and chroot_sdcard functions that use bash -e -o pipefail.
Learnt from: libiunc
PR: armbian/build#8033
File: config/kernel/linux-starfive2-vendor.config:43-43
Timestamp: 2025-03-31T12:57:13.880Z
Learning: For StarFive2 platform kernel configurations, maintain alignment with vendor-provided configurations rather than modifying security settings like SECCOMP. This ensures hardware compatibility as intended by the manufacturer.
Learnt from: djurny
PR: armbian/build#8272
File: config/bootscripts/boot-mvebu.cmd:182-186
Timestamp: 2025-06-04T23:45:38.860Z
Learning: In config/bootscripts/boot-mvebu.cmd, the `fdtfile` variable is mandatory for booting and is pre-set by U-Boot, but can be overridden via armbianEnv.txt. If `fdtfile` is empty, the subsequent device tree file search logic will eventually fail and trigger the critical error "Cannot find DT!" with proper error handling.
Learnt from: Grippy98
PR: armbian/build#8202
File: config/desktop/trixie/environments/gnome/armbian/create_desktop_package.sh:2-3
Timestamp: 2025-05-16T15:34:34.672Z
Learning: The shell scripts in the Armbian build system's desktop configuration files, such as config/desktop/trixie/environments/gnome/armbian/create_desktop_package.sh, rely on environment variables like $SRC and $destination that are expected to be set externally before the script is executed.

@coderabbitai coderabbitai bot requested a review from EvilOlaf July 19, 2025 10:47
@leggewie leggewie marked this pull request as draft September 3, 2025 21:40
@leggewie
Copy link
Collaborator

leggewie commented Sep 3, 2025

From a cursory glance, the suggestions by our rabbit seem sound. @Ayush1325 Would you be so kind as to either address or dismiss them?

@Ayush1325 Ayush1325 force-pushed the pb2-usb-gadget branch 4 times, most recently from 3be6cf1 to c2e82e6 Compare September 5, 2025 12:37
@Ayush1325 Ayush1325 marked this pull request as ready for review September 5, 2025 12:39
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
config/boards/pocketbeagle2.conf (5)

24-27: Quote paths to avoid word-splitting and globbing issues

Minor hardening; keeps behavior safe if variables ever contain spaces.

Apply:

-	mkdir -p $destination/usr/local/bin/
-	mkdir -p $destination/usr/lib/systemd/system/
-	mkdir -p $destination/etc/initramfs-tools/scripts/init-bottom/
+	mkdir -p "$destination/usr/local/bin/"
+	mkdir -p "$destination/usr/lib/systemd/system/"
+	mkdir -p "$destination/etc/initramfs-tools/scripts/init-bottom/"

50-55: Make repo toggling resilient and update package lists

Guard mv operations, update indexes, and always restore the .disabled state even on failure.

Apply:

-	mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources
-	do_with_retries 3 chroot_sdcard_apt_get_install unudhcpd
-	# disable armbian repo back
-	mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled
+	armbian_sources_dir="${SDCARD}/etc/apt/sources.list.d"
+	if [ -f "${armbian_sources_dir}/armbian.sources.disabled" ]; then
+		mv "${armbian_sources_dir}/armbian.sources.disabled" "${armbian_sources_dir}/armbian.sources" ||
+			exit_with_error "Failed to enable Armbian sources"
+	fi
+	chroot_sdcard apt-get update || exit_with_error "apt-get update failed"
+	do_with_retries 3 chroot_sdcard_apt_get_install unudhcpd ||
+		exit_with_error "Failed to install unudhcpd"
+	# disable armbian repo back (if present)
+	if [ -f "${armbian_sources_dir}/armbian.sources" ]; then
+		mv "${armbian_sources_dir}/armbian.sources" "${armbian_sources_dir}/armbian.sources.disabled" ||
+			exit_with_error "Failed to disable Armbian sources"
+	fi

Also, please confirm “unudhcpd” exists for targeted releases; otherwise fall back to udhcpd/dnsmasq.


56-60: Reload systemd before enabling; write override via heredoc instead of echo -e

Safer and clearer in chrooted environments.

Apply:

-	chroot_sdcard systemctl enable usbgadget-rndis.service
+	chroot_sdcard systemctl daemon-reload
+	chroot_sdcard systemctl enable usbgadget-rndis.service
 	# We want custom IPs. systemctl edit does not seem to work in chroot.
 	mkdir -p "${SDCARD}"/etc/systemd/system/usbgadget-rndis.service.d
-	echo -e "[Service]\nEnvironment=\"unudhcpd_host_ip=192.168.7.2\"\nEnvironment=\"unudhcpd_client_ip=192.168.7.3\"" > "${SDCARD}"/etc/systemd/system/usbgadget-rndis.service.d/override.conf
+	cat > "${SDCARD}/etc/systemd/system/usbgadget-rndis.service.d/override.conf" <<'EOF'
+[Service]
+Environment="unudhcpd_host_ip=192.168.7.2"
+Environment="unudhcpd_client_ip=192.168.7.3"
+EOF

Also confirm the service actually reads these Environment keys.


35-35: Service naming vs. functionality

The unit is named “usbgadget-rndis.service” while the new script exposes a multifunction gadget. If this unit is reused broadly, consider a neutral name (e.g., usbgadget-net.service) or add a brief comment acknowledging the mismatch to avoid confusion.


22-22: Use info level for non-problem alerts

These are informational steps; “warn” may be noisy in CI logs.

Apply:

-	display_alert "Setup USB Gadget for ${BOARD}" "${RELEASE}" "warn"
+	display_alert "Setup USB Gadget for ${BOARD}" "${RELEASE}" "info"
-	display_alert "Enable Services for ${BOARD}" "${RELEASE}" "warn"
+	display_alert "Enable Services for ${BOARD}" "${RELEASE}" "info"

Also applies to: 48-48

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a026060 and c2e82e6.

📒 Files selected for processing (2)
  • config/boards/pocketbeagle2.conf (1 hunks)
  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh
🧰 Additional context used
🧬 Code graph analysis (1)
config/boards/pocketbeagle2.conf (1)
packages/bsp/usb-gadget-network/setup-usbgadget-network.sh (1)
  • setup_usb_network_configfs (9-73)
🔇 Additional comments (4)
config/boards/pocketbeagle2.conf (4)

31-33: Renaming rationale is clear; thanks for adding error handling

The comment explains the rename and failures now surface via exit_with_error—nice.


20-45: Ensure initramfs regeneration picks up the new hooks and scripts

After installing into /etc/initramfs-tools, the image must rebuild initramfs in chroot; otherwise the hooks won’t be included.

Consider invoking during image build:

  • chroot_sdcard update-initramfs -u
  • Or rely on existing Armbian pipeline step; confirm it runs after these installs.

16-16: Use PARTUUID for stable root= specification
U-Boot without initramfs cannot resolve LABEL=; replace /dev/mmcblk1p2 with PARTUUID=<your-root-partuuid> in SRC_CMDLINE.

Suggested change:

-SRC_CMDLINE="root=/dev/mmcblk1p2 rootwait console=ttyS2,115200n8"
+SRC_CMDLINE="root=PARTUUID=<your-root-partuuid> rootwait console=ttyS2,115200n8"

Likely an incorrect or invalid review comment.


13-13: The script will print lines 430–480 of lib/functions/rootfs/distro-agnostic.sh so we can confirm exactly how and when serial-getty@ttyGS0 is enabled.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1)

43-55: Make critical mkdir/ln failures fatal or document why they’re optional

Some mkdir/ln failures only echo but will crash on the next write due to set -e, making handling inconsistent. Either mark them fatal or add a brief comment stating they’re intentionally non-fatal. Sample tightening:

-	mkdir $CONFIGFS/g1/strings/0x409 || echo "Couldn't create $CONFIGFS/g1/strings/0x409"
+	mkdir "$CONFIGFS/g1/strings/0x409" || exit_with_error "Couldn't create $CONFIGFS/g1/strings/0x409"

-	mkdir $CONFIGFS/g1/functions/"$usb_network_function" ||
-		echo "Couldn't create $CONFIGFS/g1/functions/$usb_network_function"
+	mkdir "$CONFIGFS/g1/functions/$usb_network_function" ||
+		exit_with_error "Couldn't create $CONFIGFS/g1/functions/$usb_network_function"

-	mkdir $CONFIGFS/g1/configs/c.1 ||
-		echo "Couldn't create $CONFIGFS/g1/configs/c.1"
+	mkdir "$CONFIGFS/g1/configs/c.1" ||
+		exit_with_error "Couldn't create $CONFIGFS/g1/configs/c.1"

-	mkdir $CONFIGFS/g1/configs/c.1/strings/0x409 ||
-		echo "Couldn't create $CONFIGFS/g1/configs/c.1/strings/0x409"
+	mkdir "$CONFIGFS/g1/configs/c.1/strings/0x409" ||
+		exit_with_error "Couldn't create $CONFIGFS/g1/configs/c.1/strings/0x409"

-	ln -s $CONFIGFS/g1/functions/"$usb_network_function" $CONFIGFS/g1/configs/c.1 ||
-		echo "Couldn't symlink $usb_network_function"
+	ln -s "$CONFIGFS/g1/functions/$usb_network_function" "$CONFIGFS/g1/configs/c.1" ||
+		exit_with_error "Couldn't symlink $usb_network_function"

-	mkdir -p $CONFIGFS/g1/functions/"$usb_serial_function" ||
-		echo "Couldn't create $CONFIGFS/g1/functions/$usb_serial_function"
-	ln -s $CONFIGFS/g1/functions/"$usb_serial_function" $CONFIGFS/g1/configs/c.1 ||
-		echo "Couldn't symlink $usb_serial_function"
+	mkdir -p "$CONFIGFS/g1/functions/$usb_serial_function" ||
+		exit_with_error "Couldn't create $CONFIGFS/g1/functions/$usb_serial_function"
+	ln -s "$CONFIGFS/g1/functions/$usb_serial_function" "$CONFIGFS/g1/configs/c.1" ||
+		exit_with_error "Couldn't symlink $usb_serial_function"

Note: I’m leveraging your “set -euo pipefail” learning to avoid redundant wrappers elsewhere.

Also applies to: 56-67, 69-72

🧹 Nitpick comments (9)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (6)

88-88: Correct log message: it’s unudhcpd, not dnsmasq

-	echo "Starting dnsmasq with server ip $host_ip, client ip: $client_ip"
+	echo "Starting unudhcpd with server ip $host_ip, client ip: $client_ip"

82-82: Quote UDC path redirection

-	ls /sys/class/udc | head -1 > $CONFIGFS/g1/UDC || exit_with_error "Couldn't write UDC"
+	ls /sys/class/udc | head -1 > "$CONFIGFS/g1/UDC" || exit_with_error "Couldn't write UDC"

35-37: Fix wording/typo in user-facing messages

-	echo "Setting up an USB gadget through configfs"
-	# Create an usb gadet configuration
+	echo "Setting up a USB gadget through configfs"
+	# Create a USB gadget configuration

62-63: Typo and naming: “configuration” and reflect composite setup

-	echo "NCM Configuration" > $CONFIGFS/g1/configs/c.1/strings/0x409/configuration ||
-		echo "Couldn't write configration name"
+	echo "Composite (NCM + ACM) Configuration" > "$CONFIGFS/g1/configs/c.1/strings/0x409/configuration" ||
+		echo "Couldn't write configuration name"

19-21: Message/action mismatch: “skipping” but script exits

exit_with_error aborts the script; the message says “skipping”. Align the wording.

-	exit_with_error "$CONFIGFS does not exist, skipping configfs usb gadget"
+	exit_with_error "$CONFIGFS does not exist; aborting USB gadget setup"

81-81: Remove stale shellcheck disable

SC2005 no longer applies after replacing echo $(ls …). Safe to delete the directive.

config/boards/pocketbeagle2.conf (3)

31-44: Fix systemd unit mode and quote paths in install commands

Use 0644 for .service files; quote variables to avoid word-splitting.

-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh $destination/usr/local/bin/setup-usbgadget-network.sh ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh" "$destination/usr/local/bin/setup-usbgadget-network.sh" ||
 		exit_with_error "Failed to install USB gadget setup script"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh $destination/usr/local/bin/ ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh" "$destination/usr/local/bin/" ||
 		exit_with_error "Failed to install USB gadget remove script"
-	install -Dm744 $SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service $destination/usr/lib/systemd/system/ ||
+	install -Dm644 "$SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service" "$destination/usr/lib/systemd/system/" ||
 		exit_with_error "Failed to install USB gadget service"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-hook $destination/etc/initramfs-tools/hooks/usb-gadget ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-hook" "$destination/etc/initramfs-tools/hooks/usb-gadget" ||
 		exit_with_error "Failed to install USB gadget initramfs hook"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-premount $destination/etc/initramfs-tools/scripts/init-premount/usb-gadget ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-premount" "$destination/etc/initramfs-tools/scripts/init-premount/usb-gadget" ||
 		exit_with_error "Failed to install USB gadget initramfs premount script"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/dropbear $destination/etc/initramfs-tools/scripts/init-premount/ ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/dropbear" "$destination/etc/initramfs-tools/scripts/init-premount/" ||
 		exit_with_error "Failed to install USB gadget initramfs premount dropbear"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/kill-dropbear $destination/etc/initramfs-tools/scripts/init-bottom/ ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/kill-dropbear" "$destination/etc/initramfs-tools/scripts/init-bottom/" ||
 		exit_with_error "Failed to install USB gadget initramfs premount kill dropbear"

Also applies to: 35-36


51-55: Harden repo toggle with existence checks

Guard mv to avoid failing when the file is already in desired state.

-	mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources
+	[ -f "${SDCARD}/etc/apt/sources.list.d/armbian.sources.disabled" ] && \
+		mv "${SDCARD}/etc/apt/sources.list.d/armbian.sources.disabled" "${SDCARD}/etc/apt/sources.list.d/armbian.sources"
@@
-	mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled
+	[ -f "${SDCARD}/etc/apt/sources.list.d/armbian.sources" ] && \
+		mv "${SDCARD}/etc/apt/sources.list.d/armbian.sources" "${SDCARD}/etc/apt/sources.list.d/armbian.sources.disabled"

58-60: Prefer printf over echo -e for portability

-	echo -e "[Service]\nEnvironment=\"unudhcpd_host_ip=192.168.7.2\"\nEnvironment=\"unudhcpd_client_ip=192.168.7.3\"" > "${SDCARD}"/etc/systemd/system/usbgadget-rndis.service.d/override.conf
+	printf "%s\n%s\n%s\n" "[Service]" 'Environment="unudhcpd_host_ip=192.168.7.2"' 'Environment="unudhcpd_client_ip=192.168.7.3"' > "${SDCARD}/etc/systemd/system/usbgadget-rndis.service.d/override.conf"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c2e82e6 and ba2b738.

📒 Files selected for processing (2)
  • config/boards/pocketbeagle2.conf (1 hunks)
  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-05T12:31:03.016Z
Learnt from: Ayush1325
PR: armbian/build#8382
File: packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh:104-105
Timestamp: 2025-09-05T12:31:03.016Z
Learning: Scripts using `set -euo pipefail` provide comprehensive error handling that automatically exits on any command failure, making explicit error handling for function calls redundant.

Applied to files:

  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh
🧬 Code graph analysis (2)
config/boards/pocketbeagle2.conf (1)
packages/bsp/usb-gadget-network/setup-usbgadget-network.sh (1)
  • setup_usb_network_configfs (9-73)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1)
packages/bsp/usb-gadget-network/setup-usbgadget-network.sh (2)
  • setup_usb_network_configfs (9-73)
  • set_usbgadget_ipaddress (75-103)
🔇 Additional comments (3)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (2)

33-34: Confirm ACM (ttyGS0) presence won’t break first boot

You removed console=ttyGS0, but ACM is still created. Please confirm armbian-first-run is unaffected when /dev/ttyGS0 exists without console/getty.

Also applies to: 69-72


74-83: UDC selection on multi-UDC systems

We pick the first UDC found. Confirm PB2 exposes only one, or add a board-specific UDC selection if multiple are possible.

config/boards/pocketbeagle2.conf (1)

13-16: Removing ttyGS0 console is the right call

Keeps serial console on ttyS2 only, avoiding the known armbian-first-run issue. LGTM.

Comment on lines +98 to +102
echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show $INTERFACE > /var/log/unudhcpd.log
nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
return
Copy link
Contributor

@coderabbitai coderabbitai bot Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid double-starting DHCP daemon; don’t background with nohup

Starting unudhcpd blindly can spawn multiple daemons across restarts and hides the process from systemd.

Minimal containment:

-	echo "Starting the DHCP daemon"
-	ip a show $INTERFACE > /var/log/unudhcpd.log
-	nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
+	echo "Starting the DHCP daemon"
+	ip a show "$INTERFACE" > /var/log/unudhcpd.log
+	# Skip if already running
+	if pgrep -x unudhcpd >/dev/null 2>&1; then
+		echo "unudhcpd already running; skip"
+		return
+	fi
+	unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &

Better: move unudhcpd into its own systemd unit (Type=simple), started/managed by systemd instead of “nohup &”. I can draft the unit if desired.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show $INTERFACE > /var/log/unudhcpd.log
nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
return
echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show "$INTERFACE" > /var/log/unudhcpd.log
# Skip if already running
if pgrep -x unudhcpd >/dev/null 2>&1; then
echo "unudhcpd already running; skip"
return
fi
unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
return
🤖 Prompt for AI Agents
In packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh around lines
98-102, the script launches unudhcpd directly with nohup and & which can spawn
multiple daemons across restarts and hides the process from systemd; instead
remove the nohup/ backgrounding and the return, create a dedicated systemd unit
(Type=simple) that runs /usr/bin/unudhcpd with the -i/-s/-c args (or
environment-derived values), have the script enable/start that unit (or check
systemctl is-active before starting) and rely on the journal for logs rather
than redirecting to /var/log, so systemd manages lifecycle and prevents
double-starting.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @coderabbitai here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jadonk Thank you for confirming the approach! The suggestion to move away from nohup & backgrounding and implement proper systemd service management will indeed provide better process lifecycle management and prevent the multiple daemon issue.

If @Ayush1325 would like me to draft the systemd unit file for the unudhcpd service, I'd be happy to help with that implementation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1)

2-2: Good: fail-fast posture enabled

set -euo pipefail is in place. This aligns with prior guidance.

🧹 Nitpick comments (5)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (5)

10-13: Send errors to stderr

Print errors to stderr so callers/systemd capture failures correctly.

 exit_with_error() {
-	echo "$1"
+	echo "$1" >&2
 	exit 1
 }

35-37: Fix user-facing typos and wording

Minor but visible in logs.

-echo "Setting up an USB gadget through configfs"
-# Create an usb gadet configuration
+echo "Setting up a USB gadget through configfs"
+# Create a USB gadget configuration
-echo "NCM Configuration" > $CONFIGFS/g1/configs/c.1/strings/0x409/configuration ||
-		echo "Couldn't write configration name"
+echo "Composite Configuration" > "$CONFIGFS/g1/configs/c.1/strings/0x409/configuration" ||
+		echo "Couldn't write configuration name"

Also applies to: 62-63


43-68: Quote paths/vars for safety and consistency

Quoting avoids surprises and reads cleaner; optional since paths are stable.

-mkdir $CONFIGFS/g1/strings/0x409 || echo "Couldn't create $CONFIGFS/g1/strings/0x409"
+mkdir "$CONFIGFS/g1/strings/0x409" || echo "Couldn't create $CONFIGFS/g1/strings/0x409"

-mkdir $CONFIGFS/g1/functions/"$usb_network_function" ||
+mkdir "$CONFIGFS/g1/functions/$usb_network_function" ||

-mkdir $CONFIGFS/g1/configs/c.1 ||
+mkdir "$CONFIGFS/g1/configs/c.1" ||

-echo 250 > $CONFIGFS/g1/configs/c.1/MaxPower
-mkdir $CONFIGFS/g1/configs/c.1/strings/0x409 ||
-echo "NCM Configuration" > $CONFIGFS/g1/configs/c.1/strings/0x409/configuration ||
+echo 250 > "$CONFIGFS/g1/configs/c.1/MaxPower"
+mkdir "$CONFIGFS/g1/configs/c.1/strings/0x409" ||
+echo "Composite Configuration" > "$CONFIGFS/g1/configs/c.1/strings/0x409/configuration" ||

-ln -s $CONFIGFS/g1/functions/"$usb_network_function" $CONFIGFS/g1/configs/c.1 ||
+ln -s "$CONFIGFS/g1/functions/$usb_network_function" "$CONFIGFS/g1/configs/c.1" ||

-mkdir -p $CONFIGFS/g1/functions/"$usb_serial_function" ||
-ln -s $CONFIGFS/g1/functions/"$usb_serial_function" $CONFIGFS/g1/configs/c.1 ||
+mkdir -p "$CONFIGFS/g1/functions/$usb_serial_function" ||
+ln -s "$CONFIGFS/g1/functions/$usb_serial_function" "$CONFIGFS/g1/configs/c.1" ||

Also applies to: 69-73


81-82: Minor: prefer deterministic UDC selection when multiple exist

Current head -1 is fine for PB2, but consider allowing override (e.g., deviceinfo_usb_udc) for boards with multiple UDCs.

-ls /sys/class/udc | head -1 > $CONFIGFS/g1/UDC || exit_with_error "Couldn't write UDC"
+udc="${deviceinfo_usb_udc:-$(ls /sys/class/udc | head -1)}"
+echo "$udc" > "$CONFIGFS/g1/UDC" || exit_with_error "Couldn't write UDC"

98-101: Prefer systemd to manage unudhcpd

Best: keep this script idempotent and delegate DHCP lifecycle to a dedicated unit (Type=simple), with logging via journalctl. This avoids nohup/backgrounding and multiple daemons. I can draft the unit + drop-in if helpful.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ba2b738 and 3c85140.

📒 Files selected for processing (2)
  • config/boards/pocketbeagle2.conf (1 hunks)
  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • config/boards/pocketbeagle2.conf
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-05T12:31:03.016Z
Learnt from: Ayush1325
PR: armbian/build#8382
File: packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh:104-105
Timestamp: 2025-09-05T12:31:03.016Z
Learning: Scripts using `set -euo pipefail` provide comprehensive error handling that automatically exits on any command failure, making explicit error handling for function calls redundant.

Applied to files:

  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh
🧬 Code graph analysis (1)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1)
packages/bsp/usb-gadget-network/setup-usbgadget-network.sh (2)
  • setup_usb_network_configfs (9-73)
  • set_usbgadget_ipaddress (75-103)
🔇 Additional comments (2)
packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (2)

19-26: Exit vs return: confirm intended behavior change

Previously the base script “returned” when configfs/g1 were absent/present; this version exits the whole script. If invoked from a broader provisioning hook, this could be too aggressive. Consider returning instead (consistent with the base script), unless the hard fail is intentional for PB2.

-	if ! [ -e "$CONFIGFS" ]; then
-		exit_with_error "$CONFIGFS does not exist, skipping configfs usb gadget"
-	fi
+	if ! [ -e "$CONFIGFS" ]; then
+		echo "$CONFIGFS does not exist, skipping configfs usb gadget"
+		return
+	fi

69-73: Serial ACM function: confirm it doesn’t reintroduce ttyGS0 issues

You add acm.usb0 to the config. That’s fine if no getty is spawned, but please confirm this doesn’t regress the “armbian-first-run + ttyGS0” problem mentioned in the PR.

Comment on lines +85 to +101
set_usbgadget_ipaddress() {
local host_ip="${unudhcpd_host_ip:-172.16.42.1}"
local client_ip="${unudhcpd_client_ip:-172.16.42.2}"
echo "Starting dnsmasq with server ip $host_ip, client ip: $client_ip"
# Get usb interface
INTERFACE=""
ip addr replace "${host_ip}/16" dev usb0 2>/dev/null && ip link set usb0 up && INTERFACE=usb0
if [ -z "$INTERFACE" ]; then
echo "Interfaces:"
ip link
exit_with_error "Could not find an interface to run a dhcp server on"
fi

echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show $INTERFACE > /var/log/unudhcpd.log
nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
Copy link
Contributor

@coderabbitai coderabbitai bot Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix message (dnsmasq vs unudhcpd) and avoid double-starting DHCP

  • Log mentions dnsmasq but you run unudhcpd.
  • Guard against multiple instances; prefer no nohup in systemd contexts.
 set_usbgadget_ipaddress() {
 	local host_ip="${unudhcpd_host_ip:-172.16.42.1}"
 	local client_ip="${unudhcpd_client_ip:-172.16.42.2}"
-	echo "Starting dnsmasq with server ip $host_ip, client ip: $client_ip"
+	echo "Starting DHCP (unudhcpd) with server ip $host_ip, client ip: $client_ip"
 	# Get usb interface
-	INTERFACE=""
+	local INTERFACE=""
 	ip addr replace "${host_ip}/16" dev usb0 2>/dev/null && ip link set usb0 up && INTERFACE=usb0
 	if [ -z "$INTERFACE" ]; then
 		echo "Interfaces:"
 		ip link
 		exit_with_error "Could not find an interface to run a dhcp server on"
 	fi
 
 	echo "Using interface $INTERFACE"
 	echo "Starting the DHCP daemon"
-	ip a show $INTERFACE > /var/log/unudhcpd.log
-	nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
+	ip a show "$INTERFACE" > /var/log/unudhcpd.log
+	# Skip if already running (systemd unit or prior invocation)
+	if pgrep -x unudhcpd >/dev/null 2>&1; then
+		echo "unudhcpd already running; skip"
+		return
+	fi
+	/usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
 	return
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
set_usbgadget_ipaddress() {
local host_ip="${unudhcpd_host_ip:-172.16.42.1}"
local client_ip="${unudhcpd_client_ip:-172.16.42.2}"
echo "Starting dnsmasq with server ip $host_ip, client ip: $client_ip"
# Get usb interface
INTERFACE=""
ip addr replace "${host_ip}/16" dev usb0 2>/dev/null && ip link set usb0 up && INTERFACE=usb0
if [ -z "$INTERFACE" ]; then
echo "Interfaces:"
ip link
exit_with_error "Could not find an interface to run a dhcp server on"
fi
echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show $INTERFACE > /var/log/unudhcpd.log
nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
set_usbgadget_ipaddress() {
local host_ip="${unudhcpd_host_ip:-172.16.42.1}"
local client_ip="${unudhcpd_client_ip:-172.16.42.2}"
echo "Starting DHCP (unudhcpd) with server ip $host_ip, client ip: $client_ip"
# Get usb interface
local INTERFACE=""
ip addr replace "${host_ip}/16" dev usb0 2>/dev/null && ip link set usb0 up && INTERFACE=usb0
if [ -z "$INTERFACE" ]; then
echo "Interfaces:"
ip link
exit_with_error "Could not find an interface to run a dhcp server on"
fi
echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show "$INTERFACE" > /var/log/unudhcpd.log
# Skip if already running (systemd unit or prior invocation)
if pgrep -x unudhcpd >/dev/null 2>&1; then
echo "unudhcpd already running; skip"
return
fi
/usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
return
}

Copy link
Contributor

@Grippy98 Grippy98 Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably a valid comment - doesn't regular beagle Debian image use dnsmasq already for out of box web UI anyway? Why use unudhcpd on top? - correction nvm then unudhcpd only

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@Grippy98 That's an excellent point! Let me investigate the current DHCP service usage in the Armbian BeagleBone ecosystem to understand if there's potential redundancy or conflict.


🏁 Script executed:

#!/bin/bash
# Check for existing dnsmasq usage in BeagleBone configurations
echo "=== Searching for dnsmasq usage in BeagleBone/PocketBeagle configs ==="
rg -i "dnsmasq" --type=conf --type=sh -A3 -B3

echo -e "\n=== Searching for existing DHCP server configurations ==="
rg -i "dhcp.*server|udhcpd|dnsmasq.*dhcp" --type=conf --type=sh -A2 -B2

echo -e "\n=== Checking other BeagleBone board configurations ==="
fd "beagle" -t f -e conf | head -10 | xargs cat

echo -e "\n=== Looking for existing USB gadget network implementations ==="
fd "usb.*gadget|gadget.*usb" -t f -e sh | head -5 | xargs grep -l "dhcp\|dnsmasq\|udhcpd" 2>/dev/null || true

Length of output: 6725


🏁 Script executed:

#!/bin/bash
# Let's examine the existing USB gadget network implementation and search more broadly
echo "=== Examining existing USB gadget network setup ==="
cat packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

echo -e "\n=== Checking for dnsmasq usage across the entire codebase ==="
rg -i "dnsmasq" -A2 -B2

echo -e "\n=== Looking for any DHCP-related configurations ==="
rg -i "dhcp|udhcpd" -A2 -B2 --type=sh

echo -e "\n=== Examining the systemd service file ==="
cat packages/bsp/usb-gadget-network/usbgadget-rndis.service 2>/dev/null || echo "Service file not found"

Length of output: 11217


You've raised an excellent architectural question! After investigating the codebase, here's what I found:

Current Armbian Architecture:

  • Armbian's existing USB gadget implementation (setup-usbgladget-network.sh) already uses unudhcpd, not dnsmasq
  • There's no actual dnsmasq usage found in the current Armbian BeagleBone configurations
  • The unudhcpd package is specifically installed from the Armbian repository for USB gadget networking

The Confusion:
Both the existing script and the new one have misleading log messages saying "Starting dnsmasq" while actually using unudhcpd. This is exactly what CodeRabbit flagged - the log message doesn't match the actual implementation.

Why unudhcpd vs dnsmasq:

  • unudhcpd is a lightweight, minimal DHCP server ideal for simple USB gadget scenarios
  • It has a smaller footprint and fewer dependencies than dnsmasq
  • The existing Armbian ecosystem already standardized on this approach

Regarding upstream BeagleBoard images:
You're likely thinking of the official BeagleBoard.org Debian images, which may indeed use dnsmasq. However, Armbian maintains its own approach with unudhcpd for USB gadget networking.

SystemD Ordering:
The service file shows Before=dnsmasq.service, which suggests the developers were aware of potential conflicts but designed the service to run before any dnsmasq instance that might be installed later.

Recommendation:
The original CodeRabbit suggestion to fix the log message is valid - it should say "Starting DHCP (unudhcpd)" instead of "Starting dnsmasq" to avoid confusion. The architecture choice itself appears sound and consistent with existing Armbian practices.

🐰 thoughtfully considering the DHCP ecosystem

Copy link
Member Author

@Ayush1325 Ayush1325 Sep 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably a valid comment - doesn't regular beagle Debian image use dnsmasq already for out of box web UI anyway? Why use unudhcpd on top? - correction nvm then unudhcpd only

Well, the above setup is mostly a modified version of already existing armbian infra for doing this: https://github.com/armbian/build/blob/main/packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

To address this particular commit, we would need to dissociate things from the existing infra (since I do not think it's the best idea to change the setups in all the boards that are already using the current method). And at that point, it would be much better to have it as a debian package instead of copying scripts to the image.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Armbian probably copied what we were doing already, but made some tweaks. Rather than add a new script, why not just use settings available to that script or modified to extend for our needs? Seems like we are needlessly re-inventing a re-invented wheel. Feel free to comment @coderabbitai.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@jadonk You raise an excellent architectural point about avoiding unnecessary duplication. Let me analyze both scripts to understand the differences and assess whether consolidation is feasible.


🏁 Script executed:

#!/bin/bash
echo "=== Examining the existing USB gadget network script ==="
cat packages/bsp/usb-gadget-network/setup-usbgladget-network.sh

echo -e "\n=== Examining the new multi-function script ==="
cat packages/bsp/usb-gadget-network/setup-usbgladget-network-multi.sh

echo -e "\n=== Key differences analysis ==="
echo "Comparing function names and structure..."
grep -n "^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*(" packages/bsp/usb-gadget-network/setup-usbgladget-network.sh || echo "No functions found in original"
grep -n "^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*(" packages/bsp/usb-gadget-network/setup-usbgladget-network-multi.sh || echo "No functions found in new script"

echo -e "\n=== Examining USB gadget configuration differences ==="
echo "Original script USB function configuration:"
grep -A5 -B5 "usb_network_function\|mkdir.*functions" packages/bsp/usb-gadget-network/setup-usbgladget-network.sh || echo "No USB function config found"

echo -e "\nNew script USB function configuration:"
grep -A5 -B5 "usb_network_function\|usb_serial_function\|mkdir.*functions" packages/bsp/usb-gadget-network/setup-usbgladget-network-multi.sh || echo "No USB function config found"

Length of output: 1017


Let me first locate the existing USB gadget scripts and ensure I'm examining the right files:


🏁 Script executed:

#!/bin/bash
echo "=== Finding USB gadget related scripts ==="
fd -t f -e sh | xargs grep -l "usb.*gadget\|gadget.*usb" 2>/dev/null | head -10

echo -e "\n=== Searching for existing setup scripts ==="
fd "setup.*usb" -t f

echo -e "\n=== Looking for the exact script mentioned in comments ==="
fd "setup-usbgladget-network.sh" -t f

echo -e "\n=== Current repository state ==="
pwd
git branch --show-current
git log --oneline -5

echo -e "\n=== Looking for USB-related files in packages/bsp ==="
find . -name "*usb*" -type f 2>/dev/null | head -10

echo -e "\n=== Searching for any USB gadget scripts ==="
rg -l "USB.*gadget|gadget.*USB" --type=sh | head -10

Length of output: 1702


Perfect! Now I can see both scripts exist. Let me examine them to analyze the differences and assess whether consolidation is viable:

Now let me analyze the structural differences and identify consolidation opportunities:

Based on my analysis of both scripts, here's my technical assessment:

Key Differences Between Scripts

Existing script (setup-usbgadget-network.sh):

  • Uses RNDIS function (rndis.usb0) - older, Windows-compatible protocol
  • Single function gadget (network only)
  • Simpler configuration structure

New script (setup-usbgladget-network-multi.sh):

  • Uses NCM function (ncm.usb0) - modern, cross-platform protocol
  • Multi-function gadget: Network + Serial (acm.usb0)
  • More complex configuration with multiple function links

Consolidation Assessment

You're absolutely right about the duplication concern. Here are the consolidation options:

Option 1: Parameterize the Existing Script ✅ Recommended

Option 2: Template-based Approach

Create a shared function library and board-specific wrapper scripts.

Option 3: Configuration File Driven

Use a simple config file to define gadget characteristics.

Recommendation

Extend the existing script rather than creating a new one. The differences are primarily:

  1. Network function type (RNDIS vs NCM)
  2. Addition of serial function
  3. Slightly different USB IDs

These can easily be parameterized with environment variables or function arguments, maintaining backward compatibility while enabling the multi-function capability needed for PocketBeagle 2.

Benefits of consolidation:

  • Reduces maintenance burden
  • Eliminates code duplication
  • Provides consistent behavior across boards
  • Easier to fix bugs in one place
  • Better aligns with DRY principles

Implementation suggestion:
Modify the existing script to accept parameters like USB_GADGET_TYPE=multi and USB_ENABLE_SERIAL=true, then update the PocketBeagle 2 board config to export these variables before calling the consolidated script.

This approach respects the existing Armbian architecture while avoiding unnecessary reinvention of the wheel, as you astutely pointed out.


🏁 Script executed:

#!/bin/bash
echo "=== Examining the existing USB gadget network script ==="
cat packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

echo -e "\n=== Examining the new multi-function script ==="
cat packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh

echo -e "\n=== Side-by-side function comparison ==="
echo "EXISTING SCRIPT FUNCTIONS:"
grep -n "^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*(" packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

echo -e "\nNEW SCRIPT FUNCTIONS:"
grep -n "^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*(" packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh

echo -e "\n=== Key configuration differences ==="
echo "EXISTING - USB Functions:"
grep -A2 -B2 "usb_network_function=" packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

echo -e "\nNEW - USB Functions:"
grep -A3 -B1 "usb_network_function=\|usb_serial_function=" packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh

Length of output: 8561


🏁 Script executed:

#!/bin/bash
echo "=== Analyzing gadget creation logic differences ==="
echo "EXISTING - Gadget creation:"
grep -A10 -B2 "mkdir.*CONFIGFS.*g1" packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

echo -e "\nNEW - Gadget creation:"  
grep -A10 -B2 "mkdir.*CONFIGFS.*g1" packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh

echo -e "\n=== Function linking differences ==="
echo "EXISTING - Function links:"
grep -A3 -B1 "ln -s.*functions" packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

echo -e "\nNEW - Function links:"
grep -A3 -B1 "ln -s.*functions" packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh

echo -e "\n=== Checking for parameterization opportunities ==="
echo "EXISTING - Hardcoded values:"
grep -E "rndis\.usb0|ncm\.usb0|acm\.usb0" packages/bsp/usb-gadget-network/setup-usbgadget-network.sh

echo -e "\nNEW - Hardcoded values:"
grep -E "rndis\.usb0|ncm\.usb0|acm\.usb0" packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh

Length of output: 4684


🏁 Script executed:

# Add parameters to control gadget type
usb_gadget_type="${USB_GADGET_TYPE:-rndis}"  # rndis, ncm, multi
enable_serial="${USB_ENABLE_SERIAL:-false}"

case "$usb_gadget_type" in
  "rndis") usb_network_function="rndis.usb0" ;;
  "ncm") usb_network_function="ncm.usb0" ;;
  "multi") usb_network_function="ncm.usb0"; enable_serial="true" ;;
esac

Length of output: 0


Perfect! Now I have the complete analysis. The scripts are remarkably similar - this is indeed a case of reinventing a reinvented wheel.

Detailed Technical Analysis

The scripts are 99% identical. Here are the only meaningful differences:

1. USB Product ID

  • Existing: 0x0103 (NCM Ethernet Gadget)
  • New: 0x0104 (Multifunction Composite Gadget)

2. Serial Function Addition

  • New script adds: usb_serial_function="acm.usb0"
  • New script links: Serial function to configuration

3. Minor Version Differences

  • Existing: bcdDevice = 0x0100
  • New: bcdDevice = 0x0404

4. Error Handling Style

  • Existing: Uses echo and continues gracefully
  • New: Uses exit_with_error() function (stricter)

Everything else is identical: DHCP logic, configfs setup, NCM network function, IP configuration, etc.

Consolidation Implementation

Here's exactly how to consolidate them:

#!/bin/bash
# Consolidated USB Gadget Network Setup

# Configurable parameters
USB_ENABLE_SERIAL="${USB_ENABLE_SERIAL:-false}"
USB_GADGET_PRODUCT_ID="${USB_GADGET_PRODUCT_ID:-0x0103}"  # Default: NCM only
USB_GADGET_BCD_DEVICE="${USB_GADGET_BCD_DEVICE:-0x0100}"

setup_usb_network_configfs() {
    # ... existing setup code ...
    
    # Dynamic Product ID based on configuration
    if [ "$USB_ENABLE_SERIAL" = "true" ]; then
        usb_idProduct="${deviceinfo_usb_idProduct:-${USB_GADGET_PRODUCT_ID:-0x0104}}"
        usb_serial_function="acm.usb0"
    else
        usb_idProduct="${deviceinfo_usb_idProduct:-${USB_GADGET_PRODUCT_ID:-0x0103}}"
    fi
    
    usb_network_function="ncm.usb0"
    
    # ... standard gadget creation ...
    
    # Link network function
    ln -s $CONFIGFS/g1/functions/"$usb_network_function" $CONFIGFS/g1/configs/c.1 ||
        echo "Couldn't symlink $usb_network_function"
    
    # Conditionally add serial function
    if [ "$USB_ENABLE_SERIAL" = "true" ]; then
        mkdir -p $CONFIGFS/g1/functions/"$usb_serial_function" ||
            echo "Couldn't create $CONFIGFS/g1/functions/$usb_serial_function"
        ln -s $CONFIGFS/g1/functions/"$usb_serial_function" $CONFIGFS/g1/configs/c.1 ||
            echo "Couldn't symlink $usb_serial_function"
    fi
    
    # ... rest of setup ...
}

Board Configuration Update

For PocketBeagle 2:

# In config/boards/pocketbeagle2.conf
post_family_tweaks_bsp__pocketbeagle2_firmware() {
    display_alert "Installing USB gadget networking assets" "PocketBeagle 2" "info"
    
    # Enable multi-function USB gadget
    export USB_ENABLE_SERIAL=true
    export USB_GADGET_PRODUCT_ID=0x0104
    export USB_GADGET_BCD_DEVICE=0x0404
    
    # Use the consolidated script
    run_host_command_logged cp -pv "${SRC}"/packages/bsp/usb-gadget-network/setup-usbgladget-network.sh "${destination}"/usr/bin/
    # ... rest of installation ...
}

Benefits of This Approach

Eliminates duplication - One script, multiple configurations
Maintains backward compatibility - Existing boards unchanged
Reduces maintenance - Bug fixes in one place
Follows DRY principle - Don't repeat yourself
Clear parameterization - Intent obvious from variable names
Future extensible - Easy to add RNDIS support later

Migration Path

  1. Phase 1: Update existing script with parameterization
  2. Phase 2: Update PocketBeagle 2 to use parameters
  3. Phase 3: Remove the duplicate script
  4. Phase 4: Update other boards to use parameters if desired

This approach exactly addresses your concern about needless reinvention while providing a clean, maintainable solution that respects the existing Armbian architecture.

The 15+ lines of actual difference don't justify a completely separate 105-line script when simple parameterization achieves the same goal.


🧠 Learnings used
Learnt from: pyavitz
PR: armbian/build#8421
File: config/kernel/linux-sunxi64-edge.config:805-825
Timestamp: 2025-07-27T15:53:30.629Z
Learning: In the Armbian build system, kernel configurations prioritize broad hardware compatibility over optimization concerns. Even when including numerous legacy/obsolete drivers causes technical issues like increased initramfs size and slower enumeration, the project philosophy is to "appease the masses" by ensuring maximum device compatibility rather than optimizing for specific use cases.

Learnt from: pyavitz
PR: armbian/build#8388
File: config/boards/kickpik2b.conf:1-14
Timestamp: 2025-07-17T04:12:33.125Z
Learning: In the Armbian build system, board configuration files (*.conf) follow a project standard of not including shebang lines, even though they contain bash code and are sourced by the build system. This is an established Armbian convention that individual contributors are expected to follow, and changes to this standard would require broader project maintainer approval.

Copy link
Contributor

@Grippy98 Grippy98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved from my end, CodeRawbbit seems to be hallucinating quite a bit.

Long term plans are to look at having it as a package instead of build steps.

@github-actions github-actions bot added the Ready to merge Reviewed, tested and ready for merge label Sep 25, 2025
Copy link
Contributor

✅ This PR has been reviewed and approved — all set for merge!

@github-actions github-actions bot removed the Needs review Seeking for review label Sep 25, 2025
- Use configfs API to setup Multifunction Composite Gadget
- This is already done on all BeagleBoard debian images.
- Allows ssh and serial over USB without any user setup.

Signed-off-by: Ayush Singh <ayush@beagleboard.org>
@github-actions github-actions bot added Needs review Seeking for review and removed Ready to merge Reviewed, tested and ready for merge labels Sep 25, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
config/boards/pocketbeagle2.conf (1)

47-55: Guard repo toggling to avoid build-time breakage if sources file is absent

Wrap mv with existence checks to prevent set -e cascades on boards/releases where armbian.sources(.disabled) may differ.

-	mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources
+	if [[ -e "${SDCARD}/etc/apt/sources.list.d/armbian.sources.disabled" ]]; then
+		mv "${SDCARD}/etc/apt/sources.list.d/armbian.sources.disabled" "${SDCARD}/etc/apt/sources.list.d/armbian.sources"
+	fi
 	do_with_retries 3 chroot_sdcard_apt_get_install unudhcpd
-	# disable armbian repo back
-	mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled
+	# disable armbian repo back
+	if [[ -e "${SDCARD}/etc/apt/sources.list.d/armbian.sources" ]]; then
+		mv "${SDCARD}/etc/apt/sources.list.d/armbian.sources" "${SDCARD}/etc/apt/sources.list.d/armbian.sources.disabled"
+	fi
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3c85140 and 586eb03.

📒 Files selected for processing (2)
  • config/boards/pocketbeagle2.conf (1 hunks)
  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh
🧰 Additional context used
🧬 Code graph analysis (1)
config/boards/pocketbeagle2.conf (2)
lib/functions/bsp/armbian-bsp-cli-deb.sh (5)
  • board_side_bsp_cli_postinst_update_uboot_bootscript (331-358)
  • board_side_bsp_cli_preinst (360-415)
  • board_side_bsp_cli_postinst_base (425-446)
  • board_side_bsp_cli_postinst_finish (448-471)
  • compile_armbian-bsp-cli (57-251)
lib/functions/rootfs/post-tweaks.sh (1)
  • post_debootstrap_tweaks (10-34)
🔇 Additional comments (3)
config/boards/pocketbeagle2.conf (3)

13-13: Console cleanup looks consistent

Dropping ttyGS0 from SERIALCON and SRC_CMDLINE aligns with the stated issue and avoids first-boot breakage.

Also applies to: 16-16


28-30: Good rationale for script rename

Clear explanation for keeping a stable service name while varying board configs.


56-60: Verify hook, package, and IP mapping

  • Confirm post_family_tweaks__pocketbeagle2_enable_services() is actually invoked (build may be calling post_family_tweaks_bsp, not post_family_tweaks).
  • Ensure unudhcpd exists in the target suite (same name is used elsewhere).
  • The override uses unudhcpd_host_ip/unudhcpd_client_ip as the setup scripts expect—double-check that 192.168.7.2/7.3 are assigned to the correct sides (board vs. host).

Comment on lines +25 to +44
mkdir -p $destination/usr/local/bin/
mkdir -p $destination/usr/lib/systemd/system/
mkdir -p $destination/etc/initramfs-tools/scripts/init-bottom/
# The service expects the name setup-usbgadget-network.sh. Depending on the board vendor, the
# usbgadget configuration they would like can be wildly different. However, the same service
# will work fine for almost all cases. So better to rename file rather than modifying the service.
install -Dm755 $SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh $destination/usr/local/bin/setup-usbgadget-network.sh ||
exit_with_error "Failed to install USB gadget setup script"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh $destination/usr/local/bin/ ||
exit_with_error "Failed to install USB gadget remove script"
install -Dm744 $SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service $destination/usr/lib/systemd/system/ ||
exit_with_error "Failed to install USB gadget service"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-hook $destination/etc/initramfs-tools/hooks/usb-gadget ||
exit_with_error "Failed to install USB gadget initramfs hook"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-premount $destination/etc/initramfs-tools/scripts/init-premount/usb-gadget ||
exit_with_error "Failed to install USB gadget initramfs premount script"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/dropbear $destination/etc/initramfs-tools/scripts/init-premount/ ||
exit_with_error "Failed to install USB gadget initramfs premount dropbear"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/kill-dropbear $destination/etc/initramfs-tools/scripts/init-bottom/ ||
exit_with_error "Failed to install USB gadget initramfs premount kill dropbear"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix unit file mode (0644) and quote paths to harden installs

  • Systemd unit should be 0644, not 0744.
  • Quote $SRC and $destination to avoid pathname splitting and globbing.

Apply:

-	mkdir -p $destination/usr/local/bin/
-	mkdir -p $destination/usr/lib/systemd/system/
-	mkdir -p $destination/etc/initramfs-tools/scripts/init-bottom/
+	mkdir -p "$destination/usr/local/bin"
+	mkdir -p "$destination/usr/lib/systemd/system"
+	mkdir -p "$destination/etc/initramfs-tools/scripts/init-bottom"

-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh $destination/usr/local/bin/setup-usbgadget-network.sh ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh" "$destination/usr/local/bin/setup-usbgadget-network.sh" ||
 		exit_with_error "Failed to install USB gadget setup script"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh $destination/usr/local/bin/ ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh" "$destination/usr/local/bin/" ||
 		exit_with_error "Failed to install USB gadget remove script"
-	install -Dm744 $SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service $destination/usr/lib/systemd/system/ ||
+	install -Dm644 "$SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service" "$destination/usr/lib/systemd/system/" ||
 		exit_with_error "Failed to install USB gadget service"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-hook $destination/etc/initramfs-tools/hooks/usb-gadget ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-hook" "$destination/etc/initramfs-tools/hooks/usb-gadget" ||
 		exit_with_error "Failed to install USB gadget initramfs hook"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-premount $destination/etc/initramfs-tools/scripts/init-premount/usb-gadget ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-premount" "$destination/etc/initramfs-tools/scripts/init-premount/usb-gadget" ||
 		exit_with_error "Failed to install USB gadget initramfs premount script"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/dropbear $destination/etc/initramfs-tools/scripts/init-premount/ ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/dropbear" "$destination/etc/initramfs-tools/scripts/init-premount/" ||
 		exit_with_error "Failed to install USB gadget initramfs premount dropbear"
-	install -Dm755 $SRC/packages/bsp/usb-gadget-network/kill-dropbear $destination/etc/initramfs-tools/scripts/init-bottom/ ||
+	install -Dm755 "$SRC/packages/bsp/usb-gadget-network/kill-dropbear" "$destination/etc/initramfs-tools/scripts/init-bottom/" ||
 		exit_with_error "Failed to install USB gadget initramfs premount kill dropbear"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mkdir -p $destination/usr/local/bin/
mkdir -p $destination/usr/lib/systemd/system/
mkdir -p $destination/etc/initramfs-tools/scripts/init-bottom/
# The service expects the name setup-usbgadget-network.sh. Depending on the board vendor, the
# usbgadget configuration they would like can be wildly different. However, the same service
# will work fine for almost all cases. So better to rename file rather than modifying the service.
install -Dm755 $SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh $destination/usr/local/bin/setup-usbgadget-network.sh ||
exit_with_error "Failed to install USB gadget setup script"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh $destination/usr/local/bin/ ||
exit_with_error "Failed to install USB gadget remove script"
install -Dm744 $SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service $destination/usr/lib/systemd/system/ ||
exit_with_error "Failed to install USB gadget service"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-hook $destination/etc/initramfs-tools/hooks/usb-gadget ||
exit_with_error "Failed to install USB gadget initramfs hook"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-premount $destination/etc/initramfs-tools/scripts/init-premount/usb-gadget ||
exit_with_error "Failed to install USB gadget initramfs premount script"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/dropbear $destination/etc/initramfs-tools/scripts/init-premount/ ||
exit_with_error "Failed to install USB gadget initramfs premount dropbear"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/kill-dropbear $destination/etc/initramfs-tools/scripts/init-bottom/ ||
exit_with_error "Failed to install USB gadget initramfs premount kill dropbear"
mkdir -p "$destination/usr/local/bin"
mkdir -p "$destination/usr/lib/systemd/system"
mkdir -p "$destination/etc/initramfs-tools/scripts/init-bottom"
# The service expects the name setup-usbgadget-network.sh. Depending on the board vendor, the
# usbgadget configuration they would like can be wildly different. However, the same service
# will work fine for almost all cases. So better to rename file rather than modifying the service.
install -Dm755 "$SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh" "$destination/usr/local/bin/setup-usbgadget-network.sh" ||
exit_with_error "Failed to install USB gadget setup script"
install -Dm755 "$SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh" "$destination/usr/local/bin/" ||
exit_with_error "Failed to install USB gadget remove script"
install -Dm644 "$SRC/packages/bsp/usb-gadget-network/usbgadget-rndis.service" "$destination/usr/lib/systemd/system/" ||
exit_with_error "Failed to install USB gadget service"
install -Dm755 "$SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-hook" "$destination/etc/initramfs-tools/hooks/usb-gadget" ||
exit_with_error "Failed to install USB gadget initramfs hook"
install -Dm755 "$SRC/packages/bsp/usb-gadget-network/usb-gadget-initramfs-premount" "$destination/etc/initramfs-tools/scripts/init-premount/usb-gadget" ||
exit_with_error "Failed to install USB gadget initramfs premount script"
install -Dm755 "$SRC/packages/bsp/usb-gadget-network/dropbear" "$destination/etc/initramfs-tools/scripts/init-premount/" ||
exit_with_error "Failed to install USB gadget initramfs premount dropbear"
install -Dm755 "$SRC/packages/bsp/usb-gadget-network/kill-dropbear" "$destination/etc/initramfs-tools/scripts/init-bottom/" ||
exit_with_error "Failed to install USB gadget initramfs premount kill dropbear"
🤖 Prompt for AI Agents
In config/boards/pocketbeagle2.conf around lines 25 to 44, the systemd unit is
being installed with mode 0744 and several install commands use unquoted $SRC
and $destination which can cause pathname splitting/globbing; change the
usbgadget-rndis.service install to mode 0644 and wrap all occurrences of $SRC
and $destination in double quotes (e.g., "$SRC/..." and "$destination/...") so
paths are safe and the unit file permissions are corrected.

Copy link

@jadonk jadonk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is the current state of things, but I'd rather see this be put into a package separate from the board config, but have it be included in the standard images.

display_alert "Setup USB Gadget for ${BOARD}" "${RELEASE}" "warn"

# USB Gadget Network service
mkdir -p $destination/usr/local/bin/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any distro-installed software should be in /usr/local.

OPTEE_PLATFORM="k3-am62x"

# USB Gadget
function post_family_tweaks_bsp__pocketbeagle2_firmware() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming, based on our discussion, that you won't do this here, but instead make this into a package? This just seems wrong.

KERNEL_TARGET="edge"
KERNEL_TEST_TARGET="edge"
SERIALCON="ttyS2,ttyGS0"
SERIALCON="ttyS2"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would you remove the gadget serial console?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, currently, enabling gadget serial console causes armbian first run to silently die. Or well, to be more accurate, the gadget serial console ends up being run after armbian-first run is already started. And armbian-first-run does not like a new serial console showing up all of a sudden.

display_alert "Enable Services for ${BOARD}" "${RELEASE}" "warn"

# We need unudhcpd from armbian repo, so enable it
mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels wrong.

mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled "${SDCARD}"/etc/apt/sources.list.d/armbian.sources
do_with_retries 3 chroot_sdcard_apt_get_install unudhcpd
# disable armbian repo back
mv "${SDCARD}"/etc/apt/sources.list.d/armbian.sources "${SDCARD}"/etc/apt/sources.list.d/armbian.sources.disabled
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd.

chroot_sdcard systemctl enable usbgadget-rndis.service
# We want custom IPs. systemctl edit does not seem to work in chroot.
mkdir -p "${SDCARD}"/etc/systemd/system/usbgadget-rndis.service.d
echo -e "[Service]\nEnvironment=\"unudhcpd_host_ip=192.168.7.2\"\nEnvironment=\"unudhcpd_client_ip=192.168.7.3\"" > "${SDCARD}"/etc/systemd/system/usbgadget-rndis.service.d/override.conf
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it should be in a package install.

# will work fine for almost all cases. So better to rename file rather than modifying the service.
install -Dm755 $SRC/packages/bsp/usb-gadget-network/setup-usbgadget-network-multi.sh $destination/usr/local/bin/setup-usbgadget-network.sh ||
exit_with_error "Failed to install USB gadget setup script"
install -Dm755 $SRC/packages/bsp/usb-gadget-network/remove-usbgadget-network.sh $destination/usr/local/bin/ ||
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/usr/local is just wrong in a distro-installed component.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to put this in a package outside the BSP.

Comment on lines +85 to +101
set_usbgadget_ipaddress() {
local host_ip="${unudhcpd_host_ip:-172.16.42.1}"
local client_ip="${unudhcpd_client_ip:-172.16.42.2}"
echo "Starting dnsmasq with server ip $host_ip, client ip: $client_ip"
# Get usb interface
INTERFACE=""
ip addr replace "${host_ip}/16" dev usb0 2>/dev/null && ip link set usb0 up && INTERFACE=usb0
if [ -z "$INTERFACE" ]; then
echo "Interfaces:"
ip link
exit_with_error "Could not find an interface to run a dhcp server on"
fi

echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show $INTERFACE > /var/log/unudhcpd.log
nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Armbian probably copied what we were doing already, but made some tweaks. Rather than add a new script, why not just use settings available to that script or modified to extend for our needs? Seems like we are needlessly re-inventing a re-invented wheel. Feel free to comment @coderabbitai.

Comment on lines +98 to +102
echo "Using interface $INTERFACE"
echo "Starting the DHCP daemon"
ip a show $INTERFACE > /var/log/unudhcpd.log
nohup /usr/bin/unudhcpd -i "$INTERFACE" -s "$host_ip" -c "$client_ip" >> /var/log/unudhcpd.log 2>&1 &
return
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @coderabbitai here.

@Grippy98
Copy link
Contributor

Looking at this actually there really isn't something Beagle-specific, it's more just USB gadget behavior out of box.

@leggewie this is probably something that should be packaged generically in APA so any board that exposes USB Device over it's power input port could use.

@igorpecovnik Any history here that I'm missing or something you'd like enabled? Having Serial & Ethernet for headless setup with one cable is nice on boards that support it.

@leggewie
Copy link
Collaborator

leggewie commented Sep 26, 2025

@leggewie this is probably something that should be packaged generically in APA so any board that exposes USB Device over it's power input port could use.

Absolutely, that's what I thought when I saw this very nice little feature. I didn't comment on moving this into a package at the time, though because I felt it would be appropriate to give you guys something you can point to as working well on your HW. Rather, than you doing the work and then enabling the feature for all of your competitors.

I looked into it far enough to see there is some code for this in Armbian, too. I nitpicked some spellings and PRd them but did not go further with it for the above-mentioned reasons so I am not sure how well this works in Armbian in general.

If you want, just let me know what kind of files you want shipped where. We can ship them in armbian-common or armbian-ti-common. Feel free to PR APA anytime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
08 Milestone: Third quarter release BSP Board Support Packages Hardware Hardware related like kernel, U-Boot, ... Needs review Seeking for review size/medium PR with more then 50 and less then 250 lines
Development

Successfully merging this pull request may close these issues.

4 participants