内核中每种处理器架构抽象为一个proc_info_list结构体,在arch/arm/include/asm/procinfo.h中定义,

struct proc_info_list {
unsigned int cpu_val;
unsigned int cpu_mask;
unsigned long __cpu_mm_mmu_flags; /* used by head.S */
unsigned long __cpu_io_mmu_flags; /* used by head.S */
unsigned long __cpu_flush; /* used by head.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
const char *cpu_name;
struct processor *proc;
struct cpu_tlb_fns *tlb;
struct cpu_user_fns *user;
struct cpu_cache_fns *cache;
};

proc_info_list结构体的实现与处理器架构相关,这里以arch/arm/mm/proc-v6.S为例,

    /*
* Match any ARMv6 processor core.
*/
.type __v6_proc_info, #object
__v6_proc_info:
.long 0x0007b000 /*unsigned int cpu_val*/
.long 0x0007f000 /*unsigned int cpu_mask*/
/*unsigned long __cpu_mm_mmu_flags; used by head.S */
.long PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ
/*unsigned long __cpu_io_mmu_flags; used by head.S */
.long PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ
/*unsigned long __cpu_flush; used by head.S */
b __v6_setup
.long cpu_arch_name /*const char *arch_name;*/
.long cpu_elf_name /*const char *elf_name;*/
/*unsigned int elf_hwcap;*/
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
.long cpu_v6_name /*const char *cpu_name;*/
.long v6_processor_functions /*struct processor *proc*/
.long v6wbi_tlb_fns /*struct cpu_tlb_fns *tlb*/
.long v6_user_fns /*struct cpu_user_fns *user*/
.long v6_cache_fns /*struct cpu_cache_fns *cache*/
.size __v6_proc_info, . - __v6_proc_info

1. cpu_val,cpu_mask

用于匹配下面的协处理指令读出的cupID。

MRC p15,,<Rd>,c0,c0, ;Read Main ID Register

2.__cpu_flush,arch/arm/mm/proc-v6.S

/*
* __v6_setup
*
* Initialise TLB, Caches, and MMU state ready to switch the MMU
* on. Return in r0 the new CP15 C1 control register setting.
*
* We automatically detect if we have a Harvard cache, and use the
* Harvard cache control instructions insead of the unified cache
* control instructions.
*
* This should be able to cover all ARMv6 cores.
*
* It is assumed that:
* - cache type register is implemented
*/
__v6_setup:
#ifdef CONFIG_SMP
mrc p15, , r0, c1, c0, @ Enable SMP/nAMP mode
orr r0, r0, #0x20
mcr p15, , r0, c1, c0,
#endif mov r0, #
mcr p15, , r0, c7, c14, @ clean+invalidate D cache
mcr p15, , r0, c7, c5, @ invalidate I cache
mcr p15, , r0, c7, c15, @ clean+invalidate cache
mcr p15, , r0, c7, c10, @ drain write buffer
#ifdef CONFIG_MMU
mcr p15, , r0, c8, c7, @ invalidate I + D TLBs
mcr p15, , r0, c2, c0, @ TTB control register
orr r4, r4, #TTB_FLAGS
mcr p15, , r4, c2, c0, @ load TTB1
#endif /* CONFIG_MMU */
adr r5, v6_crval
ldmia r5, {r5, r6}
mrc p15, , r0, c1, c0, @ read control register
bic r0, r0, r5 @ clear bits them
orr r0, r0, r6 @ set them
mov pc, lr @ return to head.S:__ret

3. arch_name

    .type    cpu_arch_name, #object
cpu_arch_name:
.asciz "armv6"
.size cpu_arch_name, . - cpu_arch_name

4.elf_name

    .type    cpu_elf_name, #object
cpu_elf_name:
.asciz "v6"
.size cpu_elf_name, . - cpu_elf_name
.align

5.cpu_name

cpu_v6_name:
.asciz "ARMv6-compatible processor"
.align

6.struct processor *proc

该结构体在在arch/arm/include/asm/procinfo.h中声明,

struct processor;

在include/asm-arm/cpu-multi32.h中定义,是一系列函数指针的结构体。

/*
* Don't change this structure - ASM code
* relies on it.
*/
extern struct processor {
/* MISC
* get data abort address/flags
*/
void (*_data_abort)(unsigned long pc);
/*
* Retrieve prefetch fault address
*/
unsigned long (*_prefetch_abort)(unsigned long lr);
/*
* Set up any processor specifics
*/
void (*_proc_init)(void);
/*
* Disable any processor specifics
*/
void (*_proc_fin)(void);
/*
* Special stuff for a reset
*/
void (*reset)(unsigned long addr) __attribute__((noreturn));
/*
* Idle the processor
*/
int (*_do_idle)(void);
/*
* Processor architecture specific
*/
/*
* clean a virtual address range from the
* D-cache without flushing the cache.
*/
void (*dcache_clean_area)(void *addr, int size); /*
* Set the page table
*/
void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
/*
* Set a possibly extended PTE. Non-extended PTEs should
* ignore 'ext'.
*/
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
} processor;

这些函数指针在arch/arm/mm/proc-v6.S中指定,

    .type    v6_processor_functions, #object
ENTRY(v6_processor_functions)
.word v6_early_abort
.word pabort_noifar
.word cpu_v6_proc_init
.word cpu_v6_proc_fin
.word cpu_v6_reset
.word cpu_v6_do_idle
.word cpu_v6_dcache_clean_area
.word cpu_v6_switch_mm
.word cpu_v6_set_pte_ext
.size v6_processor_functions, . - v6_processor_functions

7.struct cpu_tlb_fns *tlb

该结构体在在arch/arm/include/asm/procinfo.h中声明

struct cpu_tlb_fns;

在arch/arm/include/asm/tlbflush.h中定义,

struct cpu_tlb_fns {
void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *);
void (*flush_kern_range)(unsigned long, unsigned long);
unsigned long tlb_flags;
};

具体函数实现在arm/arm/mm/tlb-v6.S

    .type    v6wbi_tlb_fns, #object
ENTRY(v6wbi_tlb_fns)
.long v6wbi_flush_user_tlb_range
.long v6wbi_flush_kern_tlb_range
.long v6wbi_tlb_flags
.size v6wbi_tlb_fns, . - v6wbi_tlb_fns

8.struct cpu_user_fns *user

该结构体在在arch/arm/include/asm/procinfo.h中声明

struct cpu_user_fns;

在arch/arm/include/asm/page.h中定义

struct cpu_user_fns {
void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
unsigned long vaddr);
};

具体函数实现在arm/arm/mm/copypage-v6.S

struct cpu_user_fns v6_user_fns __initdata = {
.cpu_clear_user_highpage = v6_clear_user_highpage_nonaliasing,
.cpu_copy_user_highpage = v6_copy_user_highpage_nonaliasing,
};

9.struct cpu_cache_fns *cache

该结构体在在arch/arm/include/asm/procinfo.h中声明

struct cpu_cache_fns;

在arch/arm/include/asm/cacheflush.h中定义,是包含一系列函数指针的结构体

struct cpu_cache_fns {
void (*flush_kern_all)(void);
void (*flush_user_all)(void);
void (*flush_user_range)(unsigned long, unsigned long, unsigned int); void (*coherent_kern_range)(unsigned long, unsigned long);
void (*coherent_user_range)(unsigned long, unsigned long);
void (*flush_kern_dcache_page)(void *); void (*dma_inv_range)(const void *, const void *);
void (*dma_clean_range)(const void *, const void *);
void (*dma_flush_range)(const void *, const void *);
};

具体函数实现在arm/arm/mm/cache-v6.S

    .type    v6_cache_fns, #object
ENTRY(v6_cache_fns)
.long v6_flush_kern_cache_all
.long v6_flush_user_cache_all
.long v6_flush_user_cache_range
.long v6_coherent_kern_range
.long v6_coherent_user_range
.long v6_flush_kern_dcache_page
.long v6_dma_inv_range
.long v6_dma_clean_range
.long v6_dma_flush_range
.size v6_cache_fns, . - v6_cache_fns

proc_info_list的更多相关文章

  1. 第4天--linux内核学习

    驱动使用方式1.编译到内核中 * make uImage进入到系统后mknod /dev/led c 500 0 创建设备节点 2.编译为模块 M make module进入到系统后 mknod /d ...

  2. linux内核启动以及文件系统的加载过程

    Linux 内核启动及文件系统加载过程 当u-boot 开始执行 bootcmd 命令,就进入 Linux 内核启动阶段.普通 Linux 内核的启动过程也可以分为两个阶段.本文以项目中使用的 lin ...

  3. ARM Linux启动代码分析

    前言 在学习.分析之前首先要弄明白一个问题:为什么要分析启动代码? 因为启动代码绝大部分都是用汇编语言写的,对于没学过或者不熟悉汇编语言的同学确实有一定难度,但是如果你想真正深入地学习Linux,那么 ...

  4. Linux Kernel之flush_cache_all在ARM平台下是如何实现的【转】

    转自:http://blog.csdn.net/u011461299/article/details/10199989 版权声明:本文为博主原创文章,未经博主允许不得转载. 在驱动程序的设计中,我们可 ...

  5. Linux Kernel中断子系统来龙去脉浅析【转】

    转自:http://blog.csdn.net/u011461299/article/details/9772215 版权声明:本文为博主原创文章,未经博主允许不得转载. 一般来说,在一个device ...

  6. Android系统启动过程-uBoot+Kernel+Android

    摘要:本文是参考大量网上资源在结合自己查看源代码总结出来的,让自己同时也让大家加深对Android系统启动过程有一个更加深入的了解!再次强调,本文的大多数功劳应归功于那些原创者们,同时一些必要的参考链 ...

  7. 嵌入式 uboot以及kernel添加看门狗临时记录(个人记录未整理乱)

    Uboot_Kernerl_Add_Watch_Dog: U-Boot 2010.06 (Nov 01 2013 - 15:28:44) DRAM:  128 MiBCheck spi flash c ...

  8. arm linux kernel 从入口到start_kernel 的代码分析

    参考资料: <ARM体系结构与编程> <嵌入式Linux应用开发完全手册> Linux_Memory_Address_Mapping http://www.chinaunix. ...

  9. 基于linux2.6.38.8内核启动过程完全解析[一]

    转载: ************************************************************************************************ ...

随机推荐

  1. 关系型数据库---MySQL---数据类型

    一.每个数据表至少有一个数据列.用户必须为每一个数据列分别定义一个适当的数据类型: 1.整数(***Int) 1.1 默认情况下,整数类型包括:正整数.负整数: 1.2 如果给数据列定义了unsign ...

  2. Codeforces Round #378 (Div. 2) D. Kostya the Sculptor 分组 + 贪心

    http://codeforces.com/contest/733/problem/D 给定n个长方体,然后每个长方体都能选择任何一个面,去和其他长方体接在一起,也可以自己一个,要求使得新的长方体的最 ...

  3. js获取ISO8601规范时间

    var d = new Date(); d.setHours(d.getHours(), d.getMinutes() - d.getTimezoneOffset()); console.log(d. ...

  4. Elasticsearch优化

    2.out of memory错误 因为默认情况下es对字段数据缓存(Field Data Cache)大小是无限制的,查询时会把字段值放到内存,特别是facet查询,对内存要求非常高,它会把结果都放 ...

  5. cas实现单点登录原理

    1.基于Cookie的单点登录的回顾        基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中,之后访问网站时在过滤器(filter)中校验用户权限,如果没有权限则从 ...

  6. null、undefined和NaN的区别

    未定义的值和定义未赋值的值是undefined: null是一种特殊的Object,可以给变量赋一个值null,来清除变量的值: NaN是一种特殊的number:

  7. Hive的HQL(2)

    Hive基础(1) Hive的HQL(2) 1. HQL的数据定义,HQL是一种SQL方言,支持绝大部分SQL-92标准.但是和SQL的差异为:不支持行级别的操作,不支持事务等.HQL的语法接近于My ...

  8. Got error 28 from storage engine的错误处理

    早上例行检查数据库,发现Got error 28 from storage engine这个错误,天那,我的数据.心里哇凉....备份的时间还是很久以前.最近更新了不少,麻烦大了. 好在找到了解决方法 ...

  9. .NET 读取视频文件

    该篇文章 复制别人的文章 在.NET中处理视频是一件痛苦的事情,.NET并没有提供视频处理的类.于是咱们只能找一些第三方的类库或者自己实现,在项目时间比较赶的情况下,自己实现是不可能的了,而且说不定会 ...

  10. 【Python图像特征的音乐序列生成】关于数据集的分享和样例数据

    数据集还在制作中,样例数据如下: 我将一条数据作为一行,X是ID,O代表了情感向量,S是速度,是一个很关键的参数,K是调式,M是节拍,L是基本拍.后面是ABC格式的序列,通过embedding化这些音 ...