Does hikey support insmod under init.rc?

I compile some ko files and try to load the ko via init.rc automatically, but the previous line already execute but the insmod sees skipped.

diff --git a/rootdir/init.rc b/rootdir/init.rc
index 636daea..a1a819f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -397,6 +397,10 @@ on late-fs
    
     # HALs required before storage encryption can get unlocked (FBE/FDE)
     class_start early_hal
@@ -570,8 +574,11 @@ on post-fs-data
     mkdir /data/cache 0770 system cache
     mkdir /data/cache/recovery 0770 system cache
     mkdir /data/cache/backup_stage 0700 system system
-    mkdir /data/cache/backup 0700 system system
-
**+    mkdir /data/cache/backup 0700 root root**  //this part already execute by check the property. 
+    insmod /system/lib/modules/snd-soc-xxx-xx.ko  //not execute at below all
+    insmod /system/lib/modules/snd-soc-xxx-xx.ko
+    insmod /system/lib/modules/xxxxx-odsp-xx.ko
+    insmod /system/lib/modulesxxxxx-xx.ko
     init_user0

does hikey board have any limitation of the KO feature? I have not found any insmod example in the project.

Don’t think the vendor init process has permission to write to /system. Can you not build the modules as built-in instead of loadable?

Of course we could build the modules as built-in, but we also hope support the ko as loadable as needed.
As I know Qualcomm OpenQ board could load ko as init.rc but why hikey board could not do the same thing? any special setting on Hikey board?

What the aosp version on both boards?

Hikey use the Android 10.0, kernel 4.9 while OpenQ using Android 8.0 and kernel 4.9

Actually can you first try placing your .ko files under /vendor/lib/modules and see if it works from there?

I asked an engineer from our aosp team and the proper way to do it is to copy the module to somewhere in device/linaro/hikey and use BOARD_VENDOR_KERNEL_MODULES. See [1][2] for references. The module will be included in vendor.img and should be loaded automatically on boot. If not, see [3].

[1] https://android.googlesource.com/device/ti/beagle-x15/+/refs/heads/master/BoardConfig.mk#73
[2] https://source.android.com/devices/architecture/kernel/modular-kernels#android-build-system-support
[3] https://source.android.com/devices/architecture/kernel/modular-kernels#module-loading-&-versioning

Thanks for help. I will try to access these google website later(we blocked as you know).
So the Hikey platform should support the load the ko in boot phase , just need keep the method correct ,right ?

You’re welcome. Right. Project Treble compliance is mandatory from Android 9 onwards, which is most probably why the method used on the OpenQ board isn’t allowed anymore. If you use Android 8 on hikey, the method might still work, and if you use Android 10 on OpenQ, you’ll probably see it fail the way it’s failing on hikey now.

Anyway, [1] is just

BOARD_VENDOR_KERNEL_MODULES += \
	device/ti/beagle_x15-kernel/$(TARGET_KERNEL_USE)/pvrsrvkm.ko` in `BoardConfig.mk`.

[3] is mainly

on early-init
    exec u:r:modprobe:s0 -- /vendor/bin/modprobe -a -d \
        /vendor/lib/modules module_a module_b module_c ...

Correction: Actually Project Treble is mandatory from Android 8 onwards, so then maybe check the Android 8 source for the OpenQ board to see if it’s fully compliant.

Actually, it has to do with whether or not a device launched with Android 8 or higher. And I suppose in this context, it really means whether the first of google’s compliance tests it passed officially involved that version or higher.

In other words, if a device had ever passed a compliance test for android 7 and was declared for commercial launch, then it would be free to remain treble-free indefinitely.

Now on the other hand, these boards are different. There is no google compliance testing involved. That means that you’re free to do what you want with them.

Likely, the only thing needed in order to make this work, is to unset the variable “PRODUCT_FULL_TREBLE_OVERRIDE” in BoardConfigCommon.mk
*** HOWEVER, there really doesn’t seem to be any reason to resort to that for this objective.

EDIT:
Why not build the drivers into the kernel instead of building them as modules? Its generally preferred (on Android) not to use modules.

I tried to modify the b/hikey960/BoardConfig.mk on the hikey platform as below:

+++ b/hikey960/BoardConfig.mk
@@ -45,3 +45,10 @@ BOARD_VENDORIMAGE_PARTITION_SIZE := 822083584     # 784MB
 BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4
 BOARD_VENDORIMAGE_JOURNAL_SIZE := 0
 BOARD_VENDORIMAGE_EXTFS_INODE_COUNT := 2048
+vendor_hikey_dir := :device/linaro/hikey/vendor/lib/modules
+BOARD_RECOVERY_KERNEL_MODULES := \
+         $(vendor_hikey_dir)/snd-soc-xxx-1.ko \
+         $(vendor_hikey_dir)/snd-soc-xxx-2.ko \
+         $(vendor_hikey_dir)/iaxxx-xxx-3.ko \
+         $(vendor_hikey_dir)/iaxxx-xxx-1.ko
+

inf fact firstly I already move my 4 ko files at the device/linaro/hikey/vendor/lib/modules folder. but after compile again, I found these 4 ko files have not been installed into the out/target/product/hikey960/vendor/lib/modules.
That means the macro BOARD_RECOVERY_KERNEL_MODULES does not support on the hikey board.
I still suspect whether hikey board support the module load mechanism on this platform.

and then I just modify the a makefile and install my ko to /vendor/lib/modules directly.

hikey960:/vendor/lib/modules # ls
ls
xxx.ko        snd-soc-xxx.ko
iaxxx-oxxx2.ko snd-xxx3.ko

from shell command, we could find the ko already installed on the folder.
while I also update the init.rc as below to load the ko automatically:

diff --git a/rootdir/init.rc b/rootdir/init.rc
index 636daea..8037a6f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -41,7 +41,8 @@ on early-init
     mkdir /dev/memcg/system 0550 system system

     start ueventd
-
+    exec u:r:modprobe:s0 -- /vendor/bin/modprobe -a -d \
+        /vendor/lib/modules  xxx.ko xxx2.ko xxx3.ko xxx4.ko
 on init
     sysclktz 0

but these scripts also have not execute success by check by lsmod command on shell:

Z:\hikey-xxxx-0507>adb shell
hikey960:/ # lsmod
lsmod
Module                  Size  Used by

@doitright Thanks for the detailed explanation! Appreciate your insights as usual.

@yinjun2014 For future references, please enclose code/logs/outputs in your post with 3 backticks. Otherwise it’s impossible to read. See https://help.github.com/en/articles/creating-and-highlighting-code-blocks#fenced-code-blocks for references.

vendor_hikey_dir := :device/linaro/hikey/vendor/lib/modules

You have an extra colon “:” in front of device/linaro/hikey/vendor/lib/modules?

+BOARD_RECOVERY_KERNEL_MODULES := \

Please try BOARD_VENDOR_KERNEL_MODULES, not BOARD_RECOVERY_KERNEL_MODULES.

diff --git a/rootdir/init.rc b/rootdir/init.rc

What/where is rootdir? Please try it on /vendor/etc/init/init.hikey960.rc if BOARD_VENDOR_KERNEL_MODULES doesn’t work.

Hi vchong,
I found the modprobe was denied by selinux when boot. do you have any sample to show how to fix these error on hikey board?

Forked subcontext for 'u:r:vendor_init:s0' with pid 1581
e[32m[    8.274413] e[33minite[0m: Forked subcontext for 'u:r:vendor_init:s0' with pid 1582
e[32m[    8.281532] e[33minite[0m: Parsing file /init.rc...
e[32m[    8.318859] e[33maudite[0m: type=1400 audit(14.243:5): avc:  denied  { entrypoint } for  pid=1584 comm="init" path="/vendor/bin/toybox_vendor" dev="sdd11" ino=117 scontext=u:r:modprobe:s0 tcontext=u:object_r:vendor_toolbox_exec:s0 tclass=file permissive=0
e[32m[    8.384273] e[33mueventde[0m: ueventd started!
e[32m[    8.390572] e[33mselinuxe[0m: SELinux: Loaded file_contexts\x0a
e[32m[    8.397350] e[33mueventde[0m: Parsing file /ueventd.rc...
e[32m[    8.403290] e[33mueventde[0m: Parsing file /vendor/ueventd.rc...

avc: denied { entrypoint } for pid=1584 comm=“init” path="/vendor/bin/toybox_vendor" dev=“sdd11” ino=117 scontext=u:r:modprobe:s0 tcontext=u:object_r:vendor_toolbox_exec:s0 tclass=file permissive=0

If your objective is just to allow that, then you’ll need to add an allow rule something like this;

allow modprobe vendor_toolbox_exec:file { entrypoint };

Look in your “avc: denied” line and you can see where all the parts of that come from.
Also note that once it gets past that denial, there will probably be some additional surprises waiting for you. My suggestion would be to set your selinux permissive first, then collect all of the errors printed by selinux, write up a policy, and try that.

Also be aware that very often when you are trying to fight the platform in this way, you will come up against “neverallow” rules. If this happens, you have two choices; either continue down the path of hacking the selinux policy (by modifying the system policy in system/sepolicy/) or try to accomplish your objective in a better way, like building your driver into the kernel instead of loading it as a module, or following any of the other solutions that you’ve been guided towards in this thread.

in fact I already add a modprobe.te under device/linaro/hikey/sepolicy:

allow modprobe { vendor_file }:system module_load;
allow modprobe vendor_toolbox_exec:file { entrypoint };

in fact I also follow below links to add some policy under /system/sepolicy:

https://android.googlesource.com/platform/system/sepolicy/+/e41af20%5E!/ 
https://android.googlesource.com/platform/system/sepolicy/+/53add31%5E!/ 
https://android.googlesource.com/platform/system/sepolicy/+/d46b5d3%5E!/ 

after add above all modifications, I tried to compile but get follow error message:

/bin/bash -c "(rm -f out/target/product/hikey960/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows ) && (ASAN_OPTIONS=detect_leaks=0 out/host/linux-x86/bin/checkpolicy -M -c 30 -o out/target/product/hikey960/obj/ETC/sepolicy_neverallows_intermediates/sepolicy_neverallows out/target/product/hikey960/obj/ETC/sepolicy_neverallows_intermediates/policy.conf )"

libsepol.report_failure: neverallow on line 1090 of system/sepolicy/public/domain.te (or line 12528 of policy.conf) violated by allow modprobe vendor_toolbox_exec:file { read getattr map execute entrypoint open };

libsepol.report_failure: neverallow on line 1061 of system/sepolicy/public/domain.te (or line 12450 of policy.conf) violated by allow modprobe vendor_toolbox_exec:file { execute };

libsepol.check_assertions: 2 neverallow failures occurred

This means currently Hikey have .limitation of the modprobe in neverallow part in dowmain.te:
I past the part the line 1090 and Line 1061 part of the domain.te:

full_treble_only(`
  # Do not allow system components access to /vendor files except for the
  # ones whitelisted here.
  neverallow {
    coredomain
    # TODO(b/37168747): clean up fwk access to /vendor
    -crash_dump
    -init # starts vendor executables
    -kernel # loads /vendor/firmware
    userdebug_or_eng(`-perfprofd')
    userdebug_or_eng(`-heapprofd')
    -shell
    -ueventd # reads /vendor/ueventd.rc
  } {
    vendor_file_type
    -same_process_hal_file
    -vendor_file
    -vendor_app_file
    -vendor_configs_file
    -vendor_framework_file
    -vendor_idc_file
    -vendor_keychars_file
    -vendor_keylayout_file
    -vendor_overlay_file
    -vendor_public_lib_file
    -vndk_sp_file
  }:file *;
') 

does this mean the Hikey board forbidden this modprobe operation for some special reason ?
Or how to fix this conflict error?

I think I know what your problem is.

You’re trying to run your modprobe from the ROOT init.rc, which is starting from the ‘init’ context. You need to end up with the vendor_modprobe context, but you can’t get there from init. You need to start by going into the vendor_init context, which is easily done just by moving your modprobe line OUT of the root init.rc and into a VENDOR init.

Thank you. I will feedback you whenever I have update.

I searched the whole codebase and try to find the suitable vendor_init , but no found, it even have no vendor folder under the project root. But while I searched another Qualcomm platform , when I search by find . -name *.rc| grep vendor , it will listed so many init scripts like below:

/vendor/qcom/proprietary/prebuilt_HY11/target/product/msm8996/vendor/etc/init/vendor.qti.hardware.soter@1.0-service.rc
./vendor/qcom/proprietary/prebuilt_HY11/target/product/msm8996/vendor/etc/init/vendor.qti.hardware.factory@1.0-service.rc
./vendor/qcom/proprietary/prebuilt_HY11/target/product/msm8996/vendor/etc/init/android.hardware.bluetooth@1.0-service-qti.rc

So I still suspect why Hikey have no vendor folder and may have any trick inside.