Linux0 11學習筆記

2021-10-14 00:13:58 字數 2036 閱讀 4111

**目前狀態:**中斷程式已設定,第乙個任務 init_task已初始化(sched.c),main()函式裡通過move_to_user_mode()進入到task 0。

目的:手工建立第二個任務 task 1,並和task 0不停切換。

做法:

在sched.c 建立第二個任務結構,所有值採用第乙個:

union task_union;

//第乙個任務的核心sp0=(&init_task+page_size),page_size定義為4096

static union task_union init_task=;

//第二個任務的核心sp0=(&second_task+page_size),page_size定義為4096

static union task_union second_task=;

//第二個任務的使用者棧

long second_stack[page_size>>2];

long* second_stack_top=(long*)(&second_stack[page_size>>2]);

linux 0.11的任務切換是通過 ljmp指令實現的。ljmp是個長跳轉(cs:ip),32為系統下,cs和ip長度為4位元組,其中ip在低4為,cs在高4位元組。當ljmp 跳轉的是乙個任務段tss時,就會發生任務切換,這時低4位元組的值忽略。switch_to()裡,通過 struct 構建乙個 跳轉位址,a是低4位元組,所以不用賦值,b賦值_tss(n),即任務n對應的tss段。 當task 0通過ljmp跳到task 1裡時,cpu會把task0的任務資訊儲存在_tss(0),及init_task.task.tss裡,並把task 1的資訊載入(second_task.task).

task 0 並不是通過ljmp進來的,所以它對應的tss裡的值不必都正確初始化,只要0級堆疊設定正確就行。但我們想要跳轉到 task 1,必須把 task 1裡tss和對應的ldt資訊都設定正確。ldt我們可以和 task 0的一樣,及_ldt(1),具體如下:

second_task.task.tss.esp=(long)second_stack_top;

second_task.task.tss.esp0=(long)&second_task+page_size;

second_task.task.tss.eip=(long)second_task_disp_str;

second_task.task.tss.gs=0x1b;//init_task裡是 0x17

second_task.task.tss.cs=0xf; //init_task裡的是0x17

second_task.task.tss.ldt=_ldt(1);

second_task.task.tss.eflags=0x202;//init_task裡的是0

然後把second_task裡的tss和ldt位址放到gdt表裡對應的tss和ldt段描述符,在我們的例子裡,gdt對應如下

序號 偏移位址

0 0x0 null

1 0x8 code descriptor

2 0x10 data descriptor

3 0x16 //linux沒用,但我用作指向視訊記憶體區域,用於顯示字串函式disp_str(相當於printf)

4 0x20 task 0 tss //_tss(0)

5 0x28 task 0 ldt //_ldt(0)

6 0x30 task 1 tss//_tss(1)

7 0x38 task 1 ldt //_ldt(1)

…// 設定gdt裡第二個任務的tss和ldt段描述符

set_tss_desc((char*)(gdt+first_tss_entry+2),&second_task.task.tss);

set_ldt_desc((char*)(gdt+first_ldt_entry+2),&second_task.task.ldt);

在時鐘中斷裡開啟排程函式

mov al,0x20

out 0x20,al

call schedule

詳見我的主頁

linux0 11學習筆記(2)

makefile檔案 makefile 檔案是make 工具程式的配置檔案。make 程式是使用makefile資料檔案和 檔案的最後修改時間 last modification time 來確定那些檔案需要進行更新,對於每乙個需要更新的檔案它會根據makefile 中的資訊發出相應的命令。在mak...

Linux 0 11 核心筆記

1 任務0的堆疊問題 一直不明白schedule.c裡的task union的stack和user stack是什麼關係,head.s裡就設定了esp指向user stack,卻一直沒有用到task union,直到看到init task才明白,從進入保護模式到跳轉進使用者態都是用的user sta...

Linux0 11核心筆記( )

c語言 彙編知識 嵌入式彙編 x86處理器和程式設計的相關知識和 unix作業系統設計 linus在最初開發linux作業系統時參考了minix作業系統 作業系統 設計與實現 一種基於訊息傳遞在核心各模組之間進行通訊 資訊交換 重要的五個支柱 unix作業系統 分時作業系統 minix作業系統 gn...