ro.hardware 由来

来源:互联网 发布:怎么在淘宝上收藏店铺 编辑:程序博客网 时间:2024/04/28 01:04

关于这个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里面的值的

0 0