Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2959030
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: 嵌入式

2014-09-26 17:21:29

原文地址:

刚开始要分区nand flash ,

然后配置内核支持jffs2文件系统。


问题一、

NAND read: device 0 offset 0x800000, size 0x400000
4194304 bytes read: OK
Boot with zImage

Starting kernel ...

卡在这边不动了。这种从表面看是内核都还没解压就挂了,还有一种可能就是内核跑起来了,但是串口没打印信息。

网上有人给出如下几个原因

1. kernel的启动参数设置正确与否 ?

在uboot命令下输入#pri 可以查看一些参数

bootargs=mem=128M console=ttySAC0,115200n8 noinitrd root=/dev/mtdblock3 rw init=/linuxrc rootfstype=jffs2

从这里我们可以看出Debug串口的信息为“ttySAC0”,其他的是启动系统的,暂时不管。

这里应该要和内核里面的Debug串口信息一致。于是查看内核 #make menuconfig

Boot options --->

[ ] Flattened Device Tree support │ │
(0x0) Compressed ROM boot loader base address │ │
(0x0) Compressed ROM boot loader BSS address │ │
(root=/deva1 ro init=/bin/bash console=ttySAC0) Default kernel
Kernel command line type (Use bootloader kernel arguments i
[ ] Kernel Execute-In-Place from ROM
一看Debug串口的信息为“ttySAC0”(也就是console这个参数)和boot一样,可以排除这个问题。

2.U-boot中的Machine ID设置的与Kernel不一致;


这个看文档的第二点机器码问题:http://blog.csdn.net/junfeng_liu6/article/details/9421491

经过核实,也排除了这个问题。


3. 如果按上面做了还都不行,在确保上面都正确的情况下,直接使用zImage启动,如:
先把内核烧写到内存中 #tftp 0xc0008000 zImage

然后直接启动内核: #bootm c0008000

此时内核可以直接起来,这下恍然大悟,肯定是烧写到flash时出现问题:

看下烧写命令: #nand erase 0x900000 0x300000

#nand write 0xc0008000 0x900000 0x300000

看了下我内核的大小超过了3M。直接用以前的命令没仔细看真是付出很大的代价。。不过也熟悉了上面的一些知识,算是吃一堑长一智吧!!


问题二:

系统起来后一直会马上重启。

一看到这种情况,就马上想到可能看门口没设置好导致的原因。

从内核打印的信息可以看出wdt是开起来的,

s3c2416-wdt s3c2416-wdt: starting watchdog timer
s3c2416-wdt s3c2416-wdt: watchdog active, reset abled, irq enabled

这里我们可以选者在内核配置单中关闭看门狗,

DeviceDrivers --->
[*]WatchdogTimerSupport --->
< > S3C Watchdog
即可,也可以自己写段喂狗程序,然后在开机时自启动即可。
例如:watchdog.c
  1. #include#include#include#include#include#include#include#includeint main(int argc,char**argv){ int fd=0; int n=0; fd=open("/dev/watchdog",O_RDONLY); if(fd<0){ perror("/dev/watchdog"); return-1; } for(;;){ ioctl(fd,WDIOC_KEEPALIVE); //一直喂狗,不让看门狗重启CPU sleep(3); } close(fd); return 0;}
#include#include#include#include#include#include#include#includeint main(int argc,char**argv){	int fd=0;	int n=0;	fd=open("/dev/watchdog",O_RDONLY);	if(fd<0){	perror("/dev/watchdog");	return-1;	}	for(;;){	ioctl(fd,WDIOC_KEEPALIVE); //一直喂狗,不让看门狗重启CPU	sleep(3);	}	close(fd);	return 0;}
相对应的makefile为
  1. CC=arm-linux-gccEXEC=watchdogOBJS=watchdog.oCFLAGS +=LDFLAGS +=all:$(EXEC)$(EXEC):$(OBJS) $(CC)$(LDFLAGS) -o $@ $(OBJS) $(LDLIBS$(LDLIBS_$@))clean: -rm-f$(EXEC)*.elf*.gdb*.o
CC=arm-linux-gccEXEC=watchdogOBJS=watchdog.oCFLAGS +=LDFLAGS +=all:$(EXEC)$(EXEC):$(OBJS)	$(CC)$(LDFLAGS) -o $@ $(OBJS) $(LDLIBS$(LDLIBS_$@))clean:	-rm-f$(EXEC)*.elf*.gdb*.o
编译完后,弄到系统的/sbin 目录下(/bin等也行),在启动文件“/etc/init.d/rcs”添加一行: watchdog &


问题三:LCD驱动移植(型号:AT070TN83)7寸(800*480)

直接用内核3.1的7寸LCD配置值,发现屏幕会花屏

很奇怪的是开机的logo倒是很正常。

以下是对LCD参数的配置:
#elif defined(CONFIG_FB_S3C_LCD800480)
#define S3CFB_HFP 19 /* front porch */
#define S3CFB_HSW 27 /* hsync width */
#define S3CFB_HBP 37 /* back porch */

#define S3CFB_VFP 10 /* front porch */
#define S3CFB_VSW 13 /* vsync width */
#define S3CFB_VBP 26 /* back porch */

#define S3CFB_HRES 800 /* horizon pixel x resolition */
#define S3CFB_VRES 480 /* line cnt y resolution */

#define S3CFB_HRES_VIRTUAL 800 /* horizon pixel x resolition */
#define S3CFB_VRES_VIRTUAL 960 /* line cnt y resolution */

#define S3CFB_HRES_OSD 800 /* horizon pixel x resolition */
#define S3CFB_VRES_OSD 480 /* line cnt y resolution */

#define S3CFB_VFRAME_FREQ 60 /* frame rate freq */

#define S3CFB_PIXEL_CLOCK 4

//(S3CFB_VFRAME_FREQ * (S3CFB_HFP + S3CFB_HSW + S3CFB_HBP + S3CFB_HRES) * (S3CFB_VFP + S3CFB_VSW + S3CFB_VBP + S3CFB_VRES))

上网搜了一番,也不知道哪里问题。后来改了下S3CFB_PIXEL_CLOCK 改为5。之后屏幕又正常了。这里不知道什么回事,先不管,往下继续做。


问题四: 移植触摸

添加触摸后,点击触摸屏还是不能反映,

首先测试下内核触摸驱动有没问题:查看打印信息发现

s3c2416-ts s3c2416-ts: driver attached, registering input device
input: S3C24XX TouchScreen as /devices/virtual/input/input1

从这里可以看出触摸驱动设备“s3c2416-ts”。那我们现获取该设备的信息看下#cat /proc/bus/input/devices

I: Bus=0019 Vendor=dead Product=beef Version=0102
N: Name="S3C24XX TouchScreen"
P: Phys=
S: Sysfs=/devices/virtual/input/input1
U: Uniq=
H: Handlers=event1
B: PROP=0
B: EV=b
B: KEY=0
B: ABS=1000003

红色词就是我们触摸的设备节点,那我们就调用这个设备节点#cat /dev/input/event1 (我们的设备一般都是在/dev/input/下面的)。然后我们点击屏幕,串口终端有显示乱码,这说明,触摸在内核中是可以的,问题就是上层文件系统的环境。这个后面再说。


执行ts_calibration触摸无反应。解决方法如下:

1,selected device is not a touchscreen I understand
想去找源码,没找到。(后来知道,我是有源码的。)
2,可能是配置问题。也没看到有什么错。probe是成功了。
3,看到一句信息。
input_polldev: version magic '2.6.30.4-EmbedSky mod_unload ARMv4 ' should be '3.2.5apple2.0 mod_unload ARMv4 p2v8 '
insmod: can't insert '/lib/input-polldev.ko': invalid module format
怀疑input-polldev.ko没有加载出错。于是在kenrel中,发现根本没选择该项,于是选成y,加载到kernel中。然后在文件系统中删除ismod input-polldev.ko。
4,结果还是不行。于是用原本的kernel,发现input-polldev.ko模块不加载也没问题,触摸屏照用。于是只能把问题集中到“selected device is not a touchscreen I understand”
去看tslib中的源码。发现问题出在input_raw.c文件中。找到了线索。

arm交叉编译工具中的头文件库中的linux/input.h中的EV_VERSION定义为
#define EV_VERSION 0x010000
而linux内核include/linux/input.h中的EV_VERSION定义为
#define EV_VERSION 0x010001
由此可见问题就出现在内核的输入子系统的版本号不匹配的问题

解决办法:
1.将内核源代码里的include/linux/input.h中的
#define EV_VERSION 0x010001
改为:
#define EV_VERSION 0x010000


问题五:网卡DM9000问题

dm9000 Ethernet Driver, V1.31
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: read wrong id 0x2b2a2928
dm9000 dm9000: wrong id: 0x2b2a2928
dm9000 dm9000: not found (-19).

或:

[root@FriendlyARM /]# ifconfig eth0 up
ifconfig: SIOCGIFFLAGS: No such device

解决办法:

正常打印:
NET: Registered protocol family 24
dm9000 Ethernet Driver, V1.31
eth%d: Invalid ethernet MAC address. using default config, Please set using ifconfig
eth0: dm9000a at cc85e300,cc860304 IRQ 48 MAC: 10:23:45:67:89:ab (platform data)

原因是S3C24XX_PA_DM9000的地址定义错了,应该是0x08000300,错定义为0x20000300


问题六:声卡没有声音:

原因没有声卡驱动,WM9713声卡驱动移植(原来的内核有UDA1341声卡驱动,我们再次基础上直接修改)

首先查看内核/sound/soc/samsung/kconfig 配上WM9713

config SND_SOC_SAMSUNG_SMDK_WM9713
tristate "SoC AC97 Audio support for SMDK with WM9713"
## depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || ##MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210) #屏蔽掉
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX ##add by ljf
select SND_SOC_WM9713
select SND_SAMSUNG_AC97
help
Sat Y if you want to add support for SoC audio on the SMDK.

这样在内核中“make menuconfig”里面就可以看到"SoC AC97 Audio support for SMDK with WM9713",并选中他。

接下来我们要在内核中加入这个平台驱动设备:

在“arch/arm/mach-s3c2416/”的mach-tq2416.c中添加:

//add by ljf
/*
* AC97
*/
//at plat-s3c24xx/devs.c
static int s3c2416_ac97_cfg_gpio(struct platform_device *pdev)
{
return s3c_gpio_cfgpin_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(3));//S3C_GPIO_SFN(4)
}
static struct resource s3c_ac97_resource[] = {
[0] = {
.start = S3C2440_PA_AC97,
.end = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3C244x_AC97,
.end = IRQ_S3C244x_AC97,
.flags = IORESOURCE_IRQ,
},
[2] = {
.name = "PCM out",
.start = DMACH_PCM_OUT,
.end = DMACH_PCM_OUT,
.flags = IORESOURCE_DMA,
},
[3] = {
.name = "PCM in",
.start = DMACH_PCM_IN,
.end = DMACH_PCM_IN,
.flags = IORESOURCE_DMA,
},
[4] = {
.name = "Mic in",
.start = DMACH_MIC_IN,
.end = DMACH_MIC_IN,
.flags = IORESOURCE_DMA,
},
};
static struct s3c_audio_pdata s3c_ac97_pdata = {
.cfg_gpio = s3c2416_ac97_cfg_gpio,
};

static u64 s3c_device_audio_dmamask = DMA_BIT_MASK(32);//0xffffffffUL;//will change


struct platform_device s3c_device_ac97 = {
.name = "samsung-ac97",//wm9713-codec
.id = -1,
.num_resources = ARRAY_SIZE(s3c_ac97_resource),
.resource = s3c_ac97_resource,
.dev = {
.platform_data = &s3c_ac97_pdata,
.dma_mask = &s3c_device_audio_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32)//;0xffffffffUL//will change
}
};
//add by ljf

然后在“struct platform_device *tq2416_devices[] __initdata”中加入

//add by ljf
#ifdef CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713
&s3c_device_ac97,
&samsung_asoc_dma,
#endif
//add by ljf

然后编译、烧写。内核打印信息有

asoc: wm9713-hifi <-> samsung-ac97 mapping ok
ALSA device list:
#0: SMDK WM9713

但是用qtpia自带的音乐播放器,播放出来没声音,时间进度条却有在移动,时间到了也会停止,就是没声音。

在串口终端输入指令“cat /udisk/Too.mp3 > /dev/dsp”也没听到任何声音

用madplay命令播放时会出错

[root@LILLIPUT /]# madplay /udisk/Too\ Close.mp3
MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.
Title: Too Close
Artist: Alex Clare
Album: The Lateness of the Hour (Deluxe Edition)
Year: 2011
error: frame 0: lost synchronization
mapped channel 12 to 0


换一首:

[root@LILLIPUT /]# madplay /udisk/Tulisa\ -\ Young.mp3
MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al.
Title: Young
Artist: Tulisa
Album: We Are Young
mapped channel 12 to 0

就是没声音,不知道怎么解决。

移植步骤有所改变,并解决问题:http://blog.csdn.net/junfeng_liu6/article/details/16860459


问题七:串口1的完善

s3c2416有四个个串口,0用为调试口、1、2、3作为普通的口。

在文件 linux/arch/arm/plat-s3c24xx/devs.c中定义了三个串口的硬件资源


问题八:添加SD驱动移植

硬件上是接在SD1口上,中断脚nCD_SD1接在GPF1脚

  1. static struct s3c_sdhci_platdata tq2416_hsmmc1_pdata __initdata = { .max_width = 4, .cd_type = S3C_SDHCI_CD_GPIO, .ext_cd_gpio = S3C2410_GPF(1), //3 change by ljf .ext_cd_gpio_invert = 1, .get_ro = sdhci1_get_ro,};
static struct s3c_sdhci_platdata tq2416_hsmmc1_pdata __initdata = {	.max_width		= 4,	.cd_type		= S3C_SDHCI_CD_GPIO,	.ext_cd_gpio		= S3C2410_GPF(1), //3  change by ljf	.ext_cd_gpio_invert	= 1,	.get_ro			= sdhci1_get_ro,};


编译,烧写重启,插上SD卡

  1. [root@LILLIPUT /]# mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hzmmc1: new SD card at address db8dmmcblk0: mmc1:db8d SD02G 1.83 GiB mmcblk0: p1FAT-fs (mmcblk0p1): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
[root@LILLIPUT /]# mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hzmmc1: new SD card at address db8dmmcblk0: mmc1:db8d SD02G 1.83 GiB  mmcblk0: p1FAT-fs (mmcblk0p1): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
成功。



最后整合:去掉不必要的打印信息。

修改:linux-3.1_2416\drivers\usb\core\Driver.c 879行

  1. //pr_info("%s: registered new interface driver %s\n", //usbcore_name, new_driver->name); //del by ljf
	//pr_info("%s: registered new interface driver %s\n",			//usbcore_name, new_driver->name); //del by ljf
修改 \drivers\mtd\nand\ Nand_bbt.c 568行 (PS:去掉坏块所打印的信息)


  1. //printk(KERN_WARNING "Bad eraseblock %d at 0x%012llx\n", // i >> 1, (unsigned long long)from);//change by ljf


阅读(2142) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~