ecos代码分析(2)

228         bl      hal_mmu_init

此前内存初始化好了,sp也设置好了,可以运行C程序

    170 void

    171 hal_mmu_init(void)

    172 {

    173     unsigned long ttb_base = SMDK2410_SDRAM_PHYS_BASE + 0x4000;

    174     unsigned long i;

    175

    176     // Set the TTB register

    177     asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base) );

    178

    179     // Set the Domain Access Control Register

    180     i = ARM_ACCESS_TYPE_MANAGER(0)    |

    181         ARM_ACCESS_TYPE_NO_ACCESS(1)  |

    182         ARM_ACCESS_TYPE_NO_ACCESS(2)  |

    183         ARM_ACCESS_TYPE_NO_ACCESS(3)  |

    184         ARM_ACCESS_TYPE_NO_ACCESS(4)  |

    185         ARM_ACCESS_TYPE_NO_ACCESS(5)  |

    186         ARM_ACCESS_TYPE_NO_ACCESS(6)  |

    187         ARM_ACCESS_TYPE_NO_ACCESS(7)  |

    188         ARM_ACCESS_TYPE_NO_ACCESS(8)  |

    189         ARM_ACCESS_TYPE_NO_ACCESS(9)  |

    190         ARM_ACCESS_TYPE_NO_ACCESS(10) |

    191         ARM_ACCESS_TYPE_NO_ACCESS(11) |

    192         ARM_ACCESS_TYPE_NO_ACCESS(12) |

    193         ARM_ACCESS_TYPE_NO_ACCESS(13) |

    194         ARM_ACCESS_TYPE_NO_ACCESS(14) |

    195         ARM_ACCESS_TYPE_NO_ACCESS(15);

    196     asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) );

    197

    198     // First clear all TT entries - ie Set them to Faulting

    199     memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);

    200

    201     // Memory layout after MMU is turned on

    202     //

    203     //   SDRAM_BASE_ADDRESS:     0x00000000,  64M

    204     //   SRAM_BASE_ADDRESS:      0x40000000,   4K

    205     //   SFR_BASE_ADDRESS:       0x48000000, 512M

    206     //   FLASH_BASE_ADDRESS:     0x80000000,   2M

    207

    208  //Actual Virtual Size Attributes                                       Function

    209 //Base Base  MB cached? buffered? access permissions

    210     //             xxx00000  xxx00000

    211     X_ARM_MMU_SECTION(0x000,  0x800,    2,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Flash

    212     X_ARM_MMU_SECTION(0x300,  0x000,   64,  ARM_CACHEABLE,   ARM_BUFFERABLE,  ARM_ACCESS_PERM_RW_RW); // SDRAM

    213     X_ARM_MMU_SECTION(0x400,  0x400,    1,  ARM_CACHEABLE,   ARM_BUFFERABLE,  ARM_ACCESS_PERM_RW_RW); // SRAM

    214     X_ARM_MMU_SECTION(0x480,  0x480,  512,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // SFRs

    215     X_ARM_MMU_SECTION(0x300,  0x300,   64,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Raw SDRAM

    216 }

还有

#define SMDK2410_SDRAM_PHYS_BASE         0x30000000

#define SMDK2410_SDRAM_VIRT_BASE         0x00000000

 

#define SMDK2410_FLASH_PHYS_BASE         0x00000000

#define SMDK2410_FLASH_VIRT_BASE         0x80000000

内存从0x30000000开始的

ttb_base=0x30004000translation table base,虚拟地址到实地址内存映射表的基地址

177行,ttb_base要存放在cp15reg2

196行,对section的进入权限控制,存放在cp15reg3

    142 #define X_ARM_MMU_SECTION(abase,vbase,size,cache,buff,access)      \

    143     { int i; int j = abase; int k = vbase;                         \

    144       for (i = size; i > 0 ; i--,j++,k++)                          \

    145       {                                                            \

    146         ARM_MMU_SECTION(ttb_base, j, k, cache, buff, access);      \

    147       }                                                            \

148     }

    125 #define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base,              \

    126                         cacheable, bufferable, perm)                      \

    127     CYG_MACRO_START                                                       \

    128         register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc;               \

    129                                                                           \

    130         desc.word = 0;                                                    \

    131         desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID;                 \

    132         desc.section.imp = 1;                                             \

    133         desc.section.domain = 0;                                          \

    134         desc.section.c = (cacheable);                                     \

    135         desc.section.b = (bufferable);                                    \

    136         desc.section.ap = (perm);                                         \

    137         desc.section.base_address = (actual_base);                        \

    138         *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) \

    139                             = desc.word;                                  \

    140     CYG_MACRO_END

将空间划分为以section为单位,即1M每个。

开始填充每个descriptor,按照手册上的位图填好就完事。

    120 #define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \

121    (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2))

struct ARM_MMU_FIRST_LEVEL_SECTION {

    int id : 2;

    int b : 1;

    int c : 1;

    int imp : 1;

    int domain : 4;

    int sbz0 : 1;

    int ap : 2;

    int sbz1 : 8;

    int base_address : 12;

};

为了有个直观的影响,现在把填好的ttb这个表列出来

 

address

b_addr:12

sbz1:1

ap:2

sbz0:1

domain:4

imp:1

c:1

b:1

id:2

0x30004000

0x300

0

3

0

0

1

1

1

2

0

3

0

0

1

1

1

2

0x300040fc

0x33f

0

3

0

0

1

1

1

2

 

 

 

 

 

 

 

 

 

 

0x30004c00

0x300

0

3

0

0

1

0

0

2

0

3

0

0

1

0

0

2

0x30004cfc

0x33f

0

3

0

0

1

0

0

2

 

 

 

 

 

 

 

 

 

 

0x30005000

0x400

0

3

0

0

1

1

1

2

 

 

 

 

 

 

 

 

 

 

0x30005200

0x480

0

3

0

0

1

0

0

2

0

3

0

0

1

0

0

2

0x300059fc

0x67f

0

3

0

0

1

0

0

2

 

 

 

 

 

 

 

 

 

 

0x30006000

0x000

0

3

0

0

1

0

0

2

0x30006004

0x001

0

3

0

0

1

0

0

2

 

 

 

 

 

 

 

 

 

 

 

< hal/arm/arch/v3_0/src/vectors.S >

    464         // Call platform specific hardware initialization

    465         bl      hal_hardware_init

    494         // Run through static constructors

    495         bl      cyg_hal_invoke_constructors

    499         // This starts up the eCos kernel

500 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK

    501         ldr     r1,=__startup_stack

    502         mov     sp,r1

    503 #endif

    504         bl      cyg_start

465

         <hal/arm/arm9/var/v3_0/src/arm9_misc.c>

     67 void hal_hardware_init(void)

     68 {

     69     // Perform any platform specific initializations

     70     plf_hardware_init();

     72     // Set up eCos/ROM interfaces

     73     hal_if_init();

     75 #ifndef CYG_HAL_STARTUP_RAM

     76     // Invalidate caches

     77     HAL_DCACHE_INVALIDATE_ALL();

     78     HAL_ICACHE_INVALIDATE_ALL();

     79 #endif

     80     // Enable caches

     81 #ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP

     82     HAL_DCACHE_ENABLE();

     83 #endif

     84 #ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP

     85     HAL_ICACHE_ENABLE();

     86 #endif

     87 }

70

    306 void

    307 plf_hardware_init(void)

    308 {

    309     HAL_WRITE_UINT32(INTMOD, 0x0);                     //All=IRQ mode

    310     HAL_WRITE_UINT32(INTMSK, BIT_ALLMSK);              //All interrupt is masked.

    311     HAL_WRITE_UINT32(INTSUBMSK, BIT_SUB_ALLMSK);       //All sub-interrupt is masked.

    313     port_init();

    315     // Initialize real-time clock (for delays, etc, even if kernel doesn't use it)

    316     hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);

    317 }

                   313行,设置gpio

                   316行,设置时钟

73

          hal_if_init()

                   :: hal_virtual_vector_table[]初始化为空操作

hal_virtual_vector_table[]是个全局的系统调用列表,每个的具体功能如下

          // Main calling interface table. Will be assigned a location by the

// linker script. Both ROM and RAM startup applications will know about

// the location.

#define CYGNUM_CALL_IF_VERSION                    0

#define CYGNUM_CALL_IF_available_1                1

#define CYGNUM_CALL_IF_available_2                2

#define CYGNUM_CALL_IF_available_3                3

#define CYGNUM_CALL_IF_KILL_VECTOR                4

#define CYGNUM_CALL_IF_CONSOLE_PROCS              5

#define CYGNUM_CALL_IF_DEBUG_PROCS                6

#define CYGNUM_CALL_IF_available_7                7

#define CYGNUM_CALL_IF_available_8                8

#define CYGNUM_CALL_IF_available_9                9

#define CYGNUM_CALL_IF_available_10               10

#define CYGNUM_CALL_IF_available_11               11

#define CYGNUM_CALL_IF_SET_DEBUG_COMM             12

#define CYGNUM_CALL_IF_SET_CONSOLE_COMM           13

#define CYGNUM_CALL_IF_MONITOR_VERSION            14

#define CYGNUM_CALL_IF_DBG_SYSCALL                15

#define CYGNUM_CALL_IF_RESET                      16

#define CYGNUM_CALL_IF_CONSOLE_INTERRUPT_FLAG     17

#define CYGNUM_CALL_IF_DELAY_US                   18

#define CYGNUM_CALL_IF_DBG_DATA                   19

#define CYGNUM_CALL_IF_FLASH_CFG_OP               20

#define CYGNUM_CALL_IF_MONITOR_RETURN             21

#define CYGNUM_CALL_IF_FLASH_FIS_OP               22

#define CYGNUM_CALL_IF_FLASH_FIS_OP2              23

#define CYGNUM_CALL_IF_LAST_ENTRY                 CYGNUM_CALL_IF_FLASH_FIS_OP2

#define CYGNUM_CALL_IF_INSTALL_BPT_FN             35

#define CYGNUM_CALL_IF_TABLE_SIZE                 64

                   :: 初始化该数组的每个成员

                   è cyg_hal_plf_comms_init()

                            è cyg_hal_plf_serial_init()

                                      :: initiate serial and call CYGNUM_CALL_IF_SET_CONSOLE_COMM set console

                                      è cyg_hal_plf_serial_init_channel()

                                               :: initiate the serial channel

                   :: 此后串口应该设置好了,可以进行输出

 

hal_hardware_init()

                   è plf_hardware_init()

                   è hal_if_init()

                   è HAL_DCACHE_INVALIDATE_ALL()

                            :: dcache invalidate

è HAL_ICACHE_INVALIDATE_ALL()

         :: icache invalidate

è HAL_DCACHE_ENABLE()

         :: dcache enable

è HAL_ICACHE_ENABLE()

         :: icache enable

cyg_hal_invoke_constructors()

                   :: 运行指令segment内的函数,但是没有找到相应的宏定义

然后,sp指向__startup_stack

跳转到cyg_start()运行


原文见:http://blog.sina.com.cn/s/blog_559f6ffc0100mjlq.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值