kernel modules: add a quick scull port from LDD3

Also:

* fix fops.c on both kernels:
  * 5.9: the out of space error code was 1 not 8
  * 6.6: for whatever reason we can't read the user buffer as before on the
         diagnostic print, it leads to segfault and oops
* create memfile.c which is like fops.c but of unlimited size
This commit is contained in:
Ciro Santilli
2025-04-28 15:23:44 +01:00
parent 3d84eccc43
commit e4847e4b40
16 changed files with 2133 additions and 50 deletions

View File

@@ -1,7 +1,7 @@
#!/bin/sh
set -e
insmod character_device.ko
/mknoddev.sh lkmc_character_device
./mknoddev.sh lkmc_character_device
[ "$(cat /dev/lkmc_character_device)" = 'abcd' ]
rm /dev/lkmc_character_device
rmmod character_device

View File

@@ -3,7 +3,9 @@ set -e
# Setup
f=/sys/kernel/debug/lkmc_fops
insmod fops.ko
mod="${1:-fops.ko}"
shift
insmod "$mod" "$@"
# read
[ "$(cat "$f")" = abcd ]
@@ -18,7 +20,7 @@ set +e
printf 12345 > "$f"
exit_status="$?"
set -e
[ "$exit_status" -eq 8 ]
[ "$exit_status" -eq 1 ]
[ "$(cat "$f")" = abcd ]
# seek
@@ -26,5 +28,12 @@ printf 1234 > "$f"
printf z | dd bs=1 of="$f" seek=2
[ "$(cat "$f")" = 12z4 ]
# seek past the end
printf 1234 > "$f"
printf xy | dd bs=1 of="$f" seek=6
[ "$(cat "$f")" = 1234 ]
# Teardown
rmmod fops
echo passed

51
rootfs_overlay/lkmc/memfile.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/sh
set -e
# Helpers
odraw() (
od -A n -t x1 -v "$@" | tr -d '\n' | cut -c 2-
)
# Setup
f=/sys/kernel/debug/lkmc_memfile
mod="${1:-memfile.ko}"
shift
insmod "$mod" "$@"
# Starts off empty
[ -z "$(cat "$f")" ]
# write and check it is there
printf 12 > "$f"
[ 12 = "$(cat "$f")" ]
# Append and check that it is there
printf 34 >> "$f"
[ 1234 = "$(cat "$f")" ]
# Restart
printf 56 > "$f"
[ 56 = "$(cat "$f")" ]
# skip
printf 1234 > "$f"
[ 23 = "$(dd if="$f" bs=1 count=2 skip=1)" ]
# seek
printf 1234 > "$f"
printf xy | dd bs=1 of="$f" seek=1 conv=notrunc
[ 1xy4 = "$(cat "$f")" ]
# seek past the end
printf 1234 > "$f"
printf xy | dd bs=1 of="$f" seek=6 conv=notrunc
[ '31 32 33 34 00 00 78 79' = "$(odraw "$f")" ]
# Allocate 1 GB for fun.
dd if=/dev/zero of="$f" bs=1k count=1M
[ '00 00' = "$(dd if="$f" bs=1 count=2 skip=500M | odraw)" ]
# Teardown
rmmod memfile
echo passed

59
rootfs_overlay/lkmc/scull.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/sh
set -eux
name=scull
mod="${1:-$name.ko}"
shift
insmod "$mod" "$@"
major="$(awk "\$2==\"$name\" {print \$1}" /proc/devices)"
rm -f /dev/${name}[0-3]
mknod /dev/${name}0 c $major 0
mknod /dev/${name}1 c $major 1
mknod /dev/${name}2 c $major 2
mknod /dev/${name}3 c $major 3
rm -f /dev/${name}pipe[0-3]
mknod /dev/${name}pipe0 c $major 4
mknod /dev/${name}pipe1 c $major 5
mknod /dev/${name}pipe2 c $major 6
mknod /dev/${name}pipe3 c $major 7
rm -f /dev/${name}single
mknod /dev/${name}single c $major 8
rm -f /dev/${name}uid
mknod /dev/${name}uid c $major 9
rm -f /dev/${name}wuid
mknod /dev/${name}wuid c $major 10
rm -f /dev/${name}priv
mknod /dev/${name}priv c $major 11
## scull
f="/dev/${name}0"
[ -z "$(cat "$f")" ]
# Append starts writing from the start of the 4k block, not like the usual semantic.
printf asdf > "$f"
printf qw >> "$f"
[ qwdf = "$(cat "$f")" ]
# Overwrite first clears everything, then writes to start of 4k block.
printf asdf > /dev/${name}0
printf qw > /dev/${name}0
[ qw = "$(cat "$f")" ]
# Read from the middle
printf asdf > /dev/${name}0
[ df = "$(dd if="$f" bs=1 count=2 skip=2 status=none)" ]
# Write to the middle
printf asdf > "$f"
printf we | dd of="$f" bs=1 seek=1 conv=notrunc status=none
[ awef = "$(cat "$f")" ]
echo passed

View File

@@ -1,7 +1,9 @@
#!/bin/sh
set -e
f=/sys/kernel/debug/lkmc_seq_file
insmod seq_file.ko
mod="${1:-seq_file.ko}"
shift
insmod "$mod" "$@"
[ "$(cat "$f")" = "$(printf '0\n1\n2\n')" ]
[ "$(cat "$f")" = "$(printf '0\n1\n2\n')" ]
[ "$(dd if="$f" bs=1 count=2 skip=0 status=none)" = "$(printf '0\n')" ]

View File

@@ -1,7 +1,9 @@
#!/bin/sh
set -e
f=/sys/kernel/debug/lkmc_seq_file_single_open
insmod seq_file_single_open.ko
mod="${1:-seq_file_single_open.ko}"
shift
insmod "$mod" "$@"
[ "$(cat "$f")" = "$(printf 'ab\ncd\n')" ]
[ "$(dd if="$f" bs=1 count=3 skip=1)" = "$(printf "b\nc\n")" ]
rmmod seq_file_single_open