Stm32-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 = (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启动后的调试的更多相关文章
- STM32F103 ucLinux开发之四(内核启动后的调试)
Stm32-uclinux启动后的调试 1. 修改__pfn_to_page使得能够启动 根据STM32F103 ucLinux开发之三(内核启动后不正常)的描述,内核无法启动是选择了平板内存模式后 ...
- 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 ...
- FIS--关于下载php后的配置(启动fis的调试服务器(注意添加 --no-rewrite 参数),如果报错 没有php-cgi环境,请 安装 它,并把php-cgi命令加到系统的环境变量)
“启动fis的调试服务器(注意添加 --no-rewrite 参数),如果报错 没有php-cgi环境,请 安装 它,并把php-cgi命令加到系统的环境变量” 对官网这句话的解释: 下载php-5. ...
- Hadoop ha CDH5.15.1-hadoop集群启动后,两个namenode都是standby模式
Hadoop ha CDH5.15.1-hadoop集群启动后,两个namenode都是standby模式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一说起周五,想必大家都特别 ...
- spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
- 在nginx启动后,如果我们要操作nginx,要怎么做呢 别增加无谓的上下文切换 异步非阻塞的方式来处理请求 worker的个数为cpu的核数 红黑树
nginx平台初探(100%) — Nginx开发从入门到精通 http://ten 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么nginx究竟是怎么样的呢?这一节我们先来 ...
- 病症:arm启动后应用程序界面显示…
病症:病症:arm启动后应用程序界面显示不正常(左面有部分未能正常显示)也就是左面少一块区域,右面多一部, 原因:lcd显示驱动中场扫描的问题 平台:s3c2416.linux2.6.800*480l ...
- java虚拟机jvm启动后java代码层面发生了什么?
java虚拟机jvm启动后java代码层面发生了什么? 0000 我想验证的事情 java代码在被编译后可以被jdk提供的java命令进行加载和运行, 在我们的程序被运行起来的时候,都发生了什么事情, ...
- spring boot 配置启动后执行sql, 中文乱码
spring.datasource.schema指定启动后执行的sql文件位置. 我发现中文乱码,原因是没有指定执行sql script encoding: spring: datasource: u ...
随机推荐
- TensorFlow分布式部署【单机多卡】
让TensorFlow飞一会儿 面对大型的深度神经网络训练工程,训练的时间非常重要.训练的时间长短依赖于计算处理器也就是GPU,然而单个GPU的计算能力有限,利用多个GPU进行分布式部署,同时完成一个 ...
- android:项目迁移error:Please change caller according to com.intellij.....
迁移到Android Studio中的项目,在运行时有时会在Event Log中报这种错: Please change caller according to com.intellij.openapi ...
- Linux(CentOS)之-性能监控
这篇主要讲一下Linux(CentOS)上性能性能监控的操作. 1.监控cpu使用情况--uptime 该命令将会打印出当前时间 系统运行了多久 当前登陆用户数 系统平均负载 这里的负载是单位时间 ...
- redis介绍(5)主从复制
redis的主从复制: 主从复制介绍:redis的主从复制情况下,一个master节点下可以有多个slave节点,而且每个slave节点又可以有很多slave节点,形成很大的集群量级,我简单画个图,如 ...
- 扩展LV手记
情景概览 系统:CentOS Linux release 7.4.1708 (Core) 磁盘情况: 目标:将sda3扩展到sda2下的centos-root虚拟盘上 操作步骤 1.建立新的PV # ...
- 【涨姿势】Prince2和PMP的区别,大多数人都没搞清楚!
项目管理领域有2个流行的知识体系: ☑ 一个是美国项目管理协会(PMI)开发的“项目管理知识体系(PMBOK,Project Management Body of Knowledge)”,目 ...
- [翻译] WPAttributedMarkup
WPAttributedMarkup https://github.com/nigelgrange/WPAttributedMarkup WPAttributedMarkup is a simple ...
- Linux su命令详解
su switch user,用于切换用户用 su常见命令参数 用法:su [选项]... [-] [用户 [参数]... ] Change the effective user id and gro ...
- python常见释疑(有别于报错)(不定时更新)
文:铁乐与猫 01.在cmd运行py脚本后,直接回到了提示符,没有任何输出,看起来像是并没有运行一样. 答:你的感觉很可能是对的,但脚本很可能己经正常运行,只是你的代码里面很可能没有给出print提示 ...
- 生成器-yield初接触
什么是生成器? 生成器的实质就是迭代器 在python中有三种方式来获取生成器 1. 通过生成器函数 2. 通过各种推导式实现生成器 3. 通过数据的转换也可以获取生成器 将函数中的return换成y ...