Add USB_HIDDEV to kernel
free alternative firmware for the DLink DNS-320/320L/321/323/325/327L
Brought to you by:
jcard
Referencing the thread at https://groups.google.com/forum/#!topic/alt-f/nEwlQzI0O1w
I believe the reason I cannot get apcupsd to recognize my USB attached UPS is the lack of the USB_HIDDEV module in the kernel. I would like to see this added into future builds. I am willing to try out test builds to confirm if this solves the problem. Thanks.
I have managed to create a working build environment by following the wiki instructions. I still can't figure out how to modify the configuration to add hiddev as this is beyond anything I have done before. If you have a set of steps to follow I could try to build it myself and confirm that hiddev is all that is needed to get a USB UPS working.
You have to build a new kernel with usbhid build as a module and not builtin, and enabling the USB_HIDDEV or/and HIDRAW features (looks like there is no need to turn on HIDRAW).
After '. exports' (you have to do that everytime you start a new sh session os login), and the first 'make', use the command
to configure the kernel, then browse to Device Drivers, HID,
-select (space key) "/dev/hidraw raw HID device support" and read its online help (H key)
-and on "Generic HID driver" create it as a module (space key twice).
-Select "USB HID support", and select "/dev/hiddev raw HID device support", read its online help
Not sure if you need both HIDRAW and USB_HIDDEV, you have to try it yourself.
Then exit, and save config,
The differences between the initial and final kernel configs can be examine using the command
and should be
This is, HID_GENERIC is now build as a module and USB_HIDDEV and HIDRAW are now set
Do a make again.
You have to copy the kernel image and rootfs image to the box /boot directory
Notice that /Alt-F/boot must NOT exists, and do a reboot.
Fortunately you have a DNS-323, right?. (this is not working on the DNS-320/320L/325). During the reboot sequence, Alt-F will find those files on /boot and instead of a real reboot it will instead do a kexec, using the new found kernel and rootfs. But only a small set of kernel modules are made available, not the new hid-generic.
From this point on I'm not sure how/if it will work.
You have to copy the newly build modules to the box after the reboot
The kernel module will not auto load, you have to do that yourself either using
or directly using
examine the end of the kernel log message for new messages using 'dmesg' and 'lsmod' to examine loaded modules.
On USB plug you should see some activity on the kernel log. /var/log/hot_aux.log might also show some new events.
Notice that you have not flashed anything. On reboot the old kernel and rootfs will be used.
Please report back your experiences.
Last edit: João Cardoso 2018-10-17
Bottom line, it worked perfectly. I only included USB_HIDDEV in the updated config, used the insmod command, and as soon as I plugged in the UPS I got in dmesg:
usb 1-1: new low-speed USB device number 2 using orion-ehci
hid-generic 0003:051D:0002.0001: hiddev0: USB HID v1.10 Device [American Power Conversion Back-UPS ES 750 FW:841.I3 .D USB FW:I3 ] on usb-orion-ehci.0-1/input0
Apcupsd immediately finds the UPS and starts to monitor it.
At first I was stuck after the 2nd make as I didn’t have the same rootfs file you listed below. I finally figured out I needed to run ./mkinitramfs.sh to get it. Also, the path to the module is $KERNEL/drivers/hid/hid-generic.ko but I figured that out pretty quickly.
So now that the solution is known, how does it get built into firmware that works from boot? Can it not be built in with the kernel?
Thanks for the quick feedback and detailed instructions.
Last edit: Bill Rosenberg 2018-02-07
Bottom line, it worked perfectly. I only included USB_HIDDEV in the updated config, used the insmod command, and as soon as I plugged in the UPS I got in dmesg:
Apcupsd immediately finds the UPS and starts to monitor it.
At first I was stuck after the 2nd make as I didn’t have the same rootfs file you listed below. I finally figured out I needed to run ./mkinitramfs.sh to get it. Also, the path to the module is $KERNEL/drivers/hid/hid-generic.ko but I figured that out pretty quickly.
So now that the solution is known, how does it get built into firmware that works from boot? Can it not be built in with the kernel?
Thanks for the quick feedback and detailed instructions.
That is the issue. As the default kernel already has hid-generic builtin you can't load the hid-generic module, as conflicts will arise.
So the only solution is for you to fbuild and lash your own kernel using
You might get errors related to /srv/tftpboot, as the script tries to copy files there for the development cycle, but that is expected and harmless.
A check is made to see if the kernel and rootfs fits the available box flash space, so you should examine its output when generating the DNS-323...bin file carefully, namely any "kernel too big by xxx bytes" or "rootfs too big by xxx bytes" messages, as well as the "Available kernel flash space" and "Available initramfs flash space" (which by way are very low, just a few kilobytes).
You might also use the commands following commands to verify that all files are present and there is no extra unnedded files in the rootfs (and its size will not fit the available flash space)
At $BINARIES you will find the firmware .bin file that you can flash.
To make it somewow clear that you are not running a stock Alt-F, you can edit 'customroot/etc/Alt-F' and change its contents to something like 1.0M, then make, ./mkinitramfs.sh , ./mkfw.sh
The some should probably be done to the kernel, perhaps setting CONFIG_LOCALVERSION to '1' when configuring the kernel through 'make linux26-menuconfig', General Setup, "Local version - append to kernel release"; I believe that it has no consequences other than showing 4.4.86-1 with 'uname -r', but I leave that to your discretion.
You could also create your own kernel-modules-armv5 (km) package, but I leave it for another occasion. You have to remaind yourself that the hid-generic.ko file should be copied to the proper place in the box after you remove or install any future km package or delete/recreate the Alt-F directory.
Creating a km package could have the benefice that the module would auto-load, without the need to insmod it, but you can automate that in your user boot script.
By the way, what distro and version are you using? Did you had to made some adjustments? Report anything relevant to the build? Or contribute this conversation to the wiki? :-)
You might want to double verify that your produced fw file with your kernel and rootfs are OK before flashing it.
At the build host,
then, at the box,
If all is OK, then you can flash the .bin file
Notice that kexec and the ability to test a kernel and rootfs without flashing it only applies to the DNS-323/321. Kexec is not working on any other box (hmmm, it might works also on the DNS-327L, not sure)
Last edit: João Cardoso 2018-02-12
I am learning as I go here so I need to ask some newbie questions. Maybe my understanding is incorrect.
1) The config changes you had me do changed hid-generic from built in to a module and added USB_HIDDEV support. Why make it as a module instead of leaving it as a built-in but with hiddev added? Isn't this also possible?
2) If it has to be built as an external module, how does it get loaded at boot time? I assume it has to be part of the rootfs so it is available before the drives mount and before the attached USB devices are detected.
As to my build environment, I'm using openSUSE 13.2 x64 just like in the wiki. I originally tried the Leap 42.3 release but immediately ran into build errors so I decided to go with what you said would work. With 13.2 I built the release firmware on the first try with no errors.
Your questions make sense.
My answer here follows the forum topic where the question was first made: creating a kernel module with HIDDEV support without the need for a new kernel (and Alt-F release).
Looks like I tried that and that conflicts arose.
So, you can build a built in module. You only have to be certain that the added funtionality does not make the kernel size grows behind the flash capacity -- ./mkfw.sh warns you -- that is the main reason to create km and load them only as needed.
I get: mkfw: Firmware creation FAILED at kernel too big by 1144 bytes
while on a normal build I get "Available kernel flash space: 1152 bytes", and "Available initramfs flash space: 4032 bytes", so we are couting bytes -- back to good old times!?
Most of the time creating a module requires additional kernel resources, whether the final outcome fits the flash space depends on the specific module.
In name of compatibility with previous versions, I would prefer this way, but it can't fit!
So the next move is to build it as a module an keep it at the rootfs, which is also space scarce. Read the top of the configfs script, KMOD contains the rootfs contained modules. You might get a similar error message from mkfs.sh regarding the rootfs/initramfs size. This also implies a new kernel and release.
The rootfs "resident" and built in modules are the ones needed by most configurations, such as filesystems, so they can be mounted and find the Alt-F folder.
If it does not fit, the next move is to move it to the km-armv5 package, and that also requires a new kernel and release.
Regarding the second question, you have to experiment to see if loading the module after the UPS is on and USB plugged makes the driver recognizes it. Most drivers probe the hardware, so that migh work. Kernel detects when hardware is plugged and auto loads the needed km, but kernel events are lost is no module is present at the time. In the worst case scenario you have to explicitly load it at your user boot script after the Alt-F folder being detected (aufs.sh -s returns 0, OK, go on).
I need to work with this more to be sure, but it appears that even with hid-generic as an external module the kernel is still too big by around 1000 bytes. It is not clear to me why it is bigger than the release kernel if something has been removed. If there is no other option is there something else that can be safely removed from the config to save space?
A km does not means that everything module related is removed from the kernel.
This is a nightmare on every release, so I delay it until the last moment.
Accordingly to some quick experiments I have done, it looks like
CONFIG_HID_GENERIC=y, with USB_HIDDEV=y support, and building crypto hmac amd prng (HMAC=m, CRYPTO_ANSI_CPRNG=m) as modules and moving them to the rootfs (remember editing configs KMOD variable and removing km from the rootfs by using ./mkpkgs -rm kernel-modules), works. Not tested.
I was experimenting today and got a kernel and rootfs that fit by removing USB and wireless network adapter support. If I copy the zImage and rootfs from the build directory to /boot the 323 will kexec and I have no issues. However if I take the .bin firmware file, copy it to the 323 and run the dns323-fw command you mentioned above, the extracted files do not work. The system seems to hang on reboot and it is not accessible over the network. I noticed that the extracted files are slightly larger (64-72 bytes) larger than the files from the build directory. Is there really a problem with the firmware file or does the dns323-fw program not extract the files correctly? I don't want to flash anything until I am sure.
I made another build with your approach (CONFIG_HID_GENERIC=y, with USB_HIDDEV, HMAC=m, CRYPTO_ANSI_CPRNG=m) and it is also working just fine. I will stick with your config since no functionality is being removed. The only thing stopping me from flashing the firmware is the discrepancy on the file sizes when extracting from the firmware file. Do you have any ideas on that?
My fault, the fw test commands at https://sourceforge.net/p/alt-f/featurerequests/49/#ca4b were wrong, fixed now.
Differences in yours and mine file sizes are probably not important, it might depend on the make and configure sequences.
Last edit: João Cardoso 2018-02-12
Using the updated instructions I verified the bin file and flashed to the custom build. As far as I can tell everything is working as it should and I can now control my UPS. Thanks for all the guidance on the configuration changes! Is this a change you would consider making part of the standard release? If not, I can always continue to roll my own now that I know how.
Yes, sure, but if as a module or builtin I don't yet know.
E.g. on the last 4.4.114 kernel 19 bytes are missing, so the jigsaw work has to be again remade.