MINI2440 QEMU 的 eCos 啟動分析

2021-05-24 12:26:07 字數 4924 閱讀 5621

1.總覽一下ecos的啟動方式

ecos目前預設的啟動方式有三種,ram,rom,romram。

ram啟動的意思就是直接在ram中執行,這種方式一般用於除錯,不做必要的硬體初始化。

rom啟動方式的意思是在rom中直接執行,當然一定要支援xip的norflash才可以。

romram的啟動方式的意思是,rom中開始執行然後把所有的**複製到ram中繼續執行。

2.mini2440 qemu的啟動方式的選擇

mini2440中目前還沒有實現nor和nand flash,(雖然nand的**加了,但是裡面註名工作不是很正常,我姑且認為不能用吧)

所以,我們必須在ram中執行ecos,並且還要完成硬體的初始化任務,這也就有了接下來的一大串的問題。

3.mini2440 qemu的啟動方式分析

我加點注視來解釋下面的romram啟動**:

// create mmu tables

raw_led_macro 3

bl      hal_mmu_init

上面的語句會建立mmu頁表,會把0x30000000對映到0位址,0位址對映到0x80000000

raw_led_macro 4

// enable mmu

ldr     r2,=10f

#ifdef cyg_hal_startup_romram

ldr     r1,=__exception_handlers

ldr r9,=0x80000000

sub     r1,r2,r1

add     r2,r9,r1        // r9 has rom offset

這裡比較重要,首先我們必須知道我們目前還執行在rom中,經過這兩條語句,我們可以確定r2裡面存放的是10這個標號相對於

0x80000000的位址。

#endif        

ldr        r1,=mmu_control_init|mmu_control_m

mcr        mmu_cp,0,r1,mmu_control,c0

mov        pc,r2    /* change address spaces */

在這裡我們看到,mmu被對映後我們把nor的位址從0對映到了0x80000000,所以我們跳到r2時,就是mmu對映以後在nor中

的執行效果。

nopnop

nop10:

raw_led_macro 5

#ifdef cyg_hal_startup_romram

mov     r0,r9                     // relocate flash/rom to ram

ldr     r1,=__exception_handlers  // ram base & length

ldr     r2,=__rom_data_end

20:     ldr     r3,[r0],#4

str     r3,[r1],#4

cmp     r1,r2

bne     20b

ldr     r0,=30f

mov     pc,r0

這部分**就比較簡單,把rom中的**複製到ram中,然後跳過去。

nopnop

nopnop

30:             

#endif

4. vector的問題

現在來看我們的qemu的啟動,ecos的乙個特點是執行位置只是相對於啟動位置,所以無論怎樣我們的**第一條是可以在ram中跑的。

所以我們讓romram**直接跑在ram中可以做硬體的初始化。

接下來的乙個問題是,如何保證中斷向量工作正常,我們再看兩段arm平台初始化的**吧,(雖然比較枯燥)

這部分叫fix_vectors

.section ".fixed_vectors"

// interrupt/exception vsr pointers

.globl  hal_vsr_table

hal_vsr_table:

.rept   8               

.long   0

.endr

.globl  hal_dram_size

hal_dram_size:  

.long   0

// what, if anything, hal_dram_type means is up to the platform

.globl  hal_dram_type

hal_dram_type:  

.long   0

這部分是vectors複製

// reset software interrupt pointer

ldr     r0,=cyghwr_hal_vector_table_base           // move vectors

ldr     r1,.__exception_handlers

#if defined(cyg_hal_startup_ram) && /

!defined(cygdbg_hal_debug_gdb_include_stubs)

cmp     r7,#cpsr_supervisor_mode

beq     10f

#endif

ldr     r2,[r1,#hal_arm_swi_vector_addr]   // software interrupt

str     r2,[r0,#hal_arm_swi_vector_addr]

10:ldr     r2,[r1,#hal_arm_irq_vector]   // irq

str     r2,[r0,#hal_arm_irq_vector]

ldr     r2,[r1,#hal_arm_irq_vector_addr]

str     r2,[r0,#hal_arm_irq_vector_addr]

ldr     r2,[r1,#hal_arm_fiq_vector]   // fiq

str     r2,[r0,#hal_arm_fiq_vector]

ldr     r2,[r1,#hal_arm_fiq_vector_addr]

str     r2,[r0,#hal_arm_fiq_vector_addr]

ldr     r2,[r1,#hal_arm_prefetch_vector]   // abort (prefetch)

str     r2,[r0,#hal_arm_prefetch_vector]

ldr     r2,[r1,#hal_arm_prefetch_vector_addr]   

str     r2,[r0,#hal_arm_prefetch_vector_addr]

ldr     r2,[r1,#hal_arm_abort_vector]   // abort (data)

str     r2,[r0,#hal_arm_abort_vector]

ldr     r2,[r1,#hal_arm_abort_vector_addr]

str     r2,[r0,#hal_arm_abort_vector_addr]

這個是link檔案

#include

memory

ram  : origin = 0, length = 0x8000000

sram : origin = 0x40000000, length = 0x1000

sections

sections_begin

section_fixed_vectors (ram, 0x20, lma_eq_vma)

section_rom_vectors (ram, 0x8000, lma_eq_vma)

section_relocs (ram, align (0x1), lma_eq_vma)

section_text (ram, align (0x4), lma_eq_vma)

section_fini (ram, align (0x4), lma_eq_vma)

section_rodata (ram, align (0x4), lma_eq_vma)

section_rodata1 (ram, align (0x4), lma_eq_vma)

section_got (ram, align (0x4), lma_eq_vma)

section_fixup (ram, align (0x4), lma_eq_vma)

section_gcc_except_table (ram, align (0x4), lma_eq_vma)

section_data (ram, align (0x4), lma_eq_vma)

section_bss (ram, align (0x4), lma_eq_vma)

cyg_label_defn(__heap1) = align (0x8);

sections_end

看到了吧,在我們的ram中留了一塊空地叫fix_vector,我們在啟動的時候可以把vector複製過去,然後mmu_init以後

這部分剛好滿足arm920t的中斷向量位址。慶幸吧,沒修改這裡就能用了

5.**複製的問題

最後乙個問題是,既然我們本來就在ram中,我們就不用在做**複製和nor重新映**,我們只要定義新的qemu啟動方式就可以旁路掉

這兩部分**了。

最後只要qemu執行的時候載入elf格式的檔案到0x30000000就可以正常的執行**了。

(三)MINI2440的時鐘配置

時鐘源 om 3 2 選擇時鐘源 mpll main pll 主鎖相環 在mini2440開發板中,1 nreset為低時復位晶元,延時一段時間等待電壓穩定後,nreset才輸出高電平,cpu才可以工作。2 根據om 3 2 的值,選擇輸入時鐘源,在mini2440中,輸入時鐘源是12mhz的晶振 ...

基於mini2440的RTC讀寫(裸機)

很多處理器都有rtc實時時鐘功能,s3c2440也提供了這個功能,其功能主要是 實時時鐘 鬧鐘 tick中斷等。rtc的操作比較簡單。讀寫時rtccon最低位應設定為1,不讀寫時設定為0以免誤修改rtc相應暫存器。bcdsec,bcdmin,bcdhour,bcdday,bcddate,bcdmon...

Ubuntu下mini2440的系統燒寫

考完試,沒事幹,今晚拿出曾封已久的mini2440開發板出來除錯,由於本人用的是筆記本,接上usb轉串列埠,開啟超級終端xshell,連線時無法連線串列埠,就像沒有接usb轉串列埠一樣,折騰了半天還是那樣,最後藍屏讓我對windows失望。我的電腦是acer之前就有這種情況!碰巧在網上看到可以在ub...