andriod驱动之旅-了解:移植内核+Android系统到S3C2440(9)
参考:http://blog.csdn.net/blest/article/details/6215600android在2440上的移植 1.移植基本环境:我用的还是win的平台,所以使用了虚拟机:Vmware workstation 6.5.0 +ubuntu9.10;交叉编译工具包EABI——4.3.3;做好的镜像都是在win平台上使用串口烧录
参考:
http://blog.csdn.net/blest/article/details/6215600
参考:rom制作两种办法
http://www.oschina.net/question/4873_27211
http://www.360doc.com/content/10/1214/00/3884271_77896141.shtml
android在2440上的移植
1.移植基本环境:
我用的还是win的平台,所以使用了虚拟机:Vmware workstation 6.5.0 +ubuntu9.10;
交叉编译工具包EABI——4.3.3;
做好的镜像都是在win平台上使用串口烧录的 用到软件DNM;
启动之类的都用超级终端进行控制。
提示:TQ2440所附带的光盘中有很多有用的东西,建议大家看一下,所用的工具除了虚拟机及平台几乎都可以找到。
在进行正式的android系统移植时可以按照光盘中附带的“linux系统移植 step by step”这个pdf来做一下linux的移植,基本上的步骤都差不多,了解一下我们要做什么。接下来找一些文件了解一下android的系统架构、内核 构成。以上就是前期工作。
2.具体移植步骤:
经过分析 我们知道 所需完成的步骤共有三步:内核移植、驱动移植、文件系统移植。
1.移植Android内核:
(1)、解压内核代码androidkernel.rar 到虚拟机的目录下,比/opt/Embedsky/androidkernel.git
(2)、进入androidkernel.git文件夹,如cd
/opt/Embedsky/androidkernel.git/
(3)、修改arch/arm/plat-s3c24xx/common-smdk.c文件中的nand flash分区设置,如gedit arch/arm/plat-s3c24xx/common-smdk.c
修改static struct mtd_partition smdk_default_nand_part[]结构体为:
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name= "EmbedSky_Board_uboot",
.offset= 0x00000000,
.size= 0x00040000,
},
[1] = {
.name= "EmbedSky_Board_kernel",
.offset= 0x00200000,
.size= 0x00200000,
},
[2] = {
.name= "EmbedSky_Board_yaffs2",
.offset= 0x00400000,
.size= 0x0FB80000,
}
};
(4)、将交叉编译工具链的压缩文件EABI_4.3.3_Embedsky_20090807.tar.bz2文件解压
(5)、进入/opt/EmbedSky/4.3.4/文件夹
(6)、添加当前路径进入环境变量,如export PATH=$PWD:$PATH,或修改~/.bashrc文件并重新登录
(7)、进入内核文件夹,如cd
/opt/Embedsky/androidkernel.git/
(8)、修改Makefile文件,如gedit Makefile
更改ARCH和CROSS_COMPILE
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
(9)、使用make s3c2410_defconfig,默认配置2410内核
(10)、运行make menuconfig
a、确保System Type ---> ARM system type ()中的内容为Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443
b、
确保System Type ---> S3C2410 Machines --->
SMDK2410/A9M2410被勾选
c、
取消选择与Goldfish相关的内容
Device Drivers ---> Character devices ---> < > Goldfish TTY Driver
Device Drivers ---> Power supply class support ---> < > Goldfish battery driver (NEW)
Device Drivers ---> Real Time Clock ---> < > GOLDFISH (NEW)
Device Drivers ---> Graphics support ---> Support for frame buffer devices ---> < > Goldfish Framebuffer
d、选择S3C2410 LCD相关的内容
Device Drivers ---> Graphics support ---> Support for frame buffer devices ---> <*> S3C2410 LCD framebuffer support
Device Drivers ---> Graphics support --->
Bootup logo --->
Standard black and white Linux logo
Device Drivers ---> Graphics support --->
Bootup logo --->
Standard 16-color Linux logo
Device Drivers ---> Graphics support --->
Bootup logo --->
Standard 224-color Linux logo
e、选中Android内核必须选项
Kernel Features --->
Use the ARM EABI to compile the kernel
General setup --->
Use full shmem filesystem
General setup --->
Enable Android's Shared Memory Subsystem
System Type --->
Support Thumb user binaries
Device Drivers ---> Android --->
Android log driver
Device Drivers ---> Android ---> <*> Binder IPC Driver
f、
尽量选中Android内核可选选项
Device Drivers ---> Android --->
RAM buffer console
Device Drivers ---> Android --->
Android timed gpio driver
Device Drivers ---> Android --->
Only allow certain groups to create sockets
g、
其余CONFIG选项,如系统支持请一并选择
CONFIG_ANDROID_POWER =y
CONFIG_ANDROID_POWER_STAT =y
CONFIG_ANDROID_POWER_ALARM =y
(可以在Kconfig文件中查找ANDROID_POWER等字段进行选择,或者直接修改.config文件)
(11)、退出并保存.config
提示:有时软件安装错误会导致无法找到makefile;在make menuconfig时有时会因为各种库没安装而出现错误,我们要根据所提示的错误 sudo apt-get install …… 来安装所缺库。
驱动部分移植:
只提供最基本的几个驱动移植方法,谨保证android可以跑起来。
键盘驱动、sd卡驱动等移植基本上大同小异,不懂的参考linux的驱动移植。
LCD驱动(EmbedSky)
1、参数配置
修改 “ drivers/video/s3c2410fb.c ”文件,修改 370 行开始的函数, 内容如下(红色部
分):
static void s3c2410fb_activate_var(struct fb_info *info)
{
struct s3c2410fb_info *fbi = info->par;
void __iomem *regs = fbi->io;
int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT;
struct fb_var_screeninfo *var = &info->var;
struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
struct s3c2410fb_display *default_display = mach_info->displays +
mach_info->default_display;
int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock) / 2;
dprintk("%s: var->xres = %d/n", __FUNCTION__, var->xres);
dprintk("%s: var->yres = %d/n", __FUNCTION__, var->yres);
dprintk("%s: var->bpp = %d/n", __FUNCTION__, var->bits_per_pixel);
if (type == S3C2410_LCDCON1_TFT) {
s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs);
--clkdiv;
if (clkdiv < 0)
clkdiv = 0;
} else {
s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs);
if (clkdiv < 2)
clkdiv = 2;
}
// fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(default_display->setclkval);
/* write new registers */
2、完成了这部分修改之后,我们在 s3c2410fb_display 结构体中添加了一个 setclkval 的变量,那么我们需要在该结构体的原型中添加上该变量,修改 “ arch/arm/mach-s3c2410/include/mach/fb.h ” 文件,在 40 行添加如下
内容(红色部分所示):
/* LCD description */
struct s3c2410fb_display {
/* LCD type */
unsigned type;
/* Screen size */
unsigned short width;
unsigned short height;
/* Screen info */
unsigned short xres;
unsigned short yres;
unsigned short bpp;
unsigned pixclock; /* pixclock in picoseconds */
unsigned setclkval; /* clkval */
unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */
unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */
unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */
/* lcd configuration registers */
unsigned long lcdcon5;
3、修改 LCD 参数设置
然后我们修改 LCD 各个参数的配置,该配置参数在 “arch/arm/mach-s3c2440/mach-smdk2440.c”文件中的由107 行开始的结构体中,然后将其改为如下内容即可(红色部分就是修改的内容):(注意:添加上刚刚添加的那个变量 setclkval的赋值)
/* LCD driver info */
static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
.lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_PWREN |
S3C2410_LCDCON5_HWSWP,
.type = S3C2410_LCDCON1_TFT,
.width =240 ,
.height =320 ,
.pixclock = 166667 ,
.xres = 240 ,
.yres = 320 ,
.bpp = 16,
.left_margin =20 ,
.right_margin = 8 ,
.hsync_len =4,
.upper_margin =8,
.lower_margin =7 ,
.vsync_len =4 ,
};
static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
.displays = &smdk2440_lcd_cfg,
.num_displays = 1,
.default_display = 0,
#if 0
/* currently setup by downloader */
.gpccon = 0xaa940659,
.gpccon_mask = 0xffffffff,
.gpcup = 0x0000ffff,
.gpcup_mask = 0xffffffff,
.gpdcon = 0xaa84aaa0,
.gpdcon_mask = 0xffffffff,
.gpdup = 0x0000faff,
.gpdup_mask = 0xffffffff,
#endif
// .lpcsel = ((0xCE6) & ~7) | 1<<4,
};
4、然后修改 “drivers/ video /Kconfig”文件,把从 1798 到 1819 行的内容改成如下所示:
config FB_S3C24X0
tristate "S3C24X0 LCD framebuffer support"
depends on FB && ARCH_S3C2410
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
Frame buffer driver for the built-in LCD controller in the Samsung
S3C2410 processor.
This driver is also available as a module ( = code which can be
inserted and removed from the running kernel whenever you want). The
module will be called s3c2410fb. If you want to compile it as a module,
say M here and read <fileocumentation/kbuild/modules.txt>.
If unsure, say N.
choice
prompt "LCD select"
depends on FB_S3C24X0
help
S3C24x0 LCD size select
config FB_S3C24X0_S320240
boolean "3.5 inch 320x240 Samsung LCD"
depends on FB_S3C24X0
help
3.5 inch 320x240 Samsumg LCD
config FB_S3C24X0_W320240
boolean "3.5 inch 320x240 WanXin LCD"
depends on FB_S3C24X0
help
3.5 inch 320x240 WanXin LCD
config FB_S3C24X0_T240320
boolean "3.5 inch 240X320 Toshiba LCD"
depends on FB_S3C24X0
help
3.5 inch 240x320 Toshiba LCD
config FB_S3C24X0_TFT480272
boolean "4.3 inch 480X272 TFT LCD"
depends on FB_S3C24X0
help
4.3 inch 480X272 TFT LCD
config FB_S3C24X0_TFT640480
boolean "VGA 640x480"
depends on FB_S3C24X0
help
VGA 640x480
config FB_S3C24X0_TFT800480
boolean "7 inch 800x480 LCD"
depends on FB_S3C24X0
help
7 inch 800x480 LCD
config FB_S3C24X0_TFT800600
boolean "10.4 inch 800x600 TFT LCD"
depends on FB_S3C24X0
help
10.4 inch 800x480 TFT LCD
Endchoice
config FB_S3C2410_DEBUG
bool "S3C2410 lcd debug messages"
depends on FB_S3C24X0
help
Turn on debugging messages. Note that you can set/unset at run time
through sysfs
5、然后修改 “drivers/ video /Makefile”文件,把 109 行的内容改成如下所示obj-$(CONFIG_FB_MAXINE) += maxinefb.o
obj-$(CONFIG_FB_METRONOME) += metronomefb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_IMX) += imxfb.o
obj-$(CONFIG_FB_S3C24 X 0) += s3c2410fb.o
obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
obj-$(CONFIG_FB_PS3) += ps3fb.o
obj-$(CONFIG_FB_SM501) += sm501fb.o
obj-$(CONFIG_FB_XILINX) += xilinxfb.o
6、配置内核
做完以上的这些操作之后,我们就可以对 LCD 进行配置了,输入: # make menuconfig ,进入配置单,然后进行如下配置:
Device Drivers --->
Graphics support --->
<*> Support for frame buffer devices --->
Enable firmware EDID
Enable Video Mode Handling Helpers
*** Frame buffer hardware drivers ***
<*> S3C24X0 LCD framebuffer support
LCD select (3.5 inch 320x240 WanXin LCD) --->
<*> Framebuffer Console support
Bootup logo --->
Standard 224-color Linux logo
在 “LCD select (3.5 inch 320x240 WanXin LCD)” 这个选项这里选择LCD 类型,下面就是进入该配置选项出现的对话框的情况,有“ X ”的是表示选中的:
(X) 3.5 inch 320x240 WanXin LCD
7、然后进入 “ Bootup logo ” 选项的配置单,我们只需要选择是 224 色的就行了。)
配置完毕后,编译出内核镜像,烧写到 TQ2440开发板中,启动系统时,就可以看到开机
logo的画面,这就表明LCD驱动完成了。
触摸屏驱动(EmbedSky)
第一、添加触摸驱动补丁
1、在 2.6.29.3 的内核里面是没有针对S3C2440的触摸驱动的,这里我们对其打上触摸的驱动补丁,首先复制我们准备好的触摸驱动源码(名为:EmbedSky_ts.c)到内核源码的 “drivers/input/touchscreen/ ”目录下和触摸驱动的头文件(名为: ts.h)到内核源码的 “include/asm-arm/arch-s3c2410”目录下,添加 “clock.h”文件到内核源码的 “include/asm-arm/hardware/”目录下。
2、然后修改 “drivers/input/touchscreen/ ”目录下面的 “Kconfig”和 “Makefile”文件,以支持对刚刚添 加的文件的支持。
修改内核源码的 “ drivers/input/touchscreen/ ” 目录下面的 “Kconfig ” 文件,在文件的最后添加如下内容:
config TOUCHSCREEN_USB_GOTOP
default y
bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
depends on TOUCHSCREEN_USB_COMPOSITE
config EmbedSky_TOUCHSCREEN
tristate "EmbedSky touchscreen"
depends on ARCH_S3C2410 && INPUT && INPUT_TOUCHSCREEN
select SERIO
help
To compile this driver as a module, choose M here: the
module will be called EmbedSky_ts.ko.
config TOUCHSCREEN_EmbedSky_DEBUG
boolean "EmbedSky touchscreen debug messages"
depends on EmbedSky_TOUCHSCREEN
help
Select this if you want debug messages
endif
3、修改同目录下的 “Makefile”文件,在文件的最后添加如下内容(红色部分所示):
- #
- # Makefile for the touchscreen drivers.
- #
- # Each configuration option enables a list of files.
- obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
- obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
- obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
- obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
- obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
- obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
- obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
- obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
- obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
- obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o
- obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o
- obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
- obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o
- obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
- obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
- obj-$(CONFIG_ EmbedSky_TOUCHSCREEN) += EmbedSky_ts.o
4、然后在 “include/linux/interrupt.h ” 文件中的 58 行添加如下内容,用以支持 EmbedSky_ts.c 源码中的SA_SAMPLE_RANDOM 中断:
#define IRQF_DISABLED 0x00000020
#define IRQF_SAMPLE_RANDOM 0x00000040
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
#define IRQF_TIMER 0x00000200
#define IRQF_PERCPU 0x00000400
#define IRQF_NOBALANCING 0x00000800
#define IRQF_IRQPOLL 0x00001000
static inline
unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
{
return flag;
}
#define SA_INTERRUPT deprecated_irq_flag(IRQF_DISABLED)
#define SA_SAMPLE_RANDOM deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
#define SA_SHIRQ deprecated_irq_flag(IRQF_SHARED)
#define SA_PROBEIRQ deprecated_irq_flag(IRQF_PROBE_SHARED)
#define SA_PERCPU deprecated_irq_flag(IRQF_PERCPU)
#define SA_TRIGGER_LOW deprecated_irq_flag(IRQF_TRIGGER_LOW)
#define SA_TRIGGER_HIGH deprecated_irq_flag(IRQF_TRIGGER_HIGH)
#define SA_TRIGGER_FALLING deprecated_irq_flag(IRQF_TRIGGER_FALLING)
#define SA_TRIGGER_RISING deprecated_irq_flag(IRQF_TRIGGER_RISING)
#define SA_TRIGGER_MASK deprecated_irq_flag(IRQF_TRIGGER_MASK)
typedef irqreturn_t (*irq_handler_t)(int, void *);
5、打好了触摸驱动的补丁后,还需要添加触摸屏设备和配置信息。
修改内核源码的 “arch/arm/mach-s3c2440/mach-smdk2440.c”文件,在41行添加上对触摸驱动头文件的调用,内容如下:
#include <asm/plat-s3c/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/idle.h>
#include <asm/arch/fb.h>
#include <asm/arch/ts.h>
#include <asm/plat-s3c24xx/s3c2410.h>
#include <asm/plat-s3c24xx/s3c2440.h>
#include <asm/plat-s3c24xx/clock.h>
#include <asm/plat-s3c24xx/devs.h>
#include <asm/plat-s3c24xx/cpu.h>
在153 行开始添加内容如下:(红色部分所示)
//touch screen
struct platform_device s3c_device_ts = {
.name = " EmbedSky -ts",
.id = -1,
};
static struct
EmbedSky _ts_mach_info
EmbedSky _ts_info = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
};
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
&s3c_device_ts,
};
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_device_ts.dev.platform_data = & EmbedSky _ts_info;
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
s3c2410_gpio_setpin(S3C2410_GPG12, 0);
s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPIO_OUTPUT);
s3c24xx_udc_set_platdata(&whizer_udc_cfg);
}
第二、添加TSDEV的补丁
1、然后再打上TSDEV设备的补丁,复制补丁文件 “tsdev.c ”到内核源码的 “drivers/input/” 目录下面,然后修改同目录下的 “ Kconfig ” 和 “ Makefile ” 文件。修改内核源码 “drivers/input/”目录下的 “Kconfig ”文件,在117行添加如下内容(红色部分所示):
config INPUT_TSDEV
tristate "Touchscreen interface"
---help---
Say Y here if you have an application that only can understand the
Compaq touchscreen protocol for absolute pointer data. This is
useful namely for embedded configurations.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called tsdev.
config INPUT_TSDEV_SCREEN_X
int "Horizontal screen resolution"
depends on INPUT_TSDEV
default "320"
config INPUT_TSDEV_SCREEN_Y
int "Vertical screen resolution"
depends on INPUT_TSDEV
default "240"
config INPUT_EVDEV
tristate "Event interface"
help
Say Y here if you want your input device events be accessible
under char device 13:64+ - /dev/input/eventX in a generic way.
To compile this driver as a module, choose M here: the
module will be called evdev.
2、修改同目录下的 “ Makefile ” 文件,在 16 行添加如下内容(红色部分所示):
#
# Makefile for the input core drivers.
#
# Each configuration option enables a list of files.
obj-$(CONFIG_INPUT) += input-core.o
input-core-objs := input.o ff-core.o
obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o
obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o
obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
obj-$(CONFIG_INPUT_EVDEV) += evdev.o
obj-$(CONFIG_INPUT_TSDEV) += tsdev.o
obj-$(CONFIG_INPUT_EVBUG) += evbug.o
obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/
obj-$(CONFIG_INPUT_MOUSE) += mouse/
obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
obj-$(CONFIG_INPUT_TABLET) += tablet/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
第三、配置内核
修改完毕之后,输入: # make menuconfig 进入配置单,然后配置如下:
Device Drivers --->
Input device support --->
<*> Touchscreen interface
(320) Horizontal screen resolution
(240) Vertical screen resolution
<*> Event interface
< > Event debugging
Touchscreens --->
<*> whizer touchscreen
[ ] EmbedSky
touchscreen debug messages
移植网卡驱动到android内核
1、驱动源码获取
在内核里面网卡驱动是相当完善的,这里需要注意一件事情,从 2.6.25 开始的内核的
“drivers/net/dm9000.c” 这个文件对应的 DM9000 的驱动(版本为 1.3 版)并不适合 DM9000E 这颗芯片,而在TQ2440 开发板上面用的是DM9000E这颗芯片,所以我们需要更换 “dm9000.c ”这个驱动程序,只要找到 1.2版的 DM9000 的驱动就可以支持 DM9000E 这颗芯片了,下载一个linux-2.6.24.tar.bz2 的源码包,然后解压,提取 “drivers/net/dm9000.c ”这个文件,打开看一下,您可以发现这个驱动文件是 1.2 版本的,我们用它去替换掉所用的android里面的对应源码即可开始进行我们的移植操作。
2、修改驱动源码
我们只需要进行简单的修改就可以成功的驱动上 TQ2440 上面的 DM9000 的网卡芯片。
修改内核源码的 “ arch/arm/plat-s3c24xx/common-smdk.c ” 文件:
在 46 行左右添加如下内容(红色部分所示):
#include <asm/plat-s3c24xx/common-smdk.h>
#include <asm/plat-s3c24xx/devs.h>
#include <asm/plat-s3c24xx/pm.h>
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
#include <linux/dm9000.h>
#endif
/* LED devices */
static struct s3c24xx_led_platdata smdk_pdata_led4 = {
然后在 151 行左右,添加如下内容(红色部分所示):
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
/* DM9000 */
static struct resource s3c_dm9k_resource[] = {
[0] = {
.start = S3C2410_CS4, /* ADDR2=0 ,发送地址时使用这个地址 */
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S3C2410_CS4 + 4, /* ADDR2=1 ,传输数据时使用这个地址 */
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT7, /* 中断号 */
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ,
}
};
/* for the moment we limit ourselves to 16bit IO until some
* better IO routines can be written and tested
*/
static struct dm9000_plat_data s3c_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
static 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,
}
};
#endif /* CONFIG_DM9000 */
/* devices we initialise */
static struct platform_device __initdata *smdk_devs[] = {
然后在 199 行左右,添加如下内容(红色部分所示):
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
&s3c_device_dm9k,
#endif
};
修改内核源码的 “ drivers/net/dm9000.c ” 文件:
在 73 行添加如下内容(红色部分所示):
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/io.h>
#if defined(CONFIG_ARCH_S3C2410)
#include <asm/arch-s3c2410/regs-mem.h>
#endif
#include "dm9000.h"
把从 118 行开始修改为如下内容(红色部分所示):
#ifdef CONFIG_BLACKFIN
#define readsb insb
#define readsw insw
#define readsl insl
#define writesb outsb
#define writesw outsw
#define writesl outsl
#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH)
#elif defined(CONFIG_ARCH_S3C2410)
#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_RISING)
#else
#define DM9000_IRQ_FLAGS IRQF_SHARED
#endif
在 414 行添加如下内容(红色部分所示):
static int
dm9000_probe(struct platform_device *pdev)
{
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
unsigned long base;
int ret = 0;
int iosize;
int i;
u32 id_val;
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon;
unsigned int oldval_bankcon4;
#endif
/* Init network device */
在 428 行添加如下内容(红色部分所示):
/ * Init network device */
ndev = alloc_etherdev(sizeof (struct board_info));
if (!ndev) {
printk("%s: could not allocate device./n", CARDNAME);
return -ENOMEM;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
#if defined(CONFIG_ARCH_S3C2410)
oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16)) /
| S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4);
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif
PRINTK2("dm9000_probe()");
在 628 行添加内容(红色部分所示):
out:
printk("%s: not found (%d)./n", CARDNAME, ret);
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
*((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif
dm9000_release_board(pdev, db);
free_netdev(ndev);
return ret;
}
注意:还有一个问题,就是在1.2,编译“(board_info_t *) dev->priv”时,通不过。解决办法是,参照1.3,将所有的“(board_info_t *) dev->priv”改为“netdev_priv(dev)”,将所有的“(board_info_t *) ndev->priv”改为“netdev_priv(ndev)”。用替换不能全部改正,建议先全部替换,然后手动搜索替换。
另外,这样编译之后网卡已经能够驱动,在linux中能正常使用,但是,如果使用nfs去不能正常下载文件系统,好像是网卡没驱动,如果要是他能使用nfs,还必须修改dm9000.c:
dm9000_probe(struct platform_device *pdev)
{
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0};
const unsigned char *mac_src;
int ret = 0;
int iosize;
int i;
u32 id_val;
.
if (!is_valid_ether_addr(ndev->dev_addr)) {
/* try reading from mac */
for (i = 0; i < 6; i++)
ndev->dev_addr = ior(db, i+DM9000_PAR);
}
if (!is_valid_ether_addr(ndev->dev_addr)){
printk("%s: Invalid ethernet MAC address. Please "
"set using ifconfig/n", ndev->name);
for (i = 0; i < 6; i++)
ndev->dev_addr = ne_defethaddr;
}
3、配置并编译内核
修改完以上的内容之后,输入: # make menuconfig ,进入配置单,然后添加上对 DM9000 网卡的配置 :
Device Drivers --->
Network device support --->
Ethernet (10 or 100Mbit) --->
-*- Generic Media Independent Interface device support
<*> DM9000 support
(4) DM9000 maximum debug level
配置好后,保存配置单,然后编译出镜像,烧写到开发板中。
制作支持ARMv4的Android根文件系统
编译Android源代码完成后,在源码文件夹中的“/out/target/product/generic/”目录中包括了三个yaffs2格式的文件系统镜像:
randisk.img是Android的主文件系统,系统启动后会把system.img和userdata.img分别挂载到它的system和data目录下;
system.img挂载到randisk.img中的system目录下,它包含了Android文件系统的主要文件,基本上所有工具和应用程序都在这个目录下;
userdata.img挂载到randisk.img中的data目录,主要用于保存用户数据。
system的目录如下:
xbin:一些系统管理和配置工具;
modules:存放内核模块和模块配置文件的目录;
framework:存放应用框架文件,里面都是.jar和.apk文件;
fonts:字体库文件存放的目录;
etc:根目录的etc链接到这个目录,存放系统大部分配置文件的目录;
build.prop:是一个属性文件,记录系统的设置和改变;
media:存放系统声音的目录;
bin:存放用户常用的工具程序;
usr:存放用户的配置文件,如键盘布局、共享、时区等配置文件;
app:存放系统自带的Java应用程序;
lib:存放库文件的目录;
在本次实验中,我们把三个文件合成一个文件系统镜像,把randisk.img中的文件复制到新建的rootfs文件夹中,分别复制system.img和userdata.img的内容到rootfs中的system和data文件夹中。当然,其中由于开发板大小的限制,为了使得烧出的镜像不会因为太大了无法烧写进开发板中,所以对文件系统的system进行了一些裁剪,比如app中一些应用程序的删减等,然后使用yaffs2文件系统的制作工具mkyaffs2image(此工具包含于EABI4.3.3中)把rootfs制作成文件系统。将成功制作的文件系统镜像烧写到开发板中。完成本项目的android系统的移植。
至此,所有移植工作就基本完成了。
首先设置UBOOT启动参数为:
bootargs=noinitrd root=/dev/mtdblock2 init=init console=ttySAC0
然后烧写内核镜像和文件系统镜像,就可以启动移植成功的android系统了
ramdisk.img在android中的使用
ramdisk.img在android中的使用
ramdisk中包含一些对于启动android的很重要的文件,比如内核启动完后加载的第一个进程init,一些重要的配置文件等,总之它控制着整个android的启动.
ramdisk的使用有两种方法:1,编译进内核;2,将ramdisk单独烧写
1,编译进内核
将 ramdisk解压,可以看到它里面有很多文件和目录, 如:da
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE="root"
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
这些也可以直接在xxxx_defconfig改,然后make xxxx_defconfig使其生效.
这样做了以前,root将被编译进zImage,并随之一起烧进板子.
2,将ramdisk单独烧写
也 可以将ramdisk作为一个单独的包烧写,就烧在zImage的后面.假如zImage烧在0x600000,那么ramdisk就烧在 0x800000就好.值得注意的是,ramdisk在烧写之前要进行一次转换.因为bootloader在运行的时候,会将ramdisk从FLASH 加载到RAM中,它会把FLASH上0x800000-0x880000的空间作为ramdisk读取,并检查其最后四个字节,这四个字节保存的是 ramdisk.img的实际大小.所以我们要做的转换工作就是把原来的ramdisk.img(100多字节)转换成512字节,并在其最后四个字节写 ramdisk.img的实际长度.最后在bootloader中写程序把ramdisk加载到RAM.同时.config中的配置项只要:
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
更多推荐
所有评论(0)