STM32F103 ucLinux開發之四(內核啟動后的調試)


Stm32-uclinux啟動后的調試

1、  修改__pfn_to_page使得能夠啟動

根據STM32F103 ucLinux開發之三(內核啟動后不正常)的描述,內核無法啟動是選擇了平板內存模式后,下面兩個宏定義,導致計算錯誤,從而Backtrace的。

#define __pfn_to_page(pfn)     (mem_map + ((pfn) - ARCH_PFN_OFFSET))

#define __page_to_pfn(page)  ((unsigned long)((page) - mem_map) + \

                              ARCH_PFN_OFFSET)

以上兩個宏中用到的ARCH_PFN_OFFSET ->

#define ARCH_PFN_OFFSET              PHYS_PFN_OFFSET ->

#define PHYS_PFN_OFFSET      (PHYS_OFFSET >> PAGE_SHIFT) ->

#define PAGE_SHIFT                  12,

#define PHYS_OFFSET     (CONFIG_DRAM_BASE)

#define CONFIG_DRAM_BASE 0x20000000

經過這樣一番推算,確實是0x2000 0

 

根據內存的分配,我修改這里,改為下面的:

#define __pfn_to_page(pfn)    (mem_map + ((pfn) - 0x68000))

#define __page_to_pfn(page)          ((unsigned long)((page) - mem_map) + \

                                      0x68000)

這樣,運行在片內FLASH的內核,運行在片外NorFlash的內核都可以正常啟動了。

 

2、  微內核制作文件initramfs

微內核運行在片內的FLASH中,其中編譯好的xipImage,里面包含一個壓縮的cpio格式的initrd,這個initrd占據了一段空間,這樣內核不能添加其它模塊,而initrd也限制了大小,有必要將內核和initrd分離。

initramfs_data.cpio.gz與內核分離,放在片外的norflash,在populate_rootfs函數,解壓initramfs_data.cpio.gz,實際是解壓initrd_start開頭的內容,掛載根文件,這樣與Android的啟動非常類似。需要做的修改:

修改1:\init\initramfs.c

//if (err)

         //panic(err);    

           此處解壓會出錯,err返回一個大於0的數值,所以先注釋掉。  

修改2:原來編譯busybox后,生成的 initramfs-filelist 文件,每次編譯都會重新生成。將這個文件減少為4行,創建/   /dev   /rooot   /dev/console四個;

在vendors/STMicroelectronics/STM3210E-EVAL-MCU_Flash/gen-initramfs-filelist.sh文件中,除了第一行外,用if [0]; then限制,這樣每次整個編譯的時候,就不會修改內核目錄linux-2.6.x下面的initramfs-filelist文件了

修改3:boot中的參數添加initrd=0x64200000,128K(暫定起始地址是0x6420 0000,大小是128K)。

 

initramfs_data.cpio.gz的解壓與制作

        解壓縮:

                   gunzip   initramfs_data.cpio.gz

                   mkdir    temp

                   cd       temp

                   cpio    -i   -F  ../initramfs_data.cpio.gz --no-absolute-filename               //千萬要加后面的--no-absolute-filename,不然虛擬機會處問題

                  

         重新壓縮打包:

         cd   romfs/

    find . | cpio -o -H newc | gzip > ../initramfs_data.cpio.gz

 

3、  Busybox單獨編譯

原始編譯過程中,busybox跟着一起編譯,但是提供的命令非常有限,要添加命令,就需要單獨編譯busybox。需要做的修改:

修改1:編譯命令為: 

Make ARCH=arm CROSS_COMPILE=/root/CodeSourcery/Sourcery_G++_Lite/bin/arm-uclinuxeabi- ROOTDIR=/opt/stm32uclinux/uClinux-dist/

修改2:Makefile中修改CC等,加入CPUFLAG

           CPUFLAGS := -march=armv7-m -mthumb

           CC        = $(CROSS_COMPILE)gcc $(CPUFLAGS)

           AS        = $(CROSS_COMPILE)as $(CPUFLAGS)

           CXX       = $(CROSS_COMPILE)g++ $(CPUFLAGS)

           AR        = $(CROSS_COMPILE)ar

           LD        = $(CROSS_COMPILE)ld $(CPULDFLAGS)

           OBJCOPY   = $(CROSS_COMPILE)objcopy

           RANLIB    = $(CROSS_COMPILE)ranlib

           ELF2FLT   = elf2flt

           STRIPTOOL = $(CROSS_COMPILE)strip

           STRIP     = $(STRIPTOOL)

 

4、  jfss2文件系統制作

運行在片外NorFlash的內核,掛載了jfss2格式的文件系統,而這個文件系統是只讀的,調試應用程序的時候,就需要重新生成這樣的文件系統,然后下載到norflash中。

假設當前目錄下,包含romfs、原始的device.tab,則執行下面的命令,會生成rootfs.img.bin

/opt/stm32uclinux/uClinux-dist/user/mtd-utils/build/mkfs.jffs2 -D device.tab -o rootfs.img.bin -q -x rtime -x zlib -d romfs/

 

5、  如何調試,在片外SRAM運行,省去每次寫Flash操作

無論是運行在片內、還是片外,每次少些內核都需要擦除和寫入FLASH,這個時間比較長,不利於調試程序。而開發板有網口,可以在boot支持tftp下載,將內核下載到片外的SRAM中,然后boot跳轉到SRAM中執行內核。

 

5.1 修改內核編譯啟動地址,讓其在SRAM內運行

如下圖所示,修改內核啟動后的執行地址為0x6800 1000,讓出前面4K的空間,用於存放boot參數信息等。

 

還要修改arch\arm\kernel\vmlinux.lds.S文件中,原來如下面所示,這樣將數據段編譯到了0x2000 0000開頭的地方。

_etext = .;                           /* End of text and rodata section */

#ifdef CONFIG_XIP_KERNEL

         __data_loc = ALIGN(4);            /* location in binary */

         . = PAGE_OFFSET + TEXT_OFFSET;

#else

         . = ALIGN(THREAD_SIZE);

         __data_loc = .;

#endif

修改為下面這樣的,這樣數據段,就會更在內核代碼段的后面,所有的內容都編譯了片外SRAM。

_etext = .;                           /* End of text and rodata section */

#ifdef CONFIG_XIP_KERNEL

         . = ALIGN(THREAD_SIZE);

         __data_loc = .;

#else

         . = ALIGN(THREAD_SIZE);

         __data_loc = .;

#endif

 

5.2 無法運行時,修改中斷向量位置

按照5.1那樣,編譯出來的中斷向量也防止到片外。在arch\arm\mm\proc-v7m.S的__v7m_setup段,原來是下面所示,將中斷向量的位置寫入向量表基址寄存器,而內核編譯到片外以后,這個地址vector_table也在片外。Stm32f103的中斷向量不能防止到片外,這里需要修改。

@ Configure the vector table base address

         ldr    r0, =0xe000ed08               @ vector table base address

         ldr    r12, =vector_table

         str    r12, [r0]

修改為下面這樣,將編譯好的中斷向量表的內容復制到0x20008000開始的地方,然后將0x20008000設置到向量表基址寄存器

ldr    r0, =vector_table

         ldr   r5, =0x20008000

         Add  r6, r0, #0x120                   

1:      ldr    r12, [r0], #4

         str    r12, [r5], #4

         cmp r0, r6

         bne  1b

         @ Configure the vector table base address

         ldr    r0, =0xe000ed08               @ vector table base address

         ldr    r12, =0x20008000

         str    r12, [r0]

 

5.3 修改norFlash文件系統分區,使得自行編譯過的busybox文件系統可以運行

在drivers\mtd\maps\stm3210e_eval_mtd_map.c文件中,調整分區,如下所示。

static struct mtd_partition stm3210e_eval_flash_partitions [] = {

{

         .name = "Kernel raw data",

         .offset = 0,

         .size = 0x00100000,

         .mask_flags     = MTD_WRITEABLE, /* force read-only */

         },

         {

         .name = "rootfs",

         .offset = 0x00100000,

         .size = 0x00C00000,

         },

         {

         .name = "rawdata",

         .offset = 0x00D00000,

         .size = 0x30000,/* MTDPART_SIZ_FULL will expand to the end of the flash */

         },

         {

         .name = "cramfs_partition",

         .offset = 0x00D30000,

         .size = 0x30000,/* MTDPART_SIZ_FULL will expand to the end of the flash */

         },

};

將文件系統的大小由原來的384K,調整為12M,其它分區大小不變,位置需要跟着調整。

 

6、  三種方式運行速率

采用第5部分調試后,內核運行在了片外SRAM中。跟運行在片內Flash,片外的norflash中相比,速率有明顯的差異,以BogoMIPS為比較,如下面所示。

片內:                           164864     32.97                 基本准確,時鍾是72M

片外SRAM:                   9280         1.85         

片外norflash:                4096         0.81

系統時鍾是72M,所以運行在片內FLASH是正常的,而其它兩個位置,速率都非常的慢,系統變得異常了。考慮到應用程序最終要運行在片外的SRAM中,而系統運行這么慢,所以這種方式不適合ucLinux開發,不再嘗試了。下面給出一個異常的例子。

 

7、  串口的過載

微內核運行在片內的Flash中,initramfs啟動后,在超級終端上輸入命令,可以看到輸出,然后點擊PC鍵盤上的向上箭頭,可以看到上一條輸入的命令。

而無論運行在片外SRAM,還是norflash,掛載文件系統后,點擊PC鍵盤上的向上箭頭,都會打印出ttySA0 input overrun(s),意思就是傳開口過載了。

跟蹤程序發現,就是串口收到的字符沒有來得及讀取完畢,下一個字符有到來了,這樣就會出現過載。而點擊PC鍵盤上的向上箭頭,串口會連續收到0x1B 5B 41 ,3個字節的數據。運行在片外SRM或者norflash中,系統緩慢到,連串口的3個字節數據都處理不了,其它的外設也許也會出現異常。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM