學(xué)習(xí)筆記
使用教材(配書源碼以及使用方法)
《一個64位操作系統(tǒng)的設(shè)計與實現(xiàn)》
http://www.ituring.com.cn/book/2450
http://www.reibang.com/p/28f9713a9171
源碼結(jié)構(gòu)
- 配書代碼包 :第4章 \ 程序 \ 程序4-11
程序4-11 運行結(jié)果
[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 數(shù)據(jù)結(jié)構(gòu)
各結(jié)構(gòu)體大小
strcut mm_struct : 80 Bytes
struct thread_struct : 64 Bytes
struct task_struct : 88 Bytes
union task_union : 32768 Bytes
程序控制結(jié)構(gòu)體 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;
};
內(nèi)存空間分布結(jié)構(gòu)體: 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
代碼布局
聯(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
結(jié)構(gòu)體加一個數(shù)組
,之后聲明創(chuàng)建了全局變量 init_task_union 作為操作系統(tǒng)的第一個進程聯(lián)合體內(nèi)的數(shù)組空間勘究,就作為這個進程init_task_union的棸妫空間來使用
task.h
是內(nèi)核的一部分,更具體的說應(yīng)該是內(nèi)核代碼段的一部分口糕,這里聯(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
的段里結(jié)合程序4-11運行結(jié)果圖景描,可以看到其検欤基地址是
0x120000
,因為這個聯(lián)合體的大小是32K= 32678=0x8000超棺,那么就可以計算出.data.init_task
的段的起始地址0x1200000 - 0x8000 = 0x118000
同時看截圖可以知道代碼段的結(jié)束地址是
0x10b5e0
向族,很明顯聯(lián)合體init_task_union
不在代碼段內(nèi)詳細布局參見配書代碼包
Kernel.lds
文件;