2440init.s分析简化
ARM9无操作系统实验(一)LED部分
开始
设置 GPB5 为输出状态
置位 GPB5,LED0 熄灭
设置 GPB 端口禁止上拉
清零 GPB5,点亮 LED0
结束
将程序加载到开发板上,就可以看实验的结果了,其它 LED 灯的控制和 LED0 一样,只是 寄存器的设置值不同罢了。
实验二、流水灯 终于能点亮一个 LED 灯了,那么它有什么用呢?它的主要用途在于一些状态的显示上,
GPB5 LED0 GPB6 LED1 GPB8 LED2 GPB10 LED3 ********************************************/
/*---------地址声明----------*/
#include "2440addr.h"
注释:在本程序的开头,引入一个 2440addr.h 的头文件,该文件中定义了我们要常用的 寄存器的地址,以后的程序中,只需引入即可。引入的方法是将这个头文件直接放在 ADS 安装文件的 include 中就行了。
S3C2440 无操作系统实验——LED 部分
S3C2440 无操作系统实验(一)——LED 部分
小小达摩 2011-6-23
硬件:飞凌 FL2440 开发板 软件:ADS1.2
拿到 ARM 开发板,应该从哪儿开始学习呢?困扰了很多初学者,当然也正在困扰我, 因为我也是初学者。所以我想与其困惑,还不如先做些自己能做的,将会做的做熟悉了,也 许就找到学习的方向了吧。那么从哪儿入手呢,想来想去,那就从点亮一个 LED 灯作为学 习的起点。虽然很多人,不推荐用学习单片机的模式来学习 ARM,但是我感觉基础还是重 要的,再说高级的学习暂时也不会呀,呵呵。虽然这样学习会慢点,但是总比开发板落厚厚 一层灰要划得来吧(开发板买了快 2 年了,拿来玩的时间不超过 2 个月,也许很多朋友都有 这样的经历吧)。所以,把它拿出来,开始学习吧。
星S3C2440微处理器
应用实例一:嵌入式系统开发
嵌入式系统开发
星S3C2440微处理器适用于嵌入 式系统开发,其强大的处理能力 和丰富的外设接口使其成为嵌入 式领域的理想选择。
实时操作系统
星S3C2440微处理器支持实时操 作系统(RTOS)的开发,RTOS 能够提供实时任务调度和多任务 处理能力,满足实时系统的需求。
3
APB和ASB总线
APB和ASB总线用于连接低速外设,如GPIO、 UART等。
03
星S3C244ห้องสมุดไป่ตู้微处理器的指令集 架构
指令集架构概述
ARM架构
01
S3C2440微处理器采用ARM架构,属于精简指令集(RISC)的
范畴。
指令集发展历程
02
ARM架构的指令集经过多年的发展,已成为移动设备和嵌入式
指令集功能
数据处理指令
用于执行算术、逻辑、移位等基本操 作。
控制流程指令
用于控制程序的执行流程,如条件判 断、跳转等。
内存访问指令
用于读写内存和访问外部存储器。
协处理器指令
用于执行特定功能,如浮点运算、加 密等。
指令集实现方式
汇编语言
使用汇编语言编写程序,通过汇编器将汇编代码转换 为机器码。
C/C语言
星S3C2440微处理器
• 星S3C2440微处理器概述 • 星S3C2440微处理器的体系结构 • 星S3C2440微处理器的指令集架构
• 星S3C2440微处理器的编程模型 • 星S3C2440微处理器的应用实例
01
星S3C2440微处理器概述
定义与特点
定义
S3C2440是一款由三星公司开发的 ARM920T核的微处理器。
s3c2440芯片中文手册2
第二章处理器工作模式2.1概述S3C2440采用了非常先进的ARM920T内核,它是由ARM(Advanced RISC Machines) 公司研制的。
2.2 处理工作状态从程序员的角度上看,ARM920T可以工作在下面两种工作状态下的一种:● ARM 状态:执行32位字对齐的ARM指令● THUMB 状态:执行16位半字对齐的THUMB指令。
在这种状态下,PC 寄存器的第一位来选择一个字中的哪个半字注意;这两种状态的转换不影响处理模式和寄存器的内容。
2.3 切换状态进入THUMB 状态进入THUMB 状态,可以通过执行BX指令,同时将操作数寄存器的状态位(0位)置1来实现。
当从异常(IRQ,FIQ,UNDEF,ABORT,SWI等)返回时,只要进入异常处理前处理器处于THUMB状态,也会自动进入THUMB状态。
进入ARM状态进入ARM状态,可以通过执行BX指令,并且操作数寄存器的状态位(0位)清零来实现。
当处理进入异常(IRQ,FIQ,RESET,UNDEF,ABORT,SWI等)。
这时,PC值保持在异常模式下的link寄存器中,并从异常向量地址处开始执行处理程序。
存储空间的格式ARM920T将存储器空间视为从0开始由字节组成的线性集合,字节0到3中保存了第一个字节,字节4到7中保存第二个字,以此类推,ARM920T对存储的字,可以按照小端或大端的方式对待。
大端格式:在这种格式中,字数据的高字节存储在低地址中,而字数据的低字节则存放2.4 指令长度指令可以是32位长度(在ARM状态下) 或16位长度(在THUMB状态) 。
数据类型ARM920T支持字节(8位),半字(16位) 和字(32位) 数据类型。
字必须按照4字节对齐,半字必须是2字节对齐。
2.5 操作模式ARM920T支持7种操作模式:● 用户模式(user模式),运行应用的普通模式● 快速中断模式(fiq模式),用于支持数据传输或通道处理● 中断模式(irq模式),用于普通中断处理● 超级用户模式(svc模式),操作系统的保护模式● 异常中断模式(abt模式),输入数据后登入或预取异常中断指令● 系统模式(sys模式),使操作系统使用的一个有特权的用户模式● 未定义模式(und模式),执行了未定义指令时进入该模式]外部中断,异常操作或软件控制都可以改变中断模式。
keil下的s3c2440启动代码分析
由于片面问题,所以可能会看起来不太美观,可以看附件中的内容。
ARM启动代码相当于我们电脑的BIOS,也就是ARM启动时对处理器的一些初始化及嵌入式系统硬件的一些初始化。
由于它直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言。
一般包括:中断向量表,初始化存储器系统,初始化堆栈,初始化有特殊要求的断口,设备初始化,变量初始化等。
这几天对着RealView MDK-ARM中自带的启动代码研究了一下,遇到问题又对着数据手册和指令表看了一下,总算对S3C2440A的硬件有了一个大致的了解。
学习嵌入式系统重在系统,学习ARM只是为学习嵌入式系统铺路,懒猫比较笨可能在上系统之前要裸奔几天以强化以下对S3C2440A内部结构的了解。
把MDK自带的S3C2440A.S文件的注释发一下,这些是懒猫结合数据手册与ARM指令表理解了,可能会有错误,放在这里只是引导一下像我一样还没有入门的兄弟们,希望你们不要害怕ARM害怕嵌入式,老毛他老人家说的对,世上无难事,只怕有心人,ARM指令就那么多,看一遍不会就多看几遍,还有一定要学习看软件自带的帮助文件.;/*****************************************************************************/;/* S3C2440.S: Startup file for Samsung S3C440 */;/*****************************************************************************/;/* <<< Use Configuration Wizard in Context Menu >>> */ ;/*****************************************************************************/;/* This file is part of the uVision/ARM development tools. */ ;/* Copyright (c) 2005-2008 Keil Software. All rights reserved. */ ;/* This software may only be used under the terms of a valid, current, */;/* end user licence from KEIL for a compatible version of KEIL softwar e */;/* development tools. Nothing else gives you the right to use this softwa re. */;/*****************************************************************************/;下面这些参数是与CPSR状态寄存器有关;参数的由来:这里各个模式的参数是由寄存器CPSR的模式位设置M[4:0]得来的,;比如这里的用户模式,CPSR的M[4:0]设置为10000就是0x10。
2440超详细U-BOOT(UBoot介绍+H-jtag使用+Uboot使用)
凌FL2440超详细U-BOOT作业(UBoot介绍+H-jtag使用+Uboot使用)Bootloader是高端嵌入式系统开发不可或缺的部分。
它是在操作系统内核启动之前运行的一段小程序。
通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。
现在主流的bootloader有U-BOOT、vivi、Eboot等。
本次作业先做Uboot的烧写吧。
希望通过这个帖子,能让更多的初学者朋友了解一些UBoot的知识,也希望高手朋友对我的不足予以斧正。
首先说一下什么是Uboot:U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。
从FAD SROM、8xxROM、PPCBOOT逐步发展演化而来。
其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
但是U-Boot不仅仅支持嵌入式Linu x系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。
其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。
这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。
Main函数之Isr_Init分析
飞凌2440 Bootloader学习中的若干问题1.2440init.s分析1)关于HANDLER宏定义MACRO$HandlerLabel HANDLER $HandleLabel ;宏定义$HandlerLabel;由于ADS仅支持FD(满递减)型堆栈sub sp, sp,#4 ;将堆栈退一个字用于保存下面用到的R0stmfd sp!,{r0} ;将R0压入堆栈ldr r0,=$HandleLabel ;将HandleLabel的地址赋给R0ldr r0,[r0] ;将HandleLabel的地址指向的内容;(实际的中断函数的执行地址)赋给R0 str r0,[sp,#4] ;将对应的中断函数首地址入栈保护ldmfd sp!,{r0,pc} ;将中断函数的首地址出栈,放入PC中,系统将跳转到;对应中断处理函数MENDHANDLER 是宏名。
$HandlerLabel是宏展开后要被别的字符替换掉的标号,不过不叫参数。
例如:HandlerFIQ HANDLER HandleFIQ展开后为:HandlerFIQsub sp,sp,#4stmfd sp!,{r0}ldr r0,=HandleFIQldr r0,[r0]str r0,[sp,#4]ldmfd sp!,{r0,pc}启动代码中有很多的类似下面的语句:HandlerFIQ HANDLER HandleFIQHandlerIRQ HANDLER HandleIRQHandlerUndef HANDLER HandleUndefHandlerSWI HANDLER HandleSWIHandlerDabort HANDLER HandleDabortHandlerPabort HANDLER HandlePabort等等该宏定义的代码用于将对应中断服务程序ISR的入口地址装载到PC中,可称之为“加载程序”。
本初始化程序定义了一个34个字空间的数据区(文件最后),用于存放相应中断服务程序的首地址。
2440_Linux系统移植
IT_2440Linux系统开发移植一.软硬件配置(1)目标板硬件环境CPU:S3C2440ALSDRAM:SamSung K4S561632HNand flash:K9F1208(64MB)以太网芯片:DM9000LCD:Toshiba LPM084P3638.4’接口:USB;PWM控制蜂鸣器;网络接口;UART;键盘(2)目标板软件环境Linux操作系统内核版本:Linux2.6.12Bootloader:优龙viviQtopia版本:1.7.0Qt版本:2.3.7内核交叉编译工具:ARM-Linux-GCC3.4.1Qtopia交叉编译工具:ARM-Linux–Gcc3.3.2Busybox编译版本:1.1.3二.开发流程B ootloader启动代码移植使用优龙的vivi启动代码操作步骤如下:1)将优龙的源代码拷贝到指定目录;C:\桌面\开发镜像\it24402)打开ADS v1.2编译软件,点击file→打开IT2440A_bios.mcp→打开nand.c3)修改Nand Flash的分配系统空间大小,如图(1)所示,找到结构体函数,static struck partition NandPart修改如下。
注意:修改后需要保存。
图(1)4)Nand flash映射到SDRAM中需要修改SDRAM导入的地址空间大小和载入的初始地址。
修改如下:(1)打开ADS v1.2编译软件,点击file→打开IT2440A_bios.mcp→打开u2440mon.c 修改如下:(2)打开ADS v1.2编译软件,点击file→打开IT2440A_bios.mcp→打开nand.c修改如下:对于NAND FLASH修改不光只是修改NAND FLASH对整个系统空间的分配大小,还要修改载入到SDRAM的地址和空间大小,大小要与NAND FLASH大小分配相匹配。
修改后才能载入nand flash分配空间大小。
Ok2440-3看门狗驱动代码详细分析
/*希望与各位共同学习,我的QQ是254206940.红色部分为我添加的注释,蓝色把部分为代码自带的注释,紫色部分为我没理解透的地方(主要是我不不明白为什么要那些代码,它们主要起什么作用)。
希望看到我的笔记的同行不吝赐教!linux/drivers/char/watchdog/s3c2410_wdt.c** Copyright (c) 2004 Simtec Electronics* Ben Dooks <ben@>** S3C2410 Watchdog Timer Support** Based on, softdog.c by Alan Cox,* (c) Copyright 1996 Alan Cox <alan@>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** Y ou should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307 USA*/#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/types.h>#include <linux/timer.h>#include <linux/miscdevice.h>#include <linux/watchdog.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/interrupt.h>#include <linux/clk.h>#include <linux/uaccess.h>#include <linux/io.h>#include <mach/map.h>#undef S3C_V A_WA TCHDOG#define S3C_V A_WA TCHDOG (0)#include <asm/plat-s3c/regs-watchdog.h>#define PFX "s3c2410-wdt: "#define CONFIG_S3C2410_WA TCHDOG_A TBOOT(0)#define CONFIG_S3C2410_WA TCHDOG_DEFAULT_TIME (15)static int nowayout = W A TCHDOG_NOW AYOUT;static int tmr_margin = CONFIG_S3C2410_WA TCHDOG_DEFAULT_TIME;static int tmr_atboot = CONFIG_S3C2410_WA TCHDOG_A TBOOT;static int soft_noboot;static int debug;module_param(tmr_margin, int, 0);module_param(tmr_atboot, int, 0);module_param(nowayout, int, 0);module_param(soft_noboot, int, 0);module_param(debug, int, 0);MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default="__MODULE_STRING(CONFIG_S3C2410_WA TCHDOG_DEFAULT_TIME) ")"); MODULE_PARM_DESC(tmr_atboot,"Watchdog is started at boot time if set to 1, default="__MODULE_STRING(CONFIG_S3C2410_WA TCHDOG_A TBOOT)); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="__MODULE_STRING(WA TCHDOG_NOW AYOUT) ")");MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)");MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)");typedef enum close_state {CLOSE_STA TE_NOT,CLOSE_STA TE_ALLOW = 0x4021} close_state_t;static unsigned long open_lock;static struct device *wdt_dev; /* platform device attached to */static struct resource *wdt_mem;static struct resource *wdt_irq;static struct clk *wdt_clock;static void __iomem *wdt_base;static unsigned int wdt_count;static close_state_t allow_close;static DEFINE_SPINLOCK(wdt_lock);/* watchdog control routines */#define DBG(msg...) do { \if (debug) \printk(KERN_INFO msg); \} while (0)/* functions */static void s3c2410wdt_keepalive(void)//喂狗,即将计数值赋给WTCNT寄存器{spin_lock(&wdt_lock);writel(wdt_count, wdt_base + S3C2410_WTCNT);spin_unlock(&wdt_lock);}static void __s3c2410wdt_stop(void){unsigned long wtcon;wtcon = readl(wdt_base + S3C2410_WTCON);wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN);writel(wtcon, wdt_base + S3C2410_WTCON);}//将WTCON寄存器的位[5]和位[0]清零,不输出复位信号,停止看门狗static void s3c2410wdt_stop(void)//关看门狗{spin_lock(&wdt_lock);__s3c2410wdt_stop();spin_unlock(&wdt_lock);}static void s3c2410wdt_start(void){unsigned long wtcon;spin_lock(&wdt_lock);__s3c2410wdt_stop(); //关看门狗wtcon = readl(wdt_base + S3C2410_WTCON);wtcon |= S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128;/*#define S3C2410_WTCON_ENABLE (1<<5)#define S3C2410_WTCON_DIV128 (3<<3)开启看门狗,设置分频系数为128(这里并没有将其写入控制寄存器,只是设置值而已)*/if (soft_noboot) {wtcon |= S3C2410_WTCON_INTEN; //#define S3C2410_WTCON_INTEN (1<<2)使能看门狗中断wtcon &= ~S3C2410_WTCON_RSTEN; //#define S3C2410_WTCON_RSTEN (0x01),不输出复位信号} else {wtcon &= ~S3C2410_WTCON_INTEN; //禁止看门狗中断wtcon |= S3C2410_WTCON_RSTEN; //允许输出复位信号}DBG("%s: wdt_count=0x%08x, wtcon=%08lx\n",__func__, wdt_count, wtcon);writel(wdt_count, wdt_base + S3C2410_WTDA T);writel(wdt_count, wdt_base + S3C2410_WTCNT); //写入计数值writel(wtcon, wdt_base + S3C2410_WTCON); //写WTCON寄存器,前面的设置会生效spin_unlock(&wdt_lock);}static int s3c2410wdt_set_heartbeat(int timeout){unsigned int freq = clk_get_rate(wdt_clock);//获得时钟,这里的时钟应该是系统初始化时设置好了的。
2440启动串口输出乱码问题
2440 移植2.6.30 (转)解压缩内核压缩文件后进入到目录中,然后修改Makefile,找到ARCH ?=CROSS_COMPILE ?=这两项,不修改这两项的话将会默认使用x86的配置,这里修改为ARCH ?= armCROSS_COMPILE ?= arm-linux-arm-linux- 是交叉编译器~ 这里我使用的交叉编译器为友善送的arm-linux-gcc-4.3.2.tgz,带EABI然后执行make menuconfig,然后进入System Type中看看是否为ARM体系~第一行为ARM system type 说明没错~ 然后在ARM system type中选择SamSung“S3C2410...”随后在下面出现的S3C2440 Machines中选择SMDK2440退出保存~ 执行make zImage出现ERRORdrivers/video/console/vgacon.c:510:error “PCIMEM_BASE undeclared”是在vgacon_startup中,vgacon是啥?~ 不认识~ 应该是不必要的东西~ 去掉它~vim drivers/video/console/Makefile在里面看见了这句obj-$(CONFIG_VGA_CONSOLE) += vgacon.o然后执行find ./ -name “Kconfig” | xargs grep “VGA_CONSOLE”看见config VGA_CONSOLE 在driver/video/console/Kconfig中也就是说在驱动->视频->终端中,执行make menuconfig在Device Drivers->Graphics Support->Console display driver support中发现了VGA text console去掉它,保存设置后再编译编译完成后将在arch/arm/boot中得到zImage文件使用SuperVivi的USB加载功能启动这个内核文件~ 得到下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.失败信息不够丰富~ 根据kasim大大的指点,在配置中进入Kernel hacking打开Kernel debugging和Kernel low-level debugging functions 还有Kernel low-level debugging messages via S3C UART保存后再编译运行zImage后得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.Error: unrecognized/unsupported machine ID (r1 = 0x000007cf).Available machine support:ID (hex) NAME0000016a SMDK2440Please check your kernel config and/or bootloader.失败原来是machine的ID和Supervivi传递进来的ID不匹配~关于machine ID,可以参考一下这篇文章<2.6.18-2内核中对S3C2440的引导启动分析>虽然版本老了点,但是核心思想还是没有变vim arch/arm/mach-s3c2440/mach-smdk2440.c在最后一段有这句MACHINE_START(S3C2440 , ”SMDK2440”)这里S3C2440就是machine ID的代号~ 呢具体值是多少呢?~在arch/arm/tools/mach-types中s3c2440 ARCH_S3C2440 S3C2440 362原来我们的machine ID是362~呢bootloader传递进来的值是多少呢?~Error: unrecognized/unsupported machine ID (r1 = 0x000007cf).注意到没有?~ 0x7CF转换成10进制也就是1999修改mach-types中的对应项s3c2440 ARCH_S3C2440 S3C2440 1999虽然这样就和下面MINI2440的1999冲突了,但是只要不加入MINI2440的配置就没事修改后编译,再执行zImage后得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.失败咦?~ 啥都没有?~ 最起码也应该有个乱码吧这时候我的第一反应是会不会没有跳入到start_kernel中所以马上编辑init/main.c,在start_kernel的前部加上printk(KERN_INFO “in start_kernel \n”);但是这个时候内核还没有初始化,所以printk是没有作用的~继续得到kasim大大的指点,编辑kernel/printk.c中的printk函数{va_list args;int r;#ifdef CONFIG_DEBUG_LLextern void printascii(const char *);char buff[256];#endifva_start(args, fmt);r = vprintk(fmt, args);#ifdef CONFIG_DEBUG_LLvsprintf(buff, fmt, args);#endifva_end(args);#ifdef CONFIG_DEBUG_LLprintascii(buff);#endifreturn r;}编译后执行zImage,得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux........................................................................................................ done, booting the kernel.<6>in start_kernel<6>Initializing cgroup subsys cpuset<6>Initializing cgroup subsys cpu<5>Linux version 2.6.30.3 (wolf@ubuntu) (gcc version 4.3.2 (Sourcery G++ Lite2008q3-72) ) #4 Wed Aug 5 16:54:49 CST 2009 ..................................................失败虽然正常输出了~ 有进入start_kernel~ 但是为什么之前每输出呢?~ 会不会是没有找到输出设备在输出中看到这行<5>Kernel command line: noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0 console=ttySAC0 会不会是没有ttySAC0这个设备呢~ 在内核中搜索ttySAC 在driver/serial/samsung.c中得到对应项目这时候我猜想会不会没有加载samsung.c , 经过一轮Makefile和Kconfig的查询, 发现对应选项在Device Drivers->Character devices->Serial drivers中一看,原来根本就没有加载Samsung SoC serial support , 选成静态编译之后又出现了Support for console on Samsung SoC serial port ,就是它了,选上, 退出的时候顺便把Kernel low-level debugging functions给取消了否则我们设置的printk会自行输出,就不知道ttySAC有没有加载成功了编译后执行,得下列输出zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux......................................................................................................... done, booting the kernel.w# DpñGpGp´ó70ÇC¼ØûÛ»›3ó•ó¸Û0ƒw#DpñGpGp´ó•tØ›•p¸›7¿³ó•\@û7¼¿[£¼Û3•¼ó;£¸ÀÛ;[7û;D°•D@GoGpGpíó•t›7•{ð#ßóÄ;›•770ÄÄ3Çß;GoDh}û7wœ´{…[ó7ûÛ›30°ôܸ‡#_sÄ;›•770Øijœ¼DG@ÁôÛ•ûÄ;•sÄ›£Ø›•DŽ³ÃÛ70ÄGpÁ4ßœ»ôGã›30³D˜ßF[s˜£ÀÛû70ÛD8ßÄ4G8ôGv£°ÇÃGpÍ´0ƒ†# DpñGš´;óC…[4¸F¸ÄÛtÜàGp}4GGÇ4tD@Ä38ÀGpGß ôØ Û›ŸÄÛD\Cûƒ£¸ƒ;7v›Ã30Ü›4Û´£ô¼;C3[;7ù³û770‡¸°[•4tD@Ä38ÀGpGß ´´p‡ƒ•ô¼Û7ŸtÛG»4œØ…Çpíƒw# .......................................失败但这说明ttySAC加载成功了~ 不过为什么是乱码呢?~这时候就需要对比友善的配置和我们的配置有什么不同了~打开友善送的linux-2.6.29,观察arch/arm/mach-s3c2440/mach-mini2440.c和我们的2.6.30.4下面的arch/arm/mach-s3c2440/mach-smdk2440.c有什么不同由于乱码主要是时钟问题,所以我们重点观察UART的设置和基本设置,其它什么NAND LCD 的就不看先修改smdk2440_uartcfgs[][2] = {.ulcon = 0x03,}修改s3c24xx_init_clocks(12000000);然后编译再运行,输出为zImage magic = 0x016f2818Setup linux parameters at 0x30000100linux command line is: "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0" MACH_TYPE = 1999NOW, Booting Linux......Uncompressing Linux......................................................................................................... done, booting the kernel.[ 0.000000] in start_kernel[ 0.000000] Initializing cgroup subsys cpuset[ 0.000000] Initializing cgroup subsys cpu ...........................最后为Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败终于可以正常输出了,但是根文件系统挂载失败因为板子上的根文件系统为yaffs2 这时候内核还没有这个文件系统的支持,需要我们加上去拷贝友善的送的2.6.29下的fs/yaffs2目录到我们的fs目录下然后修改观察一下友善的送的2.6.29下的fs/Kconfig 和fs/Makefile和我们的有什么不同在我们的Kconfig中的source “fs/jffs2/Kconfig” 上面加上source “fs/yaffs2/Kconfig”在Makefile中的obj-$(CONFIG_FAT_FS) += fat/ 上面加上obj-$(CONFIG_YAFFS_FS) += yaffs2/然后在配置的File systems->Miscellaneous filesystems 中选上“YAFFS2 file system support” “Autoselect yaffs2 format” “Cache short names in RAM”然后编译运行,输出如下......................Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败还是不行,往上看几行VFS: Cannot open root device "mtdblock2" or unknown-block(0,0)Please append a correct "root=" boot option; here are the available partitions:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)原来是没有可用的分区这个时候就要更正我们的NAND配置了还是对照友善送的linux-2.6.29,观察arch/arm/plat-s3c24xx/common-friendly-smdk.c来修改我们的arch/arm/plat-s3c24xx/common-smdk.c主要修改smdk_default_nand_part[]{[0] = {.name = “supervivi”,.size = 0x00060000,.offset = 0,},[1] = {.name = “Kernel”,.offset = 0x00060000,.size = 0x00200000,},[2] = {.name = “root”,.offset = 0x00260000,.size = 1024*1024*1024,},[3] = {.name = “nand”,.offset = 0x00000000,.size = 1024*1024*1024,}};编译后运行,输出VFS: Cannot open root device "mtdblock2" or unknown-block(0,0)Please append a correct "root=" boot option; here are the available partitions:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败还是不行,连最起码的分区都没有看见,会不会是MTD没有加载呢?~打开配置进入Device DriversMemory Technology Device ......... 前面是个M~ 说明这个模块是动态加载的,而我们编译的zImage里面只有静态模块将MTD选为静态加载,然后进入MTD配置中看看还有什么需要选的NAND Device Support 这个也是动态,选为静态加载进入NAND Device Support原来连NAND Flash support for S3C2410/S3C2440 SoC都没选,马上选为静态加载保存配置后编译运行,再运行输出如下:NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit) Scanning device for bad blocksCreating 4 MTD partitions on "NAND 128MiB 3,3V 8-bit":0x000000000000-0x000000060000 : "supervivi"0x000000060000-0x000000260000 : "Kernel"0x000000260000-0x000040260000 : "root"mtd: partition "root" extends beyond the end of device "NAND 128MiB 3,3V 8-bit" -- size truncated to 0x7da00000x000000000000-0x000040000000 : "nand"mtd: partition "nand" extends beyond the end of device "NAND 128MiB 3,3V 8-bit" -- size truncated to 0x8000000 ...............................VFS: Cannot open root device "mtdblock2" or unknown-block(0,0)Please append a correct "root=" boot option; here are the available partitions:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)失败还是没有可用分区,虽然成功分辨了分区,但是没有加载成功,估计还是在MTD的模块选择上这时候需要对照友善的配置,经过对比,发现在友善的配置中静态编译了MTD中的下面3个模块Direct char device access to MTD devicesCommon interface to block layer for MTD …translation layers‟Caching block device access to MTD devices我们也选为静态编译保存配置后编译运行,输出如下List of all partitions:1f00 384 mtdblock0 (driver?)1f01 2048 mtdblock1 (driver?)1f02 128640 mtdblock2 (driver?)1f03 131072 mtdblock3 (driver?)No filesystem could mount root, tried: cramfsKernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)分区加载成功了,但是文件系统却不能识别,我们之前不是已经加入了yaffs2么?~回到配置中再看,原来是动态编译,并没有真正进入到内核之中,选为静态编译~保存配置后编译,输出为yaffs: dev is 32505858 name is "mtdblock2"yaffs: passed flags ""yaffs: Attempting MTD mount on 31.2, "mtdblock2"yaffs: auto selecting yaffs2yaffs_read_super: isCheckpointed 0VFS: Mounted root (yaffs filesystem) on device 31:2.Freeing init memory: 128KKernel panic - not syncing: Attempted to kill init!失败依然错误,这个时候懵了,哪里错呢~ 没办法,只能对照着友善的配置一个个大模块对着来改当改到Kernel Features的时候错误消失了,原来需要选上Use the ARM EABI to compile the kernelAllow old ABI binaries to run with thie Kernel为什么呢?~ Google了一下,原来友善的根文件系统在编译的时候也启用了EABI特性,内核和文件系统需要对上文件系统用了EABI 内核也要用EABI 内核不用EABI 也只能读取不用EABI的文件系统选上这两项之后再编译,运行,输出如下yaffs: dev is 32505858 name is "mtdblock2"yaffs: passed flags ""yaffs: Attempting MTD mount on 31.2, "mtdblock2"yaffs: auto selecting yaffs2yaffs_read_super: isCheckpointed 0VFS: Mounted root (yaffs filesystem) on device 31:2.Freeing init memory: 128Kmount: mounting none on /proc/bus/usb failed: No such file or directoryhwclock: can't open '/dev/misc/rtc': No such file or directory[01/Jan/1970:00:00:13 +0000] boa: server version Boa/0.94.13[01/Jan/1970:00:00:13 +0000] boa: server built Mar 26 2009 at 15:28:42.[01/Jan/1970:00:00:13 +0000] boa: starting server pid=845, port 80open device leds: No such file or directoryTry to bring eth0 interface up......ifconfig: SIOCGIFFLAGS: No such deviceifconfig: SIOCSIFHWADDR: No such deviceifconfig: SIOCSIFADDR: No such deviceroute: SIOCADDRT: No such processDoneifconfig: SIOCSIFADDR: No such devicePlease press Enter to activate this console.[root@FriendlyARM /]#成功了,ls后输出如下bin home lost+found proc sys vardev lib mini2440 root tmp wwwetc linuxrc opt sbin usr不过ifconfig命令没有成功,继续来配置网卡对比友善的mach-mini2440.c文件,发现我们的mach-smdk2440.c中的smdk2440_devices[]数组并没有&s3c_device_dm9k这个结构,加上,追踪发现该数据结构在arch/arm/plat-s3c24xx/devs.c中,我们的devs.c中没有该数据结构的定义,加上#include <linux/dm9000.h>static struct resource s3c_dm9k_resource[] = {[0] = {.start = S3C2410_CS4,.end = S3C2410_CS4 + 3,.flags = IORESOURCE_MEM,},[1] = {.start = S3C2410_CS4 + 4,.end = S3C2410_CS4 + 4 + 3,.flags = IORESOURCE_MEM,},[2] = {.start = IRQ_EINT7,.end = IRQ_EINT7,.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,},};static struct dm9000_plat_data s3c_dm9k_platdata = {.flags = DM9000_PLATF_16BITONLY,};struct platform_device s3c_device_dm9k = {.name = “dm9000”,.id = 0;.num_resources = ARRAY_SIZE(s3c_dm9k_resource),.resource = s3c_dm9k_resource,.dev = {.platform_data = &s3c_dm9k_platdata,}};EXPORT_SYMBOL(s3c_device_dm9k);编译,出错,error : s3c_device_dm9k undeclared here找不到结构?~ 打开mach-smdk2440.c看看有什么头文件比较显眼的就是<plat/s3c2410.h><plat/s3c2440.h><plat/devs.h>,我们刚才编辑的文件是devs.c呢么devs.h的可能性较高,通过搜索,这个devs.h在/arch/arm/plat-s3c/include/plat/中,打开,BINGO,里面都是devs.c的数据定义加上我们的s3c_device_dm9kextern struct platform_device s3c_device_dm9k;再编译,通过了,不过这个时候先别急,我们只添加了设备,驱动有没有静态加载呢?~ 打开配置Device Drivers->Networks device support->Ethernet(10 or 100Mbit)DM9000 support没选上,马上选为静态编译保存配置,编译后运行,输出如下Try to bring eth0 interface up......说明DM9000配置成功使用ping命令进行测试,发现丢包率高达78%是不是驱动没设置好呢?~ 比较了一下友善的driver/net/dm9000.c和2.6.30.4的dm9000.c,发现明显不同直接拷贝友善的dm9000.c和dm9000.h过来编译后运行,顺利进入终端,然后运行PING丢包改善,基本无丢包我对这次内核移植的总结是:一步步来~ 先做好终端输出再挂载好根文件系统最后才考虑其它驱动的配置到此移植就基本结束了= 3=)/ 感谢阅读。
eboot函数说明
Eboot代码说明一:EBOOT经过NBOOT引导后,一般会跳转到0x30038000开始执行第一条指令。
在我这EBOOT中是先执行目录下2440\Kernel\hal\arm\fw.s。
这个在有些系统能够中是setup.s,总之就是从系统ResetHandle开始执行了。
下面开始分析这段汇编代码,并且讲述它都做了一些什么工作:ldr r0, = INTMSKldr r1, = ~BIT_BAT_FLT ; all interrupt disable, nBATT_FLT =enabledstr r1, [r0]ldr r0, = INTSUBMSKldr r1, = 0x7ff ;all sub interrupt disablestr r1, [r0]ldr r0, = INTMODldr r1, = BIT_BA T_FLT ; set all interrupt as IRQ, BA T_FLT = FIQstr r1, [r0]ldr r1, =MISCCR ; MISCCR's Bit [22:20] -> 100ldr r0, [r1]bic r0, r0, #(7 << 20)bic r0, r0, #(1 << 3)bic r0, r0, #(1 << 13)orr r0, r0, #(4 << 20)str r0, [r1]bl ARMClearUTLBbl ARMFlushICacheldr r0, = (DCACHE_LINES_PER_SET - 1)ldr r1, = (DCACHE_NUM_SETS - 1)ldr r2, = DCACHE_SET_INDEX_BITldr r3, = DCACHE_LINE_SIZEbl ARMFlushDCachenopnopnopldr r0, = GPFCONldr r1, = 0x55aastr r1, [r0]ldr r0, = WTCON ; watch dog disable ldr r1, = 0x0str r1, [r0]//以上代码比较简单,但是很关键,关闭所有中断,刷新cache和快表。
JZ2440学习笔记
JZ2440学习笔记Chili2015.5前言本人入手JZ2440半个月,以前未接触过linux,但在校接触过许多不跑linux系统的CPU,具有LPC1114,LPC1343,STM32,blackfin等处理器的编程经验,对微处理器的原理以及运行方式具有一定的了解。
靠着这点小经验,以及新学习的知识,自己动手移植了最新的uboot,绝对原创,得益于韦老师的书籍以及开发板,能让我们这个小白可以踏进linux的世界,但本人毕竟在linux方面只是个类似小白的学生,许多不对之处,希望大家不吝指教!说明:阅读本文需要一点的ARM以及S3C2440的基础知识,建议先阅读《嵌入式Linux应用开发完全手册》,此书对对ARM以及JZ2440有很好的介绍和说明,在阅读中有不懂的也可以再去翻看此书,查漏补缺。
JZ2440移植最新u-boot-2015.04-rc4.tar1,配置uboot去官网下载最新uboot源代码u-boot-2015.04-rc4.tar,开发环境采用JZ2440光盘上的vmware 虚拟机ubuntu9.10。
本次采用smdk2410的默认配置来配置uboot,然后启动类似linux一样的menuconfig菜单进行配置,然后make,并烧写进JZ2440看效果,然后根据现象一步步修改。
我们移植uboot的基本原则是:因为我们刚上手,可能什么都不知道,更加不知需要更改什么,这个时候我们就先尽量什么都不改,直接烧写进去看现象,然后根据现象或者提示信息一步步更改,从而移植完成。
配置命令如下:book@book-desktop:~/uboot/u-boot-2015.04-rc4$ tar jxvf u-boot-2015.04-rc4.tar.bz2book@book-desktop:~/uboot/u-boot-2015.04-rc4$ cd u-boot-2015.04-rc4/book@book-desktop:~/uboot/u-boot-2015.04-rc4$ make smdk2410_defconfigbook@book-desktop:~/uboot/u-boot-2015.04-rc4$ make menuconfig3,在uboot根目录执行book@book-desktop:~/uboot/u-boot-2015.04-rc4$ make报错:cc1: error: bad value (armv4) for -march= switchcc1: error: bad value (armv4) for -mtune= switchmake[2]: *** [include/autoconf.mk] Error 1make[1]: *** [silentoldconfig] Error 1make: *** No rule to make target `include/config/auto.conf', needed by `include/config/uboot.release'. Stop.错误并不可怕,学会看错误提示,根据提示进行下一步工作。
Linux声卡驱动分析
Linux soc声卡构架分析(DMA)以S3C2440为例进行分析,对应的文件linux-2.6.32.2/sound/soc/s3c24xx/s3c24xx_uda134x.c 其中module_init入口内容为:357 static int __init s3c24xx_uda134x_init(void)358 {359 return platform_driver_register(&s3c24xx_uda134x_driver);360 }359行是一个平台驱动的注册函数,注册的驱动是s3c24xx_uda134x_driver。
内容如下:348 static struct platform_driver s3c24xx_uda134x_driver = {349 .probe = s3c24xx_uda134x_probe,350 .remove = s3c24xx_uda134x_remove,351 .driver = {352 .name = "s3c24xx_uda134x",353 .owner = THIS_MODULE,354 },355 };由上面的name = "s3c24xx_uda134x"可知,这个驱动对应的平台设备早在系统启动时在dev_init中注册进来了,所以接下来的事情就是直接调用probe方法。
290 static int s3c24xx_uda134x_probe(struct platform_device *pdev)291 {292 int ret;293294 printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");295296 s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;297 if (s3c24xx_uda134x_l3_pins == NULL) {298 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "299 "unable to find platform data\n");300 return -ENODEV;301 }302 s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;303 s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;304305 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,306 "data") < 0)307 return -EBUSY;308 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,309 "clk") < 0) {310 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);311 return -EBUSY;312 }313 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,314 "mode") < 0) {315 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);316 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);317 return -EBUSY;318 }319320 s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);321 if (!s3c24xx_uda134x_snd_device) {322 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "323 "Unable to register\n");324 return -ENOMEM;325 }326327 platform_set_drvdata(s3c24xx_uda134x_snd_device,328 &s3c24xx_uda134x_snd_devdata);329 s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;330 ret = platform_device_add(s3c24xx_uda134x_snd_device);331 if (ret) {332 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");333 platform_device_put(s3c24xx_uda134x_snd_device);334 }335336 return ret;337 }305-318行就是设置udal34x要用的gpio引脚的功能。
Uboot启动分析笔记Stage1(start.S与lowlevel_init.S详解)
/* These are defined in the board-specific linker script.*/ .globl _bss_start _bss_start: .word __bss_start .globl _bss_end _bss_end: .word _end #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ .globl IRQ_STACK_START IRQ_STACK_START: .word 0x0badc0de /* IRQ stack memory (calculated at run-time) */ .globl FIQ_STACK_START FIQ_STACK_START: .word 0x0badc0de #endif /* the actual reset code*/ /* 系统的复位代码。系统一上电,就跳到这里运行 */
*********************************************************/
移植2440裸奔程序到MDK1
笔者从51到stm32一直使用uvision的开发环境,TQ2440的《裸奔三部曲》示例程序都是采用ADS开发的,笔者不太习惯,因此决定将使用MDK来重新编译这些程序,现在将裸奔工程移植到MDK的工程,整个文档尽可能的包含了所有的步骤。
如果有疏漏之处,请和我联系。
我的QQ号为459819016.prife于2011/6/301:10环境:windowsMDK版本:4.0目标:将《裸奔三部曲》ADS工程改造为MDK工程,并在配合jlink工具,实现RAM在线调试。
第一部分创建MDK工程,添加源代码文件启动mdk后,点击Project->New Uvision Project图1建立一个名为mdk的文件夹,将工程保存到文件夹下,将工程名命名为ex12(读者请根据自己的需要填写名称),然后保存。
弹出目标平台配置窗口。
选择Samsung S3C2440A,然后点击OK点击OK之后,会弹出如下所示的对话框,提示是否添加启动文件,由于《三部曲》原工程中已经有启动文件2440init.s,因此这里选择否下面开始添加工程源码在左侧的Project窗口中Target上右击,选择Manage Component在弹出的对话框,配置工程的名称,添加源码文件等。
注意:下面的tq2440,和startup都是根据笔者个人爱好所使用的名字,读者可以根据自己需要编写名称。
为了简单,Groups里仅创建一个startup组然后在最右边的File为这个组添加源码文件。
在这之前,先将压缩文件解压,生成的文件夹内容如下其中,src目录和inc目录为源码文件所在的目录。
因此我们将src文件夹和inc文件夹复制到MDK工程目录下。
此时,MDK工程目录中所有文件如下现在我们继续刚才添加源码的步骤。
点击最右边的框下方的Add File,添加源码。
找到MDK工程目录下的src文件夹,经其中所有的文件都添加的工程中。
注意,src目录下有汇编文件(*.s),但是默认只会添加C文件,所以首先在弹出的对话框中,选择文件类型为All files(*.*)然后将src目录下所有文件加入选择所有文件,Add之后,Close。
JZ2440开发板使用手册
百问网·精智JZ2440使用手册提示:除了QT外,可以不看本手册,参考《嵌入式Linux应用开发完全手册》及视频即可第1章嵌入式Linux开发环境构建 (4)1.1 安装Ubuntu 9.10 (4)1.1.1 安装VMware (4)1.1.2 安装Ubuntu 9.10 (13)1.2 安装Ubuntu下的开发工具 (20)1.3 安装Windows下的开发工具 (22)第2章精智JZ2440开发板烧写程序方法 (23)2.1 使用JTAG工具烧写开发板 (23)2.1.1 Windows下并口JTAG驱动安装 (23)2.1.2 Windows下OpenJTAG驱动安装 (29)2.1.3 Ubuntu下驱动程序的安装 (29)2.1.4 JTAG烧写软件oflash的用法 (29)2.2 通过u-boot烧写整个系统 (29)2.2.1 在Windows下使用dnw和u-boot烧写系统 (30)2.2.2 在Linux下使用dnw和u-boot烧写系统 (31)第3章板上Linux系统搭建 (33)3.1 修改、编译、使用u-boot (33)3.1.1 使用补丁修改、编译u-boot (33)3.1.2 u-boot使用方法 (33)3.2 修改、编译、使用Linux内核 (36)3.2.1 使用补丁修改、编译内核 (36)3.2.2 使用uImage (36)3.3 修改、编译QT (36)3.3.1 编译依赖的软件 (36)3.3.2 使用补丁修改、编译QT (39)3.4 构造根文件系统 (39)3.4.1 基于最小根文件系统制作QT文件系统 (39)3.4.2 制作YAFFS2、JFFS2文件系统映象文件 (42)第1章 嵌入式Linux开发环境构建1.1 安装Ubuntu 9.10注意:如果使用光盘上已经制作好的虚拟机,那么1.1或1.2的内容可以忽略。
《嵌入式Linux应用开发完全手册》里使用的主机开发环境是Ubuntu 7.10,现在最新的Ubuntu版本是9.10。
FL2440根文件系统制作
根文件系统制作FL2440在移植完linux内核后,需要移植根文件系统才能正常的启动开发板上面的Linux系统。
下面介绍一下如何制作根文件系统。
首先要明确几个问题,首先,为什么要制作根文件系统?根文件系统是什么?文件系统又是什么?如何制作根文件系统?这里介绍的是制作方法,所以下面只回答最后一个问题。
至于其他问题,网上的资料以及相关的书籍上都有很详细的介绍,并且不是一句两句就能回答出来的,这里不多罗嗦。
开发板:FL2440SDRAM:64M NAND FLASH:256M环境:虚拟机vmware7.1.2.14247绿色版(网上到处是)、红帽企业版5交叉编译链:arm-linux-gcc-4.3.2(这里选择这个,低版本的比如3.4.1的等,在编译的过程中可能会提示很多错误)使用的工具:busybox-1.19.0.tar.bz2这里先改正一下错误,上次的linux-2.6.28.7内核移植到FL2440开发板时的触屏驱动有问题,需要改正几个错误,否则校正 3.5寸的屏幕时可能会出现错误,FL2440光盘中的linux-2.6.28的触屏驱动也存在此问题。
触屏校正有问题,校正不过去,需要修改源码中的触屏驱动才能解决。
文件:drivers/input/touchscreen/s3c2410_ts.cstatic irqreturn_t stylus_updown(int irq, void *dev_id)//172行函数中的data0 = readl(base_addr+S3C2410_ADCDA T0);//178行data1 = readl(base_addr+S3C2410_ADCDA T1);//179行修改为:data1 = readl(base_addr+S3C2410_ADCDA T0);//lysysjwdata0 = readl(base_addr+S3C2410_ADCDA T1);//lysysjwstatic irqreturn_t stylus_action(int irq, void *dev_id)//194行函数中的data1 = readl(base_addr+S3C2410_ADCDA T0);//199行data0 = readl(base_addr+S3C2410_ADCDA T1);//200行修改为data1 = readl(base_addr+S3C2410_ADCDA T0);//lysysjwdata0 = readl(base_addr+S3C2410_ADCDA T1);//lysysjw下面开始介绍根文件系统制作过程。
2440LCD控制器详细配置
volatile unsigned short LCD_BUFFER[SCR_YSIZE_TFT][SCR_XSIZE_TFT];//全局变量 #define M5D(n) ((n) & 0x1fffff) // To get lower 21bits
rLCDSADDR1=(((U32)LCD_BUFFER>>22)<<21)|M5D((U32)LCD_BUFFER>>1); 7. LCDSADDR2 寄存器
数据引脚输出:没有用到的引脚可用作 GPIO
系统结构图:
要显示图像,只要向 LCD_BUFFER[]先入像素数据(R(5):G(6):B(5))。LCD 控制器会自动通过 DMA 读取数据送往 TFT LCD 显示。 这里介绍一个 Bmp2RGB.exe,次程序可将 bmp 图转换为 RGB(5:6:5)格式的 c 格式的数组。
rLCDCON2=(VBPD<<24)|(LINEVAL_TFT<<14)|(VFPD<<6)|(VSPW); 相关值见上文宏定义 3. LCDCON3 寄存器
rLCDCON3=(HBPD<<19)|(HOZVAL_TFT<<8)|(HFPD); 相关值见上文宏定义 4. LCDCON4 寄存器
rLCDCON4=(MVAL<<8)|(HSPW); 相关值见上文宏定义 5. LCDCON5 寄存器
//Byte swap control //Half word swap control // 设置为 TFT 屏 // 设置为 16bpp 模式
(LCD_XSIZE_TFT-1)
#define LINEVAL_TFT (LCD_YSIZE_TFT-1) 以上有关东华屏参数设置,在 PDF 中如下所示:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
这个程序还有一个最简版,就能运行。
在2440init.s里面什么都没有,只有一个跳转到Main函数的指令。
跟底下简化版实现的功能一样,只需要一个在线调试程序里面的AXD SDRAM设置。
什么堆栈初始化,ISR程序,初始化ZI段,都是没有必要的。
IMPORT Main
AREA Init,CODE,READONLY
ENTRY
EXPORT __ENTRY
__ENTRY
ResetEntry
bl Main ;Do not use main() because ......
b .
在线仿真程序执行
出错程序:
Test interrupt and key scan
Test Touchpanel
没有测试的程序:
Test IIC EEPROM
UDA1341 play music
UDA1341 record voice
Test SD Card
Test CMOS Camera
ResetEntry
b ResetHandler
ResetHandler
关闭看门狗。
防止在初始化时,系统复位
ldr r0,=WTCON
ldr r1,=0x0
str r1,[r0]
关闭所有中断。
ldr r0,=INTMSK
ldr r1,=0xffffffff
str r1,[r0]
关闭所有子中断
ldr r0,=INTSUBMSK
ldr r1,=0x7fff
str r1,[r0]
LOCKTIME设置MPLL、UPLL的锁存时间,采用默认值0xffff_ffff,锁存时间各为300us。
说到锁存时间,就要分析下S3C2440的时钟工作过程。
在系统复位时,晶振起振稳定后,PLL开始按照默认值开始工作,但是在复位时,PLL 工作是不稳定的,所以S3C2440用FIN(12M)作为MPLL。
直到一个新的值写入MPLLCON、UPLLCON,即使用户不想改变复位后PLLCON默认值,仍然需要把这个默认值写入PLLCON,写入值之后,系统会自动插入一个PLL LOCKTIME,也就是LOCKTIME寄存器中设置的300us。
300us后,PLL就开始正常工作。
在系统正常工作后,如果要改变FCLK,写入新值到MPLLCON后,系统也会插入一个PLL LOCKTIME,300us后FCLK就变成新的频率。
ldr r0,=LOCKTIME
ldr r1,=0xffffff
str r1,[r0]
CLKDIV_VAL的值为5,表示Fclk:Hclk:Pclk=1:4:8
FCLK是CPU提供的时钟信号,如果提到CPU的主频是400MHz,就是指的这个时钟信号。
HCLK是为AHB总线提供的信号,Advanced High-performance Bus,主要用于高速外设,比如内存控制器,中断控制器,LCD控制器,DMA以及USB Host
PCLK是为APB总线提供的时钟信号,Advanced Peripherals Bus,主要用于低速外设,比如WATCHDOG,IIS,I2C,,SDI/MMC,GPIO,RTC,UART,PWM,ADC,SPI等。
ldr r0,=CLKDIVN
ldr r1,=CLKDIV_VAL
str r1,[r0]
;Configure UPLL ;Fin = 12.0MHz, UCLK = 48MHz
S3C2440具有2个PLL,一个是MPLL,用于产生FCLK、HCLK、PCLK
另一个是UPLL,专门用于驱动USB Host/Device。
并且驱动USB Host/Device的频率必须为48MHz。
ldr r0,=UPLLCON
ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)
str r1,[r0]
nop ; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.
nop
nop
nop
nop
nop
nop
;Configure MPLL; Fin = 12.0MHz, FCLK = 400MHz
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
str r1,[r0]
;Set memory control registers
配置内存控制器
adrl r0, SMRDATA ;be careful!
ldr r1,=BWSCON ;BWSCON Address
add r2, r0, #52 ;End address of SMRDATA
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne %B0
;Initialize stacks
初始化堆栈
bl InitStacks
不用搬移RO、RW段,因为是在线仿真,RO、RW段本来就是在RAM运行。
直接初始化ZI段
InitRam
ldr r2, BaseOfZero
mov r0, #0
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
ldr pc, =%F2 ;goto compiler address
2
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c
str r1,[r0]
bl Main ;Do not use main() because ......。