1.請寫出匯編指令要ldr的三種功能。
1)把立即數放入rd寄存器 构资。注意立即數沒限制, ldr不能用于寄存器給寄存器賦值唆香。
2)ldr rd, [rm, rn/#立即數] //把rm寄存器上值加上rn值的結果作為地址罢低,再把地址上值放入rd? 。
2.請說明要lr骏全,sp,PC尼斧,cpsr的寄存器的作用
R13: 別名sp, 此寄存器用于裝載棧頂的地址
R14: 別名lr, 此寄存器用于裝載返回地址
R15: 別名pc, 此寄存器用于裝載當前取指令的內存地址 (老是忘記姜贡。拿你的pc)
? ? cpsr: 當前程序狀態(tài)寄存器, 記錄當前工作模式,條件位狀態(tài)等
? ? spsr: 備份的程序狀態(tài)寄存器, 用于保存cpsr的值
3.請說明在arm程序里棺棵,返回值放在哪個寄存器楼咳,函數參數是怎么傳遞?
? 調用函數時烛恤,傳的參數從r0寄存器開始存放第1個參數, 直到r3寄存器存放第4個參數. 如還有參數則放入棧里.
? ? 被調用的函數會自動從棧里取超出的參數.
4.請說明printf函數體內參數的值是怎么樣取出來的
1)printf函數的第一個參數是一個字符串的地址爬橡,通過遍歷字符串里的’%’字符,可以得知后面還帶有多少個參數棒动。
2)參數是從r0寄存器開始傳參數糙申,直到r3寄存器存放要傳遞的第四個參數,再多的參數就需壓棧了船惨。
3)函數的參數也是局部變量在棧里分配空間柜裸。全部參數的地址都是連續(xù)的,只要獲取其中一個參數的地址粱锐,即可通過偏移獲取其它所有參數的值
5.
6.請說明棧溢出攻擊實現的原理
溢出攻擊實現原理:
數組的越界訪問
如上面的代碼, buf數組足夠大, 接收用戶輸入時如果不判斷長度, 就可以把要執(zhí)行的指令存入buf數組, 最后通過數組的越界訪問疙挺,把棧里存放的原lr寄存器的內容改成buf數組的首地址, 那么buf數組里存放的指令就可以執(zhí)行了.
而已當main函數是管理員執(zhí)行時, 那么在buf數組里存放的指令執(zhí)行就具有管理員的權限了, 手機的root用的就是這種方法
防止溢出攻擊的方法:
1). 接用戶輸時判斷數據長度, 防止數組越界訪問
2). 盡量在堆里分配空間
3). gcc 編譯時加上-fstack-protection選項(man gcc里查看
7.請說明b跳轉與ldr跳轉指令的區(qū)別怜浅,以及在什么場合使用铐然?
8.請說明在uboot上加入自定義命令的步驟以及具體實現的原理蔬崩?
具體做法:
0.只要實現一個功能函數,再調用 U_BOOT_CMD宏即可.放在cmd目錄.
1.uboot里命令統(tǒng)一放在源碼目錄里的cmd目錄.每個文件表示一類或一個命令.
2.修改cmd目錄里的Makefile搀暑, 在第16行:
? ? obj-y += cmd_mytest.o
3.回到orangepi_sdk目錄下:
make uboot
make install_uboot sdcard=/dev/sdb
3.重新啟動后沥阳,在uboot上輸入 "help"命令:
可以查看到:
mytest? - mytest - usage of mytest
4.? 執(zhí)行命令:
5.在uboot里每個命令都有一個功能函數,我們可以在自己實現的命令函數里調用其它命令的功能函數來實現相應的功能.
9.當前目錄下有文件hello.c aa.c bb.c? start.S自点,要求寫一個makefile桐罕,最終生成test.bin
///
CROSS_COMPILE ?= arm-linux-gnueabihf-
? ? OBJS += main.o
? ? OBJS += a.o
OBJS += b.o
? ? TARGET ?= test
? ? $(TARGET).bin : $(TARGET)
? ? ? ? $(CROSS_COMPILE)objcopy -O binary $<? $@
? ? $(TARGET) : $(OBJS)
? ? ? ? $(CROSS_COMPILE)ld $^ -o $@
? ? %.o : %.S
$(CROSS_COMPILE)gcc $< -c -o $@
? ? %.o : %.c
$(CROSS_COMPILE)gcc $< -c -o $@
10.請說明MMU的工作原理
管理地址單元,解決多個程序鏈接同一個地址桂敛。
⑴.MMU的使用
MMU是存儲器管理單元的縮寫功炮,是用來管理虛擬內存系統(tǒng)的器件。 MMU通常是CPU的一部分术唬,本身有少量存儲空間存放從虛擬地址到物理地址的匹配表薪伏。此表稱作TLB(轉換旁置緩沖區(qū))。所有數據請求都送往MMU粗仓,由 MMU決定數據是在RAM內還是在大容量存儲器設備內嫁怀。如果數據不在存儲空間內,MMU將產生頁面錯誤中斷潦牛。
MMU的兩個主要功能是:
1.將虛地址轉換成物理地址眶掌。
2.控制存儲器存取允許。MMU關掉時巴碗,虛地址直接輸出到物理地址總線朴爬。
有MMU單元是ARM芯片和單片機的重要區(qū)別之一。
1橡淆、將虛擬地址轉化為物理地址
2召噩、訪問權限管理
11.請描arm的異常向量表及每種異常是在什么情況下發(fā)生的?
12.請描述控制器的用途及時鐘信號的用途
13.請描述按鍵的中斷事件的流程逸爵,怎么最終調用中斷的處理函數
按鍵按下->產生IO口中斷->進入中斷處理函數halKeyPort1Isr->判斷中斷位標志具滴?
14.請說明編譯uboot源碼前:make? sp56818-drone_config這具體做了什么
15.請描述裁剪uboot的方法
16.請描述uboot環(huán)境變量(bootargs.bootcmd) 在作用
bootcmd? ? // 倒計時到0后,自動執(zhí)行里面的語句
? ? ? ? bootargs? ? // 是用于提供給內核的啟動參數語句
如果想要開發(fā)板開機后自動引導內核, 可以修改bootcmd環(huán)境變量來完成
setenv bootcmd "fatload mmc 0:1 0x43000000 /script.bin; fatload mmc 0:1 0x42000000 /uimage; bootm 0x42000000"
17.請描述uboot啟動师倔,過程越詳細越好
uboot啟動构韵?下面不對。
總結下uboot的配置過程:
? ? 1). script/orangepi.conf里的環(huán)境變量生效, 及進入uboot源碼目錄
? ? 2). make distclean
? ? 3). make orangepi_linux_defconfig
? ? 4). make menuconfig
總結下編譯主要過程:
? 1).進入uboot源碼目錄
? 2). make -j8
? 3). 生成boot.src環(huán)境變量文件
4). 生成script.bin文件
18.請描述設備驅動的作業(yè)及用戶程序之間的關系
1). 驅動是硬件與用戶進程之間的通信橋梁
用戶進程是不可以直接訪問硬件的.
如:hexdump /dev/input/event4 //這樣趋艘,程序hexdump從設備文件里接收數據并按十六進制打印出來
數據是驅動先接收到硬件反饋的數據處理后再移交給用戶進程
驅動不屬于任何一個用戶進程, 可以給多個用戶進程調用.
驅動是常駐于內存里疲恢,等待用戶進程調用.
2). 用戶進程如訪問越界則會發(fā)生段錯誤,但對其它進程沒有影響. 用戶進程在cpu的usr模式下工作 瓷胧?
驅動是在svc模式下工作(特權模式), 驅動發(fā)生錯誤显拳,會影響整個系統(tǒng)(像windows系統(tǒng)藍屏).
寫應用程序有bug僅僅是影響該進程,但寫驅動時搓萧,哈哈…
3). 驅動加載到內核后(即驅動工作), 除了初始化工作以外杂数,一般情況下是不會自動去執(zhí)行操作的, 驅動是被用戶進程調用才會觸發(fā)操作的. 所以也得注意驅動的接口函數的可重入性 宛畦。
也就是驅動是實現硬件的各種功能,但怎么去使用由用戶進程調用來決定揍移。
驅動本身是不休眠次和,只能是調用的進程或線程才可以休眠.
4)./dev”目錄里提供一個設備文件, 然后用戶進程就可以通過操作設備文件來調用驅動.
5)設備驅動實現好功能后羊精,基本上由用戶進程通過系統(tǒng)調用后進來調用的.
19.請描述linux內核怎樣操作io斯够,列出具體的函數并說明用途
1.配置寄存器的地址.(麻煩囚玫,移植性差喧锦,落后的做法)void *ioremap(cookie,size),
ioread32(地址)/readl()? ? //讀32位值
iowrite32(值, 地址) / writel? //把32位的值寫到指定的地址上
2.linux內核里有標準的GPIO操作方法抓督。驅動人員可以用內核提供的gpio標準操作函數通過gpiolib來調用控制芯片的io口.
#include? //里面聲明io口的操作函數
int gpio_request(unsigned gpio, const char *label);//每個io只能被請求一次,可防止多個驅動來控制同一個IO口
void gpio_free(unsigned gpio); //釋放已請求的io口
int gpio_direction_input(unsigned gpio); //把指定的IO口作輸入功能, gpio用于指定具體哪個io口
int gpio_direction_output(unsigned gpio, int value); //作輸出功能燃少,并根據value的值輸出高低電平
int gpio_get_value(unsigned gpio); //獲取指定IO口的電平
void gpio_set_value(unsigned gpio, int value); //設置IO口的電平為value(0/1)
int gpio_to_irq(unsigned gpio);? //根據io口,獲取到它對應的中斷號(io口大都有外部中斷功能)
20.請描述铃在,當我們把一個寫的設備驅動加入內核代碼里徐一起配置編譯時的具體實體步驟阵具。
21.請描述設備號有什么組成?設備號的作用是什么定铜?
1)設備號由主設備號與次設備號組成阳液。
在linux內核里用類型”dev_t”來表示一個設備號. 其實就是一個unsigned int.
dev_t類型有32位數, 其中高12位用于存放主設備號揣炕,低20位用于存放次設備號.
在”include/linux/kdev_t.h”里有提供設備號的操作宏帘皿。
2)提供一個設備文件,用戶進程就可以通過操作設備文件來調用驅動.
22.請描述linux字符設備驅動的實現步驟及應用程序的調用過程畸陡?
1. 申請設備號 register_chrdev_region(...);
2. 聲明一個cdev對象
? ? struct cdev mycdev;
? 聲明一個file_operations的文件操作對象
? ? struct file_operations fops = {
? ? ? ? .owner = THIS_MODULE,
? ? ? ? .read = 讀函數地址
? ? ? ? ....
? ? };
3. 初始化cdev對象鹰溜,并把fops對象與cdev對象關聯起來
? ? cdev_init(&mycdev, &fops); //mycdev.ops = &fops;
? ? mycdev.owner = THIS_MODULE;
4. 把cdev對象加入內核里cdev_map(字符設備驅動的哈希表), 并指定該驅動對象的設備號
? ? cdev_add(&mycdev, 設備號, 次設備號的個數);
5. 卸載模塊時, 要把設備驅動對象從內核里移除, 并把設備號反注冊
? ? unregister_chrdev_region(..);
? ? cdev_del(&mycdev);
23.請你描述對vfs調用接口的認識丁恭?
用戶進程操作設備驅動曹动,網絡通信等與普通的文本文件操作的編程接口基本一樣(open, read, write, ioctl…).
這套接口就是所謂的VFS(虛擬文件系統(tǒng))。
(Virtual File System)
//////////////////////////////////////
//在linux內核牲览,用一個inode節(jié)點對象描述一個要操作的文件/設備文件, 包括權限墓陈,設備號等信息. 就是描述一個要操作的文件的屬性. 一個文件可以打開很多次, 但都是共用一個inode對象來描述屬性的. 文件描述符屬于一個進程的資源,不同進程里有可能相同的文件描述符.
24.請描述互斥量第献,自旋鎖贡必,信號量的用法和區(qū)別
25.請描述中段頂半部與底半部的好處的及底半部實現方法?
26.請描述linux驅動設備模型的用途
27.請描述uart的工作原理
28.請描述i2c的工作原理和linux內核的i2c設備驅動模型實現過程
29.描述pwm工作原理及內核的調用借口
?
?
?