summaryrefslogtreecommitdiff
path: root/recipes-core/udev
diff options
context:
space:
mode:
authorJohn Klug <john.klug@multitech.com>2021-07-28 11:38:08 -0500
committerJohn Klug <john.klug@multitech.com>2021-07-28 11:38:08 -0500
commitd2f5cd07020fa0b2d325fcdae62e3815bd97a81e (patch)
treed324bde28ff0c4eeec9912c575c631f2fb3e1fe0 /recipes-core/udev
parente6cab10569eecb04097a6916683b5391e10b0f6f (diff)
downloadmeta-mlinux-d2f5cd07020fa0b2d325fcdae62e3815bd97a81e.tar.gz
meta-mlinux-d2f5cd07020fa0b2d325fcdae62e3815bd97a81e.tar.bz2
meta-mlinux-d2f5cd07020fa0b2d325fcdae62e3815bd97a81e.zip
udev recipes apply to most machines, not just Atmel
Diffstat (limited to 'recipes-core/udev')
-rw-r--r--recipes-core/udev/README3
-rw-r--r--recipes-core/udev/eudev/cellular_radios.rules86
-rw-r--r--recipes-core/udev/eudev/init138
-rw-r--r--recipes-core/udev/eudev/mtcap3.rules4
-rw-r--r--recipes-core/udev/eudev/udev-cache.default5
-rw-r--r--recipes-core/udev/eudev_%.bbappend14
-rw-r--r--recipes-core/udev/udev-extraconf/automount.rules24
-rw-r--r--recipes-core/udev/udev-extraconf/mount.patch136
-rw-r--r--recipes-core/udev/udev-extraconf_%.bbappend5
9 files changed, 408 insertions, 7 deletions
diff --git a/recipes-core/udev/README b/recipes-core/udev/README
deleted file mode 100644
index 8bca35b..0000000
--- a/recipes-core/udev/README
+++ /dev/null
@@ -1,3 +0,0 @@
-udev for Atmel was moved from meta-mlinux to meta-multitech-atmel.
-
-udev for TI was not here.
diff --git a/recipes-core/udev/eudev/cellular_radios.rules b/recipes-core/udev/eudev/cellular_radios.rules
new file mode 100644
index 0000000..d7c0521
--- /dev/null
+++ b/recipes-core/udev/eudev/cellular_radios.rules
@@ -0,0 +1,86 @@
+ACTION=="remove", GOTO="mlinux_end"
+SUBSYSTEM!="tty", GOTO="mlinux_end"
+KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="mlinux_end"
+
+SUBSYSTEMS=="usb", ENV{ID_IFACE}="$attr{bInterfaceNumber}"
+ENV{ID_IFACE}=="", GOTO="mlinux_end"
+
+# All modem ports
+# H5
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="00", SYMLINK+="modem0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="02", SYMLINK+="modem1"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="04", SYMLINK+="modem2"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="06", SYMLINK+="modem3"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="08", SYMLINK+="modem4"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="0a", SYMLINK+="modem5"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="0c", SYMLINK+="modem6"
+# LAT3, LVW3 and LEU3
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="00", SYMLINK+="modem0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="02", SYMLINK+="modem1"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="04", SYMLINK+="modem2"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="06", SYMLINK+="modem3"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="08", SYMLINK+="modem4"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="0a", SYMLINK+="modem5"
+# EV3
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{ID_IFACE}=="00", SYMLINK+="modem0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{ID_IFACE}=="01", SYMLINK+="modem1"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{ID_IFACE}=="02", SYMLINK+="modem2"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{ID_IFACE}=="03", SYMLINK+="modem3"
+# H4
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="00", SYMLINK+="modem0"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="01", SYMLINK+="modem1"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="02", SYMLINK+="modem2"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="03", SYMLINK+="modem3"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="04", SYMLINK+="modem4"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="05", SYMLINK+="modem5"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="06", SYMLINK+="modem6"
+# EV2
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", SYMLINK+="modem$env{ID_PORT}"
+
+# AT Command ports
+# H5: ttyACM0, ttyACM3
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="00", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021", ENV{ID_IFACE}=="06", SYMLINK+="modem_at1"
+# LAT3, LVW3 and LEU3
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="00", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="06", SYMLINK+="modem_at1"
+# EV3: ttyUSB2, ttyUSB3
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{ID_IFACE}=="02", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{ID_IFACE}=="03", SYMLINK+="modem_at1"
+# H4: ttyUSB3, ttyUSB4, ttyUSB5
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="03", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="04", SYMLINK+="modem_at1"
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="683c", ENV{ID_IFACE}=="05", SYMLINK+="modem_at2"
+# EV2: ttyUSB0
+ATTRS{idVendor}=="1199", ATTRS{idProduct}=="0028", ENV{ID_PORT}=="0", SYMLINK+="modem_at0"
+# LAT1, LEU1, LVW2: ttyUSB2, ttyUSB3 (port 04 and port 05)
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1201", ENV{ID_IFACE}=="04", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1201", ENV{ID_IFACE}=="05", SYMLINK+="modem_at1"
+# LJP1(LE910-JN1), LNA3(LE910-NA1): ttyACM0, ttyACM3 (port 00 and port 03)
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="00", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0036", ENV{ID_IFACE}=="06", SYMLINK+="modem_at1"
+# LJP1(LE866) ttyACM0, ttyACM2
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="2300", ENV{ID_IFACE}=="02", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="2300", ENV{ID_IFACE}=="06", SYMLINK+="modem_at1"
+# G3: ttyACM0, ttyACM1
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0022", ENV{ID_IFACE}=="00", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0022", ENV{ID_IFACE}=="02", SYMLINK+="modem_at1"
+# C2: ttyUSB0, ttyUSB1 (Telit Documentation: Modem Port = USB1, Aux Port = USB0)
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1011", ENV{ID_IFACE}=="01", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1011", ENV{ID_IFACE}=="00", SYMLINK+="modem_at1"
+# CATM Telit ME910
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1100", ENV{ID_IFACE}=="01", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1100", ENV{ID_IFACE}=="02", SYMLINK+="modem_at1"
+# CATM Telit ME910 dual USB
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{ID_IFACE}=="01", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{ID_IFACE}=="02", SYMLINK+="modem_at1"
+
+# Quectel EG-95
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0195", ENV{ID_IFACE}=="02", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0195", ENV{ID_IFACE}=="03", SYMLINK+="modem_at1"
+
+# Quectel EG-25
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{ID_IFACE}=="02", SYMLINK+="modem_at0"
+ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{ID_IFACE}=="03", SYMLINK+="modem_at1"
+
+LABEL="mlinux_end"
diff --git a/recipes-core/udev/eudev/init b/recipes-core/udev/eudev/init
new file mode 100644
index 0000000..d941401
--- /dev/null
+++ b/recipes-core/udev/eudev/init
@@ -0,0 +1,138 @@
+#!/bin/sh
+
+### BEGIN INIT INFO
+# Provides: udev
+# Required-Start: mountvirtfs
+# Required-Stop:
+# Default-Start: S
+# Default-Stop:
+# Short-Description: Start udevd, populate /dev and load drivers.
+### END INIT INFO
+
+export TZ=/etc/localtime
+
+[ -d /sys/class ] || exit 1
+[ -r /proc/mounts ] || exit 1
+[ -x @UDEVD@ ] || exit 1
+[ -f /etc/default/udev-cache ] && . /etc/default/udev-cache
+[ -f /etc/udev/udev.conf ] && . /etc/udev/udev.conf
+[ -f /etc/default/rcS ] && . /etc/default/rcS
+
+readfiles () {
+ READDATA=""
+ for filename in $@; do
+ if [ -r $filename ]; then
+ while read line; do
+ READDATA="$READDATA$line"
+ done < $filename
+ fi
+ done
+}
+
+kill_udevd () {
+ pid=`pidof -x udevd`
+ [ -n "$pid" ] && kill $pid
+}
+
+case "$1" in
+ start)
+ export ACTION=add
+ # propagate /dev from /sys
+ echo "Starting udev"
+
+ # Check for requireed devtmpfs before trying to start udev and
+ # mount a no-existant fs.
+ if ! grep -q devtmpfs /proc/filesystems
+ then
+ echo "Missing devtmpfs, which is required for udev to run";
+ echo "Halting..."
+ halt
+ fi
+ # mount the devtmpfs on /dev, if not already done
+ LANG=C awk '$2 == "/dev" && ($3 == "devtmpfs") { exit 1 }' /proc/mounts && {
+ mount -n -o mode=0755 -t devtmpfs none "/dev"
+ }
+ [ -e /dev/pts ] || mkdir -m 0755 /dev/pts
+ [ -e /dev/shm ] || mkdir -m 1777 /dev/shm
+ # the automount rule for udev needs /tmp directory available, as /tmp is a symlink
+ # to /var/tmp which in turn is a symlink to /var/volatile/tmp, we need to make sure
+ # /var/volatile/tmp directory to be available.
+ mkdir -m 1777 -p /var/volatile/tmp
+
+ # Cache handling.
+ # A list of files which are used as a criteria to judge whether the udev cache could be reused.
+ CMP_FILE_LIST="/proc/version /proc/cmdline /proc/devices /proc/atags"
+ if [ "$DEVCACHE" != "" ]; then
+ if [ -e $DEVCACHE ]; then
+ readfiles $CMP_FILE_LIST
+ NEWDATA="$READDATA"
+ readfiles /etc/udev/cache.data
+ OLDDATA="$READDATA"
+ if [ "$OLDDATA" = "$NEWDATA" ]; then
+ (cd /; tar xf $DEVCACHE > /dev/null 2>&1)
+ not_first_boot=1
+ [ "$VERBOSE" != "no" ] && echo "udev: using cache file $DEVCACHE"
+ [ -e /dev/shm/udev.cache ] && rm -f /dev/shm/udev.cache
+ else
+ # Output detailed reason why the cached /dev is not used
+ if [ "$VERBOSE" != "no" ]; then
+ echo "udev: udev cache not used"
+ echo "udev: we use $CMP_FILE_LIST as criteria to judge whether the cache /dev could be resued"
+ echo "udev: olddata: $OLDDATA"
+ echo "udev: newdata: $NEWDATA"
+ fi
+ echo "$NEWDATA" > /dev/shm/udev.cache
+ fi
+ else
+ if [ "$ROOTFS_READ_ONLY" != "yes" ]; then
+ # If rootfs is not read-only, it's possible that a new udev cache would be generated;
+ # otherwise, we do not bother to read files.
+ readfiles $CMP_FILE_LIST
+ echo "$READDATA" > /dev/shm/udev.cache
+ fi
+ fi
+ fi
+
+ # make_extra_nodes
+ kill_udevd > "/dev/null" 2>&1
+
+ # trigger the sorted events
+ echo -e '\000\000\000\000' > /proc/sys/kernel/hotplug
+ @UDEVD@ -d
+
+ udevadm control --env=STARTUP=1
+ if [ "$not_first_boot" != "" ];then
+ if [ "$PROBE_PLATFORM_BUS" != "yes" ]; then
+ PLATFORM_BUS_NOMATCH="--subsystem-nomatch=platform"
+ else
+ PLATFORM_BUS_NOMATCH=""
+ fi
+ udevadm trigger --action=add --subsystem-nomatch=tty --subsystem-nomatch=mem --subsystem-nomatch=vc --subsystem-nomatch=vtconsole --subsystem-nomatch=misc --subsystem-nomatch=dcon --subsystem-nomatch=pci_bus --subsystem-nomatch=graphics --subsystem-nomatch=backlight --subsystem-nomatch=video4linux $PLATFORM_BUS_NOMATCH
+ (udevadm settle --timeout=10; udevadm control --env=STARTUP=)&
+ else
+ udevadm trigger --action=add
+ udevadm settle
+ fi
+ ;;
+ stop)
+ echo "Stopping udevd"
+ start-stop-daemon --stop --name udevd --quiet
+ ;;
+ restart)
+ $0 stop
+ sleep 1
+ $0 start
+ ;;
+ status)
+ pid=`pidof -x udevd`
+ if [ -n "$pid" ]; then
+ echo "udevd (pid $pid) is running ..."
+ else
+ echo "udevd is stopped"
+ fi
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status|restart}"
+ exit 1
+esac
+exit 0
diff --git a/recipes-core/udev/eudev/mtcap3.rules b/recipes-core/udev/eudev/mtcap3.rules
deleted file mode 100644
index 9ea10b4..0000000
--- a/recipes-core/udev/eudev/mtcap3.rules
+++ /dev/null
@@ -1,4 +0,0 @@
-ACTION=="remove", GOTO="mlinux_end"
-SUBSYSTEM!="tty", GOTO="mlinux_end"
-
-LABEL="mlinux_end"
diff --git a/recipes-core/udev/eudev/udev-cache.default b/recipes-core/udev/eudev/udev-cache.default
new file mode 100644
index 0000000..b1aa63f
--- /dev/null
+++ b/recipes-core/udev/eudev/udev-cache.default
@@ -0,0 +1,5 @@
+# Default for /etc/init.d/udev
+
+# Comment this out to disable device cache
+#DEVCACHE="/etc/dev.tar"
+PROBE_PLATFORM_BUS="yes"
diff --git a/recipes-core/udev/eudev_%.bbappend b/recipes-core/udev/eudev_%.bbappend
new file mode 100644
index 0000000..26bcceb
--- /dev/null
+++ b/recipes-core/udev/eudev_%.bbappend
@@ -0,0 +1,14 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+PR .= ".mlinux6"
+
+# add custom rules for persistent modem device names
+SRC_URI += "file://cellular_radios.rules \
+ file://${MACHINE}.rules"
+
+do_install_append() {
+ install -m 644 ${WORKDIR}/cellular_radios.rules ${D}${sysconfdir}/udev/rules.d/
+ install -m 644 ${WORKDIR}/${MACHINE}.rules ${D}${sysconfdir}/udev/rules.d/
+}
+
+
diff --git a/recipes-core/udev/udev-extraconf/automount.rules b/recipes-core/udev/udev-extraconf/automount.rules
new file mode 100644
index 0000000..b4a8f22
--- /dev/null
+++ b/recipes-core/udev/udev-extraconf/automount.rules
@@ -0,0 +1,24 @@
+# There are a number of modifiers that are allowed to be used in some
+# of the different fields. They provide the following subsitutions:
+#
+# %n the "kernel number" of the device.
+# For example, 'sda3' has a "kernel number" of '3'
+# %e the smallest number for that name which does not matches an existing node
+# %k the kernel name for the device
+# %M the kernel major number for the device
+# %m the kernel minor number for the device
+# %b the bus id for the device
+# %c the string returned by the PROGRAM
+# %s{filename} the content of a sysfs attribute
+# %% the '%' char itself
+#
+
+SUBSYSTEM!="block", GOTO="automount_end"
+# only mount SD cards and mass storage devices
+KERNEL!="sd[a-z][0-9]*|mmcblk[0-9]p[0-9]*", GOTO="automount_end"
+
+# Media automounting
+SUBSYSTEM=="block", ACTION=="add" RUN+="/etc/udev/scripts/mount.sh"
+SUBSYSTEM=="block", ACTION=="remove" RUN+="/etc/udev/scripts/mount.sh"
+
+LABEL="automount_end"
diff --git a/recipes-core/udev/udev-extraconf/mount.patch b/recipes-core/udev/udev-extraconf/mount.patch
new file mode 100644
index 0000000..4ed3bfd
--- /dev/null
+++ b/recipes-core/udev/udev-extraconf/mount.patch
@@ -0,0 +1,136 @@
+diff -Naru orig/mount.blacklist new/mount.blacklist
+--- orig/mount.blacklist 2019-10-24 17:08:59.796796272 -0500
++++ new/mount.blacklist 2019-10-24 17:16:31.768782892 -0500
+@@ -3,3 +3,16 @@
+ /dev/mtdblock
+ /dev/md
+ /dev/dm-*
++# These should all be mounted in fstab or not at all.
++[PARTLABEL=uboot]
++[PARTLABEL=root]
++[PARTLABEL=root1]
++[PARTLABEL=root2]
++[PARTLABEL=uboot]
++[PARTLABEL=oem]
++[PARTLABEL=oem1]
++[PARTLABEL=oem2]
++[PARTLABEL=config]
++[PARTLABEL=config1]
++[PARTLABEL=config2]
++[PARTLABEL=user_data]
+diff -Naru orig/mount.sh new/mount.sh
+--- orig/mount.sh 2020-09-09 13:57:23.196157483 -0500
++++ new/mount.sh 2020-09-09 14:59:40.344046845 -0500
+@@ -4,8 +4,8 @@
+ #
+ # Attempt to mount any added block devices and umount any removed devices
+
+-BASE_INIT="`readlink -f "@base_sbindir@/init"`"
+-INIT_SYSTEMD="@systemd_unitdir@/systemd"
++BASE_INIT="`readlink -f "/sbin/init"`"
++INIT_SYSTEMD="/lib/systemd/systemd"
+
+ if [ "x$BASE_INIT" = "x$INIT_SYSTEMD" ];then
+ # systemd as init uses systemd-mount to mount block devices
+@@ -23,11 +23,38 @@
+ MOUNT="/bin/mount"
+ UMOUNT="/bin/umount"
+ fi
++LSBLK=$(type -p lsblk)
++if ((${#LSBLK} == 0)) ; then
++ LSBLK=true
++fi
+
+ PMOUNT="/usr/bin/pmount"
+-
+-for line in `grep -h -v ^# /etc/udev/mount.blacklist /etc/udev/mount.blacklist.d/*`
++for line in `grep -h -v '^#$' /etc/udev/mount.blacklist /etc/udev/mount.blacklist.d/* 2>/dev/null`
+ do
++ if [[ $line =~ ^\[([^=]*)=([^\]]*)\] ]] ; then
++ fsspectype=${BASH_REMATCH[1]}
++ tmp="$(${LSBLK} -o $fsspectype $DEVNAME | sed -e '1d')"
++ case $fsspectype in
++ PARTLABEL)
++ if [[ ${BASH_REMATCH[2]} == $tmp ]] ; then
++ logger "udev/mount.sh $DEVNAME is blacklisted, ignoring"
++ logger "$line"
++ exit 0
++ fi
++ ;;
++
++ PARTUUID)
++ if [[ ${BASH_REMATCH[2]^^} == $tmp ]] ; then
++ logger "udev/mount.sh $DEVNAME is blacklisted, ignoring"
++ logger "$line"
++ exit 0
++ fi
++ ;;
++ *)
++ logger "[$fsspectype] is unsupported in blacklist -- ignoring blacklist item"
++ ;;
++ esac
++ fi
+ if [ ` expr match "$DEVNAME" "$line" ` -gt 0 ];
+ then
+ logger "udev/mount.sh" "[$DEVNAME] is blacklisted, ignoring"
+@@ -41,7 +68,7 @@
+ # Skip the partition which are already in /etc/fstab
+ grep "^[[:space:]]*$DEVNAME" /etc/fstab && return
+ for n in LABEL PARTLABEL UUID PARTUUID; do
+- tmp="$(lsblk -o $n $DEVNAME | sed -e '1d')"
++ tmp="$($LSBLK -o $n $DEVNAME | sed -e '1d')"
+ test -z "$tmp" && continue
+ tmp="$n=$tmp"
+ grep "^[[:space:]]*$tmp" /etc/fstab && return
+@@ -49,13 +76,17 @@
+
+ [ -d "/run/media/$name" ] || mkdir -p "/run/media/$name"
+
++ if [ "$name" = mmcblk0p1 ] ; then
++ ln -sf /run/media/$name /run/media/card
++ fi
++
+ MOUNT="$MOUNT -o silent"
+
+ # If filesystemtype is vfat, change the ownership group to 'disk', and
+ # grant it with w/r/x permissions.
+ case $ID_FS_TYPE in
+ vfat|fat)
+- MOUNT="$MOUNT -o umask=007,gid=`awk -F':' '/^disk/{print $3}' /etc/group`"
++ MOUNT="$MOUNT -o errors=continue -o umask=007,gid=`awk -F':' '/^disk/{print $3}' /etc/group`"
+ ;;
+ # TODO
+ *)
+@@ -78,7 +109,11 @@
+ if [ -x "$PMOUNT" ]; then
+ $PMOUNT $DEVNAME 2> /dev/null
+ elif [ -x $MOUNT ]; then
++ if [[ $ID_FS_TYPE =~ fat ]] ; then
++ $MOUNT -o umask=002,gid=disk $DEVNAME 2> /dev/null
++ else
+ $MOUNT $DEVNAME 2> /dev/null
++ fi
+ fi
+
+ # If the device isn't mounted at this point, it isn't
+@@ -86,6 +121,11 @@
+ grep -q "^$DEVNAME " /proc/mounts && return
+
+ ! test -d "/run/media/$name" && mkdir -p "/run/media/$name"
++
++ if [ "$name" = mmcblk0p1 ] ; then
++ ln -sf /run/media/$name /run/media/card
++ fi
++
+ # Silent util-linux's version of mounting auto
+ if [ "x`readlink $MOUNT`" = "x/bin/mount.util-linux" ] ;
+ then
+@@ -96,7 +136,7 @@
+ # grant it with w/r/x permissions.
+ case $ID_FS_TYPE in
+ vfat|fat)
+- MOUNT="$MOUNT -o umask=007,gid=`awk -F':' '/^disk/{print $3}' /etc/group`"
++ MOUNT="$MOUNT -o errors=continue -o umask=007,gid=`awk -F':' '/^disk/{print $3}' /etc/group`"
+ ;;
+ # TODO
+ *)
diff --git a/recipes-core/udev/udev-extraconf_%.bbappend b/recipes-core/udev/udev-extraconf_%.bbappend
new file mode 100644
index 0000000..3a39025
--- /dev/null
+++ b/recipes-core/udev/udev-extraconf_%.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+PR = "m2"
+
+SRC_URI += "file://mount.patch"