日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux_arm_启动_c语言部分详解,[原创]Linux arm 启动 c语言部分详解第四讲

發布時間:2023/12/10 linux 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux_arm_启动_c语言部分详解,[原创]Linux arm 启动 c语言部分详解第四讲 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Linux arm啟動c語言部分詳解第四講(from setup_per_cpu_areas();)

Written by leeming

上面的setup_arch花了我們大量的篇幅,現在我們要繼續往前推進了。

注:黑色為主線,藍色為函數的一級展開,紅色是注意重要的地方。

//因為我們沒有定義CONFIG_SMP,所以這兩個函數都為空

setup_per_cpu_areas();

smp_prepare_boot_cpu();

/*

* Set up the scheduler prior starting any interrupts (such as the

* timer interrupt). Full topology setup happens at smp_init()

* time - but meanwhile we still have a functioning scheduler.

*/

//和進程初始化有關的函數,進程是任何操作系統的一個大點,因此這部分內容還是很多的,我這次主要是講解c語言的啟動,所以這部分暫時會比較淺的涉及,以后有機會也詳細談到

sched_init();

{

runqueue_t *rq;

int i, j, k;

for_each_cpu(i) {

prio_array_t *array;

//獲取每個cpu的運行隊列結構體runqurere_t

rq = cpu_rq(i);

spin_lock_init(&rq->lock);

rq->nr_running = 0;//該隊列中可運行的進程數

//prio_array_t *active, *expired, arrays[2];

rq->active = rq->arrays;

rq->expired = rq->arrays + 1;

rq->best_expired_prio = MAX_PRIO;

/*此處刪除了smp的內容*/

atomic_set(&rq->nr_iowait, 0);

//初始化active和expired隊列位圖,將優先隊列中的0-(MAX_PRIO-1)清0

//將MAX_PRIO對應的置1

for (j = 0; j < 2; j++) {

array = rq->arrays + j;

for (k = 0; k < MAX_PRIO; k++) {

INIT_LIST_HEAD(array->queue + k);

__clear_bit(k, array->bitmap);

}

// delimiter for bitsearch

__set_bit(MAX_PRIO, array->bitmap);

}

}

/*

* The boot idle thread does lazy MMU switching as well:

*/

atomic_inc(&init_mm.mm_count);

//啥都沒做

enter_lazy_tlb(&init_mm, current);

/*

* Make us the idle thread. Technically, schedule() should not be

* called from this thread, however somewhere below it might be,

* but because we are the idle thread, we just pick up running again

* when this runqueue becomes "idle".

*/

//初始化當前進程,也就是idle進程

init_idle(current, smp_processor_id());

}

/*

* Disable preemption - early bootup scheduling is extremely

* fragile until we cpu_idle() for the first time.

*/

//禁止搶占,原因如上

preempt_disable();

build_all_zonelists();

//處理器熱插拔時的失控函數,類似變頻時相應的驅動模塊做出的反應,顯然嵌入式中不可能用到

page_alloc_init();

//打印啟動參數,也就是我們再setup_arch中獲得的參數,這里只是打印,對參數的分析就在printk下面

printk(KERN_NOTICE "Kernel command line: %s\n", saved_command_line);

//再次分析參數,之前在setup_arch里面也做了一次,但那次只是得到我們的內存信息

parse_early_param();

parse_args("Booting kernel", command_line, __start___param,

__stop___param - __start___param,

&unknown_bootoption);

sort_main_extable();

//將中斷向量表所在的區域(鏈接的時候的位置不可能是0xffff0000)的內容搬運至0xffff0000;將中斷處理部分的代碼搬運至0xffff0200處。

trap_init();

rcu_init();

init_IRQ();

{

struct irqdesc *desc;

int irq;

#ifdef CONFIG_SMP

bad_irq_desc.affinity = CPU_MASK_ALL;

bad_irq_desc.cpu = smp_processor_id();

#endif

//NR_IRQS在我們的4020中定義為32個中斷,arm本身最多支持128個

for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {

//將這些中斷初始化為bad_irq_desc

*desc = bad_irq_desc;

INIT_LIST_HEAD(&desc->pend);

}

//init_arch_irq是一個全局的函數指針,它初始化的時候是一個空函數

//但是在setup_arch中把它指向了我們4020的函數,init_arch_irq = mdesc->init_irq;

//也就是在arch/arm/mach-sep4020/irq.c中的sep4020_init_irq,這里重新對我們所有的中斷進行初始化

init_arch_irq();

}

pidhash_init();

init_timers();

{

//這個函數就是timers_nb這個結構體的call函數

timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,

(void *)(long)smp_processor_id());

//這個是用的機制和cpufreq的機制是一樣的,通過notifier_chain_register(&cpu_chain, nb)注冊的;

//只不過這里的鏈是cpu_chain,而cpufreq是其他的鏈

register_cpu_notifier(&timers_nb);

//設置軟中斷行動函數描述結構變量softirq_vec[=1](系統定時器)的設置

//也就是設置timer定時器到期之后的處理函數

open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL);

}

//其中函數hrtimers_init()和高精度時鐘相關

hrtimers_init();

//和init_timers最后部分是softirq類似,只不過在那里是初始化=1的時候;

//在softirq_init中是初始化=6, =0的情況,對于整個軟中斷來說有以下幾種情況

/*enum

{

HI_SOFTIRQ=0,

TIMER_SOFTIRQ,

NET_TX_SOFTIRQ,

NET_RX_SOFTIRQ,

BLOCK_SOFTIRQ,

TASKLET_SOFTIRQ

};*/

softirq_init();

//調用arch/arm/kernel/time.c中的time_init;它首先會檢查system_timer這個全局結構體的偏移是否為空

//system_timer和我們之前在init_IRQ中提到的init_arch_irq類似,也是在setup_arch中賦值的

//system_timer = mdesc->timer;所以之前一直強調setup_arch是一個非常重要的函數,和我們處理器的移植緊密相關的

time_init();

至此,雖然start_kernel的函數只分析了一小部分,但是和平臺和處理器相關的部分已經基本完畢,相信看完了這幾講,你會清楚的知道對于arch/arm/mach-sep4020中的那些文件為什么要那么寫,是不是可以優化(肯定可以),知其然,知其所以然。

總結

以上是生活随笔為你收集整理的Linux_arm_启动_c语言部分详解,[原创]Linux arm 启动 c语言部分详解第四讲的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美精品网址 | 尤物自拍 | 开心激情av| 熟妇人妻无乱码中文字幕真矢织江 | 色成人综合网 | 日韩美一级片 | 国产在线观看一区二区三区 | 日韩专区在线播放 | 天天干夜夜欢 | 超碰2023| 大片视频免费观看视频 | 少妇性bbb搡bbb爽爽爽欧美 | 一级艳片新婚之夜 | 大咪咪av | 日韩激情免费 | 国产精品嫩草影院精东 | 友田真希一区二区 | 午夜视频在线观看一区 | www黄色片网站 | 国产精品视频大全 | 亚洲精品第一页 | 91在线免费观看网站 | 超碰人人99 | 精品人妻伦一区二区三区久久 | 色吧在线观看 | 日日干日日射 | 亚洲精品乱码久久久久 | 综合激情网五月 | 91浏览器在线观看 | av片在线观看网站 | 午夜影院在线观看 | 久久久视频在线 | 免费观看黄色网页 | 成人深夜在线 | 91精品久久人妻一区二区夜夜夜 | 哪里可以免费看毛片 | 国产日韩精品在线观看 | 国产精品污 | 国产麻豆精品在线 | 天天看天天干 | 成品人视频ww入口 | 国产农村乱对白刺激视频 | 久久久久久无码精品大片 | 在线观看黄色小视频 | 国产视频网站在线观看 | 欧美精品乱人伦久久久久久 | 在线观看av毛片 | 久久96视频 | 日韩av在线播 | 欧美精品一区二区三区三州 | 久久精品一区二区免费播放 | 日韩在线一二三 | 欧美日韩亚洲二区 | 日韩毛片无码永久免费看 | 欧美成人精品欧美一级乱黄 | 人人妻人人澡人人爽 | 国产精品自拍一区 | 经典三级在线视频 | xxxx999 | 国产九区 | 久久久九九九热 | 亚洲v在线观看 | 国产专区在线播放 | jizz俄罗斯 | 亚洲美女高潮久久久 | av无码精品一区二区三区 | 精品欧美一区二区久久久久 | 国产三级理论 | 欧美成人自拍视频 | 日韩成人免费电影 | 欧美激情亚洲综合 | 欧美丰满bbw | 美女搡bbb又爽又猛又黄www | 成人av免费看 | 欧美在线观看视频一区二区 | 人妻一区二区三区 | 国产亚洲成av人片在线观看桃 | 国产色在线视频 | 免费av导航 | 日韩有码专区 | 亚洲最新在线观看 | 狠狠综合一区 | 亚洲一区二区在线 | 成人小片 | 国产精品亚洲а∨天堂免在线 | 日韩在线中文 | 岛国色图 | 亚洲图片视频在线 | 日韩精品一区二区三区视频在线观看 | 熟女丰满老熟女熟妇 | 少妇人妻精品一区二区三区 | 伊人视频在线观看 | 奇米影视四色在线 | 精品97人妻无码中文永久在线 | 国产欧美精品一区二区 | 青草青在线视频 | 无码人妻丰满熟妇区毛片18 | 亚洲一区二三区 | yw视频在线观看 |