導航:首頁 > 操作系統 > linux內核啟動文件

linux內核啟動文件

發布時間:2023-05-25 12:55:08

1. 如何調整linux內核啟動中的驅動初始化順序

【問題】 此處我要實現的是將晶元的ID用於網卡MAC地址,網卡驅動是enc28j60_init。 但是,讀取晶元ID的函數,在as352x_afe_init模塊中,所以要先初始化as352x_afe_init。 此處,內核編譯完之後,在生成的system.map中可以看到, enc28j60_init在as352x_afe_init之前,所以,無法去讀晶元ID。 所以我們的目標是,將as352x_afe_init驅動初始化放到enc28j60_init之前, 然後才能讀取晶元ID,才能用於網卡初始化的時候的,將晶元ID設置成網卡MAC地址。

【解決過程】

【1】

最簡單想到的,是內核裡面的

archarmmach-as352xcore.c

中,去改devices設備列表中的順序。

enc28j60_init對應的是ssp_device,因為網卡初始化用到的是SPI驅動去進行和通訊的。

as352x_afe_init對應的是afe_device。

原先是:

把afe改到最前面:

但是,實際結果是,沒有任何影響,連systemp.map生成的,那麼模塊初始化順序,都沒有任何變化。 也就說明,想要實現驅動載入順序的改變,改core.c裡面的設備列表順序是沒有用的。

更多linux內核視頻教程文檔資料免費領取後台私信 【內核】 自行獲取.

Linux內核源碼/內存調優/文件系統/進程管理/設備驅動/網路協議棧-學習視頻教程-騰訊課堂

【2】

在網上看到很多帖子,其說明的也很清楚了,就是:

Linux內核為不同驅動的載入順序對應不同的優先順序,定義了一些宏:

includelinuxinit.h

把自己的驅動的函數名用這些宏去定義之後, 就會對應不同的載入時候的優先順序。

其中,我們寫驅動中所用到的mole_init對應的是 #define mole_init(x) __initcall(x); 而 #define __initcall(fn) device_initcall(fn) 所以,驅動對應的載入的優先順序為6

在上面的不同的優先順序中, 數字越小,優先順序越高。 同一等級的優先順序的驅動,載入順序是鏈接過程決定的,結果是不確定的,我們無法去手動設置誰先誰後。 不同等級的驅動載入的順序是先優先順序高,後優先順序低,這是可以確定的。

所以,像我們之前在驅動中用:

所以,大家都是同一個優先順序去初始化,

最後這些驅動載入的順序,可以查看在根目錄下,

生成的system.map:

此處就是由於 c0019920 t __initcall_i2c_dev_init6 c0019924 t __initcall_as352x_afe_i2c_init6 c0019928 t __initcall_as352x_afe_init6 在c00198e4 t __initcall_enc28j60_init6之前,所以我這里才要去改。。。 知道原理,能想到的,就是要麼把as352x_afe_init改到enc28j60_init之前一級,即優先順序為5。即在驅動中,調用:fs_initcall(as352x_afe_init);要麼把enc28j60_init改到as352x_afe_init之後,即優先順序為7即在驅動中,調用:late_initcall(enc28j60_init);但是,此處麻煩就麻煩在,如果把as352x_afe_init改到enc28j60_init之前一級,發現後面網卡初始化enc28j60_init中,雖然讀取晶元ID對了,但是後面的IP-auto configure 有問題。所以放棄。 如果把enc28j60_init改到as352x_afe_init之後,但是,從system.map中看到的是,優先順序為7的驅動中,明顯有幾個驅動,也是和網卡初始化相關的,所以,這樣改,嘗試後,還是失敗了。 所以,沒法簡單的通過調整現有的驅動的順序,去實現順序的調整。最後,被逼無奈,想到了一個可以實現我們需求的辦法,那就是,單獨定義一個優先順序,把afe相關的初始化都放到那裡面去,這樣,就可以保證,其他沒什麼相關的沖突了。最後證實,這樣是可以實現目的的。

具體添加一個新的優先順序的步驟如下: 1.定義新的優先順序 includelinuxinit.h中:

2.用對應新的宏,定義我們的驅動:

做到這里,本以為可以了,但是編譯後,在system.map中,發現之前優先順序為7的那幾個函數,被放到system.map最後了,而不是預想的,在優先順序7之後,在

之前。最後,發現時沒有把對應的鏈接文件中的宏加進去:

3.includeasm-genericvmlinux.lds.h

最後,再重新編譯,就可以實現我們要的,和afe相關的驅動初始化,都在網卡enc28j60_init之前了。也就可以在網卡裡面讀晶元ID了。當然,對應編譯生成的system.map文件中,對應的通過mole_init定義的驅動,優先順序也都變成7了。而late_initcall對應優先順序8了。 註:當前開發板arm的板子,所以,對應的load 腳本在:

linux-2.6.28.4archarmkernelvmlinux.lds 看起來,應該是這個文件: linux-2.6.28.4archarmkernelvmlinux.lds.S 生成上面那個腳本的。vmlinux.lds中的這一行:

就是將之前那些對應的init類型的函數,展開,放到這對應的位置。

【3】 不過,最後的最後,竟然發現網卡還是工作不正常,結果第二天,無意間發現是網卡地址設置導致網卡工作不正常的。 也就是說,實際是直接將afe設置到原先的優先順序5就可以的,而不用這么麻煩去改系統的東西的...

不過,至少這也是一種辦法,雖然不是那麼的好...

2. Linux系統開機時啟動內核步驟是什麼

實模式,並開始執行位於地址0xFFFF0處
的代碼,也就是ROM-BIOS起始位置的代碼。BIOS先進行一系列的系統自檢,然後初始化位
於地址0的中斷向量表。最後BIOS將啟動盤的第一個扇區裝入到0x7C00,並開始執行此處
的代碼。這就是對內核初始化過程的一個最簡單的描述。
最初,linux核心的最開始部分是用8086匯編語言編寫的。當開始運行時,核心將自
己裝入到絕對地址0x90000,再將其後的2k位元組裝入到地址0x90200處,最後將核心的其餘
部分裝入到0x10000。
當系統裝入時,會顯示Loading...信息。裝入完成後,控制轉向另一個實模式下的匯
編語言代碼boot/Setup.S。Setup部分首先設置一些系統的硬體設備,然後將核心從
0x10000處移至0x1000處。這時系統轉入保護模式,開始執行位於0x1000處的代碼。
接下來是內核的解壓縮。0x1000處的代碼來自於文件Boot/head.S,它用來初始化寄
存器和調用decompress_kernel( )程序。decompress_kernel( )程序由Boot/inflate.c,
Boot/unzip.c和Boot../misc.c組成。解壓縮後的數據被裝入到了0x100000處,這也是
linux不能在內存小於2M的環境下運行的主要原因。
解壓後的代碼在0x1010000處開始執行,緊接著所有的32位的設置都將完成: IDT、
GDT和LDT將被裝入,處理器初始化完畢,設置好內存頁面,最終調用start_kernel過程。
這大概是整個內核中最為復雜的部分。
[系統開始運行]
linux kernel 最早的C代碼從匯編標記startup_32開始執行
startup_32:
start_kernel
lock_kernel
trap_init
init_IRQ
sched_init
softirq_init
time_init
console_init
#ifdef CONFIG_MODULES
init_moles
#endif
kmem_cache_init
sti
calibrate_delay
mem_init
kmem_cache_sizes_init
pgtable_cache_init
fork_init
proc_caches_init
vfs_caches_init
buffer_init
page_cache_init
signals_init
#ifdef CONFIG_PROC_FS
proc_root_init
#endif
#if defined(CONFIG_SYSVIPC)
ipc_init
#endif
check_bugs
smp_init
rest_init
kernel_thread
unlock_kernel
cpu_idle
・startup_32 [arch/i386/kernel/head.S]
・start_kernel [init/main.c]
・lock_kernel [include/asm/smplock.h]
・trap_init [arch/i386/kernel/traps.c]
・init_IRQ [arch/i386/kernel/i8259.c]
・sched_init [kernel/sched.c]
・softirq_init [kernel/softirq.c]
・time_init [arch/i386/kernel/time.c]
・console_init [drivers/char/tty_io.c]
・init_moles [kernel/mole.c]
・kmem_cache_init [mm/slab.c]
・sti [include/asm/system.h]
・calibrate_delay [init/main.c]
・mem_init [arch/i386/mm/init.c]
・kmem_cache_sizes_init [mm/slab.c]
・pgtable_cache_init [arch/i386/mm/init.c]
・fork_init [kernel/fork.c]
・proc_caches_init
・vfs_caches_init [fs/dcache.c]
・buffer_init [fs/buffer.c]
・page_cache_init [mm/filemap.c]
・signals_init [kernel/signal.c]
・proc_root_init [fs/proc/root.c]
・ipc_init [ipc/util.c]
・check_bugs [include/asm/bugs.h]
・smp_init [init/main.c]
・rest_init
・kernel_thread [arch/i386/kernel/process.c]
・unlock_kernel [include/asm/smplock.h]
・cpu_idle [arch/i386/kernel/process.c]
start_kernel( )程序用於初始化系統內核的各個部分,包括:
*設置內存邊界,調用paging_init( )初始化內存頁面。
*初始化陷阱,中斷通道和調度。
*對命令行進行語法分析。
*初始化設備驅動程序和磁碟緩沖區。
*校對延遲循環。
最後的function'rest_init' 作了以下工作:
・開辟內核線程'init'
・調用unlock_kernel
・建立內核運行的cpu_idle環, 如果沒有調度,就一直死循環
實際上start_kernel永遠不能終止.它會無窮地循環執行cpu_idle.
最後,系統核心轉向move_to_user_mode( ),以便創建初始化進程(init)。此後,進程0開始進入無限循環。
初始化進程開始執行/etc/init、/bin/init 或/sbin /init中的一個之後,系統內核就不再對程序進行直接控制了。之後系統內核的作用主要是給進程提供系統調用,以及提供非同步中斷事件的處理。多任務機制已經建立起來,並開始處理多個用戶的登錄和fork( )創建的進程。
[init]
init是第一個進程,或者說內核線程
init
lock_kernel
do_basic_setup
mtrr_init
sysctl_init
pci_init
sock_init
start_context_thread
do_init_calls
(*call())-> kswapd_init
prepare_namespace
free_initmem
unlock_kernel
execve
[目錄]
--------------------------------------------------------------------------------
啟動步驟
系統引導:
涉及的文件
./arch/$ARCH/boot/bootsect.s
./arch/$ARCH/boot/setup.s
bootsect.S
這個程序是linux kernel的第一個程序,包括了linux自己的bootstrap程序,
但是在說明這個程序前,必須先說明一般IBM PC開機時的動作(此處的開機是指
"打開PC的電源"):
一般PC在電源一開時,是由內存中地址FFFF:0000開始執行(這個地址一定
在ROM BIOS中,ROM BIOS一般是在FEOOOh到FFFFFh中),而此處的內容則是一個
jump指令,jump到另一個位於ROM BIOS中的位置,開始執行一系列的動作,包
括了檢查RAM,keyboard,顯示器,軟硬磁碟等等,這些動作是由系統測試代碼
(system test code)來執行的,隨著製作BIOS廠商的不同而會有些許差異,但都
是大同小異,讀者可自行觀察自家機器開機時,螢幕上所顯示的檢查訊息。
緊接著系統測試碼之後,控制權會轉移給ROM中的啟動程序
(ROM bootstrap routine),這個程序會將磁碟上的第零軌第零扇區讀入
內存中(這就是一般所謂的boot sector,如果你曾接觸過電腦病
毒,就大概聽過它的大名),至於被讀到內存的哪裡呢? --絕對
位置07C0:0000(即07C00h處),這是IBM系列PC的特性。而位在linux開機
磁碟的boot sector上的正是linux的bootsect程序,也就是說,bootsect是
第一個被讀入內存中並執行的程序。現在,我們可以開始來
看看到底bootsect做了什麼。
第一步
首先,bootsect將它"自己"從被ROM BIOS載入的絕對地址0x7C00處搬到
0x90000處,然後利用一個jmpi(jump indirectly)的指令,跳到新位置的
jmpi的下一行去執行,
第二步
接著,將其他segment registers包括DS,ES,SS都指向0x9000這個位置,
與CS看齊。另外將SP及DX指向一任意位移地址( offset ),這個地址等一下
會用來存放磁碟參數表(disk para- meter table )
第三步
接著利用BIOS中斷服務int 13h的第0號功能,重置磁碟控制器,使得剛才
的設定發揮功能。
第四步
完成重置磁碟控制器之後,bootsect就從磁碟上讀入緊鄰著bootsect的setup
程序,也就是setup.S,此讀入動作是利用BIOS中斷服務int 13h的第2號功能。
setup的image將會讀入至程序所指定的內存絕對地址0x90200處,也就是在內存
中緊鄰著bootsect 所在的位置。待setup的image讀入內存後,利用BIOS中斷服
務int 13h的第8號功能讀取目前磁碟的參數。
第五步
再來,就要讀入真正linux的kernel了,也就是你可以在linux的根目錄下看
到的"vmlinuz" 。在讀入前,將會先呼叫BIOS中斷服務int 10h 的第3號功能,
讀取游標位置,之後再呼叫BIOS 中斷服務int 10h的第13h號功能,在螢幕上輸
出字串"Loading",這個字串在boot linux時都會首先被看到,相信大家應該覺
得很眼熟吧。
第六步
接下來做的事是檢查root device,之後就仿照一開始的方法,利用indirect
jump 跳至剛剛已讀入的setup部份
第七步
setup.S完成在實模式下版本檢查,並將硬碟,滑鼠,內存參數寫入到 INITSEG
中,並負責進入保護模式。
第八步
操作系統的初始化。

3. redhatenterpriselinux7的內核程序存儲於那個目錄

管理類文件夾: /boot 該目錄默認下存放的是Linux的啟動文件和內核,例如LILO或GRUB的文件。 /initrd 它的英文含義是boot loader initialized RAM disk,就是由boot loader初始化的內存檔。在linux內核啟動前,boot loader會將存儲介質(一般是硬碟)中的initrd文件載入到內存,內核啟動時會在訪問真正的根文件系統前先訪問該內存中的initrd文件系統。 /bin 該目錄中存放Linux的常用命令。 /sbin 該目錄用來存放系統管理員使用的管理程序。 /var 該目錄存放那些經常被修改的文件,包括各種日誌、數據文件。如果做mail server,則需在Linux安裝時將該目錄設梁裂置為大空間。 /etc 該目錄存放系統管理時要用到的各種配置文件和子目錄,例如網路配置文件、文件系統、X系統配置文件、設備配置信息、設置用戶信息等。如果做web server,則需在Linux安裝時將該目錄設置為大空間。 /dev 該目錄包含了Linux系統中使用的纖攜所有外部設備,它實際上是訪問這些外部設備的埠,訪問這些外部設備與訪問一個文件或一個目錄沒有區別。例如在系統中鍵入「cd /dev/cdrom」就可以看到光碟機中的文件。 /mnt 該目錄默認下有2個分別對應光碟機和軟碟機的文件夾cdrom和floppy。你可以臨時將別的文件系統掛在該目錄下,例如「掛載光碟機mount/dev/cdrom /mnt/cdrom,查看光碟機cd /mnt/cdrom」,養成良好習慣不使用時及時卸載「umount /mnt/cdrom」。 二、用戶類文件夾: /root 如果你是以超級用戶的身份登錄的,這個就是超級用戶的主目錄。 /home 如果建立一個名為「xx」的用戶,那麼在/home目錄下就有一個對應的「/home/xx」路徑,用來存放該用戶的主目錄。
三、應用程序類文件夾: /usr 用戶的應用程序和文件幾乎都存放橡豎閉在該目錄下。

4. linux安裝了多個kernel,如何配置啟動文件

2中方法:

  1. 開機的時候看到啟動菜單的時候,按上下鍵侍皮來選擇內核。

  2. vi /boot/grub/grub.conf

    default=0 改成對應鋒談正銀悔的內核即可。default=1 (如果是第二套的話)

5. Linux系統啟動的大致過程

Linux系統啟動的大致過程

Linux操作系統是基於UNIX操作系統發展而來的一種克隆系統,它誕生於1991 年的 [Linux桌面] 10 月5 日。下面我准備了關於Linux系統啟動的大致過程,提供給大家參考!

第一階段:BIOS啟動引導階段;

在該過程中實現硬體的.初始化以及查找啟動介質;

從MBR中裝載啟動引導管理器(GRUB)並運行該啟動引導管理

第二階段:GRUB啟動引導階段;

裝載stage1

裝載stage1.5

裝載stage2

讀取/boot/grub.conf文件並顯示啟動菜單;

裝載所選的kernel和initrd文件到內存中

第三階段:內核階段:

運行內核啟動參數;

解壓initrd文件並掛載initd文件系統,裝載必須的驅動;

掛載根文件系統

第四階段:Sys V init初始化階段:

啟動/sbin/init程序;

運行rc.sysinit腳本,設置系統環境,啟動swap分區,檢查和掛載文件系統;

讀取/etc/inittab文件,運行在/et/rc.d/rc<#>.d中定慶液義的不同運行級別的服務初始化腳本;

打開字清差睜符終端1-6號控制台/打開圖形顯示管理的7號控制台

同時在上述過程中各階段所需要讀取的文件和操作的對象:

BIOS啟動引導階段 GRUB啟答歲動引導階段 內核階段 /init/sysinit階段

====================================================================================

None /boot/grub/grub.conf /boot/vmlinuz- /etc/rc.d/rc.sysinit

/boot/grub/stage1_5 /boot/initrd- /etc/inittab

/boot/grub/stage2 /etc/rc.d/rc<#>.d

/etc/rc.d/init.d/*

;
閱讀全文

與linux內核啟動文件相關的資料

熱點內容
51單片機課程設計課題 瀏覽:895
手機淘寶登錄怎麼加密碼 瀏覽:481
linux快捷方式圖標 瀏覽:34
陽光車險的app叫什麼名字 瀏覽:461
購買單片機的器件時需要給商家啥 瀏覽:534
並行編譯技術的發展 瀏覽:549
阿里雲伺服器安裝管理 瀏覽:550
java手機開發教程 瀏覽:674
我的世界怎麼刪除伺服器數據 瀏覽:671
linux內存子系統 瀏覽:972
加密思維幣 瀏覽:690
魅族訪客文件夾 瀏覽:52
添加的文件夾怎麼找 瀏覽:617
程序員涉黃 瀏覽:700
maven編譯resources下的js 瀏覽:521
ubuntu文件移動命令 瀏覽:229
安卓i怎麼查找蘋果手機 瀏覽:951
雲伺服器宕機概率 瀏覽:232
在線買葯用什麼app知乎 瀏覽:815
ubuntu解壓xz文件 瀏覽:676