• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    基于SPARC多核SOC的Linux操作系統(tǒng)研究

    2017-07-21 05:13:45王海峰蔣曉華
    航天控制 2017年3期

    王海峰 蔣曉華

    1.廣東科學(xué)技術(shù)職業(yè)學(xué)院,珠海 519090 2.珠海歐比特控制工程股份有限公司,珠海 519080

    基于SPARC多核SOC的Linux操作系統(tǒng)研究

    王海峰1蔣曉華2

    1.廣東科學(xué)技術(shù)職業(yè)學(xué)院,珠海 519090 2.珠海歐比特控制工程股份有限公司,珠海 519080

    通過移植啟動(dòng)代碼,實(shí)現(xiàn)了Linux在SPARC多核處理器上的運(yùn)行,重點(diǎn)剖析Linux針對(duì)SMP多核系統(tǒng)的進(jìn)程管理機(jī)制、同步機(jī)制、進(jìn)程調(diào)度和負(fù)載平衡等,在S698PM多核處理器平臺(tái)進(jìn)行了驗(yàn)證。 關(guān)鍵詞 多核系統(tǒng);SPARC SOC;Linux;進(jìn)程調(diào)度;S698PM

    Linux作為一種開源操作系統(tǒng),具有內(nèi)核精簡(jiǎn)、應(yīng)用程序豐富、開發(fā)成本低廉和組件可配置等特點(diǎn),廣泛運(yùn)用在桌面端和嵌入式領(lǐng)域。

    目前在嵌入式領(lǐng)域,多核處理器已經(jīng)大量應(yīng)用,而多核處理器中又以SMP架構(gòu)最為常見。所謂SMP 架構(gòu),即是2個(gè)或多個(gè)同樣的處理器通過一塊共享內(nèi)存彼此連接,每個(gè)處理器可同等地訪問共享內(nèi)存(具有相同的內(nèi)存空間訪問延遲)。SMP技術(shù)提升了系統(tǒng)的性能,但同時(shí)也增加了操作系統(tǒng)內(nèi)核的復(fù)雜度和協(xié)同開銷,如何更好的支持SMP硬件系統(tǒng)是每個(gè)操作系統(tǒng)都面臨的棘手問題[1]。

    SPARC是國(guó)際上流行的RISC處理器體系架構(gòu)

    之一, SPARC V7/V8 是目前嵌入式控制系統(tǒng)常用的處理器標(biāo)準(zhǔn)版本,并在航天設(shè)備的電子系統(tǒng)中得到廣泛應(yīng)用?;赟PARC SMP的多核處理器應(yīng)用前景較好,由于SPARC嵌入式處理器主要應(yīng)用在航天軍工領(lǐng)域,Linux系統(tǒng)本身對(duì)SPARC架構(gòu)的支持有限,對(duì)SPARC SMP的支持更是空白,一般需要進(jìn)行平臺(tái)移植[2-3]。本文以此為出發(fā)點(diǎn),研究SMP系統(tǒng)中的幾個(gè)關(guān)鍵技術(shù),闡述了Linux 2.6系統(tǒng)針對(duì)SPARC多核處理器中的移植過程,并詳細(xì)分析研究了在Linux操作系統(tǒng)下如何更好地解決多個(gè)CPU之間的同步機(jī)制、負(fù)載平衡和進(jìn)程調(diào)度問題。

    1 SPARC對(duì)稱多核SOC

    以多核處理器S698PM為硬件實(shí)驗(yàn)平臺(tái)。S698PM是基于SPARC V8架構(gòu)的高性能的32位RISC嵌入式4核SOC處理器,其內(nèi)部采用SMP“對(duì)稱多處理”技術(shù),各CPU之間共享內(nèi)存子系統(tǒng)以及總線結(jié)構(gòu),總線競(jìng)爭(zhēng)和仲裁由硬件自動(dòng)完成,為了支持SMP,硬件上還集成了APIC中斷控制系統(tǒng)[4]。

    2 Linux在SPARC多核SOC中的引導(dǎo)

    在Linux2.6 SMP結(jié)構(gòu)中,CPU平等是建立在系

    統(tǒng)中有多個(gè)進(jìn)程或者多個(gè)執(zhí)行上下文的前提下,由于在系統(tǒng)的引導(dǎo)和初始化階段只有一個(gè)上下文,而同一時(shí)間,一個(gè)上下文只能有1個(gè)CPU來處理,所以在CPU系統(tǒng)初始化階段只能有1個(gè)引導(dǎo)處理器CPU0工作,而其余的應(yīng)用處理器CPU1,CPU2和CPU3處于暫停狀態(tài)。CPU0完成系統(tǒng)的引導(dǎo)和初始化,并創(chuàng)建1號(hào)進(jìn)程kernel_init和3個(gè)idle進(jìn)程,在kernel_init中通過LOCAL APIC發(fā)送IPI消息控制CPU1,CPU2和CPU3從指定的起始地址運(yùn)行,實(shí)現(xiàn)逐個(gè)啟動(dòng)CPU1,CPU2和CPU3的功能,達(dá)到SMP并行處理的要求。

    在操作系統(tǒng)中,可能會(huì)隨機(jī)分配某個(gè)CPU為啟動(dòng)CPU,因此,為確保CPU0為啟動(dòng)CPU,必須修改head.s文件中的trapbase為CPU0,如下所示。

    圖1 S698PM功能結(jié)構(gòu)

    start:trapbase:#ifdefCONFIG_SMPtrapbase_cpu0:#endif

    此外引導(dǎo)部分還需要針對(duì)SPARC架構(gòu)進(jìn)行內(nèi)存管理單元、中斷控制器和時(shí)鐘的設(shè)置,并進(jìn)行內(nèi)存清空和內(nèi)存讀寫測(cè)試等操作,只有部分工作統(tǒng)一由CPU0來完成。添加及修改的幾個(gè)主要文件包括:

    1)device.c和init.c:完成處理器信息和驅(qū)動(dòng)信息的掃描。如果掃描符合要求,系統(tǒng)才允許進(jìn)入引導(dǎo)程序,并做出下一步的初始化;

    2)prom.c:在rootnode中建立驅(qū)動(dòng)樹,為后續(xù)開發(fā)驅(qū)動(dòng)應(yīng)用程序提供幫助,使驅(qū)動(dòng)設(shè)備和其相應(yīng)的驅(qū)動(dòng)程序以及設(shè)備號(hào)能很好地對(duì)應(yīng)起來;

    3)leon_irq.c:實(shí)現(xiàn)對(duì)SPARC系統(tǒng)中斷的管理,用來對(duì)中斷初始化、中斷設(shè)置和中斷錯(cuò)誤報(bào)告相關(guān)信息的跟蹤等。

    移植完成后Linux對(duì)SMP的引導(dǎo)過程如下:

    (1)加載Linux內(nèi)核映像到內(nèi)存

    Linux內(nèi)核映像存貯在Flash中,當(dāng)系統(tǒng)加電時(shí),利用Bootloader將初始化信息傳遞給Linux內(nèi)核,Bootloader把Linux內(nèi)核復(fù)制到0開始的物理內(nèi)存處開始執(zhí)行。

    (2)執(zhí)行Linux系統(tǒng)初始化

    成功加載內(nèi)核映像之后,Boot Loader將指引CPU0跳轉(zhuǎn)到Linux內(nèi)核映像的入口地址_start函數(shù)處執(zhí)行。這時(shí),由于MMU地址映射還沒啟用,因此需要將鏈接地址轉(zhuǎn)換成物理地址來實(shí)現(xiàn)CPU中Cache,TLB以及寄存器的初始化。

    初始化后,臨時(shí)MMU地址映射開啟,CPU0跳轉(zhuǎn)到 start_kernel()繼續(xù)執(zhí)行,并構(gòu)造0號(hào)進(jìn)程rest_init運(yùn)行上下文,rest_init完成初始化部分并調(diào)用kernel_thread()函數(shù)創(chuàng)建第一個(gè)核心進(jìn)程kernel_init。kernel_init函數(shù)代碼如下:

    Statickernel_init(void){smp_prepare_cpus(max_cpus);smp_boot_cpus(max_cpus);connect_bsp_APIC();setup_local_APIC();map_cpu_to_logical_apicid();do_boot_cpu(apicid,cpu)}

    do_boot_cpu會(huì)完成應(yīng)用處理器的初始化,并通過中斷方式通知主CPU,次CPU可以啟動(dòng)。

    (3)應(yīng)用程序初始化

    init完成Linux的各項(xiàng)配置后,會(huì)在/sbin,/etc和/bin中尋找init程序來運(yùn)行。該init程序會(huì)替換kernel_init()進(jìn)程,此時(shí)處于內(nèi)核態(tài)的1號(hào)進(jìn)程kernel_init()將轉(zhuǎn)換為用戶空間內(nèi)的1號(hào)進(jìn)程init,開始系統(tǒng)的正常運(yùn)行。

    在Linux中,SMP系統(tǒng)的多核引導(dǎo)是一個(gè)分階段的過程,這中間需要主CPU和次CPU在幾個(gè)地方進(jìn)行同步,最終基本在同一時(shí)間進(jìn)入SMP的進(jìn)程調(diào)度。

    圖2 Linux SMP多核引導(dǎo)流程圖

    3 Linux內(nèi)核針對(duì)SMP的進(jìn)程管理

    3.1 同步機(jī)制

    在Linux SMP中,多個(gè)CPU可以并行運(yùn)行內(nèi)核代碼,當(dāng)內(nèi)核數(shù)據(jù)被多個(gè)內(nèi)核控制路徑共享存取時(shí),就會(huì)產(chǎn)生資源競(jìng)爭(zhēng)。根據(jù)資源競(jìng)爭(zhēng)產(chǎn)生的原因及所保護(hù)的數(shù)據(jù)不同,Linux操作系統(tǒng)為內(nèi)核代碼提供了多種同步與互斥機(jī)制,如原子操作、信號(hào)量、讀寫、大內(nèi)核鎖、讀寫鎖和自旋鎖等方法,來保護(hù)內(nèi)核數(shù)據(jù)的安全共享。操作系統(tǒng)鎖機(jī)制的基本原理是在某個(gè)鎖操作過程中不能與其他鎖操作交織執(zhí)行,以免多個(gè)執(zhí)行路徑對(duì)內(nèi)核中某些重要的數(shù)據(jù)及數(shù)據(jù)結(jié)構(gòu)進(jìn)行同時(shí)操作而造成混亂,本文主要利用自旋鎖來確保CPU的同步互斥操作。

    自旋鎖(spinlock)是使用忙等待鎖來確保互斥的一種特殊方法。每個(gè)自旋鎖都是用1個(gè)spinlock_t數(shù)據(jù)結(jié)構(gòu)來表示。只有spinlock_t的最低位被使用,如果鎖可用,則它是0;如果被取走,則它是1。

    在可搶占內(nèi)核和SMP情況下,如果2個(gè)任務(wù)競(jìng)爭(zhēng)1個(gè)共享的資源,沒有得到資源的任務(wù)將自旋以等待另一個(gè)任務(wù)使用完該共享資源,自旋鎖的實(shí)現(xiàn)如下:自旋鎖在使用前必須先初始化,自旋鎖有完全鎖和讀寫鎖2種形式。在SMP系統(tǒng)中主要用的是完全鎖。

    首先創(chuàng)建一個(gè)新的自旋鎖,

    spinlock_tpm_spinlock=SPIN_LOCK_UNLOCKED;SPINLOCK(pm_spinlock);spin_lock_init(&pm_spinlock);

    自旋鎖被初始化為值SPIN_LOCK_UNLOCKED,它也可以用spin_lock_init函數(shù)來初始化。這兩者都把spinlock_t的lock成員設(shè)置成0,也就是未鎖狀態(tài)。定義自旋鎖后,就可以使用鎖變量,每個(gè)變量用于不同的上下文。

    實(shí)際運(yùn)行時(shí)通過函數(shù)spin_lock_irqsave和spin_unlock_irqrestore來實(shí)現(xiàn)自旋鎖的獲取和釋放。當(dāng)進(jìn)程在某個(gè)CPU上運(yùn)行時(shí),需要通過spin_lock_irqsave獲取自旋鎖,并在本地處理器上禁用中斷。運(yùn)行完成之后,需要通過spin_unlock_irqrestore釋放自旋鎖,并且(通過flags參數(shù))恢復(fù)中斷,實(shí)現(xiàn)CPU之間的互斥功能。

    3.2 進(jìn)程調(diào)度

    Linux 操作系統(tǒng)在處理進(jìn)程調(diào)度時(shí),Task起關(guān)鍵作用。任務(wù)的基本數(shù)據(jù)結(jié)構(gòu)為task_struct,包涵了任務(wù)的當(dāng)前狀態(tài)、優(yōu)先級(jí)、剩余時(shí)間片、進(jìn)程號(hào)、正在使用的CPU和上一次使用的CPU以及內(nèi)核鎖的深度等參數(shù)。

    Linux 操作系統(tǒng)內(nèi)核中負(fù)責(zé)進(jìn)程調(diào)度的具體函數(shù)是Schedule,當(dāng)已經(jīng)不在運(yùn)行隊(duì)列里的進(jìn)程被喚醒時(shí),Wake up process( ) 函數(shù)將調(diào)用Reschedule idle( ) 函數(shù),嘗試在一個(gè)空閑的CPU 上運(yùn)行被喚醒的進(jìn)程,它使高優(yōu)先級(jí)的進(jìn)程得到占用CPU 的機(jī)會(huì)。此時(shí)函數(shù)Reschedule idle 被調(diào)用, 嘗試在別的CPU 上調(diào)度該進(jìn)程。

    函數(shù)Reschedule idle首先檢查進(jìn)程上次運(yùn)行的CPU,如果該CPU處于忙狀態(tài),則找其它合適的CPU,查看SMP中的每個(gè)CPU上運(yùn)行的進(jìn)程,并與現(xiàn)有進(jìn)程相比優(yōu)先權(quán),把具有最高的搶先權(quán)值的進(jìn)程記錄在target_task中。 如target_task為空,說明沒有找到合適的CPU;如果target_task不為空,則說明找到了合適的CPU,將target_task->need_resched置為1。如果運(yùn)行target_task的CPU不是當(dāng)前運(yùn)行的CPU,則向運(yùn)行target_task的CPU發(fā)送一個(gè)IPI中斷,讓它重新調(diào)度,實(shí)現(xiàn)對(duì)進(jìn)程的調(diào)度功能。

    3.3 負(fù)載均衡

    在SMP多核系統(tǒng)中,每個(gè)處理器都有獨(dú)立的運(yùn)行隊(duì)列runqueue,當(dāng)存在多個(gè)就緒進(jìn)程隊(duì)列runqueue,CPU會(huì)一直處于忙狀態(tài)。相反,當(dāng)runqueue較少時(shí),相應(yīng)的CPU可能會(huì)經(jīng)常處于空轉(zhuǎn)狀態(tài),這會(huì)導(dǎo)致CPU負(fù)載不均衡。Linux對(duì)負(fù)載均衡的實(shí)現(xiàn)重點(diǎn)體現(xiàn)在何時(shí)檢查負(fù)載,如何調(diào)整負(fù)載。

    檢查負(fù)載有2種方法:1)在進(jìn)程的啟動(dòng)、睡眠時(shí)進(jìn)行檢查;2)定時(shí)檢查。

    當(dāng)進(jìn)程調(diào)用了sleep,pause等操作時(shí),schedule()函數(shù)會(huì)調(diào)用idle_balance(),從其他CPU挪用進(jìn)程過來。定時(shí)檢查利用函數(shù)rebalance_tick()來實(shí)現(xiàn),在每個(gè)CPU上的每個(gè)定時(shí)器的tick時(shí)刻調(diào)用rebalance_tick(),檢查每個(gè)調(diào)度域,在一定的時(shí)間間隔內(nèi)調(diào)用函數(shù)load_balance()進(jìn)行負(fù)載平衡。

    Linux系統(tǒng)中,在load_balance函數(shù)及idle_balance函數(shù)中調(diào)用pull_task函數(shù)以從重載CPU上將進(jìn)程“搬運(yùn)”到輕載CPU上,實(shí)現(xiàn)負(fù)載平衡。函數(shù)load_balance根據(jù)當(dāng)前CPU是否空閑分為“忙平衡”和“空閑平衡”。每tick時(shí)鐘中斷會(huì)啟動(dòng)一次函數(shù)rebalance_tick來計(jì)算合適的時(shí)間間隔,啟動(dòng)函數(shù)load_balance平衡負(fù)載。另外,在調(diào)度器schedule中,如果本CPU的就緒隊(duì)列為空也會(huì)調(diào)用idle_balance函數(shù)進(jìn)行“空閑平衡”。函數(shù)pull_task實(shí)現(xiàn)任務(wù)的搬運(yùn)工作,更新進(jìn)程的timestamp屬性,如果搬運(yùn)過來的進(jìn)程優(yōu)先級(jí)比本CPU正運(yùn)行的進(jìn)程高,則當(dāng)前進(jìn)程被搶占。

    staticvoidrebalance_tick(){……if(idle!=SCHED_IDLE)interval?=sd->busy_factor;……}

    4 Linux在S698PM中的應(yīng)用驗(yàn)證

    移植完成后,Linux可以在S698PM平臺(tái)正確運(yùn)行,本文以S698PM處理器的1553B應(yīng)用為例,驗(yàn)證Linux SMP系統(tǒng)的運(yùn)行過程。

    應(yīng)用程序中使片內(nèi)1553B為RT模式,同時(shí)打開1553B的2路接收,相當(dāng)于在Linux操作系統(tǒng)中開啟了2個(gè)進(jìn)程來實(shí)現(xiàn)RT的接收功能,在RT接收過程中,Linux操作系統(tǒng)還需要處理其他的進(jìn)程,如:sshd守護(hù)進(jìn)程、shell進(jìn)程等,觀察程序的運(yùn)行過程可以大概了解Linux的進(jìn)程管理方法。

    執(zhí)行user/custom/Makefile腳本文件編譯應(yīng)用并生成image.dsu文件,下載到S698PM板卡中運(yùn)行,并連續(xù)向這2路1553B接口發(fā)送數(shù)據(jù),程序運(yùn)行如圖3所示。

    從圖4 可以看出,當(dāng)2路1553B同時(shí)接收時(shí),Linux會(huì)根據(jù)SMP調(diào)度機(jī)制將2路接收進(jìn)程分配在CPU0和CPU1上同時(shí)運(yùn)行,實(shí)現(xiàn)了資源合理分配和負(fù)載平衡。并且2路之間沒有出現(xiàn)延時(shí)和漏數(shù)的現(xiàn)象,證明系統(tǒng)的進(jìn)程調(diào)度和同步機(jī)制工作正常。

    5 結(jié)論

    通過修改Linux的啟動(dòng)代碼,實(shí)現(xiàn)了對(duì)基于SPARC的SMP對(duì)稱多核SOC處理器的支持,通過在S698PM處理器平臺(tái)上運(yùn)行Linux,驗(yàn)證了Linux針對(duì)SMP系統(tǒng)的同步機(jī)制、進(jìn)程調(diào)度和負(fù)載平衡這3個(gè)重要特性。

    [1] [美]ScottMaxwell. Linux 內(nèi)核源代碼分析[M]. 馮銳, 等. 譯.北京: 機(jī)械工業(yè)出版社, 2000.

    [2] Bovet, Cesati .深入理解Linux 內(nèi)核[M]. 陳莉君, 等. 譯.北京:中國(guó)電力出版社, 2001.

    [3] [美]李(Li,Q),等.嵌入式系統(tǒng)的實(shí)時(shí)概念[M].王安生.譯.北京:北京航空航天大學(xué)出版社,2004.

    [4] S698PM用戶手冊(cè)[Z].珠海歐比特控制工程股份有限公司,2014,6.

    Study on Linux Application Based on Multi-Core SPARC SOC

    Wang Haifeng1, Jiang Xiaohua2

    1. Guangdong Institute of Science and Technology, Zhuhai 519090, China 2.Orbita Control Engineering Co.,Ltd., Zhuhai 519080, China

    Firstly,bythetransplantationofthestartupcode, LinuxcanrunontheSPARCmulti-coreprocessor.Then,theLinuxprocessmanagementfortheSMPmulti-coresystemisfocused,includingsynchronizationmechanism,processschedulingandloadbalance.Finally,theactualverificationisimplementedinS698PMmulti-coreprocessorplatform.

    Multi-coresystem;SPARC SOC;Linux;Dispatchprocessing;S698PM

    圖3 Linux在S698PM運(yùn)行

    圖4 Linux 1553B RT運(yùn)行截圖

    TP316

    A

    1006-3242(2017)03-0049-05

    2015-06-10

    王海峰(1974-),男,山西永濟(jì)人,碩士,副教授,主要研究方向?yàn)殡娮优c信息系統(tǒng);蔣曉華(1978-),男,湖南衡陽人,碩士,高級(jí)工程師,主要研究方向?yàn)榧呻娐吩O(shè)計(jì)。

    武穴市| 云浮市| 荔浦县| 青龙| 通海县| 淳化县| 大城县| 靖州| 无极县| 绥芬河市| 长治县| 灌南县| 富裕县| 黄骅市| 延庆县| 高邑县| 宣汉县| 凯里市| 上高县| 宜昌市| 泽州县| 察哈| 上犹县| 塔河县| 晴隆县| 新田县| 云安县| 金平| 盐亭县| 安阳市| 余江县| 永清县| 宿松县| 大理市| 滕州市| 临漳县| 翁源县| 东乡县| 内乡县| 北宁市| 古浪县|