新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > u-boot引導VxWorks分析

        u-boot引導VxWorks分析

        作者: 時間:2016-09-12 來源:網絡 收藏

        準備工作

        本文引用地址:http://www.104case.com/article/201609/303419.htm

        在定義CONFIG_MP的情況下,會依次調用init_sequence_r里定義的初始化函數

        執行路徑為:board_init_r() -> cpu_init_r() -> setup_mp()

        setup_mp()做以下操作:

        調用determine_mp_bootpg(),使用(2G-4K)的地址作為bootpg的地址

        調用如下代碼,獲得__bootpg_addr和__spin_table_addr的物理地址

        并將這些地址填充到物理內存當中,供啟動slave core時,release.s去使用(在該core上創建TLB)

        /*

        * Store the bootpg's cache-able half address for use by secondary

        * CPU cores to continue to boot

        */

        __bootpg_addr = (u32)virt_to_phys(__second_half_boot_page);

        /* Store spin table's physical address for use by secondary cores */

        __spin_table_addr = (u32)get_spin_phys_addr();

        調用find_tlb_idx((void *)CONFIG_BPTR_VIRT_ADDR, 1),

        查找目前配置的TLB entry一個TLB當中,覆蓋了bootpg的virtual addr的TLB

        - 若找到,則將該TLB使無效,并重配一個TLB(vir:CONFIG_BPTR_VIRT_ADDR -> phy:bootpg)

        - 若未找到,則無法啟動slave core

        將bootpg的代碼:__secondary_start_page 復制到 CONFIG_BPTR_VIRT_ADDR

        調用plat_mp_up()

        - 查找當前bootpg使用的LAW,由于當前的bootpg放置在內存中,因此LAW的target_id對應于DDR

        - 設置LAW為對應的屬性到bstrar; /* Boot space translation attributes */

        - 關閉目標CPU core的time base

        - 設置brrl為啟動的目標CPU core

        - ... //此時應該目標CPU core已經從hold_off狀態激活, 并在對應的CPU core的spin table寫1

        - 等待目標CPU core是否已經啟動完成,否則打印timeout

        - 重新使能CPU core的time base

        目標CPU core上運行的bootpg(4k)的流程:

        4k的代碼范圍:start: __secondary_start_page end: __secondary_reset_vector

        spin_table對應的virtual start: __spin_table end:__spin_table_end

        spin_table的大小:CONFIG_MAX_CPUS * ENTRY_SIZE

        - 首先是4字節的跳轉,從__secondary_reset_vector執行:b __secondary_start_page

        - 使無效L1 指令和數據 cache

        - 建立新的TLB entry,使之可以訪問__bootpg_addr和__spin_table_addr

        - 代碼跳轉到__bootpg_addr物理地址去運行,即運行:__second_half_boot_page

        - 獲取到__spin_table,然后對目標CPU core所屬的BOOT_ENTRY_ADDR_LOWER位域賦值為1

        li r8,1

        msync

        stw r8,ENTRY_ADDR_LOWER(r10)

        - 相當于table[cpu * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER] = 1

        - 至此目標CPU core進入spin loop狀態,等待core0再次release core 0一旦執行cpu 1 release 0x201002e8 2 1 1

        即對目標CPU core所屬的BOOT_ENTRY_ADDR_LOWER位域填充cpu-release-addr的值

        /* spin waiting for addr */

        3:

        lwz r4,ENTRY_ADDR_LOWER(r10)

        andi. r11,r4,1

        bne 3b

        isync

        - 目標CPU core再將它所對應的的BOOT_ENTRY_ADDR_LOWER位域賦值為3

        /* mark the entry as released */

        li r8,3

        stw r8,ENTRY_ADDR_LOWER(r10)

        - 相當于table[cpu * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER] = 3

        命令

        bootm -> do_bootm() -> do_bootm_states() -> bootm_os_get_boot_func()

        其中bootm_os_get_boot_func()會去根據bootm_headers所指向的加載目標image的OS類型

        對應于boot_os[os],該數組保存加載相應各個OS類型的函數指針

        對于來說,就是do_bootm_vxworks()

        - 如果定義了CONFIG_FIT,則do_bootm_vxworks()函數會先去判斷image的頭信息是否有效 然后執行do_bootvx_fdt(images)

        - 如果未定義CONFIG_FIT,則直接執行do_bootvx_fdt(images)

        do_bootvx_fdt(images) 會依次調用下面的函數:

        -> boot_prep_vxworks(images)

        -> boot_jump_vxworks(images)

        boot_prep_vxworks(images)做以下操作:

        1. 查找FDT里/memory這個節點,若沒有找到,則會創建該節點,

        設置起始地址為:gd->bd->bi_memstart

        設置大小為:gd->bd->bi_memsize

        2. 執行ft_fixup_cpu(),在定義了CONFIG_OF_LIBFDT的情況下:

        調用get_spin_phys_addr(),獲得__spin_table的物理地址,賦值給spin_tbl_addr

        調用determine_mp_bootpg(),使用(2G-4K)的地址作為bootpg的地址

        該函數查找FDT里device_type為cpu這一項,獲取reg代表的thread的值

        對于E6500,thread/2即為物理的core的值,作為phys_cpu_id,

        根據val = phys_cpu_id * SIZE_BOOT_ENTRY + spin_tbl_addr;

        將enable_method設置為spin-table;

        將cpu-release-addr的值賦值為val

        3. 執行ft_fixup_num_cores()

        cpu_numcores() -> hweight32(cpu_mask())

        其中cpu_mask() -> compute_ppc_cpumask()返回cpu的cpu->mask

        hweight32()會返回32bit的cpu->mask當中有多少個bit被置位

        則cpu_numcores()返回當前cpu上有多少個core

        將cpu core的信息填充到FDT里device_type為cpu這一項

        4. 執行flush_cache,將data cache里的dirty數據(修改的FDT數據)刷新到DDR

        flush_cache((unsigned long)images->ft_addr, images->ft_len);

        boot_jump_vxworks(images)做以下操作:

        /* PowerPC boot interface conforms to the ePAPR standard

        * general purpuse registers:

        *

        * r3: Effective address of the device tree image

        * r4: 0

        * r5: 0

        * r6: ePAPR magic value

        * r7: shall be the size of the boot IMA in bytes

        * r8: 0

        * r9: 0

        * TCR: WRC = 0, no watchdog timer reset will occur

        */

        ((void (*)(void *, ulong, ulong, ulong,

        ulong, ulong, ulong))images->ep)(images->ft_addr,

        0, 0, EPAPR_MAGIC, getenv_bootm_mapsize(), 0, 0);

        激活的步驟

        => tftpboot 0x20100000 vxWorks.st.bin cpu 1 release 0x201002e8 2 1 1

        步驟1:

        tftpboot -> do_tftpb() -> netboot_common() -> bootm_maybe_autostart() -> do_bootm()

        步驟2:

        cpu -> cpu_cmd() -> cpu_release()

        cpu release [args]

        - Release cpu at with [args]

        [args] :

        pir - processor id (if writeable)

        r3 - value for gpr 3

        r6 - value for gpr 6

        Use '-' for any arg if you want the default value.

        Default for r3 is and r6 is 0

        When cpu is released r4 and r5 = 0.

        r7 will contain the size of the initial mapped area

        cpu_release()做以下操作:

        table[BOOT_ENTRY_ADDR_UPPER] = (u32)(boot_addr >> 32);

        /* ensure all table updates complete before final address write */

        eieio();

        table[BOOT_ENTRY_ADDR_LOWER] = (u32)(boot_addr 0xffffffff);



        關鍵詞: u-boot VxWorks

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 德兴市| 五大连池市| 平阴县| 蕉岭县| 天柱县| 金门县| 波密县| 朝阳市| 康定县| 翁牛特旗| 天门市| 陕西省| 尼木县| 庄浪县| 元江| 女性| 平凉市| 共和县| 北海市| 安顺市| 平阴县| 仁化县| 吉安市| 尤溪县| 静乐县| 华坪县| 漳浦县| 化隆| 和平县| 静海县| 吉水县| 阜康市| 星子县| 广南县| 枣强县| 上杭县| 三亚市| 北海市| 紫阳县| 腾冲县| 秦安县|