嵌入式平臺上 -/bin/sh: xxx: not found和Illegal instruction的解決辦法

問題描述

在製作TQ2440的LCD背光驅動時,碰到了一個問題:驅動已經完成,在內核啓動代碼中出現過“backlight initialized”,但是運行編譯好的背光控制程序“backlight”時,卻提示 -/bin/sh: backlight: not found
在這裏插入圖片描述
在這裏插入圖片描述

驅動EmbedSky_backlight.c的代碼

/*************************************

NAME:mickey_backlight.c
COPYRIGHT:www.embedsky.net

*************************************/

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/miscdevice.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
	 
#include <mach/regs-gpio.h>
#include <mach/fb.h>
#include <linux/cdev.h>

#define DEVICE_NAME	"backlight"

/*#define S3C2440_LCD_BASE		0x59000000*/
/*#define S3C2440_LCDCON1			(S3C2440_LCD_BASE + 0x00)*/
/*volatile int *lcdcon1 = NULL;*/


static int tq2440_backlight_ioctl(
	struct inode *inode, 
	struct file *file, 
	unsigned int cmd, 
	unsigned long arg)
{
	switch(cmd)
	{
		case 0:
			s3c2410_gpio_setpin(S3C2410_GPG4, 0);
			//*lcdcon1 = *lcdcon1 & (~(0x1<<0));
			printk(DEVICE_NAME" backlight Turn Off!\n");
			return 0;
		case 1:
			s3c2410_gpio_setpin(S3C2410_GPG4, 1);
			//*lcdcon1 |= (0x1<<0);
			printk(DEVICE_NAME" backlight Turn On!\n");
			return 0;
		default:
			return -EINVAL;
	}
}

static struct file_operations dev_fops = {
	.owner	=	THIS_MODULE,
	.ioctl	=	tq2440_backlight_ioctl
};

static struct miscdevice misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICE_NAME,
	.fops = &dev_fops,
};

static int __init dev_init(void)
{
	int ret;

/*	lcdcon1 = (int *)ioremap(S3C2440_LCDCON1, 4);*/
	ret = misc_register(&misc);

	printk (DEVICE_NAME" initialized\n");

	s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_OUTP);

	s3c2410_gpio_setpin(S3C2410_GPG4, 1);
	printk(DEVICE_NAME" backlight Turn On!\n");

	return ret;
}


static void __exit dev_exit(void)
{
	misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.embedsky.net");
MODULE_DESCRIPTION("Backlight control for EmbedSky SKY2440/TQ2440 Board");

背光控制程序backlight.c的代碼:

/*************************************

NAME:backlight.c 
COPYRIGHT:www.embedsky.net

*************************************/
#include<stdio.h> 
#include<stdlib.h> 
#include<unistd.h> 
#include<sys/ioctl.h> 
#include<fcntl.h> 
#include<linux/fb.h>

int main(int argc,char **argv) 
{ 
	int turn; 
	int fd; 
	if(argc==1) 
	{ 
		fprintf(stderr,"\nUsage:backlight on|off !\n\n"); 
		exit(1); 
	} 
	/*fd=open("/dev/fb0",O_RDWR); //對於 Linux-2.6.30.4 應該是/dev/backlight */
	fd=open("/dev/backlight",O_RDWR);

	if(fd<0)
	{ 
		perror("open LCD device!"); 
		exit(1); 
	}
	if(strcmp(argv[1],"on")==0) 
		turn=1; 
	else if(strcmp(argv[1],"off")==0) 
		turn=0; 
	else 
	{ 
		fprintf(stderr,"\nUsage:backlight on|off !\n\n"); 
		exit(1); 
	}
	/*ioctl(fd,FBIOBLANK,turn); //Linux-2.6.30.4 來講應該是:ioctl(fd,turn); */
	ioctl(fd,turn);
	close(fd); 

	return 0;
}

解決過程

  1. 可以確認backlight的二進制文件是存在的,按照網上所說修改了backlight的權限爲777也不起作用。
  2. 使用 arm-linux-readelf -d backlight 檢查依賴庫,發現缺失“libgcc_s.so.1”和“libc.so.6”。
    在這裏插入圖片描述
    於是找了兩個庫及其鏈接庫,拷貝到 /lib目錄下,但是不起作用。
  3. 後來在網上看到了一篇大佬的博客http://www.cnblogs.com/nick123/archive/2009/12/01/1614919.html,嘗試用 arm-linux-readelf -a backlight ,果然發現還缺失 /lib/ld-linux.so.3
    在這裏插入圖片描述
  4. 在拷貝 ld-linux.so.3 及其鏈接庫 到 /lib 目錄下後,終於不是 not found,錯誤變成了“Illegal instruction”。查詢了一下,好像是編譯選項需要加一個“-march=armv4t”,但我的交叉編譯工具是之前修改過的,默認有這個選項。。。
  5. 檢查後發現,應該是 ld-linux.so.3 的問題,在編譯工具下,總共有3處:
    在這裏插入圖片描述
    之前好像用的是第一項了。。。換成第二項之後,問題解決,能夠正常控制背光了٩(๑❛ᴗ❛๑)۶
    在這裏插入圖片描述

(✪ω✪)

雖然是個小問題,但通過這個過程,加深了不少對Linux系統上的應用程序,依賴庫以及嵌入式和X86平臺區別的理解,嗯。。。不錯的絆腳石。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章