移植uboot第三步:修改时钟
寫在前面:
我的博客已遷移至自建服務器:博客傳送門,CSDN博客暫時停止,如有機器學習方面的興趣,歡迎來看一看。
此外目前我在gitHub上準備一些李航的《統計學習方法》的實現算法,目標將書內算法全部手打實現,歡迎參觀并打星。GitHib傳送門
正文
這個步驟弄死我了,弄了一宿,有很多原因,老是這里那里有問題。
因為是基于s3c2410改的boot,2410和2440在使用上區別不大,所以暫時修改不大。
**1.**還是從start.S依次往下看。
**a.**設置管理模式的代碼都沒有條件編譯,肯定差不多,跳過。
**b.**關閉看門狗的條件編譯是CONFIG_S3C24X0,都一樣的,跳過
**c.*設置分頻,這里需要改,2410和2440有區別。(先做個標記)
d.CPU相關的初始化:
cpu_init_crit
Icache和Dcache的設置,估計也差不多,反正先沒管,有問題再說
最后調用了C函數lowlevel_init,
lowlevel_init:
發現是設置內存的,里面有一堆宏定義,想知道值到底是多少挺麻煩的,可能2410和2440的有不一樣(做個標記,如果出問題了再來改)
e.設置堆棧調用了C函數
board_init_f
這個函數里面就是各種板載資源的初始化,第二步里寫過,里面有一個init_sequence結構體,里面有很多的初始化函數,板載資源應該差不多,也不改了。但是里面有一個函數
board_early_init_f
這是設置時鐘的,這里有些問題,之前分頻結束,但是時鐘還沒設置,分頻以后直接去初始化了內存,之后再設置時鐘,這樣子設置內存的時候有關時間的參數設置的就不對了。比如說設置內存的時候有一個寄存器值#define REFCNT 1113 / period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */它是基于HCLK=60M的時候,沒設置時鐘的時候肯定達不到這個頻率,就有問題了(做個標記)
**2.**先把分頻改了,然后時鐘設置放到board_early_init_f前頭
解決:找到了之前寫的400M時鐘設置的代碼,把之前start.S里的分頻刪了,添加自己寫的分頻和時鐘設置,同時打開了ICache,ICache是為了速度快一點,不加也可以。
最后還要把它原先的時鐘設置的地方注釋掉
board_early_init_f /* to reduce PLL lock time, adjust the LOCKTIME register *///writel(0xFFFFFF, &clk_power->locktime);/* configure MPLL *///writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,// &clk_power->mpllcon);3.修改后的文件拖進linux里編譯,編譯成功,下載到板子里測試。
這里有一個便捷的方式測試,我是用oflash下載的,uboot充其量就是個裸機程序,也沒法NFS什么的(我當時這么認為)。編譯出來的bin524K左右,下進去很慢。后來看了韋東山老師的視頻,發現可以先下載好用的boot,我用的是韋東山老師的,200+K,下載的時間是一半,下進去以后再通過dnw下載,速度快很多。
詳細:
a.啟動uboot,按空格取消倒數,進入下載模式。
b.輸入usb 1 30000000命令,usb表示通過usb下載,1表示一直等待文件傳入(猜測0的話在等待期間還可以輸入別的命令做別的事),30000000表示下載到該地址。
c.PC端打開dnw,USB Port->Transmit,選擇bin,確定。
d.板子收到文件以后,protect off all,這是取消nor的寫保護,因為一會要把文件寫入到nor。
e.earse 0 7ffff,擦除nor,0表示起始地址,7ffff表示結束地址,我的bin算524k,十六進制7ffff,這個結束地址根據bin的實際大小來寫,可以寫大一點。
f.cp.b 30000000 0 7ffff。把代碼段拷貝進30000000這個地址,以這個為首地址,寫到末地址,也就是到7ffff。
g.重啟板子。
備注:一開始很疑惑,我原先好用的boot存在nor,我下載自己的boot的時候,先下載到內存,然后燒到nor,那我原先的boot怎么辦,老家都沒了還怎么運行。后來覺得自己傻逼了,之前自己還一直記得程序最開始就會把nor里面的代碼copy到SDRAM,早就搬家了,但是重啟以后的話,原先的boot就會徹底消失了。我真是太傻逼了,還想了好久。
測試結果:輸出了亂碼。
分析:要不就是時鐘有問題,要不就是串口波特率的問題,這個都不知道兩年單片機白寫了,我都對不起郭天祥韋東山。
4:我覺得時鐘沒問題,那就是串口有問題
void board_init_f(ulong bootflag) for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) serial_init //找到串口初始化了,再進去看一看 int serial_init(void) {return serial_init_dev(UART_NR); }是個函數調用,再進去看
static int serial_init_dev(const int dev_index)
這個函數里面有很多東西,看不懂,有點懵逼了,反正是串口初始化,各種參數的設置。感覺這種為了多種平臺而寫的東西,都會用好多宏定義,繞來繞去的很麻煩。韋東山直接反匯編去看值了,我不會匯編,跟著他的視頻看能看懂,自己看就看不懂了。
不管怎么樣,這個函數里我找到了這個函數_serial_setbrg(dev_index);,應該是波特率設置,如果不是的話我真的要一個一個看下去了。
這個函數里也就調了一個_PCLK(),它又調了get_HCLK(),其他地方就是算數,給的都是常量,感覺沒什么問題,就一直往里走
void _serial_setbrg(const int dev_index)
reg = get_PCLK() / (16 * gd->baudrate) - 1;
get_PCLK()
get_HCLK();
找到了問題,函數里是條件編譯#ifdef CONFIG_S3C2440,這個并沒有被定義,也就是說函數一直在運行return (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK();這句話,很明顯這是2410的串口初始化,所以把這個宏定義定義了就好了。
ulong get_HCLK(void) {struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); #ifdef CONFIG_S3C2440switch (readl(&clk_power->clkdivn) & 0x6) {default:case 0:return get_FCLK();case 2:return get_FCLK() / 2;case 4:return (readl(&clk_power->camdivn) & (1 << 9)) ?get_FCLK() / 8 : get_FCLK() / 4;case 6:return (readl(&clk_power->camdivn) & (1 << 8)) ?get_FCLK() / 6 : get_FCLK() / 3;} #elsereturn (readl(&clk_power->clkdivn) & 2) ? get_FCLK() / 2 : get_FCLK(); #endif }找到smdk2440.h,把下面這句話注釋掉
``#define CONFIG_S3C2410 /* specifically a SAMSUNG S3C2410 SoC */
自己添加一個#define CONFIG_S3C2440,重新編譯,結果說和s3c2410_nand.c的72行沖突了
72行:writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
找到了nand結構體 struct s3c2410_nand *nand = s3c2410_get_base_nand();
又去看了s3c2410_nand ,結果如下
這里就明白了,這個結構體是條件編譯,我把這個注釋掉了,結構體就沒了,程序出錯。我現在只想讓串口打印點東西,所以打算不要這個函數。
5.找到了s3c2410_nand.c所在地的Makefile,我打算直接不讓這個文件編譯了,試試唄。
61行:COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
說明這個文件被編譯是由宏定義CONFIG_NAND_S3C2410決定的,我去取消宏定義就好了,在smdk2440.h里找到了它的宏定義
打算把#define CONFIG_NAND_S3C2410這句話屏了,后來看韋東山更牛逼,想把NAND整個屏了,這些也都是條件編譯,可以看到是由CONFIG_CMD_NAND決定的,所以
#ifdef CONFIG_CMD_NAND,這句話直接屏蔽了再次編譯,沒有錯誤
6.下載到板子上,運行
U-Boot 2012.04.01 (Aug 10 2016 - 03:15:13)CPUID: 32440001 FCLK: 400 MHz HCLK: 100 MHz PCLK: 50 MHz DRAM: 64 MiB WARNING: Caches not enabled Flash: *** failed *** ### ERROR ### Please RESET the board ###程序死了,至少串口輸出了。
后記:dnw的驅動網上可以百度,我是win10的,dnw因為沒有簽名,所以安裝不上,百度win10取消強制簽名,可以安裝,但是實踐發現取消強制簽名只有第一次重啟有效,重啟開機驅動會問號。
選擇永久取消強制簽名,右鍵開始->命令提示符(管理員),輸入
bcdedit.exe /set nointegritychecks on
可以永久取消強制簽名,驅動就不會掉了,我也是試試,因為一直掉,設置以后還沒重啟過,等重啟以后看看有沒有掉,再來補充
總結
以上是生活随笔為你收集整理的移植uboot第三步:修改时钟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移植uboot第二步:分析uboot
- 下一篇: 移植uboot第四步:设置NAND启动