亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
樓主: frank_seng
打印 上一主題 下一主題

Linux sys_exec中可執(zhí)行文件映射的建立及讀取 [復(fù)制鏈接]

論壇徽章:
0
11 [報告]
發(fā)表于 2008-05-07 15:11 |只看該作者
原帖由 frank_seng 于 2008-5-7 14:57 發(fā)表


真的好對不起,由于歷史原因,我們的產(chǎn)品依然跑在Linux 2.4上,因此是對著2.4說的,2.6除了網(wǎng)絡(luò)部分外,還從沒看過,sorry啊!

關(guān)于COW,我寫了一些總結(jié)性文檔,貼出來獻(xiàn)丑了:假設(shè)進(jìn)程A創(chuàng)建了子進(jìn)程B,之 ...

LZ客氣了,講的很清楚。
也就是說,COW時,不管該頁面最初的擁有者是誰,只要還是多個進(jìn)程擁有,那么誰先寫就給誰分配一個新的。最老的頁面留給最后單獨(dú)擁有該頁面的進(jìn)程。
我原來以為是老頁面一直留給父進(jìn)程。LZ講的這種機(jī)制更合理。以前也只是在書上看過COW的機(jī)制,但沒看過代碼,有很多不清楚。
哪位老大知道2.6中的COW代碼在哪兒啊,麻煩給個路徑,找半天沒找到。

不好意思打斷了,LZ請繼續(xù)寫,有問題還會問的

論壇徽章:
0
12 [報告]
發(fā)表于 2008-05-07 15:12 |只看該作者

回復(fù) #9 zx_wing 的帖子

如果父子都不可寫,父寫的時候分配一個新頁面給父,那老頁面是不是就給子了呢?
答:非常對

如果子先寫,分配一個新頁面給子,老頁面是不是就給父了呢?
答:非常對

COW就是這個機(jī)制!

論壇徽章:
0
13 [報告]
發(fā)表于 2008-05-07 16:54 |只看該作者

回復(fù) #12 frank_seng 的帖子

sys_exec("/bin/apache") 執(zhí)行過程
  • 當(dāng)前進(jìn)程進(jìn)入sys_exec系統(tǒng)調(diào)用;
  • 以下為load_elf_binary:打開apache文件,讀取其128字節(jié)頭,依據(jù)頭找到elf處理模塊(假設(shè)這里apache為elf文件);
  • 確定程序所使用的動態(tài)庫,一般為/usr/lib/ld_linux.so.2(從apache文件頭部分分析出),隨后打開該庫文件(也就是解釋器);
  • 讀取解釋器的首部;
  • 以下為flush_old_exec(執(zhí)行該函數(shù)之后,調(diào)用sys_exec的進(jìn)程將直接消失,從此與當(dāng)前進(jìn)程無關(guān),而是被apache完全代替),為apache日后運(yùn)行能擁有自己獨(dú)立的信號,以免影響其他進(jìn)程,這里為apache創(chuàng)建新的信號表;
  • 釋放所有的current->mm->mmap;
  • 釋放原來老的信號表(剛剛前面在創(chuàng)建新的信號表時還沒有釋放老信號表);
  • 以下為setup_arg_pages:為命令行參數(shù)args建立相應(yīng)的vm_area_struct(start=3G-args's size;end=3G),自棧頂往下,由于sys_execv剛開始時就已經(jīng)將args讀取到內(nèi)核內(nèi)存中,這里在put_dirty_page函數(shù)中為vm_start----- vm_end這段用戶空間對應(yīng)的頁目錄項創(chuàng)建相應(yīng)的頁表,并設(shè)置相應(yīng)的該頁表的頁表項指向args所在的物理頁面;
  • 以下為 elf_map:為apache中的.code、.data等段建立vm_area_struct,并建立到apache磁盤文件中對應(yīng)磁盤頁面的映射, vm_area_struct的vm_start、vm_end和vm_pgoff已經(jīng)在apache elf文件中由編譯器指明,注意這里沒有為對應(yīng)的頁目錄表項創(chuàng)建頁表,更不存在設(shè)置頁表項了;
  • 以下為load_elf_interp:為解釋器ld_linux.so.2建立vm_area_struct,并建立到該文件的磁盤映射;
  • 重新設(shè)置current->mm的參數(shù),簡歷bss段,設(shè)置新的EIP(指向解釋器的代碼段)和ESP(指向位于棧頂?shù)腶rgs參數(shù)底部);當(dāng)sys_exec從內(nèi)核系統(tǒng)調(diào)用中返回到用戶空間時,將從該EIP處開始執(zhí)行;

注意:例如在test程序中調(diào)用execve("/bin/apache"),則執(zhí)行完畢后,test程序就不存在了,被apache完全代替,pid保持不變。

論壇徽章:
0
14 [報告]
發(fā)表于 2008-05-08 09:36 |只看該作者

回復(fù) #13 frank_seng 的帖子

0號進(jìn)程的手工構(gòu)造過程

其是利用全局變量構(gòu)造的,如下圖所示:

         init_task_union
      ---+-------------+
       ^ |             |
       | |             |
       | |             |
      8K |             |    init_task
       | |             |   ,+------------------------+
       | |             |  / |                        |
       | |             | /  | policy:    SCHED_OTHER |
       | +-------------+/   | mm:        NULL        |
       v | task_struct |    | active_mm: init_mm ------+
      ---+-------------+\   | user:      INIT_USER   | |
                         \  | .....                  | |
                          \ |                        | |
                           '+------------------------+ |
                                                       |
                        init_mm                        |
                        +-------------------------+<---+
                        |                         |
                        | mmap:    init_mmap      |
                        | pgd:     swapper_pg_dir |
                        | .....                   |
                        |                         |
                        +-------------------------+

  • ESP剛開始的指向:在head.S中:lss stack_start,%esp設(shè)置了esp寄存器,而stack_start已經(jīng)被定義為SYMBOL_NAME(init_task_union)+8192,很顯然,esp在內(nèi)核啟動時指向init_task_union頂部;
  • current的解釋:而current宏則就是按8K宏對esp取整,因此無論esp因壓棧出棧導(dǎo)致其在棧中(init_task_union)何位值,都會得到task_struct的首指針;
  • 因此,綜上,Linux內(nèi)核啟動后,current也就是init_task,可以理解成當(dāng)前進(jìn)程init_task中;
  • 注意,init_task的pid為0;

論壇徽章:
0
15 [報告]
發(fā)表于 2008-05-08 11:47 |只看該作者
10. fork之后,在哪里設(shè)置了copy-on-write的頁面只讀屬性?

        sys_fork() > do_fork() > copy_process() > copy_mm() > dup_mm() > dup_mmap() >
        copy_page_range() > copy_hugetlb_page_range() :

        int cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWARITE;
                ...
                if (cow)
                        ptep_set_wrprotect(src, addr, src_pte);
                        ...



應(yīng)該是以前在本版看到的帖子然后記錄的筆記。

論壇徽章:
0
16 [報告]
發(fā)表于 2008-05-08 11:56 |只看該作者

回復(fù) #15 albcamus 的帖子

elf文件段屬性和vm_area_struct關(guān)系:

在elf文件段中,有如下屬性:

   1. p_type:該成員指出了這個數(shù)組的元素描述了什么類型的段,或怎樣解釋該數(shù)組元素的信息。
   2. p_offset:該成員給出了該段的駐留位置相對于文件開始處的偏移。
   3. p_vaddr:該成員給出了該段在內(nèi)存中的首字節(jié)地址。
   4. p_filesz:該成員給出了文件映像中該段的字節(jié)數(shù);它可能是 0 。
   5. p_memsz:該成員給出了內(nèi)存映像中該段的字節(jié)數(shù);它可能是 0 。
   6. p_flags:該成員給出了和該段相關(guān)的標(biāo)志。定義的標(biāo)志值如下所述。
   7. p_align:就象在后面“載入程序”部分中所說的那樣,可載入的進(jìn)程段必須有合適的p_vaddr 、 p_offset 值,取頁面大小的模。該成員給出了該段在內(nèi)存和文件中排列值。 0 和 1 表示不需要排列。否則, p_align 必須為正的 2 的冪,并且 p_vaddr 應(yīng)當(dāng)?shù)扔?p_offset 模 p_align 。

那么vm_area_struct中相應(yīng)的成員和elf文件段屬性的關(guān)系為:

   1. vm_start ---> p_vaddr :該vm_area_struct對應(yīng)的用戶空間區(qū)間起始邏輯地址;
   2. vm_end ---> p_vaddr+p_filesz :該vm_area_struct對應(yīng)的用戶空間區(qū)間結(jié)束邏輯地址;
   3. vm_pgoff ---> p_offset:該vm_area_struct對應(yīng)的實際數(shù)據(jù)首字節(jié)在文件中的偏移地址;

論壇徽章:
0
17 [報告]
發(fā)表于 2008-05-08 11:57 |只看該作者

回復(fù) #16 frank_seng 的帖子

關(guān)于schedule和cpu_idle的一些問題:

   1. schedule會從一系列進(jìn)程中選擇最合適的進(jìn)程來運(yùn)行,假設(shè)某一時刻沒有合適的進(jìn)程(在尋找待切換入進(jìn)程時next時,先將next設(shè)置為init_task,然后在runqueue_head運(yùn)行隊列中找合適的進(jìn)程,找到,就將其賦給next,注意,init_task不會在runqueue_head隊列中,沒找到,則就是init_task了),則只能選擇 init_task,這樣便回到了init_task在cpu_idle->schedule()中被換出時的點(diǎn),由于此時 init_task.need_resched==0,故進(jìn)入idle(一般為poll_idle函數(shù),在此函數(shù)中, init_task.need_resched被設(shè)置為-1),此時CPU halt了,直到中斷的到來,CPU才會停止halt;
   2. 如果此時來了個中斷,則中斷處理完畢后返回前,發(fā)現(xiàn)current(也就是init_task)的need_resched為-1(!=0),又會主動調(diào)用 schedule,在schedule中,首先將current(也就是init_task)的need_resched清零,然后選擇合適的進(jìn)程來運(yùn)行,如果找不到合適的,則schedule直接就返回了,此時也就是從中斷處理中返回,這樣又回到了cpu_idle->idle-> halt被中斷時的點(diǎn),再次進(jìn)行1->2這樣的循環(huán);如果schedule找到了另一個合適的進(jìn)程,則就切換到該進(jìn)程去運(yùn)行了, init_task則被掛起在idle->halt被中斷時點(diǎn)的那個位置;

論壇徽章:
0
18 [報告]
發(fā)表于 2008-05-08 14:56 |只看該作者

回復(fù) #17 frank_seng 的帖子

#
Linux kernel啟動時第一次進(jìn)入cpu_idle的簡單分析,下圖為其流程圖,從圖中可知,由于current(也就是init_task)的need_resched現(xiàn)在等于1,故立刻開始執(zhí)行schedule();

                |
+-------------->|
| +------------>|
| |             v
| |          _,,-,,_
| |   ,,.-'``       ``'-.,,
| | current->need_resched==0? ---+
| |    `'-.,,        ,,.-'``     |
| |          ``'--'``            | N
| |            Y|                |
| |             v                v
| |      +--------------+ +--------------+
| |      |    idle()    | |  schedule()  |
| |      +--------------+ +--------------+
| |             |                |
| +-------------+                |
+--------------------------------+


  • 現(xiàn)在就兩個進(jìn)程:init_task和new_task(init),很顯然schedule->switch_to會選中new_task開始執(zhí)行,同時將init_task.need_resched置0;
  • new_task 的esp、eip在(3)中已經(jīng)被設(shè)置好了,故esp寄存器被恢復(fù)為new_task->thread.esp,也就是 union2.pt_regs底部;eip寄存器被恢復(fù)為new_task->thread.eip也就是ret_from_fork, new_task從ret_from_fork處開始執(zhí)行,由于new_task系統(tǒng)堆棧中保存的用于返回的EIP是從原來的init_task中復(fù)制過來的,而且new_task->need_resched=0,因此new_task返回到kernel_thread中;
  • 隨后在kernel_thread中,此時將esp和esi比較(esi中保存的是剛進(jìn)kernel_thread時的esp),對于new_task而言,很明顯,這里是不相等的,esp為new_task堆棧指針地址,esi為init_task堆棧指針地址;
  • 執(zhí)行函數(shù)init(),在init中會執(zhí)行execve("/sbin/init")【內(nèi)核中的execve宏定義見_syscall3】,也就是 sys_excve("/sbin/init),new_task完全被/sbin/init替代,其永遠(yuǎn)不會再回到kernel_thread了,在 sys_execve中會構(gòu)造用戶空間,/sbin/init也會啟動一些列應(yīng)用層初始化進(jìn)程,系統(tǒng)主要起始進(jìn)程啟動成功;
  • 關(guān)于kernel_thread需要說明的是:如果這里不是init()函數(shù),而是一個普通函數(shù),則kernel_thread在執(zhí)行完該普通函數(shù)后,執(zhí)行sys_exit退出并釋放該任務(wù);

論壇徽章:
0
19 [報告]
發(fā)表于 2008-05-08 16:43 |只看該作者
非常想知道這些圖是怎么畫出來的.

摟主能否講講?

論壇徽章:
0
20 [報告]
發(fā)表于 2008-05-08 17:01 |只看該作者
原帖由 xpl 于 2008-5-8 16:43 發(fā)表
非常想知道這些圖是怎么畫出來的.

摟主能否講講?

Ascii Picture Designer
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP