| linux核心代碼分析(系統(tǒng)初始化start_kernel函數(shù)) |
| 作者:佚名 來(lái)源:單片機(jī) 錄入:jdzj868 更新時(shí)間:2009-8-12 16:57:25 點(diǎn)擊數(shù):0 |
【字體:
】 |
至于x86的引導(dǎo)無(wú)非如下步驟: 1,cpu初始化自身,在固定位置執(zhí)行一條指令。 2,這條指令條轉(zhuǎn)到bios中。 3,bios找到啟動(dòng)設(shè)備并獲取mbr,該mbr指向我們的lilo 4,bios裝載并把控制權(quán)交給lilo 5,壓縮內(nèi)核自解壓,并把控制權(quán)轉(zhuǎn)交給解壓內(nèi)核。 簡(jiǎn)單點(diǎn)講,就是cpu成為內(nèi)核引導(dǎo)程序的引導(dǎo)程序的引導(dǎo)程序的引導(dǎo)程序,西西。 這時(shí)內(nèi)核將跳轉(zhuǎn)到start_kernel是/init/main.c的重點(diǎn)函數(shù),main.c函數(shù)很多定義都是為此函數(shù)服務(wù)的,這里 我簡(jiǎn)要介紹一下這個(gè)函數(shù)的初始化流程。 初始化內(nèi)核: 從start_kernel函數(shù)(/init/main.c)開始系統(tǒng)初始化工作,好,我們首先分析這個(gè)函數(shù): 函數(shù)開始首先: #ifdef __SMP__ static int boot_cpu = 1; /* "current" has been set up, we need to load it now *//*定義雙處理器用*/ if (!boot_cpu) initialize_secondary(); boot_cpu = 0; #endif 定義雙處理器。 printk(linux_banner); /*打印linux banner*/ 打印內(nèi)核標(biāo)題信息。 開始初始化自身的部分組件(包括內(nèi)存,硬件終端,調(diào)度等),我來(lái)逐個(gè)分析其中的函數(shù): setup_arch(&command_line, &memory_start, &memory_end);/*初始化內(nèi)存*/ 返回內(nèi)核參數(shù)和內(nèi)核可用的物理地址范圍 函數(shù)原型如下: setup_arch(char **, unsigned long *, unsigned long *); 返回內(nèi)存起始地址: memory_start = paging_init(memory_start,memory_end); 看看paging_init的定義,是初始化請(qǐng)求頁(yè): paging_init(unsigned long start_mem, unsigned long end_mem)(會(huì)在以后的內(nèi)存管理子系統(tǒng)分析時(shí)詳細(xì)介 紹) { int i; struct memclust_struct * cluster; struct memdesc_struct * memdesc; /* initialize mem_map[] */ start_mem = free_area_init(start_mem, end_mem);/*遍歷查找內(nèi)存的空閑頁(yè)*/ /* find free clusters, update mem_map[] accordingly */ memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb); cluster = memdesc->cluster; for (i = memdesc->numclusters ; i > 0; i--, cluster++) { unsigned long pfn, nr; /* Bit 0 is console/PALcode reserved. Bit 1 is non-volatile memory -- we might want to mark this for later */ if (cluster->usage & 3) continue; pfn = cluster->start_pfn; if (pfn >= MAP_NR(end_mem)) /* if we overrode mem size */ continue; nr = cluster->numpages; if ((pfn + nr) > MAP_NR(end_mem)) /* if override in cluster */ nr = MAP_NR(end_mem) - pfn; while (nr--) clear_bit(PG_reserved, &mem_map[pfn++].flags); } memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE); return start_mem; } trap_init(); 初始化硬件中斷 /arch/i386/kernel/traps.c文件里定義此函數(shù) sched_init() 初始化調(diào)度 /kernel/sched.c文件里有詳細(xì)的調(diào)度算法(這些會(huì)在以后進(jìn)程管理和調(diào)度的結(jié)構(gòu)分析中詳細(xì)介紹) parse_options(command_line) 分析傳給內(nèi)核的各種選項(xiàng)(隨后再詳細(xì)介紹) memory_start = console_init(memory_start,memory_end) 初始化控制臺(tái) memory_start = kmem_cache_init(memory_start, memory_end) 初始化內(nèi)核內(nèi)存cache(同樣,在以后的內(nèi)存 管理分析中介紹此函數(shù)) sti();接受硬件中斷 kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); current->need_resched = 1; need_resched標(biāo)志增加,調(diào)用schedule(調(diào)度里面會(huì)詳細(xì)說(shuō)明) cpu_idle(NULL) 進(jìn)入idle循環(huán)以消耗空閑的cpu時(shí)間片 已經(jīng)基本完成內(nèi)核初始化工作,已經(jīng)把需要完成的少量責(zé)任傳遞給了init,所身于地工作不過(guò)是進(jìn)入idle循環(huán) 以消耗空閑的cpu時(shí)間片。所以在這里調(diào)用了cpu_idle(NULL),它從不返回,所以當(dāng)有實(shí)際工作好處理時(shí),該函 數(shù)就會(huì)被搶占。 parse_options函數(shù): static void __init parse_options(char *line)/*參數(shù)收集在一條長(zhǎng)命令行中,內(nèi)核被賦給指向該命令行頭 部的指針*/ { char *next; char *quote; int args, envs; if (!*line) return; args = 0; envs = 1; /* TERM is set to 'linux' by default */ next = line; while ((line = next) != NULL) { quote = strchr(line,'"'); next = strchr(line, ' '); while (next != NULL && quote != NULL && quote < next) { next = strchr(quote+1, '"'); if (next != NULL) { quote = strchr(next+1, '"'); next = strchr(next+1, ' '); } } if (next != NULL) *next++ = 0; /* * check for kernel options first.. */ if (!strcmp(line,"ro")) { root_mountflags |= MS_RDONLY; continue; } if (!strcmp(line,"rw")) { root_mountflags &= ~MS_RDONLY; continue; } if (!strcmp(line,"debug")) { console_loglevel = 10; continue; } if (!strcmp(line,"quiet")) { console_loglevel = 4; continue; } if (!strncmp(line,"init=",5)) { line += 5; execute_command = line; args = 0; continue; } if (checksetup(line)) continue; if (strchr(line,'=')) { if (envs >= MAX_INIT_ENVS) break; envp_init[++envs] = line; } else { if (args >= MAX_INIT_ARGS) break; argv_init[++args] = line; } } argv_init[args+1] = NULL; envp_init[envs+1] = NULL; }
補(bǔ)充日期: 2001-04-03 22:15:27
我覺得我還是不適合寫文章,在搞定linux的核心初始化和freebsd的初始化后只能寫出這點(diǎn)東東來(lái),呵呵 里面牽涉到的結(jié)構(gòu)之多足以使我眼花繚亂,呵呵,也費(fèi)不了太多唇舌來(lái)解釋每個(gè)結(jié)構(gòu),那是會(huì)死人的,主要向大家 介紹一下linux的核心是如何自我啟動(dòng)的,呵呵
|
|
|
發(fā)表評(píng)論 告訴好友 打印此文 收藏此頁(yè) 關(guān)閉窗口 返回頂部 |
|
|