ºìÁªLinuxÃÅ»§
Linux°ïÖú

linuxϵͳѧϰ֮ʵ¼ù--ÐéÄâ¶à¸öcpuºËÐÄ

·¢²¼Ê±¼ä:2016-04-21 10:12:01À´Ô´:linuxÍøÕ¾×÷Õß:yanxiangyfg

Ó¦Óñ³¾°:

Ä¿Ç°androidϵͳµÄÓÎÏ·³¯×ÅÖØÐÍÊÖÓη½·¨·¢Õ¹,²¿·ÖapkÓÎÏ·¶ÔÓ²¼þÅäÖÃÒªÇ󼫸ß,ÉõÖÁΪÇó¼«ÖµÄÓû§ÌåÑ鲻ϧÏÞÖƵÍÅäÖÃÊÖ»úÓû§µÄʹÓÃ,µ±ÓÎÏ·¼ì²âµ½Ó²¼þÅäÖò»·ûºÏ×îµÍÒªÇóʱֱ½ÓÉÁÍË.apkÓ¦Óüì²âÊÖ»úÓ²¼þÅäÖÃÖ÷Òª»¹ÊǼì²âcpuºËÐÄÊý,ÄÚ´æ´óС,ÏÔ´æ´óСµÈÐÅÏ¢.

androidÄ£ÄâÆ÷²ÉÓÃvirtualbox×÷ΪÐéÄâÆ÷ÔÚwindowsµÈƽ̨ÉÏÔËÐÐandroid¾µÏñ, ¶øÔÚÖ÷»ú¶Ëcpu´ó²¿·ÖÊÇ4ºËµÄ,ΪÁËʵÏֶ࿪ģÄâÆ÷(ÿ¿ªÒ»¸öÄ£ÄâÆ÷ÖÁÉÙÐèÒª1¸öcpuºË),½«Ã¿¸ö¿ªÆôµÄvirtualboxÄ£ÄâÆ÷ÉèÖÃΪµ¥ºË(ʵ¼ÊÉÏvirtualbox¶àºË´æÔÚbug,¼´¶àºËÇé¿öÏÂvboxheadlessÕâ¸ö½ø³Ì´æÔÚ¸ßcpuÕ¼ÓÃÂʵÄÎÊÌâ). ¶øµ±Ä£ÄâÆ÷ÉèÖÃΪһºËʱ,²¿·ÖÖØÐÍÓÎÏ·¼ì²âÅäÖÃΪµ¥ºËÖ±½ÓÉÁÍË»òÕß²ÉÓõÍÅäÖÃÔËÐÐ,Ó°ÏìÄ£ÄâÆ÷¼æÈÝÐÔºÍÓû§ÌåÑé.

×ÛÉÏ: ²ÉÓÃÉèÖÃÐéÄâ»úµ¥ºËÀ´±ÜÃâvirtualboxµÄ¶àºËbug; Ä£ÄâÆ÷ÄÚ²¿²ÉÓÃÐéÄâ¶à¸öcpuºËÐĵķ½·¨À´·´Éϲãapk¶ÔcpuºËÐÄÊýµÄ¼ì²â.


ʵÏÖÔ­Àí:

androidϵͳ²ÉÓÃlinuxÄÚºË,¶øÉϲãapk¼ì²écpu¸öÊýÖ÷Òª²ÉÓÃÈçÏÂÁ½¸ö·½·¨:

1>  ɨÃè/sys/devices/system/cpuĿ¼ÏÂcpuXÎļþ¼ÐµÄ¸öÊý,ÿһ¸öcpuX´ú±íÒ»¸öcpu,Èçcpu0 cpu1µÈÎļþ¼Ð

2>  ¶ÁÈ¡/sys/devices/system/cpu/onlineÎļþÖµ,´ËÖµ´ú±íÄ¿Ç°¼¤»îµÄ¿ÉÓÃcpuµÄ¸öÊý.¾­¹ýʵ¼ù·¢ÏÖ,Ö÷Òª»¹ÊÇͨ¹ý²é¿´´ËÊôÐÔÖµÀ´×îÖÕÈ·¶¨cpuµÄºËÐÄÊý.

ΪÁËʵÏÖÐéÄâcpuºËÐÄÊý,ÎÒÃÇÐèÒªÐéÄâ³ö°üº¬cpu0µÄËĸöcpuXÎļþ¼Ð,¼´cpu0-cpu3,²¢ÇÒÐÞ¸Ä/sys/devices/system/cpu/onlineÎļþµÄֵΪ0-3. linuxÆô¶¯ÖÁÉÙ±£Ö¤Ò»¸öcpuÔÚÔËÐÐ,ËùÒÔcpu0ÔÚÉèÖõ¥ºËÆô¶¯µÄʱºò¾ÍÕæʵ´æÔÚ.ʵ¼ÊÒªÐéÄâcpu1-cpu3ÕâÈý¸öÎļþ¼Ð.


¾ßÌå²½Öè:

linuxÔÚÆô¶¯³õʼ»¯½×¶Î»á¶ÔcpuµÄÓ²¼þÐÅÏ¢½øÐгõʼ»¯,Ö÷Ҫͨ¹ýsysfsÎļþϵͳÌá½»¸øÉϲãÓ¦ÓýӿÚ,ÈçÓ¦ÓóÌÐò¿ÉÒÔÖ±½Óͨ¹ý'cat  /sys/devices/system/cpu/online'ÃüÁî²é¿´µ±Ç°cpu¸öÊý. ÕâÀïÎÊÌâ¾ÍתΪÁËÐÞ¸ÄsysfsÎļþϵͳ½¨Á¢cpuÐÅÏ¢µÄº¯ÊýÁË.

ͨ¹ýÄæÏò»òÕ߶ÔsysfsÊôÐÔ»òÕ߶ÔcpuÐÅÏ¢³õʼ»¯Á÷³ÌÊìϤµÄͬѧ¾ÍÐÒ¸£ÁË,±È½ÏÈÝÒ×ÕÒµ½ÉèÖÃ/sys/devices/system/cpu/onlineÎļþµÄÖµºÍÐéÄâcpuXÎļþ¼Ð.ÕâÀï¾Í²»Âô¹Ø×Ó,ÂíÉϸø¸÷λ¿Í¹Û³ÊÉÏÎҵĴ¦Àí·½·¨.


ÔÚ³ÊÏÖʵ¼ÊÐÞ¸ÄÄÚÈݵÄͨ¹ý»¹ÐèҪ˵ÏÂcpuÐÅÏ¢³õʼ»¯µÄ´ó¸ÅÁ÷³Ì,ÒÔ±ã´ó¼ÒÉîÈë¿´. ´óÖ¹ý³ÌÈçÏÂ,Èç¹ûÓÐɶÀí½â´íÎóµÄµØ·½,»¹Çë´ó¼ÒÅÄש:

1>  init/main.c: start_kernel()-->boot_cpu_init();´Ëº¯Êý³õʼ»¯cpu0,²»×÷¸Ä¶¯.

2>  init/main.c: start_kernel()-->rest_init()--> kernel_init-->do_basic_setup()-->driver_init()-->cpu_dev_init()

ÕâһϵÁеĵ÷ÓÃ×îÖÕµ÷Óõ½cpu_dev_init(),´Ëº¯ÊýÔÚdrivers/base/cpu.cÎļþÖÐ. Ôڴ˺¯ÊýÖпÉÒÔhotplugÆô¶¯Î´Æô¶¯µÄÆäËûcpu,ÎÒÃǾÍÔÚÕâ¸öº¯ÊýÖÐÀ´ÐéÄâcpu1-cpu3Îļþ¼Ð

3>  ÏÔʾ/sys/devices/system/cpu/onlineµÄÖµµÄº¯ÊýΪshow_cpus_attr, ÈçÏÂ,online,present,possibleÈý¸öÎļþÊôÐÔµÄÖµ¶¼ÊÇͨ¹ý´Ëº¯ÊýÀ´ÏÔʾµÄ,ʵ¼ÊÉÏÒ²ÐèÒªpresent,possibleºÍÖµ²»±ÈonlineС,ËùÒÔÕâÀï¼ÙÉ趼ÉèÖÃΪ0-3,±íʾÓÐ4¸öcpuºË´æÔÚ:

##################BEGIN#######################

#define _CPU_ATTR(name, map) \
{ __ATTR(name, 0444, show_cpus_attr, NULL), map }

/* Keep in sync with cpu_subsys_attrs */
static struct cpu_attr cpu_attrs[] = {
_CPU_ATTR(online, &cpu_online_mask),
_CPU_ATTR(possible, &cpu_possible_mask),
_CPU_ATTR(present, &cpu_present_mask),
};

###################END######################

ʵ¼ÊÐÞ¸ÄÈçÏÂ:(¸Ä¶¯³ö±ê¼ÇΪºìÉ«)

show_cpus_attrº¯Êý:

##################BEGIN#######################

static ssize_t show_cpus_attr(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));

/* ÐÂÔö±àÒëºê¿ØÖƱàÒë,дËÀÖ±½ÓÉèÖÃonlineֵΪ0-3 */
#ifdef FAKE_CPUS_CORES
sprintf(buf, "0-3\n");
n = 4;
#else

buf[n++] = '\n';
buf[n] = '\0';
#endif
return n;
}

###################END######################
cpu_dev_init()º¯Êý¸Ä¶¯:

##################BEGIN#######################

void __init cpu_dev_init(void)
{
if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
panic("Failed to register CPU subsystem");

cpu_dev_register_generic();

#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
sched_create_sysfs_power_savings_entries(cpu_subsys.dev_root);
#endif

/* ÈçÏÂΪÔö¼Ó²¿·Ö */
#ifdef FAKE_CPUS_CORES/*±àÒëºê¿ØÖÆ */
int i;
int cpu_real_count = 0;
for_each_possible_cpu(i) {/*´ËÑ­»·²é¿´ÒѾ­´æÔÚµÄʵ¼ÊÎïÀíºËÐÄÊý */
cpu_real_count++;
}

/*´Ëº¯Êý°ÑÐèҪģÄâµÄcpuÎļþ¼ÐÈ«²¿Á´½Óµ½cpu0. register_cpu_fakeº¯Êý¸ù¾Ýregister_cpuº¯Êý¸ÄÔì¶øÀ´*/
register_cpu_fake(&per_cpu(cpu_devices_fake, 0), 0,cpu_real_count);
#endif

}

##################END#######################

ÐÂÔöµÄregister_cpu_fakeº¯Êý:
#################BEGIN########################

#ifdef FAKE_CPUS_CORES  /* ±àÒëºê¿ØÖÆ */
static DEFINE_PER_CPU(struct cpu, cpu_devices_fake);

/* register_cpu_fakeÓк¯Êýregister_cpuº¯Êý¸ÄÔì¶øÀ´,´Ëº¯Êý±êºì²¿·ÖΪÏà¶Ôregister_cpuº¯ÊýµÄÐÂÔö */
int __cpuinit register_cpu_fake(struct cpu *cpu, int num, int  cpu_real_count)
{
int error =0;

cpu->node_id = cpu_to_node(num);
memset(&cpu->dev, 0x00, sizeof(struct device));
cpu->dev.id = num;
cpu->dev.bus = &cpu_subsys;
cpu->dev.release = cpu_device_release;
#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
cpu->dev.bus->uevent = arch_cpu_uevent;
#endif

error = device_register(&cpu->dev);
if (!error && cpu->hotpluggable)
register_cpu_control(cpu);
if (!error)
per_cpu(cpu_sys_devices, num) = &cpu->dev;
if (!error)
register_cpu_under_node(num, cpu_to_node(num));

#ifdef CONFIG_KEXEC
if (!error)
error = device_create_file(&cpu->dev, &dev_attr_crash_notes);
#endif

/* ´Ë´¦´úÂ뽨Á¢cpuXµ½cpu0µÄÁ´½Ó,µ¥ºËʱ½¨Á¢cpu1-cpu3µ½cpu0µÄÁ´½Ó,
*Ë«ºË´æÔÚcpu0ºÍcpu1,ËùÒÔÖ»½¨Á¢cpu2,cpu3µ½cpu0µÄÁ´½Ó
*sysfs_create_link(&cpu_subsys.dev_root->kobj, &cpu->dev.kobj, buf);º¯Êý½¨Á¢sysfsÎļþϵͳÁ´½Ó
*/
int cpu_num = cpu_real_count;

if(cpu_num < 4){
for(;cpu_num < 4;cpu_num++){
char buf[16];
sprintf(buf,"cpu%d",cpu_num);
sysfs_create_link(&cpu_subsys.dev_root->kobj, &cpu->dev.kobj, buf);
}
}
return error;
}
#endif

##################END#######################


¾­¹ýÉÏ·¸Ä¶¯,ÖØбàÒëÄں˺óÆô¶¯,Ö±½Ó½øÈë/sys/devices/system/cpuĿ¼,cat onlineÖµ·¢ÏÖʱ0-3,ÇÒÓÐcpu0-cpu3ËĸöÎļþ¼Ð,˵Ã÷³É¹¦ÐÞ¸Ä. andoridϵͳ¿ÉÒÔÔËÐа²ÍÃÍÃÀ´¼ì²â,¼ì²âµÃµ½µÄ½á¹ûÊÇ4ºË. ÖÁ´Ë,ÐéÄâ¶à¸öcpuÄں˸öÊýµÄʵ¼ù¾ÍÍêÂúÁË.


±¾ÎÄÓÀ¾Ã¸üеØÖ·£ºhttp://www.linuxdiyf.com/linux/19946.html