程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 嵌入式開發工程師面試題 – C語言部分

嵌入式開發工程師面試題 – C語言部分

編輯:C++入門知識

嵌入式開發工程師面試題 – C語言部分

申明:來源於嵌入式開發工程師面試題 – C語言部分 和 網摘)!

1.內核的裁剪怎麼裁剪

解析:在linux 下的ubuntu 上面做內核的裁剪,主要講講在UI界面做menuconfig 中配置!

下面就是UI界面的簡介

詳細介紹內核配置選項及刪改情況
第一部分:全部刪除
Code maturity level options ---> 代碼成熟等級選項
[]Prompt for development and/or incomplete code/drivers 默認情況下是選擇的,這將會在設置界面中顯示還在開發或者還沒有完成的代碼與驅動.不選。


第二部分 :除以下選項,其它全部刪除
General setup—〉
System V IPC (IPC:Inter Process Communication)是組系統調用及函數庫,它能讓程序彼此間同步進行交換信息。某些程序以及DOS模擬環境都需要它。為進程提供通信機制,這將使系統中各進程間有交換信息與保持同步的能力。有些程序只有在選Y的情況下才能運行,所以不用考慮,這裡一定要選。


第三部分:除以下選項,其它全部刪除
Loadable module support ---> 可引導模塊支持 建議作為模塊加入內核
[] Enable loadable module support 這個選項可以讓你的內核支持模塊,模塊是什麼呢?模塊是一小段代碼,編譯後可在系統內核運行時動態的加入內核,從而為內核增加一些特性或是對某種硬件進行支持。一般一些不常用到的驅動或特性可以編譯為模塊以減少內核的體積。在運行時可以使用modprobe命令來加載它到內核中去(在不需要時還可以移除它)。一些特性是否編譯為模塊的原則是,不常使用的,特別是在系統啟動時不需要的驅動可以將其編譯為模塊,如果是一些在系統啟動時就要用到的驅動比如說文件系統,系統總線的支持就不要編為模塊了,否在無法啟動系統。
[]Automatic kernel module loading 一般情況下,如果我們的內核在某些任務中要使用一些被編譯為模塊的驅動或特性時,我們要先使用modprobe命令來加載它,內核才能使用。不過,如果你選擇了這個選項,在內核需要一些模塊時它可以自動調用modprobe命令來加載需要的模塊,這是個很棒的特性,當然要選Y喽。
第四部分:全部刪除
Block layer-----〉塊設備


第五部分:除以下選項,其它全部刪除
Processor type and features ---> 處理器類型
Subarchitecture Type (PC-compatible) ---> 這選項的主要的目的,是使Linux可以支持多種PC標准,一般我們使用的PC機是遵循所謂IBM兼容結構(pc/at)。這個選項可以讓你選擇一些其它架構。我們一般選擇PC-compatible就可以了。
Processor family(386) : 它會對每種CPU做最佳化,讓它跑的好又快,一般來說,你是什麼型號的就選什麼型號的就好。我選的是386,這樣內核會省下不少空間


第六部分:除以下選項,其它全部刪除
Power management options (ACPI, APM) ---> 電源管理選項
[ ] Power Management Debug Support 電源管理的調試信息支持,如果不是要調試內核有關電源管理部份,請不要選擇這項。
ACPI Support ---〉高級電源接口配置支持,如果BIOS支持,建議選上這項
[]Button 這個選項用於注冊基於電源按鈕的事件,比如power, sleep等,當你按下按鈕時事件將發生,一個守護程序將讀取/proc/acpi/event,並執行用戶在這些事件上定義的動作比如讓系統關機。可以不選擇,根據自己的需求。


第七部分:除以下選項,其它全部刪除
Bus options (PCI, PCMCIA, EISA, MCA, ISA) ---> 總線選項
[]PCI support
PCI access mode (Any) ---> PCI外圍設備配置,強列建議選Any,系統將優先使用MMConfig,然後使用BIOS,最後使用Direct檢測PCI設備。


第八部分:除以下選項,其它全部刪除
Executable file formats --->
Kernel support for ELF binaries ELF是開放平台下最常用的二進制文件,它支持不同的硬件平台。一定要選。
第九部分:除以下選項,其它全部刪除
Networking
Networking options --->
[]Unix domain sockets
[]TCP/IP networking
第十部分:除以下選項,其它全部刪除
Device Drivers --->設備驅動
Block devices-------〉
[]Compaq SMART2 support
[] Compaq Smart Array 5xxx support
[]Loopback device support 大部分的人這一個選項都選N,因為沒有必要。但是如果你要mount iso文件的話,你得選上Y。這個選項的意思是說,可以將一個文件掛成一個文件系統。如果要燒光盤片的,那麼您很有可能在把一個文件燒進去之前,看看這個文件是否符合IS09660的文件系統的內容,是否符合您的需求。而且,可以對這個文件系統加以保護。不過,如果您想做到這點的話,您必須有最新的mount程序,版本是在2.5X版以上的。而且如果您希望對這個文件系統加上保護,則您必須有des.1.tar.gz 這個程序。注意:此處與網絡無關。建議編譯成模塊
[] RAM disk support
SCSI device support ---> 裡面有關於USB支持的,要選擇
[]SCSI device support USB要用,必須選擇
[]legacy /proc/scsi/ support USB要用,必須選擇
[]SCSI disk support USB要用,必須選擇
SCSI Low-level drivers
[]Serial ATA(SATA) support
[]Intel PIIX/ICH SATA support 這個必須選擇,否則無法產生引導文件
[]Via SATA support
Networking device support ---> 這個下面是選網卡驅動,一定要選
Ethernet(1000mbit)-我的電腦是千兆網卡所以就選這個
[]broadcom Tigon3support
Input device support ---> 這個裡面要設置你的鼠標鍵盤什麼的
[]Provide legacy /dev/psaux device
Graphics support --->
[]Support for frame buffer devices 支持Frame buffer的,一定要選擇
USB support --->
[]USB device filesystem 這個好象是用U盤必須的
[]EHCI HCD (USB 2.0) support 有usb2.0就選上把,編譯成模塊
[]OHCI HCD support 必須選擇,編譯成模塊
[]UHCI HCD (most Intel and VIA) support 必須選擇,編譯成模塊
[]USB Mass Storage support 用U盤必須選擇
USB Human Interface Device (full HID) support 裡面選擇usb鼠標和usb鍵盤,如果你有一定選上這個必需選
HID input layer support 應該選擇
/dev/hiddev raw HID device support如果這裡有USB鍵盤和鼠標選項,一定要選擇

第十一部分:除以下選項,其它全部刪除
file systems --->文件系統
<*> Second extended fs support
[*] Ext2 extended attributes
[*] Ext2 POSIX Access Control Lists
[*] Ext2 Security Labels
Ext3 journalling file system support
[*] Ext3 extended attributes
[*] Ext3 POSIX Access Control Lists
[*] Ext3 Security Labels 以上這些肯定是要選擇的,linux的標准文件系統
Kernel automounter support 內核自動掛載的,當然要選
Kernel automounter version 4 support (also supports v3) 當然要選
DOS/FAT/NT Filesystems --->
DOS FAT fs support
MSDOS fs support
VFAT (Windows-95) fs support
NTFS file system support
Native language support&#61664;語言支持,這裡就支持英語和漢語就行了,不多說了
[]NLS ISO 8859-1 必須選擇,這個是關於U盤掛載的。
CD-ROM/DVD Filesystems ---> 這個是關於掛載ISO文件的,用的話就選。
<*> ISO 9660 CDROM file system support
第十二部分: 全部刪除
Instrumentation support
第十三部分:全部刪除
Kernel hacking --->破解核心?可不是當骸客啦,不選
第十四部分:全部刪除
Security options --->
第十五部分:全部刪除
Cryptographic options --->這是核心支持加密的選項
第十六部分:全部刪除
Library routines --->




附:
內核配置
  內核配置的方法很多,make config、make xconfig、make menuconfig、make oldconfig等等,它們的功能都是一樣的,區別應該從名字上就能看出來,只有make oldconfig是指用系統當前的設置(./.config)作為缺省值。這裡用的是make menuconfig。
  需要牢記:不必要的驅動越多,內核就越大,不僅運行速度慢、占用內存多,在少數情況下、還會引發其他問題。具體步驟如下:
首先確定shell是bash。
然後
$make menuconfig
有一些默認的符號其含義如下:
y:加載
n:不加載
m:作為模塊加載

可以配置的選項有以下一些:
1)code maturity level option 代碼成熟度
prompt for development and/or incomplete code/drivers [N/y/?]
如果有興趣測試一下內核中尚未最終完成的某些模塊,就選y,否則選N,想知道更詳細的信息選?會看到聯機幫助(以下?的含義相同),N大寫表示缺省值。

2)processor type and features 處理器類型及特性
Processor family(386,486/Cx486,586/K5/5x86/6x86,Pentium/K6/TSC, PPro/6x86MX)[PPro/6x86MX]
[]內的是缺省值,我們可以根據前面介紹的uname 命令執行的結果選擇。此項如果高於386,那麼生成的內核在386機器上將不能啟動。
Math emulation(CONFIG_MATH_EMULATION)[N/y/?]
需要進行協處理器模擬嗎?一般的機器都回n。如果機器已經有硬件的協處理器,那麼內核仍將使用硬件,而忽略軟件的math-emulation,這將使內核變大變慢。
MTRR(Memory Type Range Register)support(CONFIG_MTRR)[N/y/?]
在Pentium、Pro/Pentium II類的系統中可以提高圖像寫入速度。
Symmetric multi-processing support(CONFIG_SMP)[Y/n/?]
如果您的機器有多個處理器,就選y。此時要選中下面的Enhanced Real Time Clock Support

3)loadable model support 可加載模塊支持
Enable loadable module support(CONFIG_MODULES)[Y/n/?]
最好選y,不然許多僅供動態加載的模塊就不能用了。
Set version information on all symbols for modules(CONFIG_MODVERSIONS)[N/y/?]
選N
Kernel module loader(CONFIG_KMOD)[N/y/?]

4)general setup 一般設置
Networking support(CONFIG_NET)[Y/n/?]
選y吧,現在還有幾台計算機不用上網呢?
PCI support (CONFIG_PCI)[Y/n/?]
PCI 總線和設備總該有吧。
PCI access mode(BIOS,Direct,Any)[Any]
缺省值比較保險,但如果您對您的主板很有信心,就選BIOS。
PCI quirks (CONFIG_PCI_QUIRKS)[Y/n/?]
用於修補BIOS中對PCI有影響的BUG,同樣,如果您對主板很有信心,就選n。
Backward-compatible /proc/pci〉(CONFIG_PCI_OLD_PROC)[Y/n/?]
以前的內核使用/proc/pci,新版內核使用/proc/bus/pci,要保持兼容性就選y。
MCA support(CONFIG_MCA)[N/y/?]
查看幫助吧。
SGI Visual Workstation support(CONFIG_VISWS)[N/y/?]
您的機器是SGI的嗎?是就選y。
System V IPC(CONFIG_SYSVIPC)[Y/n/?]
進程間通信函數和系統調用。Linux內核的五大組成部分之一,一定要選。
BSD Process Accounting(CONFIG_BSD_PROCESS_ACCT)[N/y/?]
用於啟動由內核將進程信息寫入文件的用戶級系統調用。就看您想不想用它了。
Sysctl support(CONFIG_SYSCTL)[Y/n/?]
在內核正在運行的時候修改內核。用8KB空間換取某種方便。別選吧,除非你真的想試試。
Kernel support for a.out binaries(CONFIG_BINFMT_AOUT)[Y/m/n/?]
為了能使用以前編譯的程序,選y。
Kernel support for ELF binaries(CONFIG_BINFMT_ELF)[Y/m/n/?]
為了能使用現在編譯的程序,選y。
Kernel support for MISC binaries(CONFIG_BINFMT_MISC)[Y/m/n/?]
一般選y,用於支持java等代碼的自動執行。
Parallel port support(CONFIG_PARPORT)[N/y/m/?]
並口設備,如打印機。

5)plug and play support 即插即用設備支持
Plug and Play support (CONFIG_PNP)[N/y/?]
選y吧。

6)block devices 塊設備
Normal PC floppy disk support(CONFIG_BLK_DEV_FD)[Y/m/n/?]
一般的軟驅。選y。
Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support(CONFIG_BLK_DEV_IDE)[Y/m/n/?]
這幾種接口的硬盤、光驅、磁帶、軟驅。選y。
Include IDE/ATAPI CDROM support(CONFIG_BLK_DEV_IDECD)[Y/m/n/?]
CDROM。選y。

7)networking options 網絡選項
Packet socket (CONFIG_PACHET)[Y/m/n/?]
按照目前網絡發展的狀況,選y比較好。當然也可以選其它的。
Kernel/User netlink socke(CONFIG_NETLINK)[N/y/?]
內核與用戶進程雙向通信。選y。
Network firewalls(CONFIG_FIREWALL)[N/Y/?]
如果真的需要用防火牆,就選y。
UNIX domain sockets(confgi_unix)[Y/m/n/?]
socket 的用處太多了。選y。
TCP/IP networking(CONFIG_INET)[Y/n/?]
選y,理由如上一條。
The IPX protocol (CONFIG_IPX)[N/y/m/?]
其實並沒有那麼多人真的需要使用或者學習IPX,所以一般選N。
Appletalk DDP(CONFIG_ATALK)[N/y/m/?]
選N,理由同上。

8)SCSI support SCSI支持,SCSI low-level drives SCSI低級驅動
根據系統中SCSI設備的實際情況選擇。

9)Networking device support 網絡設備支持
如果用LAN上網,就選擇網卡;
如果用MODEM撥號上網,就要看ISP提供那種服務了,一般都是PPP。

10)Amateur Radio support 業余收音機支持
這是什麼我不太清楚,所以選N。

11)ISDN subsystem ISDN子系統
好像已經有支持ISDN的MODEM了,所以最好先看看自己的MODEM是不是這種,再做選擇。

12)Old CD-ROM dfivers (not SCSI, not IDE) 老式光驅驅動
一般選N,因為這種設備實在很少見。

13)Character devices 字符設備
Virtual terminal(CONFIG_VT)[Y/n/?]
Linux上一般可以用Alt+F1/F2/F3/F4來切換不同的任務終端,即使在一台計算機上也可以充分使用Linux的多任務能力,一些需要以命令行方式安裝合適用的軟件如果有虛擬終端的支持就會更方便,因此選y。
Support for console on virtual terminal(CONFIG_VT_CONSOLE)[Y/n/?]
選y將支持一個虛擬終端作為控制台。一般為Alt+F1。
Support for console on serial port(CONFIG_SERIAL)[Y/m/n/?]
除非真的需要一個串口控制台,否則選n。
Extended dumb serial driver options(CONFIG_SERIAL_EXTENDED)[N/y/?]
如果希望使用"dumb"的非標准特性(如HUB6支持),選y,一般選N。
Non-standard serial port support(CONFIG_SERIAL_NONSTANDARD)[N/y/?]
非標准串口。一般選N。
UNIX98 PTY support(CONFIG_UNIX98_PTYS)[Y/n/?]
PTY指偽終端,一般用戶就選n。但如果想用telnet或者xterms作為終端訪問主機,並且已經安裝了glibc2.1,就可以選y。
Maximum number of UNIX98 PTYs in use(0-2048)(CONFIG_UNIX98_PTY_COUNT)[256]
缺省值就可以了。
Mouse Support(not serial mice)(CONFIG_MOUSE)[Y/n/?]
PS/2等非串口鼠標選y,否則選N。

14)Mice 鼠標
根據自己的鼠標類型選擇。

15)Video for Linux Linux視頻
根據系統中的音/視頻捕捉設備選擇。

16)Joystick support 操縱桿
根據系統中的游戲桿設備選擇

17)Ftape,the floopy tape device driver Ftape設備驅動
Ftape (QIC-80/Travan)support(CONFIG_FTAPE)[N/y/m/?]
如果系統中有磁帶機,選y。

18)Filesystems 文件系統
文件系統的選擇要比較仔細,因為其中的一些給某些系統功能提供支持。而且除了proc、ext2等文件系統之外,其它的文件系統(包括下面的網絡文件系統)都可以選擇為m方式,從而減小內核啟動時的體積。
Quota support(CONFIG_QUOTA)[N/y/?]
用於給用戶劃分定量的磁盤空間。如不用此功能就選N。
DOS FAT fs support(CONFIG_FAT_FS)[N/y/m/?]
為內核提供FAT支持,多數用戶有可能從Linux訪問同一系統中的WINDOWS硬盤空間,因此最好選y。
ISO 9660 CDROM filesystem support(CONFIG_ISO9660_FS)[Y/m/n/?]
有標准光驅的系統應該選Y。
Minix fs support(CONFIG_MINIX_FS)[N/y/m/?]
用於創建啟動盤的文件系統,多數應該選y或者m。
/proc filesystem support(CONFIG_PROC_FS)[Y/n/?]
虛擬文件系統,必須選Y。
Second extended fs support(CONFIG_EXT2_FS)[Y/m/n/?]
Linux標准文件系統,都應該選Y。

19)Network file systems 網絡文件系統
Coda filesystem support (advanced network fs)(CONFIG_CODA_FS)[N/y/m/?]
先看幫助再選。
NFS filesystem support(CONFIG_NFS_FS)[Y/m/n/?]
選Y或n,能夠訪問遠程NFS文件系統。
SMB filesystem support(to mount WfW shares etc.)(CONFIG_SMB_FS)[N/y/m/?]
要訪問WINDOWS系統中的共享資源選y。
NCP filesystem support(to mout NetWare volumes)(CONFIG_NCP_FS)[N/y/m/?]
如果真的需要訪問NetWare文件系統,就選y或者m。

20)Partion Types 分區類型
一般用不上;要用請參看幫助。

21)Console drivers 控制台驅動
VGA text console(CONFIG_VGA_CONSOLE)[Y/n/?]
用VGA模式下用文本方式操作Linux,一般選y。
Video mode selection support(CONFIG_VIDEO_SELECT)[N/y/?]
大多數系統都不需要這項功能。

22)Sound 聲音
Sound card support(CONFIG_SOUND)[N/y/m/?]
如果系統中安裝了聲卡,就選y(或者m),然後查看幫助。

23)Kernel hacking 內核監視
kernel hacking往往會生成非常大或者非常慢(甚至又大又慢)的內核,甚至會引起內核工作不穩定。如果一定要選,那麼也最好不要選其中的"development"、"experimental"、"debugging"項。


2 深入理解uboot


解析:Uboot是嵌入式系統中最常用的bootloader,

1什麼是ubuoot

uboot可以再很多種cpu架構上運行,同時也支持很多開發板,但是每種cpu架構之間有差別,或者開發板的資源不同,假如在某款開發板上能正常引導啟動操作系統的話,並不意味著在其他款就能引導啟動,建立一款統一的bootloader幾乎是不可能的,但是經過大師們的努力,能夠實現通過簡單的配置改動,就可以實現引導啟動很多操作系統(也就是bootloader移植)(uboot是bootloader中的一種,因為其源碼是公開的,廣受歡迎)!

2 uboot的體系結構


1 目錄樹


|--board
|--common
|--cpu
|--disk
|--doc
|--drivers
|--dtt
|--examples
|--fs
|--include
|--lib_arm
|--lib_generic
|--net
|--post
|--rtc
|--tools


1. board:和一些已有開發板有關的文件. 每一個開發板都以一個子目錄出現在當前目錄中,比如說: leopard2a子目錄中存放與我們開發板相關的配置文件.
2. common:實現uboot命令行下支持的命令,每一條命令都對應一個文件。例如bootm命令對應就是cmd_bootm.c。
3. cpu:與特定CPU架構相關目錄,每一款Uboot下支持的CPU在該目錄下對應一個子目錄,比如有子目錄arm926ejs就是我們開發板上使用的cpu架構目錄。
4. disk:對磁盤的支持。
5. doc:文檔目錄。Uboot有非常完善的文檔,推薦大家參考閱讀。
6. drivers:Uboot支持的設備驅動程序都放在該目錄,比如各種網卡、支持CFI的Flash、串口和USB等。
7. fs: 支持的文件系統,Uboot現在支持cramfs、fat、fdos、jffs2和registerfs。
8. include:Uboot使用的頭文件,還有對各種硬件平台支持的匯編文件,系統的配置文件和對文件系統支持的文件。該目錄下configs目錄有與開 發板相關的配置頭文件,如leopard2a.h。該目錄下的asm目錄有與CPU體系結構相關的頭文件,asm對應的是asmarm.
9. lib_xxxx: 與體系結構相關的庫文件。如與ARM相關的庫放在lib_arm中。
10. net:與網絡協議棧相關的代碼,BOOTP協議、TFTP協議、RARP協議和NFS文件系統的實現。
11. tools:生成Uboot

的工具,如:mkimage, crc等等

2、uboot的運行過程分析


2.1 啟動模式介紹

大多數 Boot Loader 都包含兩種不同的操作模式:"啟動加載"模式和"下載"模式,這種區別僅對於開發人員才有意義。但從最終用戶的角度看,Boot Loader 的作用就是用來加載操作系統,而並不存在所謂的啟動加載模式與下載工作模式的區別。

啟 動加載(Boot loading)模式:這種模式也稱為"自主"(Autonomous)模式。也即 Boot Loader 從目標機上的某個固態存儲設備上將操作系統加載到 RAM 中運行,整個過程並沒有用戶的介入。這種模式是 BootLoader 的正常工作模式,因此在嵌入式產品發布的時侯,Boot Loader 顯然必須工作在這種模式下。

下載(Downloading)模 式:在這種模式下,目標機上的 Boot Loader 將通過串口連接或網絡連接等通信手段從主機(Host)下載文件,比如:下載內核映像和根文件系統映像等。從主機下載的文件通常首先被 BootLoader 保存到目標機的 RAM 中,然後再被 BootLoader 寫到目標機上的FLASH 類固態存儲設備中。BootLoader 的這種模式通常在第一次安裝內核與根文件系統時被使用;此外,以後的系統更新也會使用 BootLoader 的這種工作模式。工作於這種模式下的 Boot Loader 通常都會向它的終端用戶提供一個簡單的命令行接口。

UBoot這樣功能強大的 Boot Loader 同時支持這兩種工作模式,而且允許用戶在這兩種工作模式之間進行切換。

2.2 運行過程

大 多數bootloader都分為階段1(stage1)和階段2(stage2)兩大部分,uboot也不例外。依賴於CPU體系結構的代碼(如CPU初 始化代碼等)通常都放在階段1中且通常用匯編語言實現,而階段2則通常用C語言來實現,這樣可以實現復雜的功能,而且有更好的可讀性和移植性。

U - Boot 編譯後的代碼定義一般不超過100kB ,並且這100 kB 又分成兩個階段來執行. 第一階段的代碼在start . s 中定義,大小不超過10 kB ,它包括從系統上電後在0x00000000 地址開始執行的部分. 這部分代碼運行在Flash 中,它包括對arm926ejs的一些寄存器的初始化和將U - Boot 的第二階段代碼從Flash 拷貝到SDRAM 中. 除去第一階段的代碼,剩下的部分都是第二階段的代碼. 第二階段的起始地址是在第一階段代碼中指定的,被復制到SDRAM後,就從第一階段跳到這個入口地址開始執行剩余部分代碼. 第二階段主要是進行一些BSS 段設置,堆棧的初始化等工作,最後會跳轉到main -loop 函數中,接受命令並進行命令處理. 圖1 給出了U - Boot 的詳細的運行過程包括對內核的設置、裝載及調用過程。
系統復位進入u-boot stage l的入口點硬件設備的初始化為加載uboot stage 2准備ram空間設置好堆棧跳轉到stage 2的C入口點初始化本階段要用到的設備檢查內存映射將kernel映像和文件映像從flash中讀到ram中為內核設定啟動參數調用內核
2.3 本開發板的地址分布(leopard2a)

本目標板是RAM 16M, Flash 8M,具體空間如圖所示:

1F12FFFF
Uboot
Uboot_env
Kernel
Rootfs
1F000000
1F020000
1F01FFFF
1F02FFFF
1F030000
1F130000
1F7EFFFF
Kernel
Rootfs
FLASH
SDRAM
0x00030000
0x00130000
0x00430000

可以根據變換後的分區結構,設置
uboot_addr,uboot_addr_end,kernel_addr,kernel_addr_end,rootfs_addr,rootfs_addr_end,
config_addr, config_addr_end等環境變量,調整bootloader。

SDRAM的調整修改linux-2.4.20_mvl31/drivers/mtd/maps/physmap.c

2.4 運行代碼分析

2.4.1 stage 1

uboot的stage1代碼通常放在start.s文件中,它用匯編語言寫成,其主要代碼包括定義入口,設置異常向量,設置cpu的模式和頻率,配置內存區控制寄存器,安裝uboot的棧空間,關閉看門狗等。由於本人對ram的匯編不太熟悉,所以這一部分不作具體分析。

2.4.2 stage 2

lib_arm/board.c中的start armboot是C語言開始的函數,也是整個啟動代碼中C語言的主函數,同時還是整個uboot(armboot)的主函數,該函數主要完成如下操作:

2.4.2.1 調用一系列初始化函數

1. 指定初始函數表:
init_fnc_t *init_sequence[] = {
cpu_init, /* cpu的基本設置 */
board_init, /* 開發板的基本初始化 */
interrupt_init, /* 初始化中斷 */
env_init, /* 初始化環境變量 */
init_baudrate, /* 初始化波特率 */
serial_init, /* 串口通訊初始化 */
console_init_f, /* 控制台初始化第一階段 */
display_banner, /* 通知代碼已經運行到該處 */
dram_init, /* 配制可用的內存區 */
display_dram_config,
#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2)
checkboard,
#endif
NULL,
};

執行初始化函數的代碼如下:
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}

2. 配置可用的Flash區
flash_init ()

3. 初始化內存分配函數
mem_malloc_init()

4. nand flash初始化
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND:");
nand_init(); /* go init the NAND */
#endif

5. 初始化環境變量
env_relocate ();

6. 外圍設備初始化
devices_init()

7. I2C總線初始化
i2c_init();

8. LCD初始化
drv_lcd_init();

9. VIDEO初始化
drv_video_init();

10. 鍵盤初始化
drv_keyboard_init();

11. 系統初始化
drv_system_init();

2.4.2.2 初始化網絡設備

初始化相關網絡設備,填寫IP、MAC地址等。

1. 設置IP地址
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

2. 設置mac地址
{
int i;
ulong reg;
char *s, *e;
uchar tmp[64];

i = getenv_r ((uchar*)("ethaddr"), tmp, sizeof (tmp));
s = (i > 0) ? (char*)tmp : NULL;

for (reg = 0; reg < 6; ++reg) {
gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
}

2.4.2.3 進入主UBOOT 命令行

進入命令循環(即整個boot的工作循環),接受用戶從串口輸入的命令,然後進行相應的工作。
for (;;) {
main_loop ();
}}

3、uboot的移植和測試


3.1 移植的過程

① 在宿主機上建立交叉編譯開發環境
② 修改cpu/arm926ejst目錄中的文件內容,
主要包含cpu.C,start.S,interrupts.C以及seria1.C,speed.C等文件
③ 在board目錄下創建自己的目標板(開發板)目錄leopard2a
在目錄下創建leopard2a.C,flash.C,memsetup.S
以及Makefile,u-bot.1ds,config.mk文件
④ 在include/configs目錄下創建leopard2a.h
⑤ 打開u-bot目錄下Makefile文件,加入如下兩行:
leopard2a_config : unconfig
@./mkconfig $(@:_config=) arm arm926ejs leopard2a
⑥ 編譯。運行命令:
1. make leopard2a_config
2. make
編譯成功.生成基本的u—b00t.
⑦ 燒寫.把編譯成的u-bot.bin
至此移植u-bot過程結束.

3.2 移植主要修改的文件

移植u—boot到開發板上只需要修改和硬件相關的代碼即可。這首先就聯想到cpu目錄下的啟動代碼,另外參考u—boot/readme文件可知其他還需要修改的主要文件有:

Makefile文件,和include目錄下的目標板.h頭文件(leopard2a.h),board目錄下的目標板.C文件(leopard2a.c),flash.C文件,u-boot.1ds鏈接文件,以及cpu目錄下的串口驅動文件。

具體修改如下:
① cpu/arm926ejst目錄下
start.S啟動代碼。 ② board/leopard2a
leopard2a.C文件。這個文件主要是SDRAM 的驅動程序,主要完成SDRAM 的UPM 表設置,上電初始化。暫時不改。flash.C文件。Flash的驅動程序就在此文件中。memsetup.S文件。config.mk文件.此文件用於設置程序鏈接的起始地址。u-boot.Ids文件。 ③ include/configs目錄下leopard2a.h文件.此文件是leopard2a目標板頭文件,大多數寄存器參數是在這一文件中設置完成的.

3.3 uboot網絡下載功能的添加和RAM調試

在commom/main.c 中的main_loop函數中添加tftp下載的函數,可以通過按鈕觸發下載rimage,kimage。
在燒錄u-boot.bin之前,需要進行ram調試,保證uboot可以在EVB上正常運行。
先下載U-boot 到SDRAM上, 然後執行SDRAM 上的U-boot 程序, 以確認U-boot可以正常執行, Command 如下:
1. “tftp a00000 u-boot.bin” <= 下載程序到SDRAM
2. “go a00000” <= 從SDRAM 執行程序

如果U-boot 可以相容於目前的硬件, 5VT EVB 會重新正常啟動,要是不能正常啟動,表示U-boot 不相容於目前的硬件, 請更換新的u-boot。再重新測試, 直到被測試的U-boot可以正常啟動


3.TCP/IP TCP/UDP原理是什麼?

解析:
TCP(Transmission Control Protocol,傳輸控制協議)是基於連接的協議,也就是說,在正式收發數據前,必須和對方建立可靠的連接。一個TCP連接必須要經過三次“對話”才能建立起來,其中的過程非常復雜,我們這裡只做簡單、形象的介紹,你只要做到能夠理解這個過程即可
UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是面向非連接的協議,它不與對方建立連接,而是直接就把數據包發送過去! UDP適用於一次只傳送少量數據、對可靠性要求不高的應用環境。
tcp協議和udp協議的差別 
               TCP        UDP 
是否連接      面向連接     面向非連接 
傳輸可靠性    可靠         不可靠 
應用場合     傳輸大量數據  少量數據 
速度         慢           快

4.項目裡你做了些什麼?怎麼做的?為什麼要那樣做?

解析:具體項目而定!

5.指針與數組的用法及計算

解析:參考4.3 指針,數組和指針算術之間關系

6.單鏈表和雙鏈表的用法

解析:

單鏈表就是單向訪問,雙向鏈表就是可以雙向訪問
1、單鏈表是在元素的節點結構中只能包含一個後繼結點指針,不能包含多個指針的。雙鏈表則是包含前驅和後繼兩個指針的。
2、單鏈表要求建好後返回第一個節點的指針(或者有頭結點用頭結點的指針),因為他只能朝後運行,而雙鏈表建好後可以給任意一個節點的指針,因為他可以朝前後兩個方向走。知道哪個節點的指針沒有多大關系。原則上以第一個節點為

7.虛函數,構造函數,析構函數,復制和賦值函數


解析:這是涉及到所有基礎的知識,不熟悉,可參考c++ primerplus 書籍面試的時候 ,比較喜歡給出頭文件,寫函數,下面給出函數和說明:
  class String
{
public:
String(const char *str = NULL); // 普通構造函數
String(const String &other); // 拷貝構造函數
~ String(void); // 析構函數
String & operate =(const String &other); // 賦值函數
private:
char *m_data; // 用於保存字符串
};

String::String(const char *str)//普通構造函數
{
 if(NULL == str)
 {
  m_data = new char[1];
  m_data[0] = '\0';
 }
 else
 { 
  m_data = new char[strlen(str)+1];
  strcpy(m_data,str);
 }
}

String::~ Stirng(void)//析構函數
{
 delete []m_data;
// delete m_data;
}

String::String(const String &other) //拷貝構造函數
{ 
 m_data = new char[strlen(other.m_data)+1];
 strcpy(m_data,other.m_data); 
}

String & String::operate=(const String &other) //賦值語句
{
 if(this == &other)
 { 
  return *this;
 } 
 delete []m_data;
 
 m_data = new char[strlen(other.m_data)+1];
 strcpy(m_data,other.m_data);
 return *this;
}

說明:1)構造函數是一種特殊函數,而拷貝構造函數是一種特殊的構造函數。類X的構造函數的第一個參數必須為X&,或者const X&;除了第一個參數外,構造函數要麼不存在其他參數,如果存在其他參數,其他參數必須有默認值。一個類可以有多個拷貝構造函數。 它的形式如下: X::X(X& x) X::X(const X& x) X::X(X& x, int a = 0, int b = 1…) 2)什麼時候會調用拷貝構造函數? 以下三種情況出現時,會調用一個類的拷貝構造函數: a) 用一個已經實例化了的該類對象,去實例化該類的另外一個對象; b) 用該類的對象傳值的方式作為一個函數的參數; c) 一個函數返回值為該類的一個對象。 例如: CA a; // CA b(); // 不能用這種方式聲明CA的對象b! CA c(10, 10); CA d(c); // 情況1) -> 調用拷貝構造函數 int anInt = someFun1(c); // 情況2) -> 調用拷貝構造函數 CA e = someFun2(11, 11); // 情況3) -> 調用拷貝構造函數3)什麼時候必須要顯式聲明拷貝構造函數? 如果有成員變量以指針形式存在,涉及動態內存分配等情況下,一定要顯式聲明拷貝構造函數。要注意到,如果需要顯式定義拷貝構造函數,那麼 通常都是需要同時定義析構函數(因為通常涉及了動態內存分配),至於是否必須重載操作符“=”,要視情況而定。 例如: class CA { public: Point* _point; public: CA(const Point*); // 需要增加的拷貝構造函數 CA(const CA&); // 需要增加的析構函數 virtual ~CA(); // 需要增加的拷貝賦值函數 CA& operator = (const CA&); }; int main(void) { Point apoint(1, 2); CA ca(&apoint); ca.printCoordinates(); CA cb(ca); // 調用拷貝構造函數 CA cc = cb; // 調用拷貝賦值函數 .............. }4)缺省構造函數、拷貝構造函數、拷貝賦值操作符和析構函數是特殊成員函數。5)構造函數不能有返回類型,也不能由virtual, const, static 和 volatile來修飾。但可以由inline來修飾,事實上隱式構造函數就是用inline來修飾的。inline表示編譯時展開,通常速度塊;virtual表示運行時綁定,通常意味著靈活。6)類中存在虛函數或者有虛基類的情況下需要顯式聲明構造函數。拷貝構造函數也是如此。

9.冒泡排序

解析:參考冒泡排序 --學習(二)



						

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved