cat /proc/cpuinfo

Processor : ARMv7 Processor rev 5 (v7l)
BogoMIPS : 799.53
Features : swp half thumb fastmult vfp edsp neon vfpv3
CPU implementer : 0x41
CPU architecture:
7
CPU variant : 0x2
CPU part : 0xc08
CPU revision : 5

按照ARM datasheet,ARMv7的Architecture应该是0xF Defined by CPUID scheme,为什么看到的是7

proc_cpuinfo_init()

static int __init proc_cpuinfo_init(void)
{
    proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
    return 0;
}
 
  
static const struct file_operations proc_cpuinfo_operations = {
    .open        = cpuinfo_open,//一般只有open函数需要自己实现,主要是将指定的seq_file和file关联起来
    .read        = seq_read,//系统实现
    .llseek        = seq_lseek,//系统实现
    .release    = seq_release,//系统实现
};
 
  

cpuinfo_open()

static int cpuinfo_open(struct inode *inode, struct file *file)
{
    return seq_open(file, &cpuinfo_op);
}
 
  

cpuinfo_op结构是架构相关,对于arm架构的定义在arch/arm/kernel/setup.c

const struct seq_operations cpuinfo_op = {
    .start    = c_start,
    .next    = c_next,
    .stop    = c_stop,
    .show    = c_show
};
 
  
int seq_open(struct file *file, const struct seq_operations *op)
{
    struct seq_file *p = file->private_data;

    if (!p) { //如果file->private_data为空,则为它申请空间
        p = kmalloc(sizeof(*p), GFP_KERNEL);
        if (!p)
            return -ENOMEM;
        file->private_data = p;
    }
    memset(p, 0, sizeof(*p));//清0
    mutex_init(&p->lock); //初始化mutex
    p->op = op;  //将上面传进来的cpuinfo_op赋值给file的p,以后通过file的private_data成员就能找到cpuinfo_op了

    file->f_version = 0;
    file->f_mode &= ~FMODE_PWRITE;
    return 0;
}
 
  

cpuinfo read

 seq_file文件的内核读取过程

 cpuinfo_op

c_start()

static void *c_start(struct seq_file *m, loff_t *pos)
{
    return *pos < 1 ? (void *)1 : NULL;
}
 
  

检查文件位置,如果是0,返回1,否则NULL。

c_next()

static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
    ++*pos;
    return NULL;
}
 
  

文件位置指针增加,指向下一个位置。

c_stop()

static void c_stop(struct seq_file *m, void *v)
{
}
 
  

c_show()

static int c_show(struct seq_file *m, void *v)
{
    int i;
    /*打印cpu的processor,例如例子中的Processor       : ARMv7 Processor rev 5 (v7l)*/
    seq_printf(m, "Processor\t: %s rev %d (%s)\n",
           cpu_name, read_cpuid_id() & 15, elf_platform);

#if defined(CONFIG_SMP)//如果是多核处理器,则分别打印cpu的processor信息和主频信息
    for_each_online_cpu(i) {
        /*
         * glibc reads /proc/cpuinfo to determine the number of
         * online processors, looking for lines beginning with
         * "processor".  Give glibc what it expects.
         */
        seq_printf(m, "processor\t: %d\n", i);
        seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
               per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
               (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
    }
#else /* CONFIG_SMP */
    seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
           loops_per_jiffy / (500000/HZ),
           (loops_per_jiffy / (5000/HZ)) % 100);
#endif

    /* dump out the processor features */
    seq_puts(m, "Features\t: ");//下面打印feature信息

    for (i = 0; hwcap_str; i++)
        if (elf_hwcap & (1 << i))
            seq_printf(m, "%s ", hwcap_str);

    seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
    seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);

    if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
        /* pre-ARM7 */
        seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
    } else {
        if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
            /* ARM7 */
            seq_printf(m, "CPU variant\t: 0x%02x\n",
                   (read_cpuid_id() >> 16) & 127);
        } else {
            /* post-ARM7 */
            seq_printf(m, "CPU variant\t: 0x%x\n",
                   (read_cpuid_id() >> 20) & 15);
        }
        seq_printf(m, "CPU part\t: 0x%03x\n",
               (read_cpuid_id() >> 4) & 0xfff);
    }
    seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);

    seq_puts(m, "\n");

    seq_printf(m, "Hardware\t: %s\n", machine_name);
    seq_printf(m, "Revision\t: %04x\n", system_rev);
    seq_printf(m, "Serial\t\t: %08x%08x\n",
           system_serial_high, system_serial_low);//这里我们终于看到serial打印的地方了。我们发现主要打印 system_serial_high,和system_serial_low两个变量的值。如果没有赋值,则打印0。我们要做的工作就是为这两个变量赋值。

    return 0;
}
 
  

CPU architecture信息是由proc_arch[cpu_architecture()]决定的,并不是直接打印从MIDR中的Architecture。

int __pure cpu_architecture(void)
{
	BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);

	return __cpu_architecture;
}

setup_processer()->__cpu_architecture = __get_cpu_architecture()

对于ARMv7返回的是CPU_ARCH_ARMv7为9,proc_arch[9] = ‘7’,就是代表v7。

你可能感兴趣的:(start_kernel)