[OS64][025]源碼閱讀:程序4-11:運行結果,數(shù)據(jù)結構,第一個進程init_task_union

學習筆記

使用教材(配書源碼以及使用方法)
《一個64位操作系統(tǒng)的設計與實現(xiàn)》
http://www.ituring.com.cn/book/2450
http://www.itdecent.cn/p/28f9713a9171

源碼結構

  • 配書代碼包 :第4章 \ 程序 \ 程序4-11

程序4-11 運行結果

[anno@localhost bootloader]$ make
nasm boot.asm -o boot.bin
nasm loader.asm -o loader.bin

[anno@localhost kernel]$ make
gcc -E  head.S > head.s
as --64 -o head.o head.s
gcc -E  entry.S > entry.s
as --64 -o entry.o entry.s
gcc  -mcmodel=large -fno-builtin -m64 -c main.c
gcc  -mcmodel=large -fno-builtin -m64 -c printk.c
gcc  -mcmodel=large -fno-builtin -m64 -c trap.c
gcc  -mcmodel=large -fno-builtin -m64 -c memory.c
gcc  -mcmodel=large -fno-builtin -m64 -c interrupt.c
gcc  -mcmodel=large -fno-builtin -m64 -c task.c 
ld -b elf64-x86-64 -z muldefs -o system head.o entry.o main.o printk.o trap.o memory.o interrupt.o task.o -T Kernel.lds 
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary system kernel.bin

[anno@localhost 4-11]$ sudo mount boot.img media -t vfat -o loop
[anno@localhost 4-11]$ sudo cp bootloader/loader.bin media
[anno@localhost 4-11]$ sync
[anno@localhost 4-11]$ sudo cp bootloader/boot.bin media
[anno@localhost 4-11]$ sync
[anno@localhost 4-11]$ sudo cp kernel/kernel.bin media
[anno@localhost 4-11]$ sync

[anno@localhost 4-11]$ bochs -f ./bochsrc
程序4-11

程序4-11 數(shù)據(jù)結構

各結構體大小

各結構體大小
strcut mm_struct : 80 Bytes
struct thread_struct : 64 Bytes
struct task_struct : 88 Bytes
union task_union : 32768 Bytes

程序控制結構體 PCB(Process Control Block): task_struct (task.h)

struct task_struct
{
    struct List list;
    volatile long state;
    unsigned long flags;

    struct mm_struct *mm;
    struct thread_struct *thread;

    unsigned long addr_limit;   
/*0x0000,0000,0000,0000 - 0x0000,7fff,ffff,ffff user*/
/*0xffff,8000,0000,0000 - 0xffff,ffff,ffff,ffff kernel*/

    long pid;

    long counter;

    long signal;

    long priority;
};

List 雙向鏈表 用于連接各個PCB (lib.h)

struct List
{
    struct List * prev;
    struct List * next;
};

內存空間分布結構體: mm_struct (task.h)

struct mm_struct
{
    pml4t_t *pgd;   //page table point
    
    unsigned long start_code,end_code;
    unsigned long start_data,end_data;
    unsigned long start_rodata,end_rodata;
    unsigned long start_brk,end_brk;
    unsigned long start_stack;  
};
  • pml4t_t *pgd; : CR3

pml4t_t (memory.h)

typedef struct {unsigned long pml4t;} pml4t_t;

thread_struct 用于保存執(zhí)行現(xiàn)場的寄存器值 (task.h)

struct thread_struct
{
    unsigned long rsp0; //in tss

    unsigned long rip;
    unsigned long rsp;  

    unsigned long fs;
    unsigned long gs;

    unsigned long cr2;
    unsigned long trap_nr;
    unsigned long error_code;
};

第一個進程 init_task_union

代碼布局

1st進程init_task_union 初始化 : init_thread、init_mm.png

聯(lián)合體 task_union (task.h)

// 32KB
#define STACK_SIZE 32768

union task_union
{
    struct task_struct task;
    unsigned long stack[STACK_SIZE / sizeof(unsigned long)];
}__attribute__((aligned (8)));  //8Bytes align


union task_union init_task_union 
__attribute__((__section__ (".data.init_task"))) 
= {INIT_TASK(init_task_union.task)};

  • 由聯(lián)合體 task_union的定義可見,是一個task_struct結構體加一個數(shù)組 ,之后聲明創(chuàng)建了全局變量 init_task_union 作為操作系統(tǒng)的第一個進程

  • 聯(lián)合體內的數(shù)組空間,就作為這個進程init_task_union??臻g來使用

  • task.h是內核的一部分,更具體的說應該是內核代碼段的一部分,這里聯(lián)合里定義了一個數(shù)組僅僅只是定義,并沒有在原地就開辟了一段空間出來給這個數(shù)組

  • union task_union init_task_union __attribute__((__section__ (".data.init_task"))) = {INIT_TASK(init_task_union.task)};才是真正的開辟空間,而修飾__attribute__((__section__ (".data.init_task")))意思就是把init_task_union這個聯(lián)合體放到名為.data.init_task的段里

  • 結合程序4-11運行結果圖,可以看到其?;刂肥?code>0x120000,因為這個聯(lián)合體的大小是32K= 32678=0x8000,那么就可以計算出.data.init_task的段的起始地址0x1200000 - 0x8000 = 0x118000

  • 同時看截圖可以知道代碼段的結束地址0x10b5e0,很明顯聯(lián)合體init_task_union不在代碼段內

  • 詳細布局參見配書代碼包Kernel.lds文件;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容