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

歡迎訪問 生活随笔!

生活随笔

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

linux

从linux内核启动,学习Linux内核启动过程:从start_kernel到init

發布時間:2023/12/1 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从linux内核启动,学习Linux内核启动过程:从start_kernel到init 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、實驗步驟:

1:運行menuos:

a)cd LinuxKernel/

b)qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

啟動后啟動了MenuOS。

2:使用gdb調試跟蹤menuos內核啟動和運行過程;

a)qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

-S:freeze CPU at startup

-s:shorthand for -gdb tcp::1234 如果不想使用1234端口則可以好似用 -gdb tcp:xx 來取代-s選項

在另外一個窗口調試程序打開gdb;

然后按c運行到剛才的斷點,如下圖:

然后使用list,查看start_kernel的代碼

如果想跟蹤那里,結合代碼,設置斷點繼續跟蹤;

二、從start_kernel到init進程啟動過程的詳細分析

1.Linux內核啟動時首先調用start_Kernel函數,該函數相當于應用程序中的main()函數,在start_kernel函數中會調用大量的init函數來對內核環境進行初始化;包括CPU初始化、內存管理初始化、進程管理初始化、文件系統初始化、中斷、同步互斥等。例如:

asmlinkage __visible void __init start_kernel(void)

{

.......

/*init_task即手工創建的PCB,0號進程就是最終的idle進程*/

thread_info_cache_init();//初始化thread info

cred_init();

fork_init(totalram_pages);//初始化fork

proc_caches_init();//初始化proc的catch

buffer_init();

key_init();

security_init();

dbg_late_init();//文件系統初始化

vfs_caches_init(totalram_pages);

signals_init();

/* rootfs populating might need page-writeback */

page_writeback_init();

proc_root_init();

cgroup_init();

cpuset_init();

taskstats_init_early();

delayacct_init();

check_bugs();

sfi_init_late();

if (efi_enabled(EFI_RUNTIME_SERVICES)) {

efi_late_init();

efi_free_boot_services();

}

ftrace_init();

/*以上就是各種初始化*/

/* Do the rest non-__init'ed, we're now alive */

rest_init();

}

2.從上面代碼我們看到最后一步就是:調用rest_init()函數來啟動第一個用戶進程,該進程被稱為1號進程,代碼及分析如下所示:(這個函數可以直接斷點到這里,然后按c運行到這里即可)

static noinline void __init_refok rest_init(void)

{

int pid;

rcu_scheduler_starting();

/*

* We need to spawn init first so that it obtains pid 1, however

* the init task will end up wanting to create kthreads, which, if

* we schedule it before we create kthreadd, will OOPS.

*/

kernel_thread(kernel_init, NULL, CLONE_FS);//啟動1號進程,也稱為init進程,是第一個用戶進程

numa_default_policy();

pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);

rcu_read_lock();

kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);

rcu_read_unlock();

complete(&kthreadd_done);

/*

* The boot idle thread must execute schedule()

* at least once to get things moving:

*/

init_idle_bootup_task(current);

schedule_preempt_disabled();

/* Call into cpu_idle with preempt disabled */

cpu_startup_entry(CPUHP_ONLINE); //由1號進程完成剩下的初始化工作

}我們可以看到這個進程,有一個while(1)在無限的執行下去;

總結

以上是生活随笔為你收集整理的从linux内核启动,学习Linux内核启动过程:从start_kernel到init的全部內容,希望文章能夠幫你解決所遇到的問題。

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