Android | 打开内核的ZONED相关选项踩坑记

作为一名小白,要打开区区两个内核配置相关的编译选项,成功编译,打开并进入模拟器,看起来是一件事,其实是三件事,每一件事都花费了不少时间,这篇文章尝试总结一些方法论。

打开内核相关的编译选项

要打开内核相关的编译选项,我们首先得知道它究竟使用到了哪一个,因为整个Android代码里面,为各种架构,各种版本设计的编译选项一抓一大把,改哪里,是第一个问题。

Android内核代码使用了bazel这个编译工具进行编译,我们先进入到根目录的BUILD.bazel:

//common/BUILD.bazel
21:load("//build/kernel/kleaf:common_kernels.bzl", "define_common_kernels", "define_db845c")

这里加载了一个common_kernels.bzl文件

//build/kernel/kleaf/common_kernels.bzl:49
_ARCH_CONFIGS = {
    "kernel_aarch64": {
        "arch": "arm64",
        "build_config": "build.config.gki.aarch64",
        "outs": aarch64_outs,
    },
    "kernel_aarch64_interceptor": {
        "arch": "arm64",
        "build_config": "build.config.gki.aarch64",
        "outs": aarch64_outs,
        "enable_interceptor": True,
    },
    "kernel_aarch64_debug": {
        "arch": "arm64",
        "build_config": "build.config.gki-debug.aarch64",
        "outs": aarch64_outs,
    },
    "kernel_x86_64": {
        "arch": "x86_64",
        "build_config": "build.config.gki.x86_64",
        "outs": x86_64_outs,
    },
    "kernel_x86_64_debug": {
        "arch": "x86_64",
        "build_config": "build.config.gki-debug.x86_64",
        "outs": x86_64_outs,
    },
}

可以发现,kernel_x86_64使用的build_config是

"build.config.gki.x86_64"

找到这个文件:

//common/build.config.gki.x86_64
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.common
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.x86_64
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.gki


BUILD_SYSTEM_DLKM=1
MODULES_LIST=${ROOT_DIR}/${KERNEL_DIR}/android/gki_system_dlkm_modules


BUILD_GKI_ARTIFACTS=1
BUILD_GKI_BOOT_IMG_SIZE=67108864

实际上它由三个部分组成。其中build.config.gki中:

DEFCONFIG=gki_defconfig
POST_DEFCONFIG_CMDS="check_defconfig"


if [ -n "${GKI_BUILD_CONFIG_FRAGMENT}" ]; then
source ${GKI_BUILD_CONFIG_FRAGMENT}
fi

所以我们知道了DEFCONFIG使用的是gki_defconfig。找到对应文件:

common/arch/x86/configs/gki_defconfig
里面全部是CONFIG的一些定义

在文件末尾添加上(或者修改已经存在的)我们想要的编译配置:

CONFIG_BLK_DEV_ZONED=y
CONFIG_BLK_DEV_NULL_BLK=y

好,到这里,完成了第一步。修改配置。

编译内核

打开了两个编译选项后,发现并编不过,很匪夷所思。

outside_default.png

经过学长的寻找,最后发现,要在build.config.gki文件中,注释掉deconfig的检查的那一条语句:

//common/build.config.gki
DEFCONFIG=gki_defconfig
# POST_DEFCONFIG_CMDS="check_defconfig" 注释此行


if [ -n "${GKI_BUILD_CONFIG_FRAGMENT}" ]; then
source ${GKI_BUILD_CONFIG_FRAGMENT}
fi

取消检查后就能编过了。

运行模拟器

编译过后以为可以运行起来了,就直接尝试,发现并不能:

outside_default.png

会报disagree错误,这个问题比较经典,因为之前切换内核的时候也遇到了,怀疑是版本错误,最后找到了解决方案:

outside_default.png

应该是版本检查时CRC循环冗余检验不过,由于我们这些工作都还是在测试,考虑跳过这个检查,同样修改之前的内核配置文件,将CONFIG_MODVERSIONS这个选项注释掉不打开,确实解决了这个问题,然后出现下一个问题:

outside_default.png

发现有模块还是无法成功加载,我发现,有一个version magic 'xx' should be 'xx'报错,经过查询,发现这也是一个版本校验的情况,内核与模块之间的版本不同不允许加载。

由于内核模块是通过预编译的方式,放置在AOSP代码中,内核版本与模块版本确实可能产生冲突,考虑更新模块版本,首先找到模块放置地址:

对于我的架构和Android系统版本,预编译的模块存放于:
AOSP/kernel/prebuilts/common-modules/virtual-device/5.15/x86-64

outside_default.png

使用命令:

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist

编译内核模块。编译完成后在目录:

kernel_source/bazel-bin/common-modules/virtual-device/virtual_device_x86_64

outside_default.png

把这些内核模块全部替换掉原来的内核模块,重新编译AOSP后,以上错误解决。

但是出现新错误,模拟器启动过程不会卡死,但是就是起不来。

经过逐行对比日志,发现surfaceflinger服务起不来,这个服务是Android里面图形化相关的服务,由于我们只修改了内核模块,会不会是某个模块被漏掉了?于是重新比较了一下,发现确实有若干模块并不在更新后的ko列表中。比如virtio-gpu.ko模块,很有可能是这个原因。

但是这个模块在哪呢?找到和模块编译相关的bazel文件:

common-modules/virtual-device/BUILD.bazel

搜索 virtio-gpu:

_virt_common_ext_modules = [
    "goldfish_drivers/goldfish_address_space.ko",
    "goldfish_drivers/goldfish_pipe.ko",
    "goldfish_drivers/goldfish_sync.ko",
    "virtio_gpu/virtio-gpu.ko",
]

发现它被定义为一种ext_modules,找到我们执行的命令对应条目:

kernel_build(
    name = "virtual_device_x86_64",
    srcs = [":virtual_device_x86_64_common_sources"],
    outs = [],
    base_kernel = "//common:kernel_x86_64",
    build_config = "build.config.virtual_device.x86_64",
    module_outs = _virt_common_modules + [
        # keep sorted
        "test_meminit.ko",
        "test_stackinit.ko",
    ],
)

发现它确实没有编译ext_modules,那ext_modules该怎么编呢,我在这个文件中又发现了一个编译选项:

kernel_module(
    name = "virtual_device_x86_64_external_modules",
    srcs = [":virtual_device_x86_64_common_sources"],
    outs = _virt_common_ext_modules,
    kernel_build = ":virtual_device_x86_64",
)

所以,可以通过执行:

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_external_modules

来编译external_modules。

于是执行,编译完毕后,将

bazel-bin/common-modules/virtual-device/virtual_device_x86_64_external_modules

目录下的.ko文件移动到AOSP目录对应位置,然后重新编译AOSP。

终于成功启动模拟器:

outside_default.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要测试ZNS SSD(Zoned Namespace Solid State Drive),可以采取以下步骤: 1. 确定测试目标:在进行测试之前,首先要明确测试的目标和需求。例如,测试读取速度、写入速度、随机读取/写入速度、顺序读取/写入速度、数据完整性等。 2. 选择适当的测试工具:根据测试目标,选择合适的测试工具。常用的测试工具包括FIO、IOmeter、CrystalDiskMark等。这些工具可以帮助模拟不同的负载和执行各种读写操作。 3. 进行性能测试:使用选定的工具,进行性能测试。可以通过测试不同的文件大小、读取/写入混合负载、多线程负载等方式,来评估ZNS SSD的性能表现。记录测试结果,包括读取/写入速度、IOPS(每秒输入/输出操作数)、延迟等指标。 4. 进行数据一致性测试:为了确保ZNS SSD的数据完整性,在测试过程中需要进行数据一致性测试。可以使用校验和算法来验证写入和读取的数据是否一致,以确保数据在读写过程中没有出现错误。 5. 进行耐久性测试:ZNS SSD通常具有更高的耐久性,可以进行更频繁的写入操作。可以通过反复进行写入/擦除测试,以评估其耐久性和寿命。 6. 进行其他测试:根据具体需求,还可以进行其他测试,如功耗测试、温度测试、兼容性测试等。 7. 分析和评估测试结果:根据测试结果,进行数据分析和评估。比较不同测试条件下的性能表现,确认ZNS SSD是否符合预期。 最后,根据测试结果,可以根据需求进行优化和调整,以提升ZNS SSD的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值