第零个文件 arch/armnommu/Makefile
在这个文件中定义了你编译好的内核的入口的地址和MACHINE类型,一般是通过条件编译
TEXTADDR = 0x10008000 这个值完全是根据你的cpu和内存状况确定的
MACHINE = your_processor
指定连接文件
LINKFLAGS :=-p -X -T arch/armnommu/vmlinux.lds
替换vmlinux-$(PROCESSOR).lds.in中的TEXTADDR,生成实际需要的连接脚本
arch/armnommu/vmlinux.lds: arch/armnommu/vmlinux-$(PROCESSOR).lds.in dummy
ifeq ($(CONFIG_ARCH_DSC21),y)
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >tmp.ld
@sed 's/DATAADDR/$(DATAADDR)/' <tmp.ld >$@
$(RM) tmp.ld
else
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@
endif
一般连接脚本的前面几句是这样的
ENTRY(stext)---------指定入口
SECTIONS
{
. = $(TEXTADDR);-----设定入口的绝对地址
第一个文件linux/arch/armnommu/kernel/head-armv.S
#define K(a,b,c) ((a) << 24 | (b) << 12 | (c))
#ifndef CONFIG_UCLINUX
设置符号swapper_pg_dir的地址
.globl SYMBOL_NAME(swapper_pg_dir)
.equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
定义了一个宏,该宏可以获得swapper_pg_dir的地址
.macro pgtbl, reg, rambase
adr /reg, stext
sub /reg, /reg, #0x4000
.endm
/*
* Since the page table is closely related to the kernel start address, we
* can convert the page table base address to the base address of the section
* containing both.
*/
.macro krnladr, rd, pgtable, rambase
bic /rd, /pgtable, #0x000ff000
.endm
#endif
/*
* Kernel startup entry point.
*
* The rules are:
* r0 - should be 0
* r1 - unique architecture number
* MMU - off
* I-cache - on or off
* D-cache - off
*
* See linux/arch/arm/tools/mach-types for the complete list of numbers
* for r1.
*/
.section ".text.init",#alloc,#execinstr
.type stext, #function
请注意,这里是入口点,而且此时r1中应该保存唯一的一个architecture number
ENTRY(stext)
保存r0寄存器的值?????
mov r12, r0
靠~~Rebel.COM NetWinder是什么东东,这个条件编译可以不予理会
#if defined(CONFIG_ARCH_NETWINDER)
。。。。。
#endif
#if defined(CONFIG_ARCH_L7200)
mov r1, #MACH_TYPE_L7200
#elif defined(CONFIG_ARCH_INTEGRATOR)
mov r1, #MACH_TYPE_INTEGRATOR
#elif defined(CONFIG_ARCH_P52)
mov r1, #MACH_TYPE_P52
#elif defined(CONFIG_ARCH_SWARM)
mov r1, #MACH_TYPE_SWARM
#elif defined(CONFIG_ARCH_SAMSUNG)
mov r1, #MACH_TYPE_SAMSUNG
#endif
前面预定义了部分的ARCH,如果匹配的上,R1中包含了architecture number
其实系统复位之后,ARM就处于SVC 模式,而且禁止了FIQ IRQ, 的确如注视所说--make sure
mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode
msr cpsr_c, r0 @ and all irqs disabled
使用的是atmel的arm处理器吗???跳过去吧
#if defined(CONFIG_ARCH_ATMEL)
。。。。。
#endif
又来,使用的是samsumg的arm处理器吗???跳过去吧
#if defined(CONFIG_ARCH_SAMSUNG)
。。。。。
#endif
重点还是分析通用的arm处理器的内容吧
bl __lookup_processor_type ----寻找处理器类型,R10中保存指向表示处理器类型结构的指针
teq r10, #0 @ invalid processor? ----R10 == 0????靠,发生错误
moveq r0, #'p' @ yes, error 'p'
beq __error
bl __lookup_architecture_type----寻找体系结构类型, R7中保存指向表示体系结构类型结构的指针
teq r7, #0 @ invalid architecture?----好像不用说什么了吧
moveq r0, #'a' @ yes, error 'a'
beq __error
跳过,我们一般是会定义CONFIG_UCLINUX这个宏的
__create_page_tables函数建立一个初始化阶段的页表,映射4M内存,当然足够了
#ifndef CONFIG_UCLINUX
bl __create_page_tables
#endif
adr lr, __ret @ return address
看看你的proc_info_list结构,第三个成员变量是一个跳转指令,进行一些CPU初始化的操作
返回则跳到__ret
add pc, r10, #12 @ initialise processor
@ (return control reg)
__switch_data: .long __mmap_switched
.long SYMBOL_NAME(compat)
.long SYMBOL_NAME(__bss_start)
.long SYMBOL_NAME(_end)
.long SYMBOL_NAME(processor_id)
.long SYMBOL_NAME(__machine_arch_type)
.long SYMBOL_NAME(cr_alignment)
.long SYMBOL_NAME(init_task_union)+8192
__ret: ldr lr, __switch_data
执行__switch_data
mov pc, lr
/*
* This code follows on after the page
* table switch and jump above.
*
* r0 = processor control register
* r1 = machine ID
* r9 = processor ID
*/
.align 5
在这个函数中,主要作用是清bss,设置sp到(init_task_union)+8192,
给compat processor_id __machine_arch_type __machine_arch_type cr_alignment 赋值,
后来,在setup_processor和setup_architecture中需要用到这些变量。
__mmap_switched:
adr r3, __switch_data + 4
ldmia r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat
@ sp = stack pointer
str r12, [r2]
mov fp, #0 @ Clear BSS (and zero fp)
1: cmp r4, r5
strcc fp, [r4],#4
bcc 1b
str r9, [r6] @ Save processor ID
str r1, [r7] @ Save machine type
#ifdef CONFIG_ALIGNMENT_TRAP
orr r0, r0, #2 @ ...........A.
#endif
bic r2, r0, #2 @ Clear 'A' bit
stmia r8, {r0, r2} @ Save control register values
b SYMBOL_NAME(start_kernel) 进入start_kernel
/*
* Exception handling. Something went wrong and we can't
* proceed. We ought to tell the user, but since we
* don't have any guarantee that we're even running on
* the right architecture, we do virtually nothing.
* r0 = ascii error character:
* a = invalid architecture
* p = invalid processor
* i = invalid calling convention
*
* Generally, only serious errors cause this.
*/
对出错的处理,打印消息,进入死循环
__error:
#ifdef CONFIG_DEBUG_LL
mov r8, r0 @ preserve r0
adr r0, err_str
bl printascii
mov r0, r8
bl printch
#endif
1: mov r0, r0
b 1b
#ifdef CONFIG_DEBUG_LL
err_str: .asciz "/nError: "
.align
#endif
/*
* Read processor ID register (CP#15, CR0), and look up in the linker-built
* supported processor list. Note that we can't use the absolute addresses
* for the __proc_info lists since we aren't running with the MMU on
* (and therefore, we are not in the correct address space). We have to
* calculate the offset.
*
* Returns:
* r5, r6, r7 corrupted
* r8 = page table flags
* r9 = processor ID
* r10 = pointer to processor structure
*/
在编译生成的内核影像的.proc.info段中保存了处理器类型的信息
下面的代码是在..proc.info段中寻找proc_info_list结构
__lookup_processor_type:
adr r5, 2f
ldmia r5, {r7, r9, r10}
sub r5, r5, r10 @ convert addresses 调整地址
add r7, r7, r5 @ to our address space
add r10, r9, r5
r10-----proc_info_list first addr
r7------proc_info_list end addr
找到合适的proc_info_list,则R10指向了该结构
1: ldmia r10, {r5, r6, r8} @ value, mask, mmuflags
and r6, r6, r9 @ mask wanted bits
teq r5, r6
moveq pc, lr-------------找到了适当的proc_info_list返回
add r10, r10, #36 @ sizeof(proc_info_list) 下一个proc_info_list
cmp r10, r7 是否到达结尾
blt 1b
mov r10, #0 @ unknown processor
mov pc, lr
/*
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
* more information about the __proc_info and __arch_info structures.
*/
2: .long __proc_info_end .proc.info段的END
.long __proc_info_begin .proc.info段的BEGIN
.long 2b
.long __arch_info_begin
.long __arch_info_end
/*
* Lookup machine architecture in the linker-build list of architectures.
* Note that we can't use the absolute addresses for the __arch_info
* lists since we aren't running with the MMU on (and therefore, we are
* not in the correct address space). We have to calculate the offset.
*
* r1 = machine architecture number
* Returns:
* r2, r3, r4 corrupted
* r5 = physical start address of RAM
* r6 = physical address of IO
* r7 = byte offset into page tables for IO
*/
寻找体系结构的类型
__lookup_architecture_type:
adr r4, 2b
ldmia r4, {r2, r3, r5, r6, r7} @ throw away r2, r3
sub r5, r4, r5 @ convert addresses
add r4, r6, r5 @ to our address space
add r7, r7, r5
至此我们得到了.arch.info段的起始地址
r4-----__arch_info_begin
r7-----__arch_info_end
1: ldr r5, [r4] @ get machine type
teq r5, r1 -----------architecture number是否匹配
beq 2f
add r4, r4, #SIZEOF_MACHINE_DESC
cmp r4, r7
blt 1b
mov r7, #0 @ unknown architecture
mov pc, lr-------------error 返回
找到了architecture number返回
2: ldmib r4, {r5, r6, r7} @ found, get results
mov r7, r7, lsr #18 @ pagetable byte offset
mov pc, lr
L_AT91_SF_CIDR: .long 0xfff00000
具体实现寻找体系结构其实和寻找cpu info 是一样的,不过是信息是保存在了.arch.info段
在文件linux/include/asm-arm/mach/arch.h中定义了如下结构
struct machine_desc {
/*
* Note! The first four elements are used
* by assembler code in head-armv.S
*/
unsigned int nr; /* architecture number */
unsigned int phys_ram; /* start of physical ram */
unsigned int phys_io; /* start of physical io */
unsigned int virt_io; /* start of virtual io */
const char *name; /* architecture name */
unsigned int param_offset; /* parameter page */
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
unsigned int reserve_lp0 :1; /* never has lp0 */
unsigned int reserve_lp1 :1; /* never has lp1 */
unsigned int reserve_lp2 :1; /* never has lp2 */
unsigned int soft_reboot :1; /* soft reboot */
const struct tagtable * tagtable; /* tag table */
int tagsize; /* tag table size */
void (*fixup)(struct machine_desc *,
struct param_struct *, char **,
struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
};
/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
#define MACHINE_START(_type,_name) /
const struct machine_desc __mach_desc_##_type /
__attribute__((__section__(".arch.info"))) = { /---------放入.arch.info段
nr: MACH_TYPE_##_type, /
name: _name,
#define MAINTAINER(n)
#define INITIRQ(_func) /
init_irq: _func,
而在linux/arch/arm/mach-***/arch.c文件中定义了你的machine_desc结构
当然我们这里只是定义了machine_desc中的init_irq结构
MACHINE_START(ATMEL, "EB01")
MAINTAINER("Erwin Authried")
INITIRQ(genarch_init_irq)
MACHINE_END
第二个文件linux/include/asm-armnommu/procinfo.h
#ifndef __ASM_PROCINFO_H
#define __ASM_PROCINFO_H
#ifndef __ASSEMBLY__
#include <asm/proc-fns.h>
struct proc_info_item {
const char *manufacturer;
const char *cpu_name;
};
基本上,这是一个定义处理器类型的数据结构,你可以在arch/arm/mm目录下建立关于自己processor的信息,
具体方法是,创建一个proc-myproc.S,当然这个文件修改自proc-arm*.S
struct proc_info_list {
unsigned int cpu_val;
unsigned int cpu_mask;
unsigned long __cpu_mmu_flags; /* used by head-armv.S */
unsigned long __cpu_flush; /* used by head-armv.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
struct proc_info_item *info;
#ifdef MULTI_CPU
struct processor *proc;
#else
void *unused;
#endif
};
#endif /* __ASSEMBLY__ */
#define HWCAP_SWP 1
#define HWCAP_HALF 2
#define HWCAP_THUMB 4
#define HWCAP_26BIT 8 /* Play it safe */
#define HWCAP_FAST_MULT 16
#define HWCAP_FPA 32
#define HWCAP_VFP 64
#define HWCAP_EDSP 128
#endif
第三个文件 linux/arch/armnommu/mm/proc-***.S
这个文件具体是和你的cpu相关的
在这个文件中定义了你的proc_info_list,
你可以定义若干,让程序根据ID扫描,如果专门应用在特定的CPU上,也可以直接指定proc_info_list
.align
.section ".proc.info", #alloc, #execinstr
.type __arm6_proc_info, #object
__arm6_proc_info:
.long 0x41560600
.long 0xfffffff0
.long 0x00000c1e
b __arm6_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_26BIT
.long cpu_arm6_info
.long arm6_processor_functions
.size __arm6_proc_info, . - __arm6_proc_info
在这个文件中定义了你编译好的内核的入口的地址和MACHINE类型,一般是通过条件编译
TEXTADDR = 0x10008000 这个值完全是根据你的cpu和内存状况确定的
MACHINE = your_processor
指定连接文件
LINKFLAGS :=-p -X -T arch/armnommu/vmlinux.lds
替换vmlinux-$(PROCESSOR).lds.in中的TEXTADDR,生成实际需要的连接脚本
arch/armnommu/vmlinux.lds: arch/armnommu/vmlinux-$(PROCESSOR).lds.in dummy
ifeq ($(CONFIG_ARCH_DSC21),y)
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >tmp.ld
@sed 's/DATAADDR/$(DATAADDR)/' <tmp.ld >$@
$(RM) tmp.ld
else
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@
endif
一般连接脚本的前面几句是这样的
ENTRY(stext)---------指定入口
SECTIONS
{
. = $(TEXTADDR);-----设定入口的绝对地址
第一个文件linux/arch/armnommu/kernel/head-armv.S
#define K(a,b,c) ((a) << 24 | (b) << 12 | (c))
#ifndef CONFIG_UCLINUX
设置符号swapper_pg_dir的地址
.globl SYMBOL_NAME(swapper_pg_dir)
.equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000
定义了一个宏,该宏可以获得swapper_pg_dir的地址
.macro pgtbl, reg, rambase
adr /reg, stext
sub /reg, /reg, #0x4000
.endm
/*
* Since the page table is closely related to the kernel start address, we
* can convert the page table base address to the base address of the section
* containing both.
*/
.macro krnladr, rd, pgtable, rambase
bic /rd, /pgtable, #0x000ff000
.endm
#endif
/*
* Kernel startup entry point.
*
* The rules are:
* r0 - should be 0
* r1 - unique architecture number
* MMU - off
* I-cache - on or off
* D-cache - off
*
* See linux/arch/arm/tools/mach-types for the complete list of numbers
* for r1.
*/
.section ".text.init",#alloc,#execinstr
.type stext, #function
请注意,这里是入口点,而且此时r1中应该保存唯一的一个architecture number
ENTRY(stext)
保存r0寄存器的值?????
mov r12, r0
靠~~Rebel.COM NetWinder是什么东东,这个条件编译可以不予理会
#if defined(CONFIG_ARCH_NETWINDER)
。。。。。
#endif
#if defined(CONFIG_ARCH_L7200)
mov r1, #MACH_TYPE_L7200
#elif defined(CONFIG_ARCH_INTEGRATOR)
mov r1, #MACH_TYPE_INTEGRATOR
#elif defined(CONFIG_ARCH_P52)
mov r1, #MACH_TYPE_P52
#elif defined(CONFIG_ARCH_SWARM)
mov r1, #MACH_TYPE_SWARM
#elif defined(CONFIG_ARCH_SAMSUNG)
mov r1, #MACH_TYPE_SAMSUNG
#endif
前面预定义了部分的ARCH,如果匹配的上,R1中包含了architecture number
其实系统复位之后,ARM就处于SVC 模式,而且禁止了FIQ IRQ, 的确如注视所说--make sure
mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode
msr cpsr_c, r0 @ and all irqs disabled
使用的是atmel的arm处理器吗???跳过去吧
#if defined(CONFIG_ARCH_ATMEL)
。。。。。
#endif
又来,使用的是samsumg的arm处理器吗???跳过去吧
#if defined(CONFIG_ARCH_SAMSUNG)
。。。。。
#endif
重点还是分析通用的arm处理器的内容吧
bl __lookup_processor_type ----寻找处理器类型,R10中保存指向表示处理器类型结构的指针
teq r10, #0 @ invalid processor? ----R10 == 0????靠,发生错误
moveq r0, #'p' @ yes, error 'p'
beq __error
bl __lookup_architecture_type----寻找体系结构类型, R7中保存指向表示体系结构类型结构的指针
teq r7, #0 @ invalid architecture?----好像不用说什么了吧
moveq r0, #'a' @ yes, error 'a'
beq __error
跳过,我们一般是会定义CONFIG_UCLINUX这个宏的
__create_page_tables函数建立一个初始化阶段的页表,映射4M内存,当然足够了
#ifndef CONFIG_UCLINUX
bl __create_page_tables
#endif
adr lr, __ret @ return address
看看你的proc_info_list结构,第三个成员变量是一个跳转指令,进行一些CPU初始化的操作
返回则跳到__ret
add pc, r10, #12 @ initialise processor
@ (return control reg)
__switch_data: .long __mmap_switched
.long SYMBOL_NAME(compat)
.long SYMBOL_NAME(__bss_start)
.long SYMBOL_NAME(_end)
.long SYMBOL_NAME(processor_id)
.long SYMBOL_NAME(__machine_arch_type)
.long SYMBOL_NAME(cr_alignment)
.long SYMBOL_NAME(init_task_union)+8192
__ret: ldr lr, __switch_data
执行__switch_data
mov pc, lr
/*
* This code follows on after the page
* table switch and jump above.
*
* r0 = processor control register
* r1 = machine ID
* r9 = processor ID
*/
.align 5
在这个函数中,主要作用是清bss,设置sp到(init_task_union)+8192,
给compat processor_id __machine_arch_type __machine_arch_type cr_alignment 赋值,
后来,在setup_processor和setup_architecture中需要用到这些变量。
__mmap_switched:
adr r3, __switch_data + 4
ldmia r3, {r2, r4, r5, r6, r7, r8, sp}@ r2 = compat
@ sp = stack pointer
str r12, [r2]
mov fp, #0 @ Clear BSS (and zero fp)
1: cmp r4, r5
strcc fp, [r4],#4
bcc 1b
str r9, [r6] @ Save processor ID
str r1, [r7] @ Save machine type
#ifdef CONFIG_ALIGNMENT_TRAP
orr r0, r0, #2 @ ...........A.
#endif
bic r2, r0, #2 @ Clear 'A' bit
stmia r8, {r0, r2} @ Save control register values
b SYMBOL_NAME(start_kernel) 进入start_kernel
/*
* Exception handling. Something went wrong and we can't
* proceed. We ought to tell the user, but since we
* don't have any guarantee that we're even running on
* the right architecture, we do virtually nothing.
* r0 = ascii error character:
* a = invalid architecture
* p = invalid processor
* i = invalid calling convention
*
* Generally, only serious errors cause this.
*/
对出错的处理,打印消息,进入死循环
__error:
#ifdef CONFIG_DEBUG_LL
mov r8, r0 @ preserve r0
adr r0, err_str
bl printascii
mov r0, r8
bl printch
#endif
1: mov r0, r0
b 1b
#ifdef CONFIG_DEBUG_LL
err_str: .asciz "/nError: "
.align
#endif
/*
* Read processor ID register (CP#15, CR0), and look up in the linker-built
* supported processor list. Note that we can't use the absolute addresses
* for the __proc_info lists since we aren't running with the MMU on
* (and therefore, we are not in the correct address space). We have to
* calculate the offset.
*
* Returns:
* r5, r6, r7 corrupted
* r8 = page table flags
* r9 = processor ID
* r10 = pointer to processor structure
*/
在编译生成的内核影像的.proc.info段中保存了处理器类型的信息
下面的代码是在..proc.info段中寻找proc_info_list结构
__lookup_processor_type:
adr r5, 2f
ldmia r5, {r7, r9, r10}
sub r5, r5, r10 @ convert addresses 调整地址
add r7, r7, r5 @ to our address space
add r10, r9, r5
r10-----proc_info_list first addr
r7------proc_info_list end addr
找到合适的proc_info_list,则R10指向了该结构
1: ldmia r10, {r5, r6, r8} @ value, mask, mmuflags
and r6, r6, r9 @ mask wanted bits
teq r5, r6
moveq pc, lr-------------找到了适当的proc_info_list返回
add r10, r10, #36 @ sizeof(proc_info_list) 下一个proc_info_list
cmp r10, r7 是否到达结尾
blt 1b
mov r10, #0 @ unknown processor
mov pc, lr
/*
* Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
* more information about the __proc_info and __arch_info structures.
*/
2: .long __proc_info_end .proc.info段的END
.long __proc_info_begin .proc.info段的BEGIN
.long 2b
.long __arch_info_begin
.long __arch_info_end
/*
* Lookup machine architecture in the linker-build list of architectures.
* Note that we can't use the absolute addresses for the __arch_info
* lists since we aren't running with the MMU on (and therefore, we are
* not in the correct address space). We have to calculate the offset.
*
* r1 = machine architecture number
* Returns:
* r2, r3, r4 corrupted
* r5 = physical start address of RAM
* r6 = physical address of IO
* r7 = byte offset into page tables for IO
*/
寻找体系结构的类型
__lookup_architecture_type:
adr r4, 2b
ldmia r4, {r2, r3, r5, r6, r7} @ throw away r2, r3
sub r5, r4, r5 @ convert addresses
add r4, r6, r5 @ to our address space
add r7, r7, r5
至此我们得到了.arch.info段的起始地址
r4-----__arch_info_begin
r7-----__arch_info_end
1: ldr r5, [r4] @ get machine type
teq r5, r1 -----------architecture number是否匹配
beq 2f
add r4, r4, #SIZEOF_MACHINE_DESC
cmp r4, r7
blt 1b
mov r7, #0 @ unknown architecture
mov pc, lr-------------error 返回
找到了architecture number返回
2: ldmib r4, {r5, r6, r7} @ found, get results
mov r7, r7, lsr #18 @ pagetable byte offset
mov pc, lr
L_AT91_SF_CIDR: .long 0xfff00000
具体实现寻找体系结构其实和寻找cpu info 是一样的,不过是信息是保存在了.arch.info段
在文件linux/include/asm-arm/mach/arch.h中定义了如下结构
struct machine_desc {
/*
* Note! The first four elements are used
* by assembler code in head-armv.S
*/
unsigned int nr; /* architecture number */
unsigned int phys_ram; /* start of physical ram */
unsigned int phys_io; /* start of physical io */
unsigned int virt_io; /* start of virtual io */
const char *name; /* architecture name */
unsigned int param_offset; /* parameter page */
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
unsigned int reserve_lp0 :1; /* never has lp0 */
unsigned int reserve_lp1 :1; /* never has lp1 */
unsigned int reserve_lp2 :1; /* never has lp2 */
unsigned int soft_reboot :1; /* soft reboot */
const struct tagtable * tagtable; /* tag table */
int tagsize; /* tag table size */
void (*fixup)(struct machine_desc *,
struct param_struct *, char **,
struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
};
/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
#define MACHINE_START(_type,_name) /
const struct machine_desc __mach_desc_##_type /
__attribute__((__section__(".arch.info"))) = { /---------放入.arch.info段
nr: MACH_TYPE_##_type, /
name: _name,
#define MAINTAINER(n)
#define INITIRQ(_func) /
init_irq: _func,
而在linux/arch/arm/mach-***/arch.c文件中定义了你的machine_desc结构
当然我们这里只是定义了machine_desc中的init_irq结构
MACHINE_START(ATMEL, "EB01")
MAINTAINER("Erwin Authried")
INITIRQ(genarch_init_irq)
MACHINE_END
第二个文件linux/include/asm-armnommu/procinfo.h
#ifndef __ASM_PROCINFO_H
#define __ASM_PROCINFO_H
#ifndef __ASSEMBLY__
#include <asm/proc-fns.h>
struct proc_info_item {
const char *manufacturer;
const char *cpu_name;
};
基本上,这是一个定义处理器类型的数据结构,你可以在arch/arm/mm目录下建立关于自己processor的信息,
具体方法是,创建一个proc-myproc.S,当然这个文件修改自proc-arm*.S
struct proc_info_list {
unsigned int cpu_val;
unsigned int cpu_mask;
unsigned long __cpu_mmu_flags; /* used by head-armv.S */
unsigned long __cpu_flush; /* used by head-armv.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
struct proc_info_item *info;
#ifdef MULTI_CPU
struct processor *proc;
#else
void *unused;
#endif
};
#endif /* __ASSEMBLY__ */
#define HWCAP_SWP 1
#define HWCAP_HALF 2
#define HWCAP_THUMB 4
#define HWCAP_26BIT 8 /* Play it safe */
#define HWCAP_FAST_MULT 16
#define HWCAP_FPA 32
#define HWCAP_VFP 64
#define HWCAP_EDSP 128
#endif
第三个文件 linux/arch/armnommu/mm/proc-***.S
这个文件具体是和你的cpu相关的
在这个文件中定义了你的proc_info_list,
你可以定义若干,让程序根据ID扫描,如果专门应用在特定的CPU上,也可以直接指定proc_info_list
.align
.section ".proc.info", #alloc, #execinstr
.type __arm6_proc_info, #object
__arm6_proc_info:
.long 0x41560600
.long 0xfffffff0
.long 0x00000c1e
b __arm6_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_26BIT
.long cpu_arm6_info
.long arm6_processor_functions
.size __arm6_proc_info, . - __arm6_proc_info