11、1、uboot移植前的準備工作
1、三星移植過的uboot源代碼準備
(1)三星對于S5PV210的官方開發板為SMDKV210,對應移植過的uboot是android_uboot_smdkv210.tar.bz2在資源下載中
(2)這個源代碼網上是下載不到的,剛開始是下載不到的,三星官方是不會把這些東西放在官網上下載的。這些東西最初都是隨著官方的開發板一起流出的。
2、SI的準備
(1)移植的時候,最重要的工作就是看代碼,改代碼,編譯運行測試
(2)編譯代碼必須在Linux中進行編譯(因為要創建符號鏈接,Windows共享文件夾中配置uboot是不行的),看代碼和改代碼可以在Linux中(vim)也可以在windows中(SI)。
(3)正確的方法,應該是,在windows中解壓一份uboot源代碼,在Linux也解壓一份源代碼,這兩分開始時是一模一樣的,然后我們移植的時候,是在windows中的這一份去看代碼,改代碼,然后在Linux中這一份去編譯燒寫。這種做法需要在windows中和Linux中兩分代碼之間保持一個同步,就是你windows中改過了后,要把改過后的源代碼復制到Linux中那一份去覆蓋Linux里面的同目錄通文件
(4)問題來了,怎么在windows中和Linux中去同步代碼?通過共享文件夾在Linux中進行復制,也可以通過一些專用的工具sshsecureshell
11、2、便捷文件傳輸工具sshsecureshell
1、windows中安裝sshsecureshell客戶端
在Ubuntu10.04版本中,重啟網卡的命令是 /etc/init.d/networking/ restart
在Ubuntu14.04版本中,重啟網卡的命令是 ifdown eth0 ifup eth0 校園網時發現NAT模式下好使
11、3、Ubuntu14.04上網及安裝openssh
1、虛擬機上網要注意,你是用橋接上網的,還是NAT模式上網的。第二個要注意,Ubuntu中網絡的配置文件中的,/etc/network/interfaces 這個文件中是配置網卡信息的,是靜態IP還是dhcp靜態IP是多少。第三個如果是橋接模式要注意,要注意橋接到哪個網卡上,一般筆記本有兩個網卡,有限網卡和無線網卡。如果是NAT模式是沒有關系的。
Ubuntu14.04中重啟網卡的命令變了,ifdown eth0 ifup eth0。
如果用的校園網的話,你要想上網只能通過NAT模式,因為我們的電腦要連到校園網的dhcp服務器上,會自動給我們電腦和ubunut分配一個ip地址,所以/etc/network/interfaces 這個文件中的內容,要設置成dhcp自動獲取IP地址的方式,同時網絡中心中的虛擬機獲取方式也要設置成自動獲取ip地址的方式。
如果用wife的話,NAT模式也好時,橋接模式也好時。
如果你想讓虛擬機Ping通windows,首先虛擬機要選擇橋接模式上網,要橋接到有線網卡上,同時由于windows有bug,所以widows的網上口,必須用網線連接到一個有上網能力的地方。之后將,Ubuntu中的/etc/network/interfaces 文件中改成static靜態模式,因為這樣在每次開機的時候ip地址就不會變了。將里面的ip地址設置成和我們主機windows在同一個網段上。之后重啟網卡ifdown eth0 ifup eth0 ,在Ubuntu終端下,ping主機,如果ping通了,就OK了,這時你的SSH通信就可以了。openssh類似的工具就可以使用了
2、搭建openssh環境
(1)、ubuntu上網
(2)、安裝openssh-server。如果報錯提示依賴錯誤,可以參考:http://www.cnblogs.com/mliudong/p/4094519.html
(3)securecrt登錄
(4)sshsecretshell登錄 兩者都可以
如果ssh登錄不上,要修改/etc/ssh/sshd_config,參考:http://blog.sina.com.cn/s/blog_5f435c130102v6pv.html。 修改完重啟時如果/etc/init.d/ssh restart不起作用,可以使用:ps -e | grep ssh,看sshd的進程號,然后kill -9 進程號殺死ssh進程以達到重啟的目的,或者直接重啟ubuntu系統。
11、4、三星的uboot移植
0、先直接用三星移植過的uboot,看什么情況
1、將uboot復制到Linux的源生目錄下,解壓。
2、檢查makefile中的交叉編譯工具鏈
3、配置,我們配置的時候,因為三星的是smdkv210xxxx,所以我們先重第一個開始試,先用smdkv210single_config來配置一下試試,用這個的話,我們配置頭文件是在include/config/smdkv210single.h
4、配置完成后,直接make編譯,完了之后直接燒錄到SD卡上,啟動下試試。
5、在uboot/sd_fusing/sd_fusing.sh 這個腳本是用來燒錄的。但有時這個腳本需要修改一些的東西,看腳本中的BL1的位置在哪里,還有整個uboot的大小分別放在了SD的哪個扇區。多少個扇區。應該是1和49,可以從uboot的源代碼中找到那個計算公式,自己推到出來。在燒錄的過程要看燒錄運行時的打印出來的信息,分析看燒錄沒燒錄成功,注意mkdbl1 和sd_fisk文件的屬性位數是否和我們當前Ubuntu的位數一致。
6、燒錄成功后,插到開發板上試一下。
11、5、 1、代碼分析,問題查找
1、插到開發板上啟動后,發現打印出來SD 檢查錯誤(這個信息是IROM中做的)。但是電源自鎖是工作的。
回想,uboot串口打印信息時,最早打印的是OK,是在start.S中的lowlevel_init中初始化時打印的。串口沒有輸出O,說明代碼在沒有執行到O之前,代碼就已經死掉了。但是開發板的供電鎖存是成功的,供電鎖存也是在start.S中的lowlevel_init中,所以說在供電鎖存的前面一部分代碼是沒有問題的。所以可以初步判斷,錯誤在供電鎖存之后和串口打印出來O之前這一段代碼就有問題了。
2、接著就需要代碼的分析了,在windows下建立SI工程。發現可能是lowlevel_init.S中調用PMIC的問題,因為我們開發板并沒有這個電源管理芯片,所以當我們調用這個函數的時候,I2C向PMIC發送信息是得不到PMIC電源管理芯片的應答的,所以程序死在了這里。
將上面這個調用PMIC的函數屏蔽掉后,發現uboot可以啟動了。但是很多的配置信息是有問題的,很多的功能應該也是不能用的,都要去查驗。
3、更改開始打印的uboot版本號后們的值,在start_armboot函數中的調用的display_banner函數中的version_string對應的宏的值,也就是這個宏CONFIG_IDENT_STRING的值為for"xxx",這個宏在smdkv210single.h中,這是關鍵配置的頭文件。改完后,同步到Linux源生目錄下,之后在make distclean, make smdkv210single_config, make
4、時鐘配置
時鐘的代碼是不用修改的,在lowlevel_init.S中,因為我們三星用的芯片也是這個芯片,我們用的芯片也是這個芯片,所以我們大多數關注的應該是開發板級別的移植,從串口打印的信息也可以看出來,時鐘的配置確實是對的,如果想改時鐘的配置,也只是需要在smdkv210single.h頭文件中打開或者關閉一個宏即可。如果要改時鐘的配置,不用改時鐘函數中的代碼,只需要改動配置頭文件smdkv210single.h中的宏的配置就行。
5、DDR配置信息的更改
(1)因為三星的uboot運行時打印出來的DDR大小是1G,但是我們的DDR是512M的,所以有問題,DDR的相關信息是有問題的??梢栽趗boot運行的時候,用bdinfo命令看DDR等更多的信息。從bdinfo命令打印出來的信息可以看出來,DDR的起始地址三星配置為0X20000000和0X40000000,DDR的大小每片都配置成了0X20000000(512M大)。
(2)我們使用md命令和mw命令,分別讀DDR的內存中的內容,和往內存中寫東西,發現DDR是可以用的,所以說明DDR的初始化是成功的,只是配置的不對,我們在訪問0X30000000地址時,發現訪問的情況和訪問0X20000000的情況是一樣的,可以說明我們的DDR本身確實是沒有512M大的,只有256M大小的,那為什么訪問0X30000000和訪問0X20000000內存地址處的情況一樣呢,可能是內存本身的一些特性,也可能是代碼中實現的。
6、DDR地址另外配置
(1)目標,將DDR端口0的起始地址配置為0X30000000,配置成30000000開頭的地址就可以和我們板子上的bank1第二片DDR的40000000地址連起來了。因為我們的板子上的大小是256MB。
(2)DDR初始化的代碼在lowlevel_init.S中,初始化的代碼是不用我們改的,我們只需要改在include/configs/xxx.h中的宏配置就行。
(3)關于DDR相關參數的設置,要結合我們開發板的數據手冊進行配置。
將配置頭文件中的#define DMC0_MEMCONFIG_0 0x20E01323 改成 #define DMC0_MEMCONFIG_0 0x30E01323
這樣的話,將來往那個DMC0CONTRL寄存器中寫入的值就變了,寄存中的值變了,相應的硬件就會發生了變化,地址就真的映射到了3開頭的地址去了,但是硬件變了,但是軟件的配置還沒有變,所以我們要把配置文件中的這個宏#define MEMORY_BASE_ADDRESS 0x20000000 內存的基地址也改成 0X30000000,這個是在軟件架構成,我們告訴uboot內存的起始地址是從哪里開始的
(4)虛擬地址映射表中相應修改
uboot中開啟了MMU對內存進行了段式映射,有一張內存映射表。
(5)怎么找這個虛擬地址映射表呢?
現在start.S中找_mmu_table_base:
.word mmu_table
找到mmu_table相關的符號,找到了mmu_table在去在SI中索引mmu_table處,最后找到是在lowlevel_init.s中。
怎么看呢?
.set __base,0
// Access for iRAM
.rept 0x100
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
意思是從0地址開始的地方到0X10000000地址的地方這256M的空間原樣
.rept 0x200 - 0x100
.word 0x00000000
.endr
意思是0x20000000-0x10000000,這段地址映射到了0地址,應該是不可以訪問的
.set __base,0x200
// should be accessed
.rept 0x600 - 0x200
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
意思是0x200開頭的地址范圍到0x600映射到0x200,開始的地址,原樣映射
.rept 0x800 - 0x600
.word 0x00000000
.endr
意思是0x8000-0x600地址也是不可訪問的
set __base,0x200
// 256MB for SDRAM with cacheable
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
意思是0x200開頭的地址被映射到了0XC00到0XD00范圍,一共是256M
(6)所以我們虛擬地址映射表中,應該把C0000000-D0000000地址空間映射到30000000-40000000這個256MB的地址中去
方法是:修改這樣
set __base,0x300
// 256MB for SDRAM with cacheable
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
(7)修改完以后,在細細的檢查一下配置頭文件中的,關于內存的宏的配置是否正確,主要是看地址是否是我改過的。
(8)運行時,發現只打印出來了OK,經過分析,發現是DMC0_MEMCONFIG_0的問題,把這個宏的值改成0X30F01323,之后在編譯燒錄,運行,發現好了一部分了。但是到SD卡打印的那段就不運行了。
(9)經過分析是虛擬地址到物理地址的映射函數中的問題。將-0x20000000改成-0x30000000,在 uboot/board/samsung/smdkc110/smdkc110.c中。
(10)iNand驅動問題的解決
@1:先從現象定位問題。將打印出來的錯誤信息,找到關鍵字在SI中搜索,發現問題的所在地方,在看當前位置的上下文,來理解是什么原因造成的,最后發現是從mmc設備的擴展寄存器中讀取到的版本號大于了我們代碼中給的5版本號導致的。我們第一個解決方案是將大于5改成大于8,給一更大的版本號。
@2:其中還有一個事情,就是三星的uboot中,代碼中,初始化打印的是mmc通道0的,也就inand,我們如果將這個設備號改成了1,可能就會給外部的SD卡發送讀取到SD卡的版本號,inand的版本比SD卡的版本高,雖然兩者很類似,所以改了這個通道,可能也會解決問題,就是在初始化mmc設備時的傳遞的參數。
(11)修改輸出到控制臺的串口號 ,從三星默認的串口2,修改到串口0,
@1:只需要改動,smdkv210single.h中的關于串口的那一個宏就行。串口初始化的代碼是在lowlevel_init.S中,跟標準輸入輸出綁定的是在seriver.c中??偤甓x決定初始化哪個串口的宏是在smdkv110.h中
(12)修改網絡的配置信息,也是在smdkv210single.h中的關于網絡配置的宏中修改就行。
(13)在我們uboot剛開始運行的時候,如果你用的mmc設備是0,用的是板子上的inand的話,你的環境變量剛開始用的是uboot內部自帶的環境變量的值,但是當你改過了以后你在saveenv后,如果你選擇的mmc設備是0的話,那么就會保存到你mmc設備0通道對應的設備中,我們的板子對應的是inand,所以就保存到了inand中了,并不是保存到了你的mmc設備通道1對應的那個sd卡通道2,我們的sd卡,
(14)所以如果我們要破壞inand中的那一份環境變量的值,而想用uboot源碼中自帶的環境變量的值的話,就需要先破壞掉inand中被從DDR中的環境變量分區保存到了inand中環境變量分區的那一份環境變量,破壞方法就在用mmc writer 0 30000000 11# 32 因為我的環境變量保存時,是放在了第17個扇區,分區大小是32個扇區。意思就是將內存中0x30000000中的開始的環境變量分區到整個環境變量分區的大小,全部寫成0,完了之后保存到了mmc設備通道0對應的設備中。所以這個時候,mmc設備中對應的環境變量分區的值就是不對了,將來在校驗的時候,就會發現這個設備中沒有環境變量可以用,所以用的時候就會用uboot源碼中自帶的環境變量的值了。
(15)網卡驅動的移植1
@1:srom是sram/rom,是一個統稱,SOC內部的srom controller控制器就是SOC對外提供的一種總線式連接sram/rom的一種接口,如果我們的SOC要外部連接一個sram或這rom存儲芯片,或者一些偽裝成srom接口的芯片(如網卡芯片,DM9000),就需要用到SOC的這個srom controller來連接進行外部擴展??偩€式訪問的好處就是可以直接用地址的方式來進行訪問,不需要通過什么發命令啊什么的,時序好什么的去訪問。當網卡芯片通過srom接口接在了soc上的時候,我們的主機soc去訪問網卡芯片內部的寄存器時,就可以直接通過總線來用尋址的方式來直接放問網卡芯片。我們的板子上,網卡芯片是接在soc的srom中的一個bank上。
@2:網卡芯片內部有很多個寄存器,既然網卡芯片和我們的soc是通過srom接口進行鏈接的,我們就可以總線式的尋址去訪問網卡芯片,由于網卡芯片內部的寄存器相對于網卡來說,是從0開始編址的,所以我們的soc要想通過地址去訪問到網卡芯片內部的寄存器的時候,就要用一個相對地址去訪問網卡芯片,就是起始地址+網卡芯片本身寄存器的地址。
起始地址指的就是網卡芯片接在soc的srom的bank上的那個bank對應的地址。也就是用soc訪問網卡芯片內部寄存器的時候,要用網卡芯片接在srom bank上的那個基地址加上一個網卡芯片內部地址的。相當于用基地址加偏移量的方式去訪問,很好理解。
@3:主機soc要想上網,就要對網卡芯片內部寄存器進行操作和網卡芯片內部的緩沖區(可以理解為內存)來進行上網,所以主機soc是通過網卡芯片來實現間接上網的。
@4:所以,如果連上了網以后,如果主機要通過網絡來接受數據的話,網卡芯片硬件會自動的將從網絡來的數據放到自己內部的緩沖區中,我們的主機soc只要去這個網卡芯片內部的緩沖區中讀取數據就可以了,如果我們的主機soc想通過網路來發送數據的話,就只需要將我們想要發送的數據丟到網卡芯片內部的緩沖區中,就行,網卡芯片硬件也會自動從自己的緩沖區中把數據通過網絡發送出去。
@5:通過看我們開發板的原理圖,可以知道,我們網卡芯片有16根數據線和我們的soc相連接了,所以說明我們的soc的srom控制器用的16bit接口模式的。
@6:網線有8根線,但是有用的只有四根線,其他四根線是跟抗干擾有管的,這四根有用的線中,兩根發,兩根收。因為網線中傳輸的差分信號。差分信號傳輸的距離相對較遠,抗干擾能力也較強
@7:網卡芯片有一個CS引腳:chip selcte,片選信號,意思就是主機向CS發送有效信號,則我們的從機芯片工作,主機向CS發送無效信號,則從機芯片不工作。這個引腳要接到我們soc中的srom bank中的片選信號。我們的每一個srom bank中都有一個片選信號端CSn,從原理圖中可以看出來,我們DM9000的片選信號端接在soc中的srom bank1上,因為是cs1,所以我們DM9000相對我們主機soc的總線基地址就是我們主機soc中的sromc bank1的基地址(0x88000000)。
@8:DM9000的CMD引腳接到了soc的addr2引腳上,這個引腳也很重要。DM9000為了減少芯片的引腳數,數據線和地址線是復用的。DATA0-DATA15這16根線是有時做數據線傳輸數據的,有時做地址線傳輸地址的,當DM9000的CMD引腳的接受到高電平的時候,代表這時復用的是數據線,當CMD為低電平的時候傳輸的是地址,在DM9000中叫index,索引的意思,也就是相對于主機的地址的索引地址。這是查DM9000的數據手冊時知道的。
@9:這些引腳上面的電平變化都是我們soc中的sromc控制器做的,我們只需要在配置寄存器的值時,充分考慮到硬件電路的接法,給我們相應的寄存器配置正確的值就行。
(15)網卡驅動的移植2
@1:uboot程序中本身就有很多網卡芯片驅動的程序,在uboot/drivers/net文件夾下,有很多個關于不同網卡芯片的驅動程序,大多數都是來自于Linux內核,我們網卡芯片是DM9000,所以我們應該看這個net文件夾下的dm9000.c和dm9000.h
,這兩個文件我們目前就不用看了,因為會越看越糊涂的,因為還沒有開始學習驅動,對驅動,對Linux內核對網絡驅動這塊的框架不是很熟悉。
@2:我們可以不用看這個網卡驅動DM9000的代碼,因為驅動是做好的,數據和代碼是分離開的,這里只是驅動代碼,數據是由我們開發板中的接法決定的,數據由一定的數據結構提供,所以驅動具有可移植性,所以這里的代碼我們我可以不用動,我們要動的是數據,數據就在smdkc210single.h中關于網卡配置的那些宏
@3:網卡移植的關鍵:初始化。在uboot的第二階段,start_armboot中那個函數指針數組中,里面就有一個board_init,這個函數指針指向的那個函數中,就有網卡的初始化,這個初始化才是網卡移植的關鍵,這個初始化只要把網卡芯片初始化好了,網卡芯片就可以工作(意思是網卡驅動dm9000x.c和dm9000x.h依賴于這里的初始化而工作。)
@4:dm9000_pre_init這個函數就是移植網卡芯片的關鍵。這個初始化函數和我們開發板上的DM9000硬件連接有關,必須要結合我們開發板的原理圖來分析,然后了決定這個函數怎么編程,所以我們要根據自己的開發板的硬件接法去修改這個初始化函數,來讓我們的網卡芯片工作
@5:DM9000_16BIT_DATA這個宏用來表示DM9000工作在16位模式下,我們的開發板上的DM9000也是工作在16位模式下的
@6:SROM_BW_REG,從三星的源碼中和對應數據手冊,可以看出三星將網卡芯片DM9000接在了SOC中的sromc中的bank5上,而我們的開發板DM9000網卡芯片是接在SOC中的srom中的bank1上的,所以根據手冊我們要操作這個寄存的bit4-bit7,這里四個bit位表示的是bank1的。
@7:我們是工作在16位模式的,所以這個SROM_BW_REG寄存中的bit4是1,因為我們數據線是一一對齊的,所以bit5是1,其他兩位,按照模式來的話,按照別人的經驗配置成1,非必須情況可以不用弄清楚這兩個位。
@8:所以根據數據手冊和實際情況,我們應該修改的寄存有三個SROM_BC5_REG SROM_BW_REG MP01CON_REG,最后一個是在GPIO中。
@8:基地址的配置:修改完上面那個初始化函數后,因為驅動分為兩個部分:代碼和數據,代碼不用動,所以我們還要修改一些數據,在配置頭文件中,關于網卡的那些宏。
CONFIG_DM9000_BASE 是DM9000網卡通過srom bank 映射到SOC的地址空間的地址,因為我們用的是srom中的bank1 所以根據數據手冊中的內存圖,可以知道,我們的基地址應該是0X88000000。
#define DM9000_IO (CONFIG_DM9000_BASE) 這個表示訪問我們網卡芯片IO的基地址,尋找芯片內部寄存器等的時候。
#define DM9000_DATA (CONFIG_DM9000_BASE+4) 還有這個宏,我們要改成4,這個宏是來決定我們當前發送的是數據的,當我們要發送數據的時候,由原理圖知道,我們的CMD引腳接在了ADDR2,也就第二根地址線上,4的就100,所以就是讓第二根地址線保持高電平,這樣就表示復用發送數據。
@9:改完這些,網卡實際上不可以直接工作的,還要修改CONFIG_DM9000_BASE 將這個地址的0X88000000改成0X88000300,為什么改成這個呢,猜想可能是因為網卡芯片由于版本的問題,自身有了一個偏移量,在以前的時候,可以用這個0X88000000地址,也就是這個srom bank的地址直接就能找到DM9000本身內部的那些寄存器的起始地址,但是可能由于版本問題,現在DM9000本身的寄存器的地址是從300H開始的。
@10:內核啟動不起來,將串口改到串口2,因為三星提供的Linux內核用的是串口2,看配置頭文件中有沒有這兩個宏,
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_CMDLINE_TAG
這兩個宏,確保傳參的
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。