### Example GKI Kernel Release Source: https://source.android.com/docs/core/architecture/kernel/gki-versioning An example of a complete GKI kernel release string. ```plaintext 5.4.42-android12-0-00544-ged21d463f856 ``` -------------------------------- ### Sync Kernel Source Code with Repo Source: https://source.android.com/docs/core/architecture/kernel/gki-release-builds Execute these commands to initialize and sync the kernel source code repository. Ensure you have the repo tool installed and configured. ```bash repo init -u https://android.googlesource.com/kernel/manifest mv .repo/manifests repo init -m manifest.xml repo sync ``` -------------------------------- ### Example ABI Difference Report Source: https://source.android.com/docs/core/architecture/kernel/howto-abi-monitor This is an example of the output indicating that ABI differences have been detected during the build process. Automation should check the build command's exit code. ```text INFO: From [stg] Comparing Kernel ABI @//common:kernel_aarch64_abi_diff: INFO: ABI DIFFERENCES HAVE BEEN DETECTED! ``` -------------------------------- ### ION vs DMA-BUF Heap Allocation Example Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps This table illustrates the differences in allocating from system heaps using libion and libdmabufheap. Use BufferAllocator::Alloc with heap names for libdmabufheap. ```text Type of allocation | libion | libdmabufheap --- --- --- Cached allocation from system heap | `ion_alloc_fd(ionfd, size, 0, ION_HEAP_SYSTEM, ION_FLAG_CACHED, &fd)` | `allocator->Alloc("system", size)` **Uncached allocation from system heap** | `ion_alloc_fd(ionfd, size, 0, ION_HEAP_SYSTEM, 0, &fd)` | `allocator->Alloc("system-uncached", size)` ``` -------------------------------- ### Example .symtypes File Entry: Typedef Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor Illustrates the format of a `.symtypes` file, specifically showing a `typedef` entry. Keys like `t#bool` refer to `typedef bool`. ```text t#bool typedef _Bool bool ``` -------------------------------- ### Example .symtypes File Entry: Symbol Name Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor Demonstrates a `.symtypes` file entry for a symbol name. Keys without an `x#` prefix represent direct symbol names, often including their type and signature. ```text find_module s#module * find_module ( const char * ) ``` -------------------------------- ### Install APK on Device using ADB Source: https://source.android.com/docs/core/architecture/kernel/incfs Install a signed APK onto the Android device or emulator using the ADB command. This step is part of testing IncFS with the Android SDK. ```bash ./adb install game.apk ``` -------------------------------- ### Setup ueventd to support DMA-BUF heaps Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps Add a new entry to the device's ueventd.rc file to support device-specific DMA-BUF heaps. ```text This Setup ueventd to support DMA-BUF heaps example demonstrates how this done for the DMA-BUF system heap. ``` -------------------------------- ### Add required permissions for DMA-BUF heap access Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps This example shows the sepolicy permissions created for various clients to access the DMA-BUF system heap. ```text This add required permissions example shows the sepolicy permissions created for various clients to access the DMA-BUF system heap. ``` -------------------------------- ### Example GKI KMI Version Source: https://source.android.com/docs/core/architecture/kernel/gki-versioning Extracts the KMI version from a given kernel release example. ```plaintext 5.4-android12-0 ``` -------------------------------- ### Configure EROFS fstab Entries Source: https://source.android.com/docs/core/architecture/kernel/erofs Set the fstab type to 'erofs' with 'ro' mount option. Includes an example for dual-booting with EXT4. ```text system /system erofs ro wait,slotselect,avb=vbmeta_system,logical,first_stage_mount system /system ext4 ro,barrier=1 wait,slotselect,avb=vbmeta_system,logical,first_stage_mount ``` -------------------------------- ### Tracepoint eBPF Program Example Source: https://source.android.com/docs/core/architecture/kernel/bpf An example eBPF C program for a tracepoint that records the PID of the latest task run on a CPU. ```c #include #include #include #include DEFINE_BPF_MAP(cpu_pid_map, ARRAY, int, uint32_t, 1024); struct switch_args { unsigned long long ignore; char prev_comm[16]; int prev_pid; int prev_prio; long long prev_state; char next_comm[16]; int next_pid; int next_prio; }; DEFINE_BPF_PROG("tracepoint/sched/sched_switch", AID_ROOT, AID_SYSTEM, tp_sched_switch) (struct switch_args *args) { int key; uint32_t val; key = bpf_get_smp_processor_id(); val = args->next_pid; bpf_cpu_pid_map_update_elem(&key, &val, BPF_ANY); return 1; // return 1 to avoid blocking simpleperf from receiving events } LICENSE("GPL"); ``` -------------------------------- ### Example CRC Value Check for 'module_layout' Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor This example demonstrates how to use the `nm` command to retrieve the CRC value for the `module_layout` symbol, illustrating the process of checking symbol-specific CRC values. ```bash nm vmlinux | grep __crc_module_layout 0000000008663742 A __crc_module_layout ``` -------------------------------- ### Example build-time error from CRC_CATCH Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor This is an example of a build-time error message generated when using the `CRC_CATCH` macro. It shows the chain of included header files leading to the CRC mismatch, helping to identify the problematic include. ```text In file included from .../drivers/clk/XXX.c:16: In file included from .../include/linux/of_device.h:5: In file included from .../include/linux/cpu.h:17: In file included from .../include/linux/node.h:18: .../include/linux/device.h:16:2: error: "Included from here" #error "Included from here" ``` -------------------------------- ### Run GTS Tests for IncFS Source: https://source.android.com/docs/core/architecture/kernel/incfs Execute the GTS test suite for incremental installation. Ensure your development environment is set up and all implementation tasks are complete before running. ```bash /gts-tests/tests/packageinstaller/incremental/src/com/google/android/packageinstaller/incremental/gts/IncrementalInstallerTest.java ``` -------------------------------- ### Kernel Header Data Type Change Example Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor This diff shows a change in the signature of `iova_to_phys_hard` within `include/linux/iommu.h`, illustrating how adding a parameter can affect ABI compatibility. ```diff diff --git a/include/linux/iommu.h b/include/linux/iommu.h --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -259,7 +259,7 @@ struct iommu_ops { void (*iotlb_sync)(struct iommu_domain *domain); phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain, - dma_addr_t iova); + dma_addr_t iova, unsigned long trans_flag); int (*add_device)(struct device *dev); void (*remove_device)(struct device *dev); struct iommu_group *(*device_group)(struct device *dev); ``` -------------------------------- ### Kernel Presubmit Test Configuration Source: https://source.android.com/docs/core/architecture/kernel/android-common Example configuration for enabling a kernel presubmit test using test-mapping in the Android platform source tree. This ensures specific tests are run before code check-in. ```json { "kernel-presubmit": [ { "name": "vts_kernel_proc_file_api_test" } ] } ``` -------------------------------- ### Reproduce GKI Binaries Source: https://source.android.com/docs/core/architecture/kernel/gki-releases Use this command to reproduce GKI binaries from a specific build. Ensure you have the manifest XML file and have synced the repository. ```bash repo init -u https://android.googlesource.com/kernel/manifest mv manifest_7364300.xml .repo/manifests repo init -m manifest_7364300.xml --depth=1 repo sync # build the GKI images # You may want to use LTO=thin to build faster for development BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh # (optional) build virtual platform modules BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.aarch64 build/build.sh ``` -------------------------------- ### Create initial device symbol list Source: https://source.android.com/docs/core/architecture/kernel/howto-symbol-lists Create an empty symbol list file for a device. This file will later be added to the base GKI kernel build's `additional_kmi_symbol_lists`. ```bash touch common/gki/aarch64/symbols/virtual_device ``` -------------------------------- ### Build Kernel and ABI Artifacts Source: https://source.android.com/docs/core/architecture/kernel/howto-abi-monitor Run this command to build the GKI kernel and its ABI representation. The artifacts are copied to the default distribution directory. ```bash tools/bazel run //common:kernel_aarch64_abi_dist ``` -------------------------------- ### Asignación almacenada en caché desde el montón del sistema con libdmabufheap Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps?hl=es-419 Utiliza libdmabufheap para asignar memoria con caché desde el montón del sistema. Se especifica el nombre del montón "system" y el tamaño. ```c allocator->Alloc("system", size) ``` -------------------------------- ### Initialize and Sync Kernel Manifest Source: https://source.android.com/docs/core/architecture/kernel/incfs Initializes the kernel manifest repository and synchronizes the common kernel from the specified branch. ```bash repo init -u https://android.googlesource.com/kernel/manifest -b common-android-mainline repo sync ``` -------------------------------- ### Build Kernel and ABI with Custom Destination Source: https://source.android.com/docs/core/architecture/kernel/howto-abi-monitor Use this command to build the kernel and ABI artifacts, specifying a custom destination directory for the output using the --destdir option. ```bash tools/bazel run //common:kernel_aarch64_abi_dist -- --destdir=out/dist ``` -------------------------------- ### Asignación sin caché desde el montón del sistema con libdmabufheap Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps?hl=es-419 Utiliza libdmabufheap para asignar memoria sin caché desde el montón del sistema. Se especifica el nombre del montón "system-uncached" y el tamaño. ```c allocator->Alloc("system-uncached", size) ``` -------------------------------- ### Sign APK with v4 Signature Source: https://source.android.com/docs/core/architecture/kernel/incfs Sign an APK with the v4 signature format using apksigner. This is a prerequisite for installing the APK on a target device or emulator for IncFS testing. ```bash ./apksigner sign --ks debug.keystore game.apk ``` -------------------------------- ### Define Init Service for Module Loading Source: https://source.android.com/docs/core/architecture/kernel/boot-time-opt Configure an `init.rc` file to run the module loading script as a disabled, one-shot service. This ensures the script executes only once during boot. ```rc service insmod-sh /vendor/etc/init.insmod.sh /vendor/etc/init.insmod..cfg class main user root group root system Disabled oneshot ``` -------------------------------- ### Get Kernel Release String Source: https://source.android.com/docs/core/architecture/kernel/gki-versioning Retrieves the full kernel release string using the `uname(2)` system call. Returns an empty string if the call fails. ```C++ std::string get_kernel_release() { struct utsname buf; return uname(&buf) == 0 ? buf.release : ""; } ``` -------------------------------- ### Example of ABI Breakage in Kernel Header Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor?hl=id This diff shows a change to the 'struct mm_struct' in a kernel header file, which introduces an ABI breakage by adding a new member 'tickle_count'. ```diff diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 42786e6364ef..e15f1d0f137b 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -657,6 +657,7 @@ struct mm_struct { ANDROID_KABI_RESERVE(1); } + int tickle_count; /* * The mm_cpumask needs to be at the end of mm_struct, because it * is dynamically sized based on nr_cpu_ids. ``` -------------------------------- ### Asignación sin caché desde el montón del sistema con libion Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps?hl=es-419 Utiliza libion para asignar memoria sin caché desde el montón del sistema. Requiere especificar el descriptor de archivo de ION, el tamaño, el ID del montón y las marcas. ```c ion_alloc_fd(ionfd, size, 0, ION_HEAP_SYSTEM, 0, &fd) ``` -------------------------------- ### Example KMI CRC Mismatch Error Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor This is a typical error message observed at module load time when a CRC mismatch occurs due to a version incompatibility between a module and the kernel's `vmlinux`. ```text init: Loading module /lib/modules/kernel/.../XXX.ko with args "" XXX: disagrees about version of symbol module_layout init: Failed to insmod '/lib/modules/kernel/.../XXX.ko' with args '' ``` -------------------------------- ### Asignación almacenada en caché desde el montón del sistema con libion Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps?hl=es-419 Utiliza libion para asignar memoria con caché desde el montón del sistema. Requiere especificar el descriptor de archivo de ION, el tamaño, el ID del montón y las marcas, incluyendo ION_FLAG_CACHED. ```c ion_alloc_fd(ionfd, size, 0, ION_HEAP_SYSTEM, ION_FLAG_CACHED, &fd) ``` -------------------------------- ### Configure Kernel Modules in Board.mk Source: https://source.android.com/docs/core/architecture/kernel/boot-time-opt Use Board.Config.mk files to define and filter kernel modules for the boot and recovery ramdisks, ensuring efficient loading and placement in the vendor partition. ```makefile # All kernel modules KERNEL_MODULES := $(wildcard $(KERNEL_MODULE_DIR)/*.ko) KERNEL_MODULES_LOAD := $(strip $(shell cat $(KERNEL_MODULE_DIR)/modules.load) # First stage ramdisk modules BOOT_KERNEL_MODULES_FILTER := $(foreach m,$(BOOT_KERNEL_MODULES),%/$(m)) # Recovery ramdisk modules RECOVERY_KERNEL_MODULES_FILTER := $(foreach m,$(RECOVERY_KERNEL_MODULES),%/$(m)) BOARD_VENDOR_RAMDISK_KERNEL_MODULES += $(filter $(BOOT_KERNEL_MODULES_FILTER) $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES)) # ALL modules land in /vendor/lib/modules so they could be rmmod/insmod'd, # and modules.list actually limits us to the ones we intend to load. BOARD_VENDOR_KERNEL_MODULES := $(KERNEL_MODULES) # To limit /vendor/lib/modules to just the ones loaded, use: # BOARD_VENDOR_KERNEL_MODULES := $(filter-out \ # $(BOOT_KERNEL_MODULES_FILTER),$(KERNEL_MODULES)) # Group set of /vendor/lib/modules loading order to recovery modules first, # then remainder, subtracting both recovery and boot modules which are loaded # already. BOARD_VENDOR_KERNEL_MODULES_LOAD := $(filter-out $(BOOT_KERNEL_MODULES_FILTER), \ $(filter $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD))) BOARD_VENDOR_KERNEL_MODULES_LOAD += $(filter-out $(BOOT_KERNEL_MODULES_FILTER) $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD)) # NB: Load order governed by modules.load and not by $(BOOT_KERNEL_MODULES) BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := $(filter $(BOOT_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD)) # Group set of /vendor/lib/modules loading order to boot modules first, # then the remainder of recovery modules. BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD := $(filter $(BOOT_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD)) BOARD_VENDOR_RAMDISK_RECOVERY_KERNEL_MODULES_LOAD += $(filter-out $(BOOT_KERNEL_MODULES_FILTER), \ $(filter $(RECOVERY_KERNEL_MODULES_FILTER),$(KERNEL_MODULES_LOAD))) ``` -------------------------------- ### Initialize Module Loading Service Script Source: https://source.android.com/docs/core/architecture/kernel/boot-time-opt Use a shell script like `/vendor/etc/init.insmod.sh` to manage kernel module loading during the second stage of the init process. This script handles different actions like inserting modules, setting properties, enabling devices, and using modprobe. ```sh #!/vendor/bin/sh . . . if [ $# -eq 1 ]; then cfg_file=$1 else # Set property even if there is no insmod config # to unblock early-boot trigger setprop vendor.common.modules.ready setprop vendor.device.modules.ready exit 1 fi if [ -f $cfg_file ]; then while IFS="|" read -r action arg do case $action in "insmod") insmod $arg ;; "setprop") setprop $arg 1 ;; "enable") echo 1 > $arg ;; "modprobe") modprobe -a -d /vendor/lib/modules $arg ;; . . . esac done < $cfg_file fi ``` -------------------------------- ### Diff of symtypes for ubuf_info and ubuf_info_ops Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor This diff illustrates a significant change in the type definitions for `ubuf_info` and `ubuf_info_ops`. The `ubuf_info` structure gains members, and `ubuf_info_ops` gets a full definition, which can lead to CRC mismatches if not handled. ```diff --- good/drivers/android/vendor_hooks.symtypes +++ bad/drivers/android/vendor_hooks.symtypes @@ -1051 +1051,2 @@ -s#ubuf_info structure_type ubuf_info { } +s#ubuf_info structure_type ubuf_info { member pointer_type { const_type { s#ubuf_info_ops } } ops data_member_location(0) , member t#refcount_t refcnt data_member_location(8) , member t#u8 flags data_member_location(12) } byte_size(16) s#ubuf_info_ops structure_type ubuf_info_ops { member pointer_type { subroutine_type ( formal_parameter pointer_type { s#sk_buff } , formal_parameter pointer_type { s#ubuf_info } , formal_parameter t#bool ) -> base_type void } complete data_member_location(0) , member pointer_type { subroutine_type ( formal_parameter pointer_type { s#sk_buff } , formal_parameter pointer_type { s#ubuf_info } ) -> base_type int byte_size(4) encoding(5) } link_skb data_member_location(8) } byte_size(16) ``` -------------------------------- ### Build and Update Kernel ABI (Legacy) Source: https://source.android.com/docs/core/architecture/kernel/howto-abi-monitor Use this command with legacy build scripts to build the kernel, extract the ABI representation, and update the reference ABI. It accepts environment variables for customization. ```bash BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh ``` -------------------------------- ### Example of an ABI Breakage in Kernel Code Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor This patch introduces an ABI breakage by adding a new field to the 'struct mm_struct'. This will cause a change in the byte size and member offset, leading to ABI detection by monitoring tools. ```diff diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 42786e6364ef..e15f1d0f137b 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -657,6 +657,7 @@ struct mm_struct { ANDROID_KABI_RESERVE(1); } __randomize_layout; + int tickle_count; /* * The mm_cpumask needs to be at the end of mm_struct, because it * is dynamically sized based on nr_cpu_ids. ``` -------------------------------- ### Update and Report Kernel ABI Differences (Legacy) Source: https://source.android.com/docs/core/architecture/kernel/howto-abi-monitor This command builds the kernel, extracts the ABI, and updates the reference ABI representation. The `--print-report` option shows differences, while `--update` overwrites the reference ABI. ```bash BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh --update --print-report ``` -------------------------------- ### Consumer Driver Reading DT Property for Regulator Lookup Source: https://source.android.com/docs/core/architecture/kernel/vendor-module-guidelines This C code snippet demonstrates a driver reading a device-specific DT property to get a string for regulator lookup. This is part of a 'worst-of-both-worlds' scenario where string lookups are still used. ```c str = of_property_read(np, "fizz,core-regulator"); core_reg = regulator_get(dev, str); str = of_property_read(np, "fizz,sensor-regulator"); sensor_reg = regulator_get(dev, str); ``` -------------------------------- ### Build GKI Kernel with KBUILD_SYMTYPES (Android 13 and lower) Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor For older Android versions, prepend `KBUILD_SYMTYPES=1` to the kernel build command. This ensures symbol type information is generated for comparison. ```bash KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh ``` -------------------------------- ### Add Vendor Fields to Structures with ANDROID_VENDOR_DATA Source: https://source.android.com/docs/core/architecture/kernel/kernel-code Use ANDROID_VENDOR_DATA macros to append vendor-specific data fields to kernel structures. Ensure to use separate macros for vendor and OEM data to avoid conflicts. This example shows how to declare a single u64 field and an array of u64 fields. ```c #include ... struct important_kernel_data { [all the standard fields]; /* Create vendor data for use by hook implementations. The * size of vendor data is based on vendor input. Vendor data * can be defined as single u64 fields like the following that * declares a single u64 field named "android_vendor_data1" : */ ANDROID_VENDOR_DATA(1); /* * ...or an array can be declared. The following is equivalent to * u64 android_vendor_data2[20]: */ ANDROID_VENDOR_DATA_ARRAY(2, 20); /* * SoC vendors must not use fields declared for OEMs and * OEMs must not use fields declared for SoC vendors. */ ANDROID_OEM_DATA(1); /* no further fields */ } ``` -------------------------------- ### ION vs. libdmabufheap Allocation Source: https://source.android.com/docs/core/architecture/kernel/dma-buf-heaps Compares the allocation calls between libion and libdmabufheap for different heap and flag configurations. Use libdmabufheap for new allocations. ```text Allocation type | libion | libdmabufheap ---|---|--- Allocation from `my_heap` with flag `ION_FLAG_MY_FLAG` unset | `ion_alloc_fd(ionfd, size, 0, ION_HEAP_MY_HEAP, 0, &fd)` | `allocator->Alloc("my_heap", size)` Allocation from `my_heap` with flag `ION_FLAG_MY_FLAG` set | `ion_alloc_fd(ionfd, size, 0, ION_HEAP_MY_HEAP, ION_FLAG_MY_FLAG, &fd)` | `allocator->Alloc("my_heap_special", size)` ``` -------------------------------- ### Cherry-pick a CL to a Target Release Branch Source: https://source.android.com/docs/core/architecture/kernel/gki-respin This example demonstrates how to cherry-pick a commit from a development branch to a specific release branch and update the commit message to include the Respin Bug ID. Ensure the patch is merged into the GKI development branch and applied to the appropriate GKI release branch before amending. ```bash # 1. Checkout the target release branch git checkout android16-6.12-2025-12 # 2. Fetch the upstream development branch (Source of Truth) git fetch aosp android16-6.12 # 3. Cherry-pick the commit (Preserving metadata) git cherry-pick -x # 4. Update the commit message to include the Respin Bug ID # (Do not remove existing Bug IDs or change the Change-Id) ``` -------------------------------- ### Enable Loadable Kernel Modules Source: https://source.android.com/docs/core/architecture/kernel/loadable-kernel-modules These kernel configuration options must be enabled in all device kernels to support loadable kernel modules. `CONFIG_MODULE_UNLOAD` and `CONFIG_MODVERSIONS` are recommended for better module management. ```kconfig CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y ``` -------------------------------- ### Locate .symtypes Files in Bazel Build Artifacts Source: https://source.android.com/docs/core/architecture/kernel/abi-monitor Navigate to the Bazel build output directory and list the `.symtypes` files. This step is necessary to access the generated symbol type information for comparison. ```bash cd bazel-bin/common/kernel_aarch64/symtypes ls -1 kernel/module/version.symtypes ``` -------------------------------- ### Load Kernel Modules on Early Init Source: https://source.android.com/docs/core/architecture/kernel/loadable-kernel-modules Use modprobe -a to load multiple kernel modules during the early-init stage to avoid repeated C runtime initialization. ```bash on early-init exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \ /vendor/lib/modules module_a module_b module_c ... ``` -------------------------------- ### Build fips140.ko with Bazel Source: https://source.android.com/docs/core/architecture/kernel/gki-fips140-module Use this command to build the fips140.ko module and embed HMAC-SHA256 digest contents using Bazel. ```bash tools/bazel run //common:fips140_dist ```