[OS64][025]源码阅读:程序4-11:运行结果,数据结构,第一个进程init_task_union

学习笔记

使用教材(配书源码以及使用方法)
《一个64位操作系统的设计与实现》
http://www.ituring.com.cn/book/2450
https://www.jianshu.com/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 数据结构

各结构体大小

各结构体大小
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 用于保存执行现场的寄存器值 (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

联合体 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)};

  • 由联合体 task_union的定义可见,是一个task_struct结构体加一个数组 ,之后声明创建了全局变量 init_task_union 作为操作系统的第一个进程

  • 联合体内的数组空间,就作为这个进程init_task_union栈空间来使用

  • task.h是内核的一部分,更具体的说应该是内核代码段的一部分,这里联合里定义了一个数组仅仅只是定义,并没有在原地就开辟了一段空间出来给这个数组

  • 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这个联合体放到名为.data.init_task的段里

  • 结合程序4-11运行结果图,可以看到其栈基地址是0x120000,因为这个联合体的大小是32K= 32678=0x8000,那么就可以计算出.data.init_task的段的起始地址0x1200000 - 0x8000 = 0x118000

  • 同时看截图可以知道代码段的结束地址0x10b5e0,很明显联合体init_task_union不在代码段内

  • 详细布局参见配书代码包Kernel.lds文件;

你可能感兴趣的:([OS64][025]源码阅读:程序4-11:运行结果,数据结构,第一个进程init_task_union)