中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux中arm64多核啟動流程是怎樣的

發布時間:2022-01-27 15:59:44 來源:億速云 閱讀:276 作者:iii 欄目:開發技術

今天小編給大家分享一下Linux中arm64多核啟動流程是怎樣的的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

Linux中arm64多核啟動流程是怎樣的

Kernel :4.12.8

arm64多核啟動流程

smp_init_cpus() //設置多核啟動參數和動作
=>static int __init smp_cpu_setup(int cpu) //位于 arch/arm64/kenerl/smp.c
=> cpu_read_ops
=> cpu_get_ops
{ ops = acpi_disabled ? dt_supported_cpu_ops : acpi_supported_cpu_ops; }

.cpu_init    = smp_spin_table_cpu_init,

//分析從dts獲取啟動多核的兩種方式 spin_table 和 psci
static const struct cpu_operations *dt_supported_cpu_ops[] __initconst = {
&smp_spin_table_ops,
&cpu_psci_ops,
NULL,
};

// spin_table 方式的幾個動作接口
const struct cpu_operations smp_spin_table_ops = {
.name        = “spin-table”,
.cpu_init    = smp_spin_table_cpu_init,
.cpu_prepare    = smp_spin_table_cpu_prepare,
.cpu_boot    = smp_spin_table_cpu_boot, //bring up實際動作
};

bringup_cpu
=>int __cpu_up(unsigned int cpu, struct task_struct *idle)
=>ret = boot_secondary(cpu, idle);
cpu_ops[cpu]->cpu_boot(cpu); //實際調用 smp_spin_table_cpu_boot 之類的啟動

==============================
下面分析怎么執行cpu_boot的過程
==============================
static struct cpuhp_step cpuhp_bp_states[] =
/* Kicks the plugged cpu into life */
[CPUHP_BRINGUP_CPU] = {
.name            = “cpu:bringup”,
.startup.single        = bringup_cpu,
.teardown.single    = NULL,
.cant_stop        = true,
},

cpuhp_get_step() //喚起一個核有多步,這個是根據state選擇對應的狀態動作
sp = cpuhp_is_ap_state(state) ? cpuhp_ap_states : cpuhp_bp_states;
return sp + state;

kernel_init() =>kernel_init_freeable()

|=>void __init smp_prepare_cpus(unsigned int max_cpus)
/*
* Initialise the present map (which describes the set of CPUs
* actually populated at the present time) and release the
* secondaries from the bootloader.
*/
for_each_possible_cpu(cpu) {
err = cpu_ops[cpu]->cpu_prepare(cpu);
|=>smp_init => cpu_up=>do_cpu_up  // 同樣是從kernel_init_freeable()調用下來的
=>_cpu_up(unsigned int cpu, int tasks_frozen, enum cpuhp_state target)
=>cpuhp_up_callbacks
=>cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state,
bool bringup, struct hlist_node *node)
{
if (!step->multi_instance) {
cb = bringup ? step->startup.single : step->teardown.single;
ret = cb(cpu);
//這里實際就是拿出了bringup_cpu,調用之

}

   spin table方式啟動

實際就是把地址寫入spin table中,然后發出sev (send envent,是一個指令)從核就奔跑起來了。

在smp_prepare_cpus() 中調用了smp_spin_table_cpu_prepare() 從核就開始跑了,不過內核設置了wfe 等待真正任務才能真正執行任務。

smp_init()中調用了smp_spin_table_cpu_boot()就是真正的啟動了一個idle任務了(待確認)

 
 static int smp_spin_table_cpu_prepare(unsigned int cpu) {  __le64 __iomem *release_addr; 
  if (!cpu_release_addr[cpu])   return -ENODEV; 
  /*   * The cpu-release-addr may or may not be inside the linear mapping.   * As ioremap_cache will either give us a new mapping or reuse the   * existing linear mapping, we can use it to cover both cases. In   * either case the memory will be MT_NORMAL.   */  release_addr = ioremap_cache(cpu_release_addr[cpu],          sizeof(*release_addr));  if (!release_addr)   return -ENOMEM; 
  /*   * We write the release address as LE regardless of the native   * endianess of the kernel. Therefore, any boot-loaders that   * read this address need to convert this address to the   * boot-loader's endianess before jumping. This is mandated by   * the boot protocol.   */  writeq_relaxed(__pa_symbol(secondary_holding_pen), release_addr);  __flush_dcache_area((__force void *)release_addr,        sizeof(*release_addr)); 
  /*   * Send an event to wake up the secondary CPU.   */  sev(); 
  iounmap(release_addr); 
  return 0; } 
 static int smp_spin_table_cpu_boot(unsigned int cpu) {  /*   * Update the pen release flag.   */  write_pen_release(cpu_logical_map(cpu)); 
  /*   * Send an event, causing the secondaries to read pen_release.   */  sev(); 
  return 0; }

以上就是“Linux中arm64多核啟動流程是怎樣的”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

嘉峪关市| 大理市| 南京市| 灵寿县| 五常市| 招远市| 阳东县| 千阳县| 都江堰市| 西充县| 新乡县| 友谊县| 萝北县| 宁河县| 洪雅县| 德安县| 泉州市| 望都县| 黎川县| 麦盖提县| 曲阜市| 来安县| 香格里拉县| 新营市| 桦川县| 平邑县| 什邡市| 合作市| 深泽县| 延寿县| 商都县| 涞源县| 万全县| 泸西县| 金塔县| 文昌市| 永修县| 繁昌县| 广州市| 彭水| 莱芜市|