版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、實現(xiàn)一個什么都不能做的嵌入式操作系統(tǒng)1 .首先確定CPU,在這里為了簡單,就選用嵌入式的CPU比如ARM系列,之所以用RISC(簡單指令集類型的CPU,其方便之處是沒有實模式與保護模式之分,采用線性的統(tǒng)一尋址,也就是不需要進行段頁式內(nèi)存管理,還有就是芯片內(nèi)部集成了一些常用外設(shè)控制器,比如以太網(wǎng)卡,申口等等,不需要像在PC機的主板上那么多外設(shè)芯片2 .確定要實現(xiàn)的模塊和功能,為了簡單,只實現(xiàn)多任務(wù)調(diào)度(但有限制,比如最多不超過10,實現(xiàn)中斷處理(不支持中斷優(yōu)先級,不進行動態(tài)SHELL交互,不實現(xiàn)動態(tài)模塊加載,不實現(xiàn)fork之類的動態(tài)進程派生和加載(也就是說要想在你的操作系統(tǒng)上加入用戶程序,只能靜
2、態(tài)編譯進內(nèi)核中;不支持文件系統(tǒng),不支持網(wǎng)絡(luò),不支持PCI,USB,磁盤等外設(shè)(除了支持串口,呵呵,串口最簡單嘛,不支持虛擬內(nèi)存管理(也就是說多任務(wù)中的每個進程都可以訪問到任何地址,這樣做的話,一個程序死了,那么這個操作系統(tǒng)也就玩完了3 .確定要使用的編譯器,這里采用GCC,文件采用ELF格式,當(dāng)然,最終的文件就是BIN格式,GCC和LINUX有著緊密的聯(lián)系,自己的操作系統(tǒng),需要C庫支持和系統(tǒng)調(diào)用支持,所以需要自己去裁剪C庫,自己去實現(xiàn)系統(tǒng)調(diào)用4 .實現(xiàn)步驟:首先是CPU選型,交叉編譯環(huán)境的建立,然后就是寫B(tài)OOTLOADER,寫操作系統(tǒng)。如何實現(xiàn)BOOTLOADER1 .之所以要實現(xiàn)一個專用的
3、BOOTLOADER,一是為了更好的移植和自身的開級,二是為了方便操作系統(tǒng)的調(diào)試,當(dāng)然,你完全可以將這部分所要實現(xiàn)的與操作系統(tǒng)相關(guān)的功能集成到操作系統(tǒng)中去2 .確定一個簡單的BOOTLOADER所要完成的功能:我們這里只需要完成兩個主要功能,一是將操作系統(tǒng)加載到內(nèi)存中去運行,二是將自己和操作系統(tǒng)內(nèi)核固化到ROM存儲區(qū)(這里的ROM可以是很多設(shè)備,比如嵌入式芯片中的FLASH,PC機上的軟盤,U盤,硬盤等3 .BOOTLOADER的編寫:第一步:要進行相關(guān)硬件的初使化,比如在at91rm9200這塊嵌入式板子上(以后都使用這一款芯片,主要是我對這款芯片比較熟悉,嘿嘿,大概要做接下來的幾方面的工作
4、,其一:將CPU模式切換進系統(tǒng)模式,關(guān)閉系統(tǒng)中斷,關(guān)閉看門狗,根據(jù)具體情況進行內(nèi)存區(qū)域映射,初始化內(nèi)存控制區(qū),包括所使用的內(nèi)存條的相關(guān)參數(shù),刷新頻率等,其二:設(shè)定系統(tǒng)運行頻率,包括使用外部晶振,設(shè)置CPU頻率,設(shè)置總線頻率,設(shè)置外部設(shè)備所采用的頻率等。其三:設(shè)置系統(tǒng)中斷相關(guān)包括定時器中斷,是否使用FIQ中斷,外部中斷等,還有就是中斷優(yōu)先級設(shè)置,這里只實現(xiàn)兩個優(yōu)先級,只有時鐘中斷高一級,其它都一樣,而中斷向量初始化時都將這些中斷向量指向0x18處,并關(guān)閉這里的所有中斷,如果板子還接有諸如FLASH設(shè)備的話,還需要設(shè)置諸如FLASH相關(guān)操制寄存器,其四要關(guān)閉CACHE,到此為止,芯片相關(guān)內(nèi)容就完成
5、初始化了第二步:中斷向量表,ARM的中斷與PC機芯片的中斷向量表有一點差異,嵌入式設(shè)備為了簡單,當(dāng)發(fā)生中斷時,由CPU直接跳入由0x0開始的一部分區(qū)域(ARM芯片自身決定了它中斷時就會跳入0x0開始的一片區(qū)域內(nèi),具體跳到哪個地址是由中斷的模式?jīng)Q定的,一般用到的就是復(fù)位中斷,F(xiàn)IQ,IRQ中斷,SWI中斷,指令異常中斷,數(shù)據(jù)異常中斷,預(yù)取指令異常中斷,而當(dāng)CPU進入相應(yīng)的由0x0開始的向量表中時,這就需要用戶自己編程接管中斷處理程序了,這就是需要用戶自己編寫中斷向量表,中斷向量表里存放的就是一些跳轉(zhuǎn)指令,比如當(dāng)CPU發(fā)生一個IRQ中斷時,就會自動跳入到0x18處,這里就是用戶自己編寫的一個跳轉(zhuǎn)指
6、令,假如用戶在此編寫了一條跳轉(zhuǎn)到0x20010000處的指令,那么這個地址就是一個總的IRQ中斷處理入口,一個CPU可能有多個IRQ中斷,在這個總的入口處如何區(qū)分不同的中斷呢?就由用戶編程來決定了,具體實現(xiàn)請參見以后相關(guān)部分,中斷向量表的一般用一個vector.S文件,當(dāng)然,如何命名那是你自己的喜愛,但有一點需要聲明,那就是在鏈接時一定要將它定位在0x0處第三步:設(shè)置堆棧,一般使用三個棧,一個是IRQ棧,一個是系統(tǒng)模式下的棧(系統(tǒng)模式下和用戶模式共享寄存器和內(nèi)存空間,這主要是為了簡單,設(shè)置棧的目的主要是為了進行函數(shù)調(diào)用和局部變量的存放,不可能全用匯編,也不可能不用局部變量第四步:將自己以后的代
7、碼段和數(shù)據(jù)段全部拷貝至內(nèi)存,并將BSS段清零第五步:進行串口的初始化(主要是為了與用戶交互,進行與PC機的文件傳輸,F(xiàn)LASH的初始化(這里在FLASH中存放BOOT和內(nèi)核,F(xiàn)LASH驅(qū)動的編寫(這里的驅(qū)動有別于平常所說的驅(qū)動,由于FLASH不像SDRAM,只要設(shè)定了相關(guān)控制器之后就可以直接讀寫指定地址的數(shù)據(jù),對FLASH的寫操作是一塊一塊數(shù)據(jù)進行,而不是一個字節(jié)一個字節(jié)地寫,具體請查閱相關(guān)資料第六步:等待一定的秒數(shù),來接收用戶進行輸入,如果在指定的秒數(shù)內(nèi)用戶未輸入任何字符,那么BOOT就開始在FLASH中的指定位置(可以由自己指定,這么做主要是為了簡單讀取內(nèi)核的所有數(shù)據(jù)到內(nèi)存中(具體是內(nèi)存中
8、的什么位置由自己指定,也可以采用LINUX之類的做法,就是在內(nèi)存的起始位置加上一個0x8000處,將跳轉(zhuǎn)到內(nèi)核的第一條代碼處;如果用戶在指定的秒數(shù)內(nèi)鍵入了字符(這主要是為了方便開發(fā),如果開發(fā)定型之后完全可以不要這段代碼,那么就在用口與用戶進行交互,接受用戶在串口輸入的命令,比如用戶要求下載文件在FLASH中指定的位置等,具體內(nèi)容可參考U-BOOT之類的開源項目到這里為止,BOOT部分已完成,這個BOOT非常簡單,僅僅只是將PC機上傳下來的文件固化到FLASH中,然后再將FLASH中的操作系統(tǒng)內(nèi)核部分加載進內(nèi)存中,并將CPU的控制權(quán)交給操作系統(tǒng),下一頁開始講解如何寫一個最簡單的操作系統(tǒng),呵,到現(xiàn)
9、在才開始切入正題呢!!!如何實現(xiàn)一個最簡單的操作系統(tǒng)這里為了簡單,就不考慮可移植性開求,不從BOOT部分來接收參數(shù),也不對硬件進行檢測,也不需要進行DATA段,代碼段的重定位。我只是讀了LINUX內(nèi)核相關(guān)部分,并未自己去實現(xiàn)一個操作系統(tǒng),所以我以下所說的只是概念性的東西:1.接管系統(tǒng)的中斷處理,由于BOOT部分的代碼決定了那個中斷向量表,從而決定了系統(tǒng)中斷之后進入的內(nèi)存位置,但BOOT并不知道操作系統(tǒng)的中斷處理函數(shù)位置所在啊,怎么辦呢?有幾種方法,其一是:如果你的板子可以重映射地址,也就是可以將內(nèi)存條所在的位置重映射成0x0開始,那么在鏈接內(nèi)核的時候,就將操作系統(tǒng)自己的中斷向量表定位在0x0處
10、并且在BOOTLOADER引導(dǎo)結(jié)束時就完成映射操作,并讓CPU跳轉(zhuǎn)到0x0處執(zhí)行;如果沒有重映射功能,我就不曉得怎么辦了,不過我想到一個折衷的辦法,就是在BOOTLOADER啟動完成時(也就是將CPU控制權(quán)交給操作系統(tǒng)內(nèi)核時,重新改寫FLASH的0x0區(qū)域,就是將操作系統(tǒng)的內(nèi)核的中斷向量表寫入FLASH區(qū)的0x0處,比如,當(dāng)一個IRQ發(fā)生時,CPU決定了會跳入0x18(假設(shè)這里FLASH占用地址總線0x0至0x0fffffff,內(nèi)存占用0x20000000至0x2fffffff,而BOOTLOADER在最后將0x18處的代碼修改成了0x20000000加上0x18的地址處的代碼,而這個地址就是
11、內(nèi)核的中斷向量表中的相關(guān)跳轉(zhuǎn)指令,就相當(dāng)于跳轉(zhuǎn)進了內(nèi)核所關(guān)聯(lián)的IRQ處理函數(shù)的地址上去執(zhí)行中斷處理函數(shù)了,而這樣的不好之處在于:當(dāng)系統(tǒng)重新上電之后BOOT的中斷向量表已經(jīng)被修改,除非BOOT本身不使用中斷,呵,在這樣簡單的系統(tǒng)中,BOOT是不需要中斷功能的2 .這里為了簡單,所以沒有使用分頁內(nèi)存管理,就不需要建立頁表等操作,直接進行操作系統(tǒng)的堆棧設(shè)置,同BOOT一樣的設(shè)置過程一樣,接著就進行BSS段清零操作,這里的BSS段是指操作系統(tǒng)自身的BSS段,與BOOT的BSS段是同一個含義只是用在了不同的地方了,接著就跳入了MAIN函數(shù)3 .為了最大可能的簡單,采用靜態(tài)建立任務(wù)結(jié)構(gòu)數(shù)組,比如只建立十個
12、任務(wù),那么首先要為這十個任務(wù)結(jié)構(gòu)分配段內(nèi)存,可以在堆上分配(這個分配的內(nèi)存直到操作系統(tǒng)結(jié)束才會被釋放,當(dāng)然也可以指定一片操作系統(tǒng)的其它地方都用不到的內(nèi)存區(qū)域,不過這樣寫的話就有點外行的味道了,而符務(wù)結(jié)構(gòu)數(shù)組的指針卻是全局變量,存放在BSS段或者DATA段,由于在上一步中已經(jīng)分配了一個系統(tǒng)堆棧,那么我們這十個任務(wù)就分享這總體的堆棧區(qū)域這里的重點就是如果定義每個任務(wù)結(jié)構(gòu)數(shù)組里面的結(jié)構(gòu),可以參照LINUX的相關(guān)部分設(shè)計4 .中斷處理:在第一步中已經(jīng)確定了CPU進行相關(guān)的幾類型的中斷跳轉(zhuǎn)地址,而相同類型的中斷卻只有一個入口地址,這里的中斷處理就會完成以幾個動作:其一:入棧操作,包括所有寄存器入棧,至于
13、這個棧,就是在第二步中所設(shè)置的IRQ棧,其二:屏掉所有中斷,呵,這里為了簡單起見,所以在處理中斷時不允許再次發(fā)生中斷其三:讀取中斷相關(guān)的寄存器,判別是發(fā)生了什么中斷,以至于跳進相關(guān)的中斷處理函數(shù)中去執(zhí)行(在這里只包括兩種中斷,一是時鐘中斷,另一個是SWI中斷,也就是所謂的系統(tǒng)調(diào)用時需要用到的其四:等待中斷處理完成,然后就開啟中斷并出棧,恢復(fù)現(xiàn)場,將CPU控制權(quán)交給被中斷的代碼處注意:其一:在MIAN中必須首先確定整個系統(tǒng)有哪些需要處理的中斷,也就是有哪些中斷處理函數(shù),然后才編寫這里的中斷處理函數(shù)其二:本操作系統(tǒng)不處理虛擬內(nèi)存,具至連CPU異常都不處理(一切都為了簡單,一旦發(fā)生異常,系統(tǒng)就死機5
14、 .對TIMER的實現(xiàn),首先確定時間片,為了讓系統(tǒng)更穩(wěn)定,而且我們不需要實時功能,盡可能讓時間片設(shè)置長一點,比如我們讓一個任務(wù)運行20個時鐘滴答數(shù),然后應(yīng)根據(jù)系統(tǒng)頻率來確定每個系統(tǒng)滴答所占用的毫秒,這里使用5毫秒讓系統(tǒng)定時器中斷一次,那么就需要寫時鐘寄存器,具體參閱芯片資料,計算下來,一個任務(wù)最大可能連續(xù)運行100毫秒,注意:我們的操作系統(tǒng)不支持內(nèi)核搶占,同時只支持兩級中斷優(yōu)先級,就是只有時鐘中斷的優(yōu)先級高一點,其它的優(yōu)先級都低一級,但是在中斷處理一節(jié)中卻屏掉了這個功能因為一進入中斷處理,就禁止中斷,所以不管其它中斷優(yōu)先級有多高都沒有用的這樣做優(yōu)點是簡單了,但不好之處顯而易見,特別在相關(guān)中斷處
15、理函數(shù)如果進入了死循環(huán),那么整個系統(tǒng)就死了,而且時間片也變得不準確了,反正都不用實時,也不需要實時鐘支持嘛至于中斷優(yōu)先級設(shè)置請參閱芯片資料6 .進程調(diào)度的實現(xiàn),也就是do_timer函數(shù)(時鐘中斷處理函數(shù),有一個全局變量指針,指向的就是當(dāng)前任務(wù)結(jié)構(gòu)數(shù)組(或者鏈表,當(dāng)時鐘中斷時,就進入此函數(shù)中,首先判斷任務(wù)結(jié)構(gòu)體中的時間片是否用完,如未用完,就減一,然后退出中斷,讓CPU繼續(xù)運行當(dāng)前的任結(jié)構(gòu),若用完了時間片,就重置時間片,并重新尋找任何結(jié)構(gòu)數(shù)組中的下一個等待運行的任務(wù),若找到了,就切換至新的任務(wù),至于如何切換,請見下一頁描述,如果未找到就切換到IDLE任務(wù)(類似于LINUX,呵呵,所有的處理就是
16、模仿LINUX,由于本人水平太差,所就不能自創(chuàng)一招,注意:為了簡單,所以沒有實現(xiàn)任務(wù)優(yōu)先級,也未實現(xiàn)任務(wù)休眠等,也就是說只要靜態(tài)地決定了有十個任務(wù),這十個任務(wù)就按先后順序一個一個執(zhí)行而且每個任務(wù)都不允許結(jié)束,就是說在每個進程中的最后一句代碼都必須用死循環(huán),不然的話系統(tǒng)就跑飛了,還有一點,進程不支持信號,沒有休眠與喚醒操作,這個CPU就是不停地在運行,呵呵,反正CPU又不是人,所以不需要人權(quán)的哈!!這種調(diào)度是不是簡單得不能再簡單了???!!7 .串口不使用中斷,這就是最大可能的降低難度,用口使用論詢的方式來實現(xiàn)讀寫(當(dāng)然是阻塞的方式了哦,而且只有寫,不允許讀,因為讀的時候需要涉及到采用中斷方式,
17、因為輪詢方式有個不好的地方,那就是正在讀的時候,這里有可能當(dāng)前進程的時問片用完了,系統(tǒng)切換到另一個進程,這里你在PC機的串口輸入的數(shù)據(jù)就丟棄了,唉,又是為了簡單嘛8,最后一步就是MIAN函數(shù)的最后一部分,將本進程當(dāng)作IDLE進程(相當(dāng)于修改任務(wù)結(jié)構(gòu)數(shù)組中白數(shù)據(jù),開啟中斷,將當(dāng)前進程加入一段死循環(huán),以免它退出去。9.編譯你的BOOTLOADER,KERNEL,并燒寫至FLASH,反復(fù)調(diào)試10.至此將你的at91rm9200城者是其它相類似的芯片的用口接上PC機打開超級終端,打開板子電源,說不定你的操作系統(tǒng)就打印出了"hello,world"了!一個最簡單的操作系統(tǒng)就出來了任務(wù)
18、結(jié)才數(shù)組(或鏈表的實現(xiàn)我們的任務(wù)結(jié)構(gòu)就采用鏈表形式吧,但其長度是限定了的,頭指針是一個全局指針變量(指針變量是一個無符號整型指針,其指針本身所在的地址是在BSS段,但其指向的內(nèi)容是分配在堆上的一片內(nèi)存,分配內(nèi)核內(nèi)存的函數(shù)就用kmalloc吧,kmalloc函數(shù)需要自己編寫呵,為了簡單,這個函數(shù)只接受一個參數(shù),就是所需分配大小,這個函數(shù)做得很簡單,首先有一個全局針指,它在初始化時指向了整個堆的起始位置,并且固定大小,就是所謂的內(nèi)核堆棧,在內(nèi)核堆棧之后就是用戶堆棧,由于總共有十個任務(wù),當(dāng)然不包括內(nèi)核本身的任務(wù),所以整個堆棧就平均分成十一部分,注意:在所有任務(wù)初始化完成之后,還有一個步驟就是將內(nèi)核這
19、個任務(wù)移到用戶態(tài),相當(dāng)于要將自己的任務(wù)結(jié)構(gòu)的堆棧指針修改一下就行了,判斷大小是否超出了內(nèi)核堆的可分配范圍,還有一點,需要維護內(nèi)核堆和其它任務(wù)的堆,需要進行分塊,并且有一個全局的內(nèi)存使用標識,就用數(shù)組吧,簡單,0表示相應(yīng)的內(nèi)存部分未占用,1就表示占用,對應(yīng)的kfree就相當(dāng)于把標志置0,對于內(nèi)存的維護,比較復(fù)雜,為了簡單,就定為4K,并且不能進行大于四K的內(nèi)存申請,因為大于4K之后,由于沒有虛擬地址的概念,就不能實現(xiàn)堆上的連續(xù)分配地址,當(dāng)然在棧上分配是可以大于4K的棧是由編譯器和CPU所決定了的任務(wù)結(jié)才包括:1 .所剩的時間片2 .本任務(wù)所指向的代碼段內(nèi)存地址,這里也就是函數(shù)入口地址3 .本任務(wù)
20、所指向的數(shù)據(jù)段地址,這里的數(shù)據(jù)段被包含進了整個內(nèi)核中,所以并沒有用,作為保留4 .本任務(wù)的函數(shù)體是否存在,也就是否會被調(diào)度5 .本任務(wù)所使用的棧指針6 .本任務(wù)所使用的堆指針7 .本任務(wù)的標識,用0代表是IDLE,1代表是其它進程8 .所有寄存器的值9 .當(dāng)前PC值,初始化時被置成了函數(shù)入口地址首先講解一下任務(wù)數(shù)組結(jié)構(gòu)的初始化:將先定義一個全局指針,然后將此指針強制轉(zhuǎn)換為一個任務(wù)結(jié)構(gòu)指針,并通過kmalloc函在內(nèi)核所占用的堆(前而講過內(nèi)核的堆的起始就是整個堆的起始上去分配十個任務(wù)結(jié)構(gòu)所占的內(nèi)存,這里是絕不會超過4K的并且為這十個任務(wù)結(jié)構(gòu)賦值,將第一個任務(wù)置為IDLE,時間片為20,代碼段內(nèi)存
21、地址為main函數(shù)的的地址,數(shù)據(jù)段地址忽略,函數(shù)體存在,可以被調(diào)度,棧指針指向的位置根據(jù)以下來計算:假定每個給每個任務(wù)可使用的堆棧設(shè)定為64K,而整個堆的起始位置是0x20030000,那么第一個堆指針所指向的就是0x20030000,棧就是0X20030000+64K的位置,第二個以后就以此類推注意:在初始化任務(wù)結(jié)構(gòu)之前,不允許系統(tǒng)使用堆,但可以使用棧,那么內(nèi)核任務(wù)棧部分就分成了兩個,在未進行調(diào)度之前,棧就是上一頁中第二步中所設(shè)的棧,那么上一頁設(shè)置堆棧的時候就得注意必須將堆棧空間設(shè)成十個64K再加上在本步驟使用以前的最大可能所需的??臻g再講解一下任務(wù)切換時所要做的事情:進入整個中斷處理入口時
22、,會將所有寄存器推入IRQ棧之中,并把值拷貝到當(dāng)前任務(wù)結(jié)構(gòu)相應(yīng)的字段當(dāng)中,并取出被中斷的進程的當(dāng)前PC值存入當(dāng)前任務(wù)結(jié)構(gòu)中的相應(yīng)字段中,接卜就判別中斷類型以進入相應(yīng)的中斷處理函數(shù),這里就會進入do_timer函數(shù)中,以下就是進入此函數(shù)之后的流程:內(nèi)核中還有一個全局指針,就是當(dāng)前任務(wù)指針,它本身也是在系統(tǒng)BSS段中,它的定義如上一步中的那個全局指針一樣,當(dāng)由系統(tǒng)時鐘中斷之后,就取出這個全局指針,上一步初始化完成之后,還會把這個指針指向第一個任務(wù)結(jié)構(gòu)所在位置,也就是0x20030000處,那么就取出這個任務(wù)結(jié)構(gòu)中的時問片字段,判斷其是否為0,若為0,就進行以下的操作:保存用戶態(tài)下的棧指針至當(dāng)前任務(wù)
23、結(jié)構(gòu),保存堆指針,并將搜索一下可以被調(diào)度的任務(wù)結(jié)構(gòu),并將此任務(wù)結(jié)構(gòu)賦給當(dāng)前任務(wù)指針,置需要進行任務(wù)切換標識,此標識同樣是一個全局變量,但它是被賦了初值,會放在整個系統(tǒng)的DATA段中,返回do_timer函數(shù)。若不為0,就進行以下操作:將時間片減一,返回do_timer函數(shù)接下來判斷任務(wù)切換標識,若為0,則進行以下操作:不需要進行任務(wù)切換,所有寄存器出棧(這里的棧指的是IRQ棧,重新開啟中斷,切換到用戶模式,加載當(dāng)前任務(wù)結(jié)構(gòu)中的當(dāng)前PC值字段,以退出中斷處理程序若此標識為1,則執(zhí)行以下操作:就需要進行任務(wù)切換,讓所有寄存器出棧(這里的棧指的是IRQ棧,將當(dāng)前任務(wù)結(jié)構(gòu)中的所有寄存器的值恢復(fù)到相應(yīng)寄
24、存器中,將用戶態(tài)下的棧指針恢復(fù)至當(dāng)前任務(wù)結(jié)構(gòu)棧指針,將堆指針恢復(fù)至當(dāng)前任務(wù)結(jié)構(gòu)堆指針,并把需要進行任務(wù)切換標識恢復(fù)為0,重新開啟中斷,切換到用戶模式,任務(wù)切換是通過加載PC值來實現(xiàn)的,也就是通過加載當(dāng)前任務(wù)結(jié)構(gòu)中的當(dāng)前PC值字段,以退出中斷處理程序系統(tǒng)調(diào)用的實現(xiàn)本系統(tǒng)是完全可以不實現(xiàn)系統(tǒng)調(diào)用的,因為沒有實現(xiàn)內(nèi)核態(tài)和用戶態(tài)的保護,完全可以不實現(xiàn)自己的C庫,所有的函數(shù)都像kmalloc之類的實現(xiàn)一樣,在內(nèi)核中直接寫函數(shù)原型,但為了以后擴展,還是說一下系統(tǒng)調(diào)用,這里以malloc系統(tǒng)調(diào)用來實現(xiàn)首先說明還有一個堆指針(前面在kmalloc時有一個堆指針,不過那個堆指針是為內(nèi)核任務(wù),中斷處理所提供,這里
25、這個堆指針是用于用戶態(tài)的,它在系統(tǒng)初始化完成之前會賦上初值,其初值就是第一個任務(wù)結(jié)構(gòu)所使用的堆的起始位置,也就是在內(nèi)核所使用的堆加上64K的位置函數(shù)庫中的malloc函數(shù)實現(xiàn)步驟如下:1 .首先檢測申請大小是否超出了4K,若超出4K,就返回錯誤2 .進行系統(tǒng)調(diào)用(這里用_syscall1并只傳遞一個參數(shù)(所需分配大小系統(tǒng)調(diào)用函數(shù)_syscall1的實現(xiàn):1 .將寄存器壓入堆棧(這里的棧指向就是當(dāng)前任務(wù)的棧2 .將系統(tǒng)調(diào)用號1放至R0,參數(shù)放入R13 .發(fā)出SWI指令以產(chǎn)生SWI中斷(就是所說的軟中斷,陷阱此時系統(tǒng)發(fā)生中斷,會進入SWI中斷處理入口,下面說一下SWI入口函數(shù)的實現(xiàn)1 .取出R0的值,判斷其值,進入相應(yīng)的分支處理代碼段2 .在此進入_malloc處理
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 煤礦挖機租賃合同范例
- 商品購買合同范例簡易
- 工程保潔設(shè)備合同范例
- 《生活變變變:3 家鄉(xiāng)交通的變遷》教學(xué)實錄-2023-2024學(xué)年四年級下冊綜合實踐活動滬科黔科版
- 裝修主材合作合同范例
- 購買日用品合同范例
- 井字架合同范例
- 房屋銷售置換合同范例
- 2025項目預(yù)咨詢服務(wù)合同范本
- 2025年南昌貨運從業(yè)資格證摸擬考試試題答案
- 廉潔應(yīng)征承諾書
- 品質(zhì)部年終工作總結(jié)
- 2023甘肅蘭州生物制品研究所限責(zé)任公司招聘77人歷年高頻難易度、易錯點模擬試題(共500題)附帶答案詳解
- 光伏清潔機器人行業(yè)報告
- 中國平安體育營銷品牌策略
- 《汽車銷售禮儀》課件
- 《小小主持人》課件
- 安全教育為快樂成長保駕護航
- 關(guān)于初中學(xué)生計算能力的培養(yǎng)的探究課題實施方案
- 2024青海高校大學(xué)《輔導(dǎo)員》招聘考試題庫
- 培智五年級上次數(shù)學(xué)期末考試題
評論
0/150
提交評論