ro.hardware 由来

关于这个ro.hardware 这个东西是怎么来的?
这个不是在我们编译之后就知道的, 是在nit进程里面算出来的
在 init main 函数里面 会call下面两个
get_hardware_name(hardware, &revision);
process_kernel_cmdline();

先看get_hardware_name,
void get_hardware_name(char *hardware, unsigned int *revision)
{
const char *cpuinfo = “/proc/cpuinfo”;
char *data = NULL;
size_t len = 0, limit = 1024;
int fd, n;
char *x, *hw, *rev;

/* Hardware string was provided on kernel command line */
if (hardware[0])
    return;

fd = open(cpuinfo, O_RDONLY);
if (fd < 0) return;

for (;;) {
    x = realloc(data, limit);
    if (!x) {
        ERROR("Failed to allocate memory to read %s\n", cpuinfo);
        goto done;
    }
    data = x;

    n = read(fd, data + len, limit - len);
    if (n < 0) {
        ERROR("Failed reading %s: %s (%d)\n", cpuinfo, strerror(errno), errno);
        goto done;
    }
    len += n;

    if (len < limit)
        break;

    /* We filled the buffer, so increase size and loop to read more */
    limit *= 2;
}

data[len] = 0;
hw = strstr(data, "\nHardware");
rev = strstr(data, "\nRevision");

if (hw) {
    x = strstr(hw, ": ");
    if (x) {
        x += 2;
        n = 0;
        while (*x && *x != '\n') {
            if (!isspace(*x))
                hardware[n++] = tolower(*x);
            x++;
            if (n == 31) break;
        }
        hardware[n] = 0;
    }
}

if (rev) {
    x = strstr(rev, ": ");
    if (x) {
        *revision = strtoul(x + 2, 0, 16);
    }
}

done:
close(fd);
free(data);

这个就是从 proc cpuinfo里面 去读取 Hardware字段, 拿出来的值就保存在hardware中,

然后看 
static void process_kernel_cmdline(void)

{
/* don’t expose the raw commandline to nonpriv processes */
chmod(“/proc/cmdline”, 0440);

/* first pass does the common stuff, and finds if we are in qemu.
 * second pass is only necessary for qemu to export all kernel params
 * as props.
 */
import_kernel_cmdline(0, import_kernel_nv);
if (qemu[0])
    import_kernel_cmdline(1, import_kernel_nv);

/* now propogate the info given on command line to internal variables
 * used by init as well as the current required properties
 */
export_kernel_boot_props();

}

这主要就是读取kernel 启动参数,kernel 启动参数保存在/proc/cmdline
对于一般进程的启动参数保存在 /proc/pid/cmdline里面,然后把一些值转成属性保存,

我们看看 import_kernel_nv这个里面主要就是把cmdline里面的东西转成属性的
static void import_kernel_nv(char *name, int for_emulator)
{
char *value = strchr(name, ‘=’);
int name_len = strlen(name);

if (value == 0) return;
*value++ = 0;
if (name_len == 0) return;

if (for_emulator) {
    /* in the emulator, export any kernel option with the
     * ro.kernel. prefix */
    char buff[PROP_NAME_MAX];
    int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );

    if (len < (int)sizeof(buff))
        property_set( buff, value );
    return;
}

if (!strcmp(name,"qemu")) {
    strlcpy(qemu, value, sizeof(qemu));

ifdef BUILD_FOR_STB

} else if(!strcmp(name,"resolution")) {
    strlcpy(resolution, value, sizeof(resolution));
} else if(!strcmp(name,"reproducerate")) {
    strlcpy(reproducerate, value, sizeof(reproducerate));

endif

} else if(!strcmp(name,"ENV")){
    strlcpy(envtype, value, sizeof(envtype));
} else if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
    const char *boot_prop_name = name + 12;
    char prop[PROP_NAME_MAX];
    int cnt;

    cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name);
    if (cnt < PROP_NAME_MAX)
        property_set(prop, value);
}

}

这里我就说下 androidboot. 开头的参数, 我们看一下一般kernel 启动参数
shell@sky828_8s70:/ # cat proc/cmdline
console=ttyS0,115200 androidboot.console=ttyS0 root=/dev/ram rw rootwait init=/init
CORE_DUMP_PATH=/data/core_dump.%%p.gz KDebug=1 delaylogo=true androidboot.selinux=permissive
LX_MEM=0x3D800000 LX_MEM2=0xA0000000,0x1FF00000 EMAC_MEM=0x100000 PM51_ADDR=0x20010000
PM51_LEN=0x10000 CMA0=OTHERS,miu=0,hid=23,sz=0x5800000,st=0x11000000 CMA1=XC,miu=0,
hid=22,sz=0x6000000,st=0x16800000 CMA2=OTHERS2,miu=1,hid=24,sz=0x1c00000,st=0x0 CMA3=VDEC1,
miu=1,hid=19,sz=0xc400000,st=0x1c00000 BOOTLOGO_IN_MBOOT ENV_VAR_OFFSET=0x0 ENV_VAR_SIZE=0x10000
ENV=EMMC SECURITY=ON BOOTTIME_SBOOT=295
BOOTTIME_UBOOT=3566=EMMC SECURITY=ON BOOTTIME_SBOOT=295 BOOTTIME_UBOOT=3566
其中就有androidboot打头的,
androidboot.console=ttyS0
androidboot.selinux=permissive

这段code 就会根据上面这两个, 把 其对应成属性保存在下面这两个属性里面‘
ro.boot.console
ro.boot.permissive 里面, 我们看板子里面确实是这两个。
shell@sky828_8s70:/ # getprop |grep ro.boot
在看下export_kernel_boot_props 这个函数

static void export_kernel_boot_props(void)
{
char tmp[PROP_VALUE_MAX];
int ret;
unsigned i;
struct {
const char *src_prop;
const char *dest_prop;
const char *def_val;
} prop_map[] = {
{ “ro.boot.serialno”, “ro.serialno”, “”, },
{ “ro.boot.mode”, “ro.bootmode”, “unknown”, },
{ “ro.boot.baseband”, “ro.baseband”, “unknown”, },
{ “ro.boot.bootloader”, “ro.bootloader”, “unknown”, },
};

for (i = 0; i < ARRAY_SIZE(prop_map); i++) {
    ret = property_get(prop_map[i].src_prop, tmp);
    if (ret > 0)
        property_set(prop_map[i].dest_prop, tmp);
    else
        property_set(prop_map[i].dest_prop, prop_map[i].def_val);
}

ret = property_get("ro.boot.console", tmp);
if (ret)
    strlcpy(console, tmp, sizeof(console));

/* save a copy for init's usage during boot */
property_get("ro.bootmode", tmp);
strlcpy(bootmode, tmp, sizeof(bootmode));

/* if this was given on kernel command line, override what we read
 * before (e.g. from /proc/cpuinfo), if anything */
ret = property_get("ro.boot.hardware", tmp);
if (ret)
    strlcpy(hardware, tmp, sizeof(hardware));
property_set("ro.hardware", hardware);

snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
property_set("ro.revision", tmp);

/* TODO: these are obsolete. We should delete them */
if (!strcmp(bootmode,"factory"))
    property_set("ro.factorytest", "1");
else if (!strcmp(bootmode,"factory2"))
    property_set("ro.factorytest", "2");
else
    property_set("ro.factorytest", "0");

这段红色部分的code就是从 ro.boot.hardware 属性里面取出值来, 然后设置属性
property_set(“ro.hardware”, hardware);

这个就是ro.hardware 的来历, 而且我们kernel 启动参数里面如果有androidboot.hardware 的话, 是会覆盖proc cpuinfo里面的值的

你可能感兴趣的:(ro-hardwar)