高通QSPR读写NV

需求:通过QSPR自定义SN号显示在设置栏里面

1 QSPR是qcom发布的软件,下图可以看出QSPR是将自定义的SN号写入到NV的2497项里面。

  “设置-关于手机-Model&hardware-Serial number”显示的值是根据“ro.serialno”属性去读取的。想显示的SN号与QSPR写入的值一致。

ro.serialno 的值是在BootLoader里面读取硬件信息值赋值给android.serialno,通过uboot传递给kernel的cmdline获取,system里面通过ExportKernelBootProps()函数转换成ro.serialno。

看一下转换的关系:

      bootable\bootloader\edk2\QcomModulePkg\Library\BootLib\UpdateCmdLine.c

        STATIC CONST CHAR8 *UsbSerialCmdLine = " androidboot.serialno=";

        android.serialno赋值的地方:

        bootable/bootloader/edk2/QcomModulePkg/Library/BootLib/board.c

        通过这个函数获取SN的值:BoardSerialNum (CHAR8 *StrSerialNum, UINT32 Len);

        bootable/bootloader/edk2/QcomModulePkg/Library/BootLib/UpdateCmdLine.c

        函数调用:

        Status = BoardSerialNum (StrSerialNum, sizeof (StrSerialNum));

        值传导:

        CmdLineLen += AsciiStrLen (UsbSerialCmdLine);

        Param.UsbSerialCmdLine = UsbSerialCmdLine;

        ro.serialno赋值的地方:

        /system/core/init/property_service.cpp

        static void ExportKernelBootProps() {
            constexpr const char* UNSET = "";
            struct {
                const char* src_prop;
                const char* dst_prop;
                const char* default_value;
            } prop_map[] = {
                    // clang-format off
                { "ro.boot.serialno",   "ro.serialno",   UNSET, },
                { "ro.boot.mode",       "ro.bootmode",   "unknown", },
                { "ro.boot.baseband",   "ro.baseband",   "unknown", },
                { "ro.boot.bootloader", "ro.bootloader", "unknown", },
                { "ro.boot.hardware",   "ro.hardware",   "unknown", },
                { "ro.boot.revision",   "ro.revision",   "0", },
                    // clang-format on
            };   
            for (const auto& prop : prop_map) {
                std::string value = GetProperty(prop.src_prop, prop.default_value);
                if (value != UNSET) InitPropertySet(prop.dst_prop, value);
            }    
        }

整体思路为:读取NV2497项的值,赋值给ro.serialno这个属性。

        给ro.serialno这个属性赋值的地方前面已经阐述清楚,下面要解决的问题是:读取NV的2497项

        1 高通读取NV,已经提供了完整的接口函数:                                                                  ​​​​​​​        ​​​​​​​        ​​​​​​​vendor/qcom/proprietary/commonsys/fastmmi/libmmi/nv.h

        int  diag_nv_read(nv_items_enum_type item, /*!< Which NV item to read */unsigned char *data_ptr, /*!< buffer pointer to put the read data */ int len);在系统中,这个函数被编译进libmmi.so这个库里面。需要使用这个函数,个人理解最方便的方式是通过dlopen函数直接调用libmmi库。

下面是一部分示例代码:

#define libmmi64                        "/system_ext/lib64/libmmi.so"

char mmiso[128] = libmmi64;

static int nvctrl_read(nv_items_enum_type item,     /*!< Which NV item to read */
                               unsigned char *data_ptr,     /*!< buffer pointer to put the read data */
                               int len) {                   /*!< size of read buffer */
            unsigned char reply_buf[len + 3]; 
            int retry = 0;
            int i = 0;

            if (nvread) {
                do {
                    memset(reply_buf, 0, sizeof(reply_buf));
                    nvread(item, reply_buf, sizeof(reply_buf));
                    if ((reply_buf[0] == DIAG_NV_READ_F)
                            && (reply_buf[1] == CHAR_PTR(item)[0])
                            && (reply_buf[2] == CHAR_PTR(item)[1])) {
                        nv_revert_transfer(&reply_buf[3], len);
                        memcpy(data_ptr, &reply_buf[3], len);
                        return SUCCESS;
                    }   
                    usleep(100 * 1000);
                } while (++retry < 10);
            }   
            return FAILED;
        }

        handle = dlopen(mmiso, RTLD_LAZY);

        nvread = (nvctrl_t) dlsym(handle, "_Z12diag_nv_read18nv_items_enum_typePhi"/*         "diag_nv_read" */);

        nvctrl_read(NV_FACTORY_DATA_1_I, nv_read, sizeof(nv_read));

        到这里NV的值被读取出来了,但是因为libmmi.so库加载顺序原因,serialno赋值的地方比较靠前,所以把读取NV并通过property_set函数设置属性这一块做成可执行程序,在系统起来后自动运行可执行程序。

        说到这里,这个需求大致实现了,后面还遇到自启动可执行文件AVC权限问题,本篇不再赘述

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
传统的QSAR(Quantitative Structure-Activity Relationship)自动化接口主要是指利用机器学习和统计建模的方法,通过计算和预测化合物结构与活性之间的定量关系,实现高通量筛选和毒理评估等药物发现领域的自动化流程。 传统的QSAR自动化接口一般包括以下几个主要方面。 首先是特征选择和抽取。这一步骤通过对化合物结构进行编码,提取重要的化学或物理特征,例如分子量、溶解度、环路计数等,以及药物活性相关的成分特征,如活性团等。通过合适的特征选择和抽取方法,可以提高计算模型的准确性和可解释性。 其次是模型建立和训练。传统的QSAR自动化接口通常采用统计学和机器学习的方法构建预测模型。常用的模型算法包括线性回归、支持向量机、随机森林等。在训练过程中,需要提供已知化合物的结构和相关活性数据,建立模型的输入输出关系,并通过参数优化和交叉验证等方法提高模型的性能和预测能力。 然后是模型评估和验证。在模型建立之后,需要对其进行评估和验证。常用的评估指标包括均方根误差(RMSE)、相关系数(R2)等。通过与验证集的比较和外部数据集的预测,可以评估模型的稳定性和可靠性。 最后是应用和扩展。建立好的QSAR模型可以用于大规模化合物库的筛选和优化,加速药物发现过程。另外,还可以通过模型解释和结构活性关系的分析,指导设计更活性和稳定的化合物。此外,还可以通过引入更多的分子描述符、改进算法和建模方法等,进一步提高QSAR模型的性能和应用范围。 总之,传统的QSAR自动化接口在药物发现和毒理评估领域具有重要的应用价值,通过计算和预测化学结构与药物活性之间的定量关系,帮助研究人员快速筛选和优化有潜力的化合物,提高药物研发过程的效率和成功率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值