linux lr is at?Linux修改时间
遇到Fatal signal 11 求解答
项目问题,目前已解决;在此记录。前些天在调试Camera模块;发现相同的代码在厂家提供的环境里边编译、就是ok的,在我们的源码树中编译,将HAL库推进去后、就会signal11退出。一、现象[plain]viewplaincopy在CODE上查看代码片派生到我的代码片F/libc(4250):Fatalsignal11(SIGSEGV)at0x00000000(code=1),thread4358(CameraPreviewTh)I/DEBUG(2366):************************************************I/DEBUG(2366):Buildfingerprint:'TV/tclm6/tclm6:4.2.1/V8-AML7601-LF1R001/20130523:eng/test-keys'I/DEBUG(2366):Revision:'32'I/DEBUG(2366):pid:4250,tid:4358,name:CameraPreviewTh>>>/system/bin/mediaserver>>>>srcis0x45d0f000D/V4LCameraAdapter(2371):TK---------->>>>>>destis0x0D/V4LCameraAdapter(2371):TK------------>>>>>widthis640D/V4LCameraAdapter(2371):TK--------->>>>>heightis480不难发现,上边dest指针为NULL、导致的signal11。4.解决通过对比编译环境发现,在dest赋值处;用到的头文件位置不同,导致结果差异。通过重新设置头文件路径,问题解决。三、思考目前掌握的结局signal11故障的方法是使用交叉编译工具链给我们提供的arm-none-linux-gnueabi-addr2line工具,通过地址定位源文件中出错的函数或具体行数。四、补充:Fatalsignal8(SIGFPE)最近在帮助同事看一个打印堆栈问题时发现,程序并没有被kill掉[plain]viewplaincopy在CODE上查看代码片派生到我的代码片F/libc(3254):Fatalsignal8(SIGFPE)at0x00000cb6(code=0),thread3254(TVMSFserver)I/DEBUG(2455):************************************************I/DEBUG(2455):Buildfingerprint:'TV/tclm6/tclm6:4.2.2/V8-AML7602-LF1V002/20140520:eng/test-keys'I/DEBUG(2455):Revision:'32'I/DEBUG(2455):pid:3254,tid:3254,name:TVMSFserver>>>TVMSFserver,std::allocator>::xsputn(charconst*,int)+8)通过地址定位:arm-none-linux-gnueabi-addr2line0001827c-elibc.so结果:bionic/libc/arch-arm/bionic/kill.S:46[plain]viewplaincopy在CODE上查看代码片派生到我的代码片ENTRY(kill)stmfdsp!,{r4-r7,ip,lr}ldrr7,=__NR_killswi#0ldmfdsp!,{r4-r7,ip,lr}//46行,恢复现场movsr0,r0bxpllrb__set_syscall_errnoEND(kill)后发现signal8问题一般是由于除数为0导致,后问题解决;通过该问题分析:可能是因为signal8后系统需要kill该进程、但没有kill成功。
linux驱动编写过程中遇到的几个问题及解决
1、显示错误:unknown field'ioctl' specified in initializer
解决办法,查看内核include/linux/fs.h文件,发现里边定义的struct file_operations中没有ioctl,这里我们用.unlocked_ioctl取代,形参去掉 struct inode*。
2、在应用程序中,将ioctl替换为unlocked_ioctl后,会出现以下错误:undefined reference to `unlocked_ioctl'。因为系统调用ioctl是没有改变的,还是原来的系统调用接口,只是系统调用的实现中,ioctl()变成了unlocked_ioctl,在应用层你根本不用关注内核中的这些实现上的改变,你只需要按照系统调用的用法用就可以了。所以把应用程序里的unlocked_ioctl改为ioctl,编译,OK,通过。
3、驱动编译完成,在开发板上insmod,出现以下错误:
WARNING: at lib/kobject.c:595 kobject_put+0x50/0x64()
kobject:'扑'(cbc60a00): is not initialized, yet kobject_put() is being called.
---[ end trace da227214a82491b9 ]---
insmod: cannot insert'led_dev.ko': Cannot allocate memory
原来是忘了写内存申请的代码,添加kmalloc和memset。
4、再次insmod,出现下列错误代码:
Unable to handle kernel paging request at virtual address 7f008820
pgd= cbc70000
[7f008820]*pgd=00000000
Internal error: Oops: 5 [#1]
Modules linked in: led_dev(+)
CPU: 0 Tainted: G W(3.0.1#439)
PC is at led_init+0xa8/0x108 [led_dev]
LR is at kobj_map+0x144/0x154
pc: [<bf0020a8>] lr: [<c0246e70>] psr: 60000013
sp: cbc6bf10 ip: cbc6beb0 fp: cbc6bf24
r10: 00000000 r9: bf002000 r8: cbc6a000
r7: 00000000 r6: bf0002bc r5: 00000000 r4: 00000000
r3: 00000000 r2: 00000000 r1: 7f008000 r0: 00000000
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 00c5387d Table: 5bc70008 DAC: 00000015
Process insmod(pid: 112, stack limit= 0xcbc6a268)
Stack:(0xcbc6bf10 to 0xcbc6c000)
bf00: 00000000 c07463c0 cbc6bf7c cbc6bf28
bf20: c00343c8 bf00200c cbc6bf64 cbc6bf38 c0073e24 00000000 00000000 00000000
bf40: 00000000 0000ef52 000d5bf9 bf0002bc 00000000 0000ef52 000d5bf9 bf0002bc
bf60: 00000000 c0034ce8 cbc6a000 00000000 cbc6bfa4 cbc6bf80 c0085960 c0034398
bf80: c00e8738 c00e8610 402004a8 000dfcf8 00000000 00000080 00000000 cbc6bfa8
bfa0: c0034b40 c00858e0 402004a8 000dfcf8 00b5d038 0000ef52 000d5bf9 ffff5f01
bfc0: 402004a8 000dfcf8 00000000 00000080 00000069 00000001 be9c2e64 be9c2e68
bfe0: be9c2e68 be9c2b14 00021cfc 402c1d74 60000010 00b5d038 5fffe821 5fffec21
[<bf0020a8>](led_init+0xa8/0x108 [led_dev]) from [<c00343c8>](do_one_initcall+0x3c/0x188)
[<c00343c8>](do_one_initcall+0x3c/0x188) from [<c0085960>](sys_init_module+0x8c/0x1a4)
[<c0085960>](sys_init_module+0x8c/0x1a4) from [<c0034b40>](ret_fast_syscall+0x0/0x30)
Code: e59f0060 eb52980e ea00000b e59f1058(e5910820)
---[ end trace da227214a82491b9 ]---
Segmentation fault
最后是各种百度,各种谷歌,参考别人的驱动,发现它们的开发板硬件地址并不是自己写的头文件,而是调用mach中已经定义好的头文件,好吧,寻找相应开发板,相应端口的地址头文件,在驱动文件中添加以下头文件:
#include<mach/map.h>
#include<mach/regs-gpio.h>
#include<mach/gpio-bank-m.h>
Ok,打完收工,开发板,测试。运行无阻。完成。
5、在做到DS18B20温度测试模块驱动的时候,看到网上的代码有些函数可以直接对引脚的功能进行设置,比如:s3c2410_gpio_cfgpin(DQ_PIN, DQ_PIN_OUTP);但是对应于我的s3c6410的开发板就不知道用什么函数了,网上找了半天,发现以上函数是在#include<plat/gpio-cfg.h>中,6410中对应的函数为:extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
6、最近学习移植linux内核,移植了新的linux内核以及挂载了新的NFS之后,重新测试led驱动,发现安装模块以后,运行测试程序会出现以下错误:
-/bin/sh:./main: not found(main为主机上编译好的测试程序)
原因:
编译busybox的时候选择了静态编译:
Build Options->
Build BusyBox as a static binary(no shared libs)
Build with Large File Support(for accessing file>2GB)
如果选择 Build BusyBox as a static binary(no shared libs)方式进行编译时,所需的库已经与程序静态地链接在一起,这些程序不需要额外的库就可以单独运行,但是自己编写的程序在文件系统上运行必须采用静态编译,否则会报诸如:bin/sh: main:not found的错误。
静态编译如:
arm-linux-gcc–static main.c–o main
7.按照普通方法安装配置tftp,并且关闭了防火墙,但是在开发板上tftp主机,总会报错:
tftp: server error:(0) Permission denied
解决办法:
修改文件/etc/sysconfig/selinux,设定其中的
SELINUX=disabled
然后重启电脑即可
求助s3c2410把nandflash中的程序搬到sdram中并运行的程序
你可以自己写一个汇编的程序,把Nand Flash中的程序搬到SDRAM中。因为S3C2410有Nor Flash和Nand Flash有两种启动方式,所以在搬移过程中略有不同。如果用Nand Flash启动可以使用下面的代码,至于Nor Flash启动就相对简单了,你可以自己研究一下。
文件1.head.s
@文件 head.s
@作用:关闭看门狗、SDRAM的初始化设置、搬移 Nand Flash 4K以后
@的代码到 SDRAM的指定位置、执行 SDRAM中的代码
.text
.global _start
_start:
ldr r0,=0x53000000@ Close Watch Dog Timer
mov r1,#0x0
str r1, [r0]
bl memory_setup@ Initialize memory setting
bl flash_to_sdram@ Copy code to sdram
ldr sp,=0x34000000@ Set stack pointer
ldr pc,=main@ execute the code in SDRAM
文件2:flash.s
@文件 flash.s
@作用:设置 Nand Flash的控制寄存器、读取 Nand Flash
@中的代码到 SDRAM的指定位置
.equ NFCONF, 0x4e000000
.equ NFCMD, 0x4e000004
.equ NFADDR, 0x4e000008
.equ NFDATA, 0x4e00000c
.equ NFSTAT, 0x4e000010
.equ NFECC, 0x4e000014
.global flash_to_sdram
flash_to_sdram:
@ Save return addr
mov r10,lr
@ Initialize Nand Flash
mov r0,#NFCONF
ldr r1,=0xf830
str r1,[r0]
@ First reset and enable Nand Flash
ldr r1,[r0]
bic r1, r1,#0x800
str r1,[r0]
ldr r2,=NFCMD
mov r3,#0xff
str r3,[r2]
@ for delay
mov r3,#0x0a
1:
subs r3, r3,#1
bne 1b
@ Wait until Nand Flash bit0 is 1
wait_nfstat:
ldr r2,=NFSTAT
ldr r3,[r2]
tst r3,#0x01
beq wait_nfstat
@ Disable Nand Flash
ldr r0,=NFCONF
ldr r1,[r0]
orr r1,r1,#0x8000
str r1,[r0]
@ Initialzie stack
ldr sp,=4096
@ Set arguments and call
@ function nand_read defined in nand_read.c
ldr r0,=0x30000000
mov r1,#4096
mov r2,#1024
bl nand_read
@ return
mov pc,r10
文件3:interrupt.c
/*
*文件 interrupt.c
*作用:设置并响应按键中断
*/
#include"printf.h"
#define GPECON(*(volatile unsigned long*)0x56000040)
#define GPEDAT(*(volatile unsigned long*)0x56000044)
#define GPEUP(*(volatile unsigned long*)0x56000048)
#define GPFCON(*(volatile unsigned long*)0x56000050)
#define GPFDAT(*(volatile unsigned long*)0x56000054)
#define GPFUP(*(volatile unsigned long*)0x56000058)
#define GPGCON(*(volatile unsigned long*)0x56000060)
#define GPGDAT(*(volatile unsigned long*)0x56000064)
#define GPGUP(*(volatile unsigned long*)0x56000068)
#define EINTMASK(*(volatile unsigned long*)0x560000a4)
#define INTMSK(*(volatile unsigned long*)0X4a000008)
#define PRIORITY(*(volatile unsigned long*)0x4a00000c)
#define EINTPEND(*(volatile unsigned long*)0x560000a8)
#define INTPND(*(volatile unsigned long*)0X4a000010)
#define SRCPND(*(volatile unsigned long*)0X4a000000)
#define BIT_EINT0(0x1<< 0)
#define BIT_EINT2(0x1<< 2)
#define BIT_EINT8_23(0x1<< 5)
#define SET_KEY_INTERRUPT_REG()({\
GPGCON=(GPGCON&(~((3<<12)|(3<<4))))|((1<<12)|(1<<4));\
GPGDAT= GPGDAT&(~((1<<6)|(1<<2)));\
GPECON=(GPECON&(~((3<<26)|(3<<22))))|((1<<26)|(1<<22));\
GPEDAT= GPEDAT&(~((1<<13)|(1<<11)));\
GPGCON=(GPGCON&(~((3<<22)|(3<<6))))|((2<<22)|(2<<6));\
GPFCON=(GPFCON&(~((3<<4)|(3<<0))))|((2<<4)|(2<<0));\
})
__inline void ClearPending(int bit)
{
SRCPND= bit;
INTPND= bit;
}
void init_irq(){
GPFCON=((0x1<<8)|(0x1<< 10)|(0x1<< 12)|(0x1<< 14));// Set the led D9~D12 output
/*
GPGCON=(GPGCON&(~((3<<12)|(3<<4))))|((1<<12)|(1<<4));// GPGCON6,2 set output
// GPGCON6:KSCAN1
// GPGCON2:KSCAN3
GPGDAT= GPGDAT&(~((1<<6)|(1<<2)));// GPGDAT6,2 output 0
GPECON=(GPECON&(~((3<<26)|(3<<22))))|((1<<26)|(1<<22));// GPECON13,11 set output
GPEDAT= GPEDAT&(~((1<<13)|(1<<11)));// GPEDAT13,11 output 0
GPGCON=(GPGCON&(~((3<<22)|(3<<6))))|((2<<22)|(2<<6));// GPGCON11,3 set EINT
GPFCON=(GPFCON&(~((3<<4)|(3<<0))))|((2<<4)|(2<<0));// GPFDAT2,0 set EINT
*/
// Use the defined micro instead of above code
SET_KEY_INTERRUPT_REG();
GPFUP|=(1<<0)|(1<<2);// Up
GPGUP|=(1<<3)|(1<<11);// Up
EINTPEND|=(1<< 19)|(1<< 11);// Clear eint 11,19
EINTMASK&=(~((1<< 19)|(1<< 11)));// Enable EINT11,19
ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);// Enable EINT0,2 and the EINT8_23
INTMSK&=(~0x25);
return;
}
int Key_Scan( void)
{
int i;
for(i= 0; i< 1000;i++);
GPGDAT=(GPGDAT&(~((1<<6)|(1<<2))))|(1<<6)|(0<<2);//GPG6,2 output 0
GPEDAT=(GPEDAT&(~((1<<13)|(1<<11))))|(1<<13)|(1<<11);//GPE13,11 output 0
if((GPFDAT&(1<< 0))== 0) return 16;
else if((GPFDAT&(1<< 2))== 0) return 15;
else if((GPGDAT&(1<< 3))== 0) return 14;
else if((GPGDAT&(1<<11))== 0) return 13;
GPGDAT=(GPGDAT&(~((1<<6)|(1<<2))))|(0<<6)|(1<<2);//GPG6,2 output 0
GPEDAT=(GPEDAT&(~((1<<13)|(1<<11))))|(1<<13)|(1<<11);//GPE13,11 output 0
if((GPFDAT&(1<< 0))== 0) return 11;
else if((GPFDAT&(1<< 2))== 0) return 8;
else if((GPGDAT&(1<< 3))== 0) return 5;
else if((GPGDAT&(1<<11))== 0) return 2;
GPGDAT=(GPGDAT&(~((1<<6)|(1<<2))))|(1<<6)|(1<<2);//GPG6,2 output 0
GPEDAT=(GPEDAT&(~((1<<13)|(1<<11))))|(1<<13)|(0<<11);//GPE13,11 output 0
if((GPFDAT&(1<< 0))== 0) return 10;
else if((GPFDAT&(1<< 2))== 0) return 7;
else if((GPGDAT&(1<< 3))== 0) return 4;
else if((GPGDAT&(1<<11))== 0) return 1;
GPGDAT=(GPGDAT&(~((1<<6)|(1<<2))))|(1<<6)|(1<<2);//GPG6,2 output 0
GPEDAT=(GPEDAT&(~((1<<13)|(1<<11))))|(0<<13)|(1<<11);//GPE13,11 output 0
if((GPFDAT&(1<< 0))== 0) return 12;
else if((GPFDAT&(1<< 2))== 0) return 9;
else if((GPGDAT&(1<< 3))== 0) return 6;
else if((GPGDAT&(1<<11))== 0) return 3;
else return 0xff;
}
void EINT_Handle( void){
GPGCON=(GPGCON&(~((3<<22)|(3<<6))))|((0<<22)|(0<<6));//GPG11,3 set input
GPFCON=(GPFCON&(~((3<<4)|(3<<0))))|((0<<4)|(0<<0));//GPF2, 0 set input
if(INTPND==BIT_EINT8_23){
if(EINTPEND&(1<<11))
EINTPEND|= 1<< 11;
if(EINTPEND&(1<<19))
EINTPEND|= 1<< 19;
ClearPending(BIT_EINT8_23);
}
else if(INTPND==BIT_EINT0){
ClearPending(BIT_EINT0);
} else if(INTPND==BIT_EINT2){
ClearPending(BIT_EINT2);
}
int key= Key_Scan();
if( key!= 0xff){
uart_printf("K%d is pressed!\n", key);
GPFDAT=~(key<< 4);
}
SET_KEY_INTERRUPT_REG();
return;
}
文件4:mem.s
@文件 mem.s
@作用:SDRAM的初始化设置
@关于初始化的更多细节,请参考我的前一篇随笔
.global memory_setup@导出 memory_setup,使其对链接器可见
memory_setup:
mov r1,#0x48000000
adrl r2, mem_cfg_val
add r3, r1,#13*4
1:
@ write initial values to registers
ldr r4, [r2],#4
str r4, [r1],#4
cmp r1, r3
bne 1b
mov pc, lr
.align 4
mem_cfg_val:
.long 0x22111110@ BWSCON
.long 0x00000700@ BANKCON0
.long 0x00000700@ BANKCON1
.long 0x00000700@ BANKCON2
.long 0x00000700@ BANKCON3
.long 0x00000700@ BANKCON4
.long 0x00000700@ BANKCON5
.long 0x00018005@ BANKCON6
.long 0x00018005@ BANKCON7 9bit
.long 0x008e07a3@ REFRESH
.long 0x000000b2@ BANKSIZE
.long 0x00000030@ MRSRB6
.long 0x00000030@ MRSRB7
文件5:nand_read.c
/*文件 nand_read.c
*作用:从 Nand Flash中读取一块数据到 SDRAM中的指定位置
*/
#define NFCONF(*(volatile unsigned long*)0x4e000000)
#define NFCMD(*(volatile unsigned long*)0x4e000004)
#define NFADDR(*(volatile unsigned long*)0x4e000008)
#define NFDATA(*(volatile unsigned long*)0x4e00000c)
#define NFSTAT(*(volatile unsigned long*)0x4e000010)
#define NFECC(*(volatile unsigned long*)0x4e000014)
#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK 0x1ff
void wait_idle(){
int i;
for(i= 0; i< 50000;++i);
}
int nand_read(unsigned char*buf, unsigned long start_addr, int size){
int i, j;
/*
* detect the argument
*/
if((start_addr& NAND_BLOCK_MASK)||(size& NAND_BLOCK_MASK)){
return-1;
}
/* chip Enable*/
NFCONF&=~0x800;
for(i=0; i<10; i++){
;
}
for(i=start_addr; i<(start_addr+ size); i+=NAND_SECTOR_SIZE){
NFCMD= 0;
/* Write Address*/
NFADDR= i& 0xff;
NFADDR=(i>> 9)& 0xff;
NFADDR=(i>> 17)& 0xff;
NFADDR=(i>> 25)& 0xff;
wait_idle();
for(j=0; j< NAND_SECTOR_SIZE; j++){
*buf++=(NFDATA& 0xff);
}
}
NFCONF|= 0x800;/* chip disable*/
return 0;
}
文件6:sdram.c
/*文件 sdram.c
*作用:循环点 FS2410开发板上的 D9、D10、D11、D12
*四个发光二极管。
*/
#define GPFCON(*(volatile unsigned long*)0x56000050)
#define GPFDAT(*(volatile unsigned long*)0x56000054)
int main()
{
int i,j;
while(1){
for(i= 0; i<4;++i){
GPFCON= 0x1<<(8+i*2);
GPFDAT= 0x0;
// for delay
for(j=0;j<50000;++j);
}
}
}
文件7:nand.lds
SECTIONS{
first 0x00000000:{ head.o mem.o flash.o nand_read.o}
second 0x30000000: AT(4096){ sdram.o}
}
文件8:Makefile
sdram:head.s flash.s mem.s sdram.c
arm-linux-gcc-c-o head.o head.s
arm-linux-gcc-c-o mem.o mem.s
arm-linux-gcc-c-o flash.o flash.s
arm-linux-gcc-c-o nand_read.o nand_read.c
arm-linux-gcc-c-o sdram.o sdram.c
arm-linux-ld-Tnand.lds head.o mem.o flash.o nand_read.o sdram.o-o sdram_tmp.o
arm-linux-objcopy-O binary-S sdram_tmp.o sdram
clean:
rm-f*.o
rm-f sdram
好了,你把这些文件拷下去,执行make命令就能生成可执行的二进制代码sdram,把sdram烧写到板子上就能运行了。祝你好运