
国产成人亚洲综合无码精品
人妻少妇偷人精品视频
書接上回,上回書咱們說到,time_init 形式通過與 CMOS 端口進行讀寫交互,獲取到了年月日時分秒等數據,并通過這些計算出了開機時間 startup_time 變量,是從 1970 年 1 月 1 日 0 時起到開機當時經過的秒數。
我們繼續往下看,大名鼎鼎的進程調度启动化,shed_init。
void 人妻少妇偷人精品视频main(void) { ... mem_init(main_memory_start,memory_end); trap_init(); blk_dev_init(); chr_dev_init(); tty_init(); time_init(); sched_init(); buffer_init(buffer_memory_end); hd_init(); floppy_init(); sti(); move_to_user_mode(); if (!fork()) {init();} for(;;) pause(); }
這形式可了不得,因為它等于多進程的基石!
終于來到了興奮的時刻,是不是很激動?不過先別激動,這里仅仅進程調度的启动化,也等于為進程調度所需要用到的數據結構做個準備,果真的進程調度還需要調度算法、時鐘中斷等機制的合营。
當然,對于瓦解操作系統,经过和數據結構最為伏击了,而這一段作為整個经过的起點,以及确立數據結構的地点,就顯得颠倒伏击了。
我們進入這個形式,一點點往后看。
void sched_init(void) { set_tss_desc(gdt+4, &(init_task.task.tss)); set_ldt_desc(gdt+5, &(init_task.task.ldt)); ... }
兩行代碼启动化了下 TSS 和 LDT。
先別急問這倆結構是啥。還記得之前講的全局刻画符表 gdt 么?它在內存的這個位置,况兼被設置成了這個樣子。
忘了的看一劣等八回 | 煩死了又要从头設置一遍 idt 和 gdt,這就說明之前看似沒用的細節有多伏击了,群众一定要有耐性。
說回這兩行代碼,其實等于往后又加了兩項,分別是 TSS 和 LDT。
好,那再說說這倆結構是干嘛的,不過本篇先簡單瓦解,后头會詳細講到。
TSS 叫任務狀態段,等于保存和恢復進程的高下文的,所謂高下文,其實等于各個寄存器的信息良友,這樣進程切換的時候,能力做到保存和恢復高下文,繼續執行。
由它的數據結構你應該不错看出點酷爱酷爱。
struct tss_struct{ long back_link; long esp0; long ss0; long esp1; long ss1; long esp2; long ss2; long cr3; long eip; long eflags; long eax, ecx, edx, ebx; long esp; long ebp; long esi; long edi; long es; long cs; long ss; long ds; long fs; long gs; long ldt; long trace_bitmap; struct i387_struct i387; };
而 LDT 叫局部刻画符表,是與 GDT 全局刻画符表相對應的,內核態的代碼用 GDT 里的數據段和代碼段,而用戶進程的代碼用每個用戶進程我方的 LDT 里得數據段和代碼段。
先不论它,我這里放一張超綱的圖,你先找找感覺。
我們接著往下看。
struct desc_struct { unsigned long a,b; } struct task_struct * task[64] = {&(init_task.task), }; void sched_init(void) { ... int i; struct desc_struct * p; p = gdt+6; for(i=1;i<64;i++) { task[i] = NULL; p->a=p->b=0; p++; p->a=p->b=0; p++; } ... }
這段代碼有個循環,干了兩件事。
一個是給一個長度為 64,結構為 task_struct 的數組 task 附上启动值。
這個 task_struct 結構等于代表每一個進程的信息,這关联词個相當相當伏击的結構了,把它放在心里。
struct task_struct { /* these are hardcoded - don't touch */ long state; /* -1 unrunnable, 0 runnable, >0 stopped */ long counter; long priority; long signal; struct sigaction sigaction[32]; long blocked; /* bitmap of masked signals */ /* various fields */ int exit_code; unsigned long start_code,end_code,end_data,brk,start_stack; long pid,father,pgrp,session,leader; unsigned short uid,euid,suid; unsigned short gid,egid,sgid; long alarm; long utime, 娇小娇小与黑人tustime,cutime,cstime,start_time; unsigned short used_math; /* file system info */ int tty; /* -1 if no tty, so it must be signed */ unsigned short umask; struct m_inode * pwd; struct m_inode * root; struct m_inode * executable; unsigned long close_on_exec; struct file * filp[NR_OPEN]; /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */ struct desc_struct ldt[3]; /* tss for this task */ struct tss_struct tss; };
這個循環做的另一件事,是給 gdt 剩下的位置填充上 0,也等于把剩下留給 TSS 和 LDT 的刻画符都先附上空值。
人妻少妇偷人精品视频
往后瞻望一下的話,等于以后每創建一個新進程,就會在后头添加一組 TSS 和 LDT 暗示這個進程的任務狀態段以及局部刻画符表信息。
還記得剛剛的超綱圖吧,未來整個內存的規劃等于這樣的,不過你先不必瓦解得很細。
那為什么一開始就先有了一組 TSS 和 LDT 呢?現在也沒創建進程呀。錯了,現在雖然我們還沒有确立起進程調度的機制,但我們正在運行的代碼等于會作為未來的一個進程的领导流。
也等于當未來進程調度機制一确立起來,正在執行的代碼就會化身成為進程 0 的代碼。是以我們需要提前把這些未來會作為進程 0 的信息寫好。
要是你覺得很猜忌,別急,等后头整個進程調度機制确立起來,况兼讓你親眼看到進程 0 以及進程 1 的創建,以及它們后头因為進程調度機制而切換,你就显着這一切的意義了。
好,收回來,启动化了一組 TSS 和 LDT 后,再往下看兩行。
#define ltr(n) __asm__("ltr %%ax"::"a" (_TSS(n))) #define lldt(n) __asm__("lldt %%ax"::"a" (_LDT(n))) void sched_init(void) { ... ltr(0); lldt(0); ... }
這又触及到之前的知識咯。
還記得 lidt 和 lgdt 领导么?一個是給 idtr 寄存器賦值,以告訴 CPU 中斷刻画符表 idt 在內存的位置;一個是給 gdtr 寄存器賦值,以告訴 CPU 全局刻画符表 gdt 在內存的位置。
那這兩行和剛剛的類似,ltr 是給 tr 寄存器賦值,以告訴 CPU 任務狀態段 TSS 在內存的位置;lldt 一個是給 ldt 寄存器賦值,以告訴 CPU 局部刻画符 LDT 在內存的位置。
Elizabeth Holmes,伊丽莎白·福尔摩斯,天使面孔,“颠覆性”创业,一众VC大佬背书——甚至被冠以“女版乔布斯”之名,最终证明是彻头彻尾的大忽悠。
今天,国产成人亚洲综合无码精品北大光华-度小满金融科技实验室发布了「2022全球金融科技十大技术趋势」,涵盖隐私计算、大模型、多模态学习、数字孪生等多个前沿领域。
马云喜欢表演武术
但是,有几个因素会影响数据工程师的平均工资,其中一些包括:
虽然庆幸自己前几年急流勇退,放弃互联网大厂的高薪工作,跳槽到一家国企工作,拿着不到半数的工资,过上了别人眼中“躺平”的日子,但现在的国企也不如以前那么好混了。
当程序员第一次接触一门新的编程语言,总是要输出这串神奇的字符向世界宣告他的到来。
越南最大的加密货币交易平台ONUS运行有漏洞的Log4j版本的支付系统遭遇网络攻击。攻击者要求ONUS支付500万美元的赎金,并威胁公布用户数据。
数据分析为什么在企业应用中体现得越来越重要?
這樣,CPU 之后就能通過 tr 寄存器找到當前進程的任務狀態段信息,也等于高下文信息,以及通過 ldt 寄存器找到當前進程在用的局部刻画符表信息。
我們繼續看。
void sched_init(void) { ... outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */ outb_p(LATCH & 0xff , 0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ set_intr_gate(0x20,&timer_interrupt); outb(inb_p(0x21)&~0x01,0x21); set_system_gate(0x80,&system_call); ... }
四行端口讀寫代碼,兩行設置中斷代碼。
端口讀寫我們已經很闇练了,等于 CPU 與外設交互的一種表情,之前講硬盤讀寫以及 CMOS 讀寫時,已經接觸過了。
而這次交互的外設是一個可編程定時器的芯片,這四行代碼就開啟了這個定時器,之后這個定時器變會持續的、以一定頻率的向 CPU 發出中斷信號。
而這段代碼中設置的兩個中斷,第一個等于時鐘中斷,中斷號為 0x20,中斷處理形式為 timer_interrupt。那么每次定時器向 CPU 發出中斷后,便會執行這個函數。
這個定時器的觸發,以及時鐘中斷函數的設置,是操作系統主導進程調度的一個關鍵!沒有他們這樣的外部信號不斷觸發中斷,操作系統就沒有辦法作為進程惩办的主人,通過強制的工夫收回進程的 CPU 執行權限。
第二個設置的中斷叫系統調用 system_call,中斷號是 0x80,這個中斷又是個尽头尽头尽头尽头尽头尽头尽头伏击的中斷,所灵验戶態形式想要調用內核提供的形式,都需要基于這個系統調用來進行。
比如 Java 形式員寫一個 read,底層會執行匯編领导 int 0x80,這就會觸發系統調用這個中斷,最終調用到 Linux 里的 sys_read 形式。
這個過程之后會重點講述,現在只需要清醒,在這個地点,悄悄把這個極為伏击的中斷,設置好了。
是以你看這一章的內容,悄悄設置了影響進程和影響用戶形式調用系統形式的兩個分量級中斷處理函數,不簡單呀~
到当今為止,中斷已經設置了不少了,我們現在望望所設置好的中斷有哪些。
中斷號 中斷處理函數 0 ~ 0x10 trap_init 里設置的一堆 0x20 timer_interrupt 0x21 keyboard_interrupt 0x80 system_call
其中 0-0x10 這 17 個中斷是 trap_init 里启动化設置的,是一些基本的中斷,比如除零異常等。這個在 第14回 中斷启动化 trap_init 有講到。
之后,在规定臺启动化 con_init 里,我們又設置了 0x21 鍵盤中斷,這樣按下鍵盤就有反應了。這個在 第16回 规定臺启动化 tty_init 有講到。
現在,我們又設置了 0x20 時鐘中斷,况兼開啟定時器。终末又悄悄設置了一個極為伏击的 0x80 系統調用中斷。
找到些感覺沒,有沒有越來越發現,操作系統有點靠中斷驅動的酷爱酷爱,各個模塊不斷启动化各種中斷處理函數,况兼開啟指定的外設開關,讓操作系統我方迟缓“活”了起來,逐漸通過中斷艰辛于各種事情中,無法自拔。
恭喜你,我們已經逐漸在接近操作系統的本質了。
回顧一下我們今天干了什么,就三件事。
第一,我們往全局刻画符表寫了兩個結構,TSS 和 LDT,作為未來進程 0 的任務狀態段和局部刻画符表信息。
第二,我們启动化了一個結構為 task_struct 的數組,未來這里會存放系数進程的信息,况兼我們給數組的第一個位置附上了 init_task.init 這個具體值,亦然作為未來進程 0 的信息。
第三,設置了時鐘中斷 0x20 和系統調用 0x80,一個作為進程調度的起點,一個作為用戶形式調用操作系統功能的橋梁,尽头之伏击。
后头,我們將會逐漸看到,這些伏击的事情,是若何緊密且精妙地結合在一道,發揮特殊妙的作用。
欲知后事若何,且聽下回分解。
本文轉載自微信公眾號「低并發編程」,不错通過以下二維碼關注。轉載本文請聯系低并發編程公眾號。本網站已獲得低并發編程的授權
Powered by 人妻出轨合集500篇最新 @2013-2022 RSS地图 HTML地图