Little kernel module to enable gpio-shutdown overlay

Hi,

For my pi I needed a button to safely shut it down. Found the gpio-shutdown overlay you can add in config.txt. This adds some stuff in the device tree. This little driver makes use of that.
Code is here.

Should I just leave it there, or add it to ports somehow? I would like a code review, because it is my first kernel module, I only wrote some bare metal drivers for embedded stuff before.
 
I have load the module on my OrangePi PC and pressed the button, I have the string "gpio_shutdown0: button pressed, shutting down" and even couple of terminated on signal 15 services, ssh is failed. But the OPi still answered on ping until I powered it off.
 
Hi,

For my pi I needed a button to safely shut it down. Found the gpio-shutdown overlay you can add in config.txt. This adds some stuff in the device tree. This little driver makes use of that.
Code is here.

Should I just leave it there, or add it to ports somehow? I would like a code review, because it is my first kernel module, I only wrote some bare metal drivers for embedded stuff before.
I got a question for you - I am in the same boat you are in (lots of embedded experience - and decades device driver development - but currently experimenting with FreeBSD).

1) are you cross developing ? meaning is your development on an x86/x86-64 but you are building for an arm like i am ?
2) how did you get the Makefile to build for arm on the development host ?

I grabbed the skeleton.c example driver from the freebsd architecture handbook as well as the 9 line Makefile
SRCS=skeleton.c
KMOD=skeleton

.include <bsd.kmod.mk>


Now when I run
make TARGET=arm TARGET_ARCH=armv7

**It generates a module thats clearly built for x86-64 my host development machine and NOT for the target I specified**

machine -> /home/devel/nfsroot/usr/src/sys/amd64/include
x86 -> /home/devel/nfsroot/usr/src/sys/x86/include
i386 -> /home/devel/nfsroot/usr/src/sys/i386/include

Warning: Object directory not changed from original /home/devel/nfsroot/bsd_example_driver

cc -O2 -pipe -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc -DHAVE_KERNEL_OPTION_HEADERS -include /home/devel/nfsroot/obj/home/devel/nfsroot/usr/src/arm.armv7/sys/GENERIC/opt_global.h -I. -I/home/devel/nfsroot/usr/src/sys -I/home/devel/nfsroot/usr/src/sys/contrib/ck/include -fno-common -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=/home/devel/nfsroot/usr/src/sys=/usr/src/sys -ffile-prefix-map=/home/devel/nfsroot/obj/home/devel/nfsroot/usr/src/arm.armv7/sys/GENERIC=/usr/obj/usr/src/amd64.amd64/sys/GENERIC -ffile-prefix-map=/home/devel/nfsroot/bsd_example_driver=/usr/obj/usr/src/amd64.amd64/sys/GENERIC/modules/usr/src/sys/modules/bsd_example_driver -fdebug-prefix-map=./machine=/usr/src/sys/amd64/include -fdebug-prefix-map=./x86=/usr/src/sys/x86/include -fdebug-prefix-map=./i386=/usr/src/sys/i386/include -I/home/devel/nfsroot/obj/home/devel/nfsroot/usr/src/arm.armv7/sys/GENERIC -MD -MF.depend.skeleton.o -MTskeleton.o -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float -fno-asynchronous-unwind-tables -ffreestanding -fwrapv -fstack-protector -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wundef -Wno-pointer-sign -D__printf__=__freebsd_kprintf__ -Wmissing-include-dirs -fdiagnostics-show-option -Wno-unknown-pragmas -Wno-error=tautological-compare -Wno-error=empty-body -Wno-error=parentheses-equality -Wno-error=unused-function -Wno-error=pointer-sign -Wno-error=shift-negative-value -Wno-address-of-packed-member -Wno-format-zero-length -mno-aes -mno-avx -std=gnu99 -c skeleton.c -o skeleton.o

ld -m elf_x86_64_fbsd -warn-common --build-id=sha1 -T /home/devel/nfsroot/usr/src/sys/conf/ldscript.kmod.amd64 -r -o skeleton.ko skeleton.o

:> export_syms

awk -f /home/devel/nfsroot/usr/src/sys/conf/kmod_syms.awk skeleton.ko export_syms | xargs -J% objcopy % skeleton.ko

objcopy --strip-debug skeleton.ko


What am I doing wrong?
 
I have load the module on my OrangePi PC and pressed the button, I have the string "gpio_shutdown0: button pressed, shutting down" and even couple of terminated on signal 15 services, ssh is failed. But the OPi still answered on ping until I powered it off.
Thank you for testing and reporting back . I'm not sure if this is correct, but I do know that a actual power down needs hardware AND driver support.
 
**It generates a module thats clearly built for x86-64 my host development machine and NOT for the target I specified**

I usually build (and actually develop) a driver on my arm PC, I find it easier. To do this, I mount an nfs directory /usr/src/ (and /usr/ports/ when I want to create a set of files for a port) from my amd64 host... Then I create the port using my simple template and use the port to build a package, right here on the arm PC.
 
Thank you for testing and reporting back . I'm not sure if this is correct, but I do know that a actual power down needs hardware AND driver support.
If I remember right my Orange Pi PC looks dead after a 'shutdown' (or a 'halt'), not answers on icmp-packets. I'm not at home this week, I can check it later. And if you want I can send you my .dtso-file for your project.
 
I got a question for you - I am in the same boat you are in (lots of embedded experience - and decades device driver development - but currently experimenting with FreeBSD).

1) are you cross developing ? meaning is your development on an x86/x86-64 but you are building for an arm like i am ?
2) how did you get the Makefile to build for arm on the development host ?

I grabbed the skeleton.c example driver from the freebsd architecture handbook as well as the 9 line Makefile
SRCS=skeleton.c
KMOD=skeleton

.include <bsd.kmod.mk>


Now when I run
make TARGET=arm TARGET_ARCH=armv7

**It generates a module thats clearly built for x86-64 my host development machine and NOT for the target I specified**

machine -> /home/devel/nfsroot/usr/src/sys/amd64/include
x86 -> /home/devel/nfsroot/usr/src/sys/x86/include
i386 -> /home/devel/nfsroot/usr/src/sys/i386/include

Warning: Object directory not changed from original /home/devel/nfsroot/bsd_example_driver

cc -O2 -pipe -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc -DHAVE_KERNEL_OPTION_HEADERS -include /home/devel/nfsroot/obj/home/devel/nfsroot/usr/src/arm.armv7/sys/GENERIC/opt_global.h -I. -I/home/devel/nfsroot/usr/src/sys -I/home/devel/nfsroot/usr/src/sys/contrib/ck/include -fno-common -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=/home/devel/nfsroot/usr/src/sys=/usr/src/sys -ffile-prefix-map=/home/devel/nfsroot/obj/home/devel/nfsroot/usr/src/arm.armv7/sys/GENERIC=/usr/obj/usr/src/amd64.amd64/sys/GENERIC -ffile-prefix-map=/home/devel/nfsroot/bsd_example_driver=/usr/obj/usr/src/amd64.amd64/sys/GENERIC/modules/usr/src/sys/modules/bsd_example_driver -fdebug-prefix-map=./machine=/usr/src/sys/amd64/include -fdebug-prefix-map=./x86=/usr/src/sys/x86/include -fdebug-prefix-map=./i386=/usr/src/sys/i386/include -I/home/devel/nfsroot/obj/home/devel/nfsroot/usr/src/arm.armv7/sys/GENERIC -MD -MF.depend.skeleton.o -MTskeleton.o -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float -fno-asynchronous-unwind-tables -ffreestanding -fwrapv -fstack-protector -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wundef -Wno-pointer-sign -D__printf__=__freebsd_kprintf__ -Wmissing-include-dirs -fdiagnostics-show-option -Wno-unknown-pragmas -Wno-error=tautological-compare -Wno-error=empty-body -Wno-error=parentheses-equality -Wno-error=unused-function -Wno-error=pointer-sign -Wno-error=shift-negative-value -Wno-address-of-packed-member -Wno-format-zero-length -mno-aes -mno-avx -std=gnu99 -c skeleton.c -o skeleton.o

ld -m elf_x86_64_fbsd -warn-common --build-id=sha1 -T /home/devel/nfsroot/usr/src/sys/conf/ldscript.kmod.amd64 -r -o skeleton.ko skeleton.o

:> export_syms

awk -f /home/devel/nfsroot/usr/src/sys/conf/kmod_syms.awk skeleton.ko export_syms | xargs -J% objcopy % skeleton.ko

objcopy --strip-debug skeleton.ko


What am I doing wrong?
[SOLVED]

 
Should I just leave it there, or add it to ports somehow? I would like a code review, because it is my first kernel module, I only wrote some bare metal drivers for embedded stuff before.
You asked, I hope this will be useful.
You are missing a man page. You are missing an config.txt example.
For good man pages, you need 3 examples:
1) a simple example
2) a common use example
3) a complex example

If your initial case they might all be the same.
For a complex example, I would consider something like a matrix input keyboard. That goes back to the "break" key of 8 bit home computers. Or see my wish list below.

For you man page, Start with a copy of a simple other kernel module man page preferably one originated by someone in the bsd core team and modify to suit. If you can't find one, look at the boot ones (and if you find a good one, update the docs on how to doc docs).

Since I'm already asking for stuff...
Can you add "instant touch", and/or "hold for 3 sec to do thing A, hold for 10 sec to do thing B"?
Or more than one button... I can see a use of "restart the NTP" thing... except I need it to resycn the local gps while not screwing with everything else which requires injecting a command into ntpc which tells ntpd odd stuff. Of, the other button could reset all of NTP and the last one just does a nice warm restart. Extra points for flipping LED status either built in or I/O pin. I did mention 3) a complex example.

Also what happens on a simple install where the console happens to be a on your "sane reboot" pin? Writing that off as a config err is ok.

Final comment is make sure you have a decent name for your module. It should be specific, unambiguous but not too complex.
 
Back
Top