色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

多核CPU的啟動方式

科技綠洲 ? 來源:一起學嵌入式 ? 作者:一起學嵌入式 ? 2023-06-22 10:04 ? 次閱讀

工作中遇到的多核 ARM CPU 越來越多,總結分享一些多核啟動的知識,希望能幫助更多小伙伴。

在 ARM64 架構下如果想要啟動多核,有 spin-table 和 psci 兩種方式,下面針對這兩種啟動流程進行分析。

代碼版本

  • boot-wrapper-aarch64 version : 28932c41e14d730b8b9a7310071384178611fb32
  • linux v5.14

多核 CPU 的啟動方式

嵌入式系統的啟動的基本流程是先運行 bootloader ,然后由 bootloader 引導啟動 kernel,這里無論啟動的是 rt-thread 或者是 linux 原理都是一樣的。

上電后所有的 CPU 都會從 bootrom 里面開始執行代碼,為了防止并發造成的一些問題,需要將除了 primary cpu 以外的 cpu 攔截下來,這樣才能保證啟動的順序是可控的。

spin-table 啟動方法

在啟動的過程中,bootloader 中有一道柵欄,它攔住了除了 cpu0 外的其他 cpucpu0 直接往下運行,進行設備初始化以及運行 Kernel。其他 cpu0 則在柵欄外進入睡眠狀態。

cpu0 在初始化 smp 的時候,會在 cpu-release-addr 里面填入一個地址并喚醒其他 cpu。這時睡眠的 cpu 接收到信號,醒來的時候會先檢查 cpu-release-addr 這個地址里面的數據是不是有效。如果該地址是有效的(非 0 ),意味著自己需要真正開始啟動了,接下來他會跳轉到。

下面我們看看 arm64 里面的實現,在 arch/arm64/boot/dts/xxx.dts 中有如下描述:

1cpu@0 {
2    device_type = "cpu";
3    compatible = "arm,armv8";
4    reg = < 0x0 0x0="" >;
5    enable-method = "spin-table"; /* 選擇使用 spin-table 方式啟動  */
6    cpu-release-addr = < 0x0 0x8000fff8="" >;
7};

arch/arm64/kernel/smp_spin_table.c 中處理了向其他 cpu 發送信號的方法:

1、先是獲取 release_addr 的虛擬地址

2、向該地址寫入從 cpu 的入口地址

3、通過 sev() 指令喚醒其他 cpu

1static int smp_spin_table_cpu_prepare(unsigned int cpu)
 2{
 3    __le64 __iomem *release_addr;
 4    phys_addr_t pa_holding_pen = __pa_symbol(function_nocfi(secondary_holding_pen));
 5
 6    if (!cpu_release_addr[cpu])
 7        return -ENODEV;
 8
 9    /*
10     * The cpu-release-addr may or may not be inside the linear mapping.
11     * As ioremap_cache will either give us a new mapping or reuse the
12     * existing linear mapping, we can use it to cover both cases. In
13     * either case the memory will be MT_NORMAL.
14     */
15    release_addr = ioremap_cache(cpu_release_addr[cpu],
16                     sizeof(*release_addr));
17    if (!release_addr)
18        return -ENOMEM;
19
20    /*
21     * We write the release address as LE regardless of the native
22     * endianness of the kernel. Therefore, any boot-loaders that
23     * read this address need to convert this address to the
24     * boot-loader's endianness before jumping. This is mandated by
25     * the boot protocol.
26     */
27    writeq_relaxed(pa_holding_pen, release_addr);
28    dcache_clean_inval_poc((__force unsigned long)release_addr,
29                (__force unsigned long)release_addr +
30                    sizeof(*release_addr));
31
32    /*
33     * Send an event to wake up the secondary CPU.
34     */
35    sev();
36
37    iounmap(release_addr);
38
39    return 0;
40}

Bootloader 部分以 boot-wrapper-aarch64 中的代碼做示例,非主 CPU 會輪詢檢查 mbox(其地址等同cpu-release-addr)中的值,當其值為 0 的時候繼續睡眠,否則就跳轉到內核執行,代碼如下所示:

1/**
 2 * Wait for an address to appear in mbox, and jump to it.
 3 *
 4 * @mbox: location to watch
 5 * @invalid: value of an invalid address, 0 or -1 depending on the boot method
 6 * @is_entry: when true, pass boot parameters to the kernel, instead of 0
 7 */
 8void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry)
 9{
10    unsigned long addr = invalid;
11
12    while (addr == invalid) {
13        wfe();
14        addr = *mbox;
15    }
16
17    if (is_entry)
18#ifdef KERNEL_32
19        jump_kernel(addr, 0, ~0, (unsigned long)&dtb, 0);
20#else
21        jump_kernel(addr, (unsigned long)&dtb, 0, 0, 0);
22#endif
23
24    jump_kernel(addr, 0, 0, 0, 0);
25
26    unreachable();
27}
28
29/**
30 * Primary CPU finishes platform initialisation and jumps to the kernel.
31 * Secondaries are parked, waiting for their mbox to contain a valid address.
32 *
33 * @cpu: logical CPU number
34 * @mbox: location to watch
35 * @invalid: value of an invalid address, 0 or -1 depending on the boot method
36 */
37void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
38               unsigned long invalid)
39{
40    if (cpu == 0) {
41        init_platform();
42
43        *mbox = (unsigned long)&entrypoint;
44        sevl();
45        spin(mbox, invalid, 1);
46    } else {
47        *mbox = invalid;
48        spin(mbox, invalid, 0);
49    }
50
51    unreachable();
52}

PSCI 啟動方法

另外一種 enable-method 就是 PSCI,依舊先從 kernel 開始分析。先看 arch/arm64/boot/dts/mediatek/mt8173.dtsi 文件,里面 cpu 節點選擇了PSCI 的方法:

1cpu0: cpu@0 {
2    compatible = "arm,cortex-a53";
3    device_type = "cpu";
4    enable-method = "psci";    /* 啟動方式選擇 PSCI */
5    operating-points-v2 = < &cpu_opp_table >;
6    reg = < 0x0 >;
7    cpu-idle-states = < &CPU_SLEEP_0 >;
8};

并且有一個 PSCI 的節點:

1psci {
2    compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
3    method = "smc";
4    cpu_suspend   = < 0x84000001 >;
5    cpu_off          = < 0x84000002 >;
6    cpu_on          = < 0x84000003 >;
7};

PSCI 中的節點詳細說明請參考文檔:

kernel/Documentation/devicetree/bindings/arm/psci.txt。

在此僅說一下 method 字段。該字段有兩個可選值:smc 和 hvc。表示調用 PSCI 功能使用什么指令。smc、hvc、svc 這些指令都是由低運行級別向更高級別請求服務的指令。

和系統調用一樣。調用了該指令,cpu 會進入異常,切入更高的權限。

異常處理程序根據下面傳上來的參數決定給予什么服務,smc 陷入 EL3,hvc 陷入 EL2,svc 陷入EL1。在 ARMv8 里面,EL3 總是是 secure 狀態,EL2 是虛擬機狀態,EL1 是普通的系統態。

接下來可以看看 arch/arm64/kernel/psci.c 里面的代碼,psci_ops.cpu_on 最終調用 smc call:

1static int cpu_psci_cpu_boot(unsigned int cpu)
 2{
 3    phys_addr_t pa_secondary_entry = __pa_symbol(function_nocfi(secondary_entry));
 4    int err = psci_ops.cpu_on(cpu_logical_map(cpu), pa_secondary_entry);
 5    if (err)
 6        pr_err("failed to boot CPU%d (%d)\\n", cpu, err);
 7
 8    return err;
 9}
10
11static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
12            unsigned long arg0, unsigned long arg1,
13            unsigned long arg2)
14{
15    struct arm_smccc_res res;
16
17    arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
18    return res.a0;
19}

Bootloader 以 boot-wrapper-aarch64 作分析,看 psci.c 里的 psci_call 實現函數,通過 fid 與 PSCI_CPU_OFF 和 PSCI_CPU_ON 相比,找出需要執行的動作:

1long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
 2{
 3    switch (fid) {
 4    case PSCI_CPU_OFF:
 5        return psci_cpu_off();
 6
 7    case PSCI_CPU_ON_64:
 8        return psci_cpu_on(arg1, arg2);
 9
10    default:
11        return PSCI_RET_NOT_SUPPORTED;
12    }
13}

當然 boot-wrapper-aarch64 里也需要同樣的定義:

1#define PSCI_CPU_OFF        0x84000002
2#define PSCI_CPU_ON_32      0x84000003
3#define PSCI_CPU_ON_64      0xc4000003

boot-wrapper-aarch64 按照和 kernel 約定的好參數列表,為目標 cpu 設置好跳轉地址,然后返回到 kernel 執行,下面給出關鍵代碼說明:

1static int psci_cpu_on(unsigned long target_mpidr, unsigned long address)
 2{
 3    int ret;
 4    unsigned int cpu = find_logical_id(target_mpidr);
 5    unsigned int this_cpu = this_cpu_logical_id();
 6
 7    if (cpu == MPIDR_INVALID)
 8        return PSCI_RET_INVALID_PARAMETERS;
 9
10    bakery_lock(branch_table_lock, this_cpu);
11    ret = psci_store_address(cpu, address);   /* 寫入啟動地址  */
12    bakery_unlock(branch_table_lock, this_cpu);
13
14    return ret;
15}

總結

目前比較主流的多核啟動方式是 PSCI,一般正式的產品都有 ATF。通過 PSCI 可以實現 CPU 的開啟關閉以及掛起等操作。

在實際的移植工作過程中,如果有帶有 ATF 的 bootloader, 那多核移植就相對容易很多,如果沒有的話,也可以采用 spin_table 的方式來啟動多核。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10878

    瀏覽量

    212169
  • 程序
    +關注

    關注

    117

    文章

    3791

    瀏覽量

    81156
  • 代碼
    +關注

    關注

    30

    文章

    4801

    瀏覽量

    68735
收藏 人收藏

    評論

    相關推薦

    C6678 多核啟動的問題

    我想知道怎么讓dsp啟動的時候多核啟動,debug的時候可以選擇下載到那個核,然后運行,選擇的核就會開始運行。 如果我把程序寫到eeprom那么boot起來后就只有core0,運行,怎么讓所有的核都
    發表于 06-21 14:36

    目前使用6657,想通過TFTP完成多核啟動~

    各位大大們~~我的板子是6657,使用IBL實現了OUT(ELF)文件在TFTP的方式啟動成功;1)不知道能不能把兩個OUT文件合并,完成多核啟動;2)我看到IBL中有一種BTBL
    發表于 08-06 07:36

    ARM64 SMP多核啟動相關資料推薦(下)

    2、psci方式多核啟動描述上面說了pin-table的多核啟動方式,看似很繁瑣,實際上并不復雜
    發表于 06-06 17:11

    介紹在ARM64架構下啟動多核的兩種方式

    : 28932c41e14d730b8b9a7310071384178611fb32linux v5.14多核 CPU啟動方式嵌入式系統的啟動
    發表于 06-13 18:23

    多核CPU、多進程、多線程之間的聯系解析

    多核cpu主要分原生多核和封裝多核。Windows 應用程序中消息有兩種送出途徑;直接和排隊。Windows或某些運行的應用程序可直接發布消息給窗口過程。線程,是指從軟件或者硬件上實
    發表于 12-01 09:37 ?9363次閱讀
    <b class='flag-5'>多核</b><b class='flag-5'>CPU</b>、多進程、多線程之間的聯系解析

    多核CPU打游戲更快嗎

    隨著AMD銳龍的橫空出世,電腦CPU進入了多核震懾的時代。
    發表于 07-28 09:57 ?2643次閱讀

    多核CPU和SoC芯片及其工作原理

    前言:現在的CPU或SoC基本都是在單芯片中集成多個CPU核心,形成通常所說的4核、8核或更多核CPU或SoC芯片。為什么要采用這種方式
    的頭像 發表于 01-06 11:35 ?1.5w次閱讀
    <b class='flag-5'>多核</b>心<b class='flag-5'>CPU</b>和SoC芯片及其工作原理

    多核CPU和單核的區別~

    昨天有同學問我多核cpu和單核的區別大不大,今天簡單寫一篇回復下吧。大家有其他問題也可以文末給我留言,我會盡量抽時間寫文回復。首先回顧下基本概念,cpu,就是中央處理器,包括運算器和控制器...
    發表于 12-01 20:06 ?1次下載
    <b class='flag-5'>多核</b><b class='flag-5'>CPU</b>和單核的區別~

    ARM64 SMP多核啟動(下)—PSCI

    上面說了pin-table的多核啟動方式,看似很繁瑣,實際上并不復雜,無外乎主處理器喚醒從處理器到指定地址上去執行指令
    發表于 06-09 14:31 ?762次閱讀
    ARM64 SMP<b class='flag-5'>多核</b><b class='flag-5'>啟動</b>(下)—PSCI

    基于Tricore芯片的AUTOSAR架構下的多核啟動

    隨著汽車ECU迅速的往域控制器方向發展,ECU要出來任務越來越多,單核CPU的負載越來越大,多核ECU勢在必行。AUTOSAR架構下OS支持多核處理,本系列文章將詳細介紹AUTOSAR架構下的
    的頭像 發表于 10-23 10:15 ?3336次閱讀
    基于Tricore芯片的AUTOSAR架構下的<b class='flag-5'>多核</b><b class='flag-5'>啟動</b>

    如何在內核中啟動secondary cpu

    給調度器之前,并沒有實際的業務進程,而我們知道內核中cpu在空閑時會執行idle進程。因此,在其啟動之前需要為每個cpu初始化一個idle進程。 另外,由于將一個cpu通過熱插拔
    的頭像 發表于 12-05 15:46 ?629次閱讀
    如何在內核中<b class='flag-5'>啟動</b>secondary <b class='flag-5'>cpu</b>

    SMP多核啟動cpu操作函數

    其中spin-table啟動方式的回調如下: const struct cpu_operations smp_spin_table_ops = {.name= "spin-table
    的頭像 發表于 12-05 16:04 ?809次閱讀
    SMP<b class='flag-5'>多核</b><b class='flag-5'>啟動</b><b class='flag-5'>cpu</b>操作函數

    使用自旋表啟動的平臺設備樹cpu節點介紹

    補充一下一個使用自旋表作為啟動方式的平臺設備樹cpu節點: arch /arm64/ boot /dts/ xxx.dtsi: cpu@ 0 { device_type = "
    的頭像 發表于 12-05 16:19 ?864次閱讀

    SMP多核secondary cpu啟動流程

    secondary cpu啟動 由于psci方式啟動secondary cpu的流程,除了其所執行的cp
    的頭像 發表于 12-05 17:41 ?917次閱讀
    SMP<b class='flag-5'>多核</b>secondary <b class='flag-5'>cpu</b><b class='flag-5'>啟動</b>流程

    多核CPU的優勢是什么

    多核CPU(Central Processing Unit,中央處理器)作為現代計算機技術的重要里程碑,其優勢在于顯著提升了計算性能、多任務處理能力、系統穩定性以及能效比等多個方面。以下將詳細闡述多核
    的頭像 發表于 08-22 14:30 ?2911次閱讀
    主站蜘蛛池模板: adc年龄确认大驾光临入口| 国产免费毛片在线观看| 亚洲国产亚综合在线区尤物| 国产高清视频青青青在线| 午夜伦理一yy4480影院| 精品国产九九| 99久久国产宗和精品1上映| 日本欧美午夜三级| 99精品国产在热| 三级黄色在线观看| 国产亚洲精品成人AV久久| 视频成人永久免费看| WWW国产亚洲精品久久久日本| 啦啦啦WWW在线观看免费高清版 | 国产人妻人伦精品熟女麻豆| 一本之道高清在线观看一区| 回复术士人生重启在线观看| 亚洲国产夜色在线观看| 男女做爽爽爽视频免费软件 | 亚洲h视频在线观看| 国产无线乱码一区二三区| 中国字字幕在线播放2019| 色列少女漫画| 精品一产品大全| 电影 qvod| 最近的2019中文字幕国语| 旧里番ovaの催○セイ活指导| 北原多香子qvod| 亚洲一品AV片观看五月色婷婷| 久久国产高清字幕中文| 中文乱码35页在线观看| 沈芯语麻豆0076 视频| 看免费人成va视频全| 国产精品婷婷久青青原| 亚洲日韩精品AV中文字幕| 欧美巨大xxxx做受孕妇视频| 好男人好资源在线播放| 中文字幕亚洲欧美日韩2019| 天天摸夜添狠狠添高| 精品久久久久中文字幕| 成人国产亚洲精品A区天堂蜜臀|