機(jī)電之家資源網(wǎng)
單片機(jī)首頁(yè)|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
linux核心代碼分析(系統(tǒng)初始化start_kernel函數(shù))
linux核心代碼分析(系統(tǒng)初始化start_kernel函數(shù))
 更新時(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)的,呵呵
  • 上一篇: 讓linux支持你的DMA66硬盤
  • 下一篇: 尋找Linux下的網(wǎng)絡(luò)鄰居(圖形工具:gnomba,Tk Samba,xSMBrowser,LinNeighborhood)
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁(yè)  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國(guó)行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營(yíng)許可證:浙B2-20080178-1