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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

基于imx6ull的Linux-4.9.88内核启动过程

發布時間:2023/12/24 综合教程 24 生活家
生活随笔 收集整理的這篇文章主要介紹了 基于imx6ull的Linux-4.9.88内核启动过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、內核配置編譯過程

/Linux-4.9.88$ make mrproper
/Linux-4.9.88$ make 100ask_imx6ull_defconfig
/Linux-4.9.88$ make zImage

2、make 100ask_imx6ull_defconfig的作用

分析過內核的啟動過程后,我逐漸意識到make 100ask_imx6ull_defconfig命令的重要性,我們vi去看看里面包含了什么重要的東西。

CONFIG_ARCH_MXC=y
CONFIG_SOC_IMX6ULL=y

  我們看看這兩項有什么作用。

arch/arm/Makefile中決定了會編譯其中的哪一些單板,

當我們vi arch/arm/Makefile中會看到

所有,Makefile會編譯到arch/arm/mach-imx這個目錄中的文件。這樣就將我們編譯到的單板定位到了imx目錄下

可以看到里面確實多了很多.o文件,說明被編譯了。

那么,雖然編譯了mach-imx下的文件,但是imx文件中還有很多的單板,又怎么確定我們編譯的是哪一個單板呢?

接下來,我們看看CONFIG_SOC_IMX6ULL=y的作用,因為涉及到了某一個固定的單板,這樣跟設備樹會有很大的關系了。因此我們去設備樹目錄下看看,能發現什么。

看到這么多關于imx6ull的設備樹,我們首先想到的就是Makefile

這樣,我們就看到了,只要是定義了CONFIG_SOC_IMX6ULL=y之后,我們想使用的設備樹就會被編譯到,我們使用的設備樹是100ask_imx6ull-14x14.dts。

我們看看里面包含了什么。

我們看到,在根目錄下包含了一個“compatible”屬性,他就說明了,與他匹配的文件中也肯定會有相同的“compatible”屬性。

搜索!!目標越來越近了

就是他了

我們看到,這個文件中確實包含了imx6ull相關的單板信息,當我們把DT_MACHINE_START展開,就會看到,他是包含在.arch.info.init段中的。以后會提到他的用途。

3、內核啟動過程

下面我們順著第一句程序往下走,我們看arch/arm/kernel/vmlinux.lds中的程序入口是哪

他是定義在arch/arm/kernel/head.S中的

咦,我們會發現,竟然沒有低內核版本中設置機器ID的操作了。

作者是這么說的:

前面經過一系列程序后,就是為了

最后在__mmap_switched中,會調用到

開始了啟動內核的道路

其中有兩個函數

setup_arch
    setup_machine_fdt
        mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);
            of_flat_dt_match
                of_fdt_match
                    of_fdt_is_compatible
                        cp = fdt_getprop(blob, node, "compatible", &cplen);
                        if(of_compat_cmp(cp, compat, strlen(compat)) == 0)
     dump_machine_table
      for_each_machine_desc(p)
        early_print("%08x %s ", p->nr, p->name);
#define for_each_machine_desc(p)
  for (p = __arch_info_begin; p < __arch_info_end; p++) 

  看到了吧!結合上一節的內容,這樣就把imx6ull單板的信息接收到了!

setup_arch
    parse_early_param
        parse_early_options
            do_early_param
                for (p = __setup_start; p < __setup_end; p++) /* 開始處理__setup段early定義的內容了 */

unknown_bootoption
    obsolete_checksetup
        p = __setup_start;/* 開始處理__setup段非early定義的內容了 */
	do {
		int n = strlen(p->str);
		if (parameqn(line, p->str, n)) {
			if (p->early) {
				if (line[n] == '' || line[n] == '=')
					had_early_param = true;
			} else if (!p->setup_func) {
				pr_warn("Parameter %s is obsolete, ignored
",
					p->str);
				return true;
			} else if (p->setup_func(line + n))
				return true;
		}
		p++;
	} while (p < __setup_end);

  

mm_init();
sched_init();
init_IRQ();
hrtimers_init();
softirq_init();
console_init();
rest_init();    /* 這是一個關鍵的函數 */

  

rest_init()
    kernel_thread(kernel_init, NULL, CLONE_FS);/* 創建第一個進程 */

kernel_init
    kernel_init_freeable
        if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
		pr_err("Warning: unable to open an initial console.
");

	(void) sys_dup(0);
	(void) sys_dup(0);    /* 這就是熟悉的標準輸入 標準輸出 標準錯誤 */
        
        /* 別忘了內核的目的是為了掛載根文件系統 */  
        prepare_namespace
            saved_root_name中保存的就是掛載根目錄的位置
                mount_root();  /* 掛載根文件系統 */

static int __init root_dev_setup(char *line)
{
	strlcpy(saved_root_name, line, sizeof(saved_root_name));
	return 1;
}

__setup("root=", root_dev_setup);    /* 看到了吧 */             

  

kernel_init
    kernel_init_freeable    /* 上面已經分析過了 */
    /* 接下來就是運行init進程 */
    if(execute_command)
        run_init_process(execute_command);

    /* 執行到下面的任意一個就不會返回了 */
    try_to_run_init_process("/sbin/init")
    try_to_run_init_process("/etc/init")
    try_to_run_init_process("/bin/init")
    try_to_run_init_process("/bin/sh")

static int __init init_setup(char *str)
{
	unsigned int i;

	execute_command = str;    /* execute_command進程也是從__setup傳入的 */
	/*
	 * In case LILO is going to boot us with default command line,
	 * it prepends "auto" before the whole cmdline which makes
	 * the shell think it should execute a script with such name.
	 * So we ignore all arguments entered _before_ init=... [MJ]
	 */
	for (i = 1; i < MAX_INIT_ARGS; i++)
		argv_init[i] = NULL;
	return 1;
}
__setup("init=", init_setup);

  

總結

以上是生活随笔為你收集整理的基于imx6ull的Linux-4.9.88内核启动过程的全部內容,希望文章能夠幫你解決所遇到的問題。

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