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        = (CROSSCOMPILE)gcc(CROSSCOMPILE)gcc(CPUFLAGS)

AS        = (CROSSCOMPILE)as(CROSSCOMPILE)as(CPUFLAGS)

CXX       = (CROSSCOMPILE)g++(CROSSCOMPILE)g++(CPUFLAGS)

AR        = $(CROSS_COMPILE)ar

LD        = (CROSSCOMPILE)ld(CROSSCOMPILE)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个字节数据都处理不了,其它的外设也许也会出现异常。

Stm32-uclinux启动后的调试的更多相关文章

  1. STM32F103 ucLinux开发之四(内核启动后的调试)

    Stm32-uclinux启动后的调试 1.  修改__pfn_to_page使得能够启动 根据STM32F103 ucLinux开发之三(内核启动后不正常)的描述,内核无法启动是选择了平板内存模式后 ...

  2. STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085和串口只发送数据不能接收数据问题

    STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085的问题讨论:http://www.rt-thr ...

  3. FIS--关于下载php后的配置(启动fis的调试服务器(注意添加 --no-rewrite 参数),如果报错 没有php-cgi环境,请 安装 它,并把php-cgi命令加到系统的环境变量)

    “启动fis的调试服务器(注意添加 --no-rewrite 参数),如果报错 没有php-cgi环境,请 安装 它,并把php-cgi命令加到系统的环境变量” 对官网这句话的解释: 下载php-5. ...

  4. Hadoop ha CDH5.15.1-hadoop集群启动后,两个namenode都是standby模式

    Hadoop ha CDH5.15.1-hadoop集群启动后,两个namenode都是standby模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一说起周五,想必大家都特别 ...

  5. spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

  6. 在nginx启动后,如果我们要操作nginx,要怎么做呢 别增加无谓的上下文切换 异步非阻塞的方式来处理请求 worker的个数为cpu的核数 红黑树

    nginx平台初探(100%) — Nginx开发从入门到精通 http://ten 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢?这一节我们先来 ...

  7. 病症:arm启动后应用程序界面显示…

    病症:病症:arm启动后应用程序界面显示不正常(左面有部分未能正常显示)也就是左面少一块区域,右面多一部, 原因:lcd显示驱动中场扫描的问题 平台:s3c2416.linux2.6.800*480l ...

  8. java虚拟机jvm启动后java代码层面发生了什么?

    java虚拟机jvm启动后java代码层面发生了什么? 0000 我想验证的事情 java代码在被编译后可以被jdk提供的java命令进行加载和运行, 在我们的程序被运行起来的时候,都发生了什么事情, ...

  9. spring boot 配置启动后执行sql, 中文乱码

    spring.datasource.schema指定启动后执行的sql文件位置. 我发现中文乱码,原因是没有指定执行sql script encoding: spring: datasource: u ...

随机推荐

  1. 1000! mod 10^250

    1000! mod 10^250  =============== the answer is 2 ================ Hi I'm trying to solve the above ...

  2. 微信小程序为什么不被看好?

    我自认为对新技术还是比较有热情的,可对于小程序这个“新技术”,我却完全是被动的.去年9月份的时候,微信小程序开始内测,瞬间引爆朋友圈.知乎等一众分享平台.当时我大概了解了一下,觉得从技术角度上来说没啥 ...

  3. 润乾V4导出TXT时自定义分隔符

     ◆ 背景说明 报表中,导出text时,默认没有分隔符:应用中对导出Text,希望能自定义分隔符.在tag中定义了 textDataSeparator属性,让用户在导出Text时自定义分隔符,从而 ...

  4. redis 命令clear、set、get、del、rename、keys *、exists、type、expire、expireat、persist、ttl、move、select

    清屏 clear 新增/修改set 查询get 删除del 修改key rename old new 查询所有的key keys *查询一个key是否存在 exists,有返回1,没有返回0查询值的类 ...

  5. Automate the Sizing of your SGA in Oracle 10g

    How much memory does each of the individual components of the SGA need? Oracle now has methods to de ...

  6. redis介绍(7)高级用法

    redis的过期策略以及内存淘汰机制 分析:这个问题其实相当重要,到底redis有没用到家,这个问题就可以看出来.比如你redis只能存5G数据,可是你写了10G,那会删5G的数据.怎么删的,这个问题 ...

  7. Week4——Hello.java分析

    如下图源码所示: 该段代码声明了一个entity实体类,该类有一个变量name,对该变量写了对应的get和set方法.类中还有一个空的构造方法hello(). @RequestScoped用于指定一个 ...

  8. 动态修改JDBC数据源配置

    因项目需要能动态修改数据源的配置,及修改后不用重启整个应用.使用的数据源是apache的BasicDataSource,网上千篇一律的是如下实现: BasicDataSource bds=getDat ...

  9. spring boot(10)-tomcat jdbc连接池

    默认连接池 tomcat jdbc是从tomcat7开始推出的一个连接池,相比老的dbcp连接池要优秀很多.spring boot将tomcat jdbc作为默认的连接池,只要在pom.xml中引入了 ...

  10. SQL server数据库压缩空间

    SQL server数据库,在手动删除或者自动删除数据后,查看数据库物理文件发现占用空间并没有释放,果断采用万能的重启.(反正是自己用的一个服务器,随便玩.如果不是只有自己用的服务器,还是建议让运维或 ...