Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pltagent-msc-host: ext2 #35

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#!/bin/bash

# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) 2023 Blue Clover Devices
#
# Handler for USB-MSC gadget driver

# References:
#- https://developer.ridgerun.com/wiki/index.php?title=How_to_use_mass_storage_gadget
#- https://linuxlink.timesys.com/docs/wiki/engineering/HOWTO_Use_USB_Gadget_File_Storage

should_mount=0
should_present=0

CMD="$1"
CMDOPT="$2"

if [ "$CMD" = "mount" ]; then
should_mount=1
fi

if [ "$CMD" = "present" ]; then
should_present=1
fi

# USB Device Controller
#udc_dev="*"
udc_dev="fe980000.usb"
sysfs_udc_dev_path="/sys/class/udc/${udc_dev}"
sysfs_udc_state_path="${sysfs_udc_dev_path}/state"

sysfs_msc_lun_path="/sys/kernel/config/usb_gadget/pltagent/functions/mass_storage.0/lun.0"
sysfs_msc_file_path="${sysfs_msc_lun_path}/file"
sysfs_msc_forced_eject_path="${sysfs_msc_lun_path}/forced_eject"

backing_file_path="/run/pltagent/usb-msc.img"
backing_file_size="256M"

local_mount_path="/run/pltagent/mnt"
loopdev="/dev/loop0"

if [ ! -f "${sysfs_udc_state_path}" ]; then
echo "FAIL:${sysfs_udc_state_path} not found"
exit 1
fi
if [ ! -f "${sysfs_msc_file_path}" ]; then
echo "FAIL:${sysfs_msc_file_path} not found"
exit 1
fi
if [ ! -f "${sysfs_msc_forced_eject_path}" ]; then
echo "FAIL:${sysfs_msc_forced_eject_path} not found"
exit 1
fi
# if [ ! -f "${backing_file_template_path}" ]; then
# echo "FAIL:${backing_file_template_path} not found"
# exit 1
# fi

if [ ! -d "${local_mount_path}" ]; then
mkdir -m 0755 -p "${local_mount_path}"
fi

function gen_image {
dd if=/dev/zero of="{backing_file_path}" bs=${backing_file_size} count=1
/usr/sbin/parted --script "${backing_file_path}" -- mklabel msdos \
mkpart primary ext2 1MiB -2048s
mke2fs "${backing_file_path}" "${backing_file_size}"
/usr/sbin/mkfs.ext2 -v --offset=1024 -L RAMDISK "${backing_file_path}"
}

function mount_locally {
if [ "$CMDOPT" = "-forced_eject" ]; then
echo "Forcing eject.."
echo "1" >"${sysfs_msc_forced_eject_path}"
echo "" >"${sysfs_msc_file_path}"
elif [ "$CMDOPT" = "-await_eject" ]; then
while [ ! -z "$(cat "${sysfs_msc_file_path}")" ]; do
sleep 1
echo "Awaiting eject.."
done
echo "Ejected"
else
echo "" >"${sysfs_msc_file_path}"
fi
if [ ! -f "${backing_file_path}" ]; then
gen_image
fi
parted_output=$(/usr/sbin/parted -m "${backing_file_path}" print)
partition_offset=$(echo "${parted_output}" | grep "${backing_file_path}" | cut -d: -f4)
echo "partition_offset: ${partition_offset}"
/sbin/losetup -o "${partition_offset}" "${loopdev}" "${backing_file_path}"
mount -t ext2 "${loopdev}" "${local_mount_path}"
}

function check_is_mounted {
mount_entry=$(cat /proc/mounts | cut -d\ -f2 | grep ${local_mount_path})
echo " mount_entry: '${mount_entry}'"
if [ -n "${mount_entry}" ]; then return 1; fi
return 0
}

function present_to_usbhost {
umount "${local_mount_path}" 2>/dev/null
/sbin/losetup -D
if [ ! -f "${backing_file_path}" ]; then
gen_image
fi
echo "${backing_file_path}" >"${sysfs_msc_file_path}"
}

function check_is_presented {
sysfs_msc_file=$(cat ${sysfs_msc_file_path})
if [ -z "${sysfs_msc_file}" ]; then return 0; fi
return 1
}

can_mount=0
can_present=0

check_is_presented
is_presented=$?
udc_state=$(cat ${sysfs_udc_state_path})

case ${udc_state} in
"not attached")
echo "USB gadget is not attached"
;;
"addressed")
echo "USB gadget is being addressed"
# ```
# usb <USBPATH>: new high-speed USB device number <USBDEVNUM> using <DRIVER>
# usb <USBPATH>: New USB device found, idVendor=0525, idProduct=a4a5, bcdDevice= 6.01
# usb <USBPATH>: New USB device strings: Mfr=3, Product=4, SerialNumber=0
# usb <USBPATH>: Product: Mass Storage Gadget
# usb <USBPATH>: Manufacturer: Linux 6.1.20-v8 with <USBDEV>
# ```
;;
"configured")
echo "USB gadget is configured (connected to PLT)"
# ```
# usb-storage <USBPATH>:1.0: USB Mass Storage device detected
# usb-storage <USBPATH>:1.0: Quirks match for vid 0525 pid a4a5: 10000
# scsi <SCSINUM>: usb-storage <USBPATH>:1.0
# scsi <SCSINUM>:0:0:0: Direct-Access Linux File-Stor Gadget 0601 PQ: 0 ANSI: 2
# sd <SCSINUM>:0:0:0: Power-on or device reset occurred
# sd <SCSINUM>:0:0:0: [sdc] Media removed, stopped polling
# sd <SCSINUM>:0:0:0: [sdc] Attached SCSI removable disk
# ```
can_present=1
;;
"suspended")
echo "USB gadget is suspended (disconnected from PLT)"
;;
"powered")
echo "USB gadget is powered (connected to a power supply)"
;;
*)
echo "WARN:udc_state:'${udc_state}'"
;;
esac

check_is_mounted
is_mounted=$?

if [ ${is_mounted} -eq 1 ]; then
can_present=0
fi

echo "is_presented: ${is_presented}"
echo " udc_state: ${udc_state}"
echo " is_mounted: ${is_mounted}"
echo " can_mount: ${can_mount}"
echo " can_present: ${can_present}"

case ${is_mounted} in
0)
if [ ${should_mount} -eq 1 ]; then
echo "Mounting disk image locally.."
mount_locally
is_presented=0
else
echo "Disk image is not mounted locally"
fi
;;
1)
echo "Disk image is mounted locally"
;;
*)
echo "FAIL:is_mounted:'${is_mounted}'"
exit -1
;;
esac

case ${is_presented} in
0)
if [ ${should_present} -eq 1 ]; then
echo "Presenting disk image to PLT.."
present_to_usbhost
else
echo "Disk image is not presented to PLT"
fi
;;
1)
echo "Disk image is presented to PLT"
# ```
# sd <SCSINUM>:0:0:0: Attached scsi generic sg1 type 0
# sd <SCSINUM>:0:0:0: Power-on or device reset occurred
# sd <SCSINUM>:0:0:0: [sdb] 20481 512-byte logical blocks: (10.5 MB/10.0 MiB)
# sd <SCSINUM>:0:0:0: [sdb] Write Protect is off
# sd <SCSINUM>:0:0:0: [sdb] Mode Sense: 0f 00 00 00
# sd <SCSINUM>:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
# sdb: sdb1
# sd <SCSINUM>:0:0:0: [sdb] Attached SCSI disk
# ```
;;
*)
echo "FAIL:is_presented:${is_presented}"
exit -1
;;
esac
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ sysfs_msc_file_path="${sysfs_msc_lun_path}/file"
sysfs_msc_forced_eject_path="${sysfs_msc_lun_path}/forced_eject"

backing_file_path="/run/pltagent/usb-msc.img"
backing_file_template_path="/opt/pltagent/usb-msc-vfat-empty.img.xz"
backing_file_size="256M"
partition_offset_dosfs="1024"
partition_offset="1024K"

local_mount_path="/run/pltagent/mnt"
loopdev="/dev/loop0"
Expand All @@ -52,30 +54,36 @@ if [ ! -f "${sysfs_msc_forced_eject_path}" ]; then
echo "FAIL:${sysfs_msc_forced_eject_path} not found"
exit 1
fi
if [ ! -f "${backing_file_template_path}" ]; then
echo "FAIL:${backing_file_template_path} not found"
exit 1
fi

if [ ! -d "${local_mount_path}" ]; then
mkdir -m 0755 -p "${local_mount_path}"
fi

function gen_image {
xzcat "${backing_file_template_path}" >"${backing_file_path}"
dd if=/dev/zero of="${backing_file_path}" bs=${backing_file_size} count=1
/usr/sbin/parted --script "${backing_file_path}" -- mklabel msdos \
mkpart primary fat16 1MiB -2048s
/usr/sbin/mkfs.vfat.dosfstools -v --offset="${partition_offset_dosfs}" -S 1024 -F 16 -n RAMDISK "${backing_file_path}"
}

function mount_locally {
if [ "$CMDOPT" = "-forced_eject" ]; then
echo "Forcing eject.."
echo "1" >"${sysfs_msc_forced_eject_path}"
echo "" >"${sysfs_msc_file_path}"
elif [ "$CMDOPT" = "-await_eject" ]; then
while [ ! -z "$(cat "${sysfs_msc_file_path}")" ]; do
sleep 1
echo "Awaiting eject.."
done
echo "Ejected"
else
echo "" >"${sysfs_msc_file_path}"
fi
echo "" >"${sysfs_msc_file_path}"
if [ ! -f "${backing_file_path}" ]; then
gen_image
fi
parted_output=$(/usr/sbin/parted -m "${backing_file_path}" print)
partition_offset=$(echo "${parted_output}" | grep "${backing_file_path}" | cut -d: -f4)
echo "partition_offset: ${partition_offset}"
/sbin/losetup -o "${partition_offset}" "${loopdev}" "${backing_file_path}"
mount -t vfat "${loopdev}" "${local_mount_path}"
Expand Down
9 changes: 5 additions & 4 deletions recipes-mfgtools/pltagent-msc-host/pltagent-msc-host.bb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384

SRC_URI = "\
file://pltagent-msc-host-handler.sh \
file://pltagent-msc-host-handler-ext2.sh \
file://pltagent-msc-mount.sh \
file://pltagent-msc-present.sh \
file://pltagent-msc-profile.sh \
file://pltagent-msc-program.sh \
file://pltagent-prompt.bashrc \
file://pltagent-usbgadget-handler.sh \
file://usb-msc-vfat-empty.img.xz;unpack=0 \
"

S = "${WORKDIR}"
Expand All @@ -23,8 +23,8 @@ FILES:${PN} += " /opt/pltagent/bin/pltagent-msc-program"
FILES:${PN} += " /opt/pltagent/bin/pltagent-msc-profile.sh"
FILES:${PN} += " /opt/pltagent/etc/pltagent-prompt.bashrc"
FILES:${PN} += " /opt/pltagent/sbin/pltagent-msc-host-handler.sh"
FILES:${PN} += " /opt/pltagent/sbin/pltagent-msc-host-handler-ext2.sh"
FILES:${PN} += " /opt/pltagent/sbin/pltagent-usbgadget-handler.sh"
FILES:${PN} += " /opt/pltagent/usb-msc-vfat-empty.img.xz"

DEPENDS += " packagegroup-base"
DEPENDS += " pltagent"
Expand All @@ -33,6 +33,8 @@ DEPENDS += " pltagent"
RDEPENDS:${PN} += " bash"
RDEPENDS:${PN} += " coreutils"
RDEPENDS:${PN} += " dosfstools"
RDEPENDS:${PN} += " e2fsprogs-e2fsck"
RDEPENDS:${PN} += " e2fsprogs-mke2fs"
RDEPENDS:${PN} += " parted"
#RDEPENDS:${PN} += " pltagent-prog"
RDEPENDS:${PN} += " util-linux-losetup"
Expand All @@ -43,8 +45,6 @@ RRECOMMENDS:${PN} += " kernel-module-g-file-storage"
RRECOMMENDS:${PN} += " kernel-module-g-mass-storage"

do_install () {
install -m 0755 -d "${D}/opt/pltagent"
install -m 0644 "${S}/usb-msc-vfat-empty.img.xz" "${D}/opt/pltagent"
install -m 0755 -d "${D}/opt/pltagent/bin"
install -m 0755 "${S}/pltagent-msc-mount.sh" "${D}/opt/pltagent/bin/pltagent-msc-mount"
install -m 0755 "${S}/pltagent-msc-present.sh" "${D}/opt/pltagent/bin/pltagent-msc-present"
Expand All @@ -53,6 +53,7 @@ do_install () {
install -m 0755 "${S}/pltagent-prompt.bashrc" "${D}/opt/pltagent/etc/pltagent-prompt.bashrc"
install -m 0755 -d "${D}/opt/pltagent/sbin"
install -m 0755 "${S}/pltagent-msc-host-handler.sh" "${D}/opt/pltagent/sbin"
install -m 0755 "${S}/pltagent-msc-host-handler-ext2.sh" "${D}/opt/pltagent/sbin/pltagent-msc-host-handler-ext2.sh"
install -m 0755 "${S}/pltagent-usbgadget-handler.sh" "${D}/opt/pltagent/sbin"
install -m 0755 -d "${D}/etc/profile.d"
install -m 0644 "${S}/pltagent-msc-profile.sh" "${D}/etc/profile.d/pltagent-msc.sh"
Expand Down
2 changes: 2 additions & 0 deletions scripts/kas/kas-base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
SDKMACHINE = "x86_64"
USER_CLASSES = "buildstats"
PATCHRESOLVE = "noop"
BB_HASHSERVE_UPSTREAM = "hashserv.yocto.io:8687"
SSTATE_MIRRORS ?= "file://.* http://cdn.jsdelivr.net/yocto/sstate/all/PATH;downloadfilename=PATH"

Check warning on line 45 in scripts/kas/kas-base.yml

View workflow job for this annotation

GitHub Actions / lintAllTheThings

45:81 [line-length] line too long (101 > 80 characters)
diskmon: |
BB_DISKMON_DIRS = "\
STOPTASKS,${TMPDIR},1G,100K \
Expand All @@ -54,6 +56,6 @@
meta-bcddev: |
INIT_MANAGER = "systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES = "acl ipv4 ipv6 usbgadget usbhost xattr vfat seccomp multiarch ldconfig systemd"

Check warning on line 59 in scripts/kas/kas-base.yml

View workflow job for this annotation

GitHub Actions / lintAllTheThings

59:81 [line-length] line too long (101 > 80 characters)
#INHERIT += "create-spdx"
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
Loading