系统移植
1.由于Linux3.12.16上没有适用于OK6410的BSP文件,所以我们拷贝一份现有的BSP文件,然后在这上面做修改,使其支持OK6410,将arch/arm/mach-s3c64xx/下的,mach-smdk6410.c复制一份并重命名为mach-ok6410.c;
2.在arch/arm/mach-s3c64xx/这个目录的Kconfig中,模仿“config MACH_SMDK6410”添加配置项:
config MACH_OK6410
bool "OK6410"
select CPU_S3C6410
select HAVE_S3C2410_WATCHDOG if WATCHDOG
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_I2C1
select S3C64XX_SETUP_IDE
select S3C64XX_SETUP_KEYPAD
select S3C64XX_SETUP_SDHCI
select S3C64XX_SETUP_USB_PHY
select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_I2C1
select S3C_DEV_RTC
select S3C_DEV_USB_HOST
select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
help
Machine support for the Samsung OK6410
3.修改复制后的文件mach-ok6410.c,将该文件中的所有"smdk6410"改成"ok6410",不要改大写"SMDK6410"的.可用批量字符串替换命令:
perl -p -i -e "s/smdk6410/ok6410/g" ./mach-ok6410.c
意思是说将当前目录下mach-ok6410.c文件中的“smdk6410”都替换为“ok6410”。
修改 MACHINE_START(SMDK6410, "SMDK6410") 为 MACHINE_START(OK6410, "OK6410")//这个要和Kconfig里的MACH_OK6410匹配
4.在当前目录的Makefile最后一行加上:obj-$(CONFIG_MACH_OK6410) += mach-ok6410.o
5.打开arch/arm/tools/mach-types文件,在:
smdk6410 MACH_SMDK6410 SMDK6410 1626
后面添加:
ok6410 MACH_OK6410 OK6410 1626
6.修改源码根目录的Makefile
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
改为
CROSS_COMPILE ?= /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-
7.复制arch/arm/configs/s3c6400-defconfig文件到根目录,重命名为.config
8.执行make menuconfig对内核进行配置:
9.执行 make zImage 生成zImage(在/arch/arm/boot下)
10.将该zImage下到开发板运行:
通过以上简单几步,内核已经移植成功了,接下来移植驱动。
LED驱动移植
-
Linu内核下drivers/leds/ledsgpio.c实现了一个体系结构无关的GPIO LED驱动,使用此LED 驱动,开发者不需要修改一行代码,只需要在 BSP 的板文件(对于OK6410 为arch/arm/machs3c6410/mach-ok6410.c)中定义相关的platform设备和数据。在 OK6410开发板上,GPM0~GPM3 实现了四个 LED,因此其对应的platform 信息如下:
arch/arm/machs3c6410/mach-ok6410.c:
static struct gpio_led ok6410_leds[] ={ [0]= { .name = "LED1", .gpio = S3C64XX_GPM(0), }, [1]= { .name = "LED2", .gpio = S3C64XX_GPM(1), }, [2]= { .name = "LED3", .gpio = S3C64XX_GPM(2), }, [3]= { .name = "LED4", .gpio = S3C64XX_GPM(3), }, }; static struct gpio_led_platform_data ok6410_gpio_led_pdata ={ .num_leds = ARRAY_SIZE(ok6410_leds), .leds =ok6410_leds, }; static struct platform_device ok6410_device_led ={ .name = "leds-gpio", .id = -1, .dev ={ .platform_data = &ok6410_gpio_led_pdata, }, };
- 将&ok6410_device_led添加到static struct platform_device *ok6410_devices[] __initdata中。
-
配置内核:
Device Drivers --->
[*] LED Support --->
<*> LED Support for GPIO connected LEDs
下载内核后开发板上的四个LED这时候已经全部都亮了
按键驱动移植
-
Linux内核下的drivers/input/keyboard/gpio_keys.c 实现了一个体系结构无关的 GPIO 按键驱动,使用此按键驱动,开发者不需要修改一行代码,只需要在BSP 的板文件(对于 OK6410为arch/arm/machs3c6410/mach-ok6410.c)中定义相关的platform 设备和数据。在 OK6410开发板上,用 GPN0~GPN5实现了DOWN、ENTER、HOME、UP、TAB、END 六个按键,因此其对应的 platform 信息如下:
arch/arm/machs3c6410/mach-ok6410.c:
#include <linux/gpio_keys.h> static struct gpio_keys_button ok6410_buttons[] = { { .gpio = S3C64XX_GPN(0), .code = KEY_UP, .desc = "Up", .active_low = 1, .wakeup = 0, }, { .gpio = S3C64XX_GPN(1), .code = KEY_DOWN, .desc = "Down", .active_low = 1, .wakeup = 0, }, { .gpio = S3C64XX_GPN(2), .code = KEY_LEFT, .desc = "Left", .active_low = 1, .wakeup = 0, }, { .gpio = S3C64XX_GPN(3), .code = KEY_RIGHT, .desc = "Right", .active_low = 1, .wakeup = 0, }, { .gpio = S3C64XX_GPN(4), .code = KEY_ENTER, .desc = "Enter", .active_low = 1, .wakeup = 0, }, { .gpio = S3C64XX_GPN(5), .code = KEY_ESC, .desc = "Esc", .active_low = 1, .wakeup = 0, } }; static struct gpio_keys_platform_data ok6410_button_data ={ .buttons =ok6410_buttons, .nbuttons =ARRAY_SIZE(ok6410_buttons), }; static struct platform_device ok6410_device_button = { .name ="gpio-keys", .id = -1, .dev = { .platform_data =&ok6410_button_data, }, };
-
将&ok6410_device_button添加到static struct platform_device *ok6410_devices[] __initdata中
-
配置linux内核
Device Drivers --->
Input device support --->
[*] Keyboards --->
<*> GPIO Buttons
LCD驱动移植
1.根据芯片手册,修改mach-ok6410.c里面相应的平台信息:
/*
pixclock = 1000000 / DCLK = 1000000 / 9 = 111111
left_margin = Thb = 2
right_margin = Thf = 2
hsync_len = Thp = 41
upper_margin = Tvb = 2
lower_margin = Tvf = 2
vsync_len = Tvp = 10
xres = Thd = 480
Yres = Tvd = 272
*/
static struct s3c_fb_pd_win ok6410_fb_win0 = {
.max_bpp = 32,
.default_bpp = 16,
.xres = 480,
.yres = 272,
.virtual_y = 272 * 2,
.virtual_x = 480,
};
static struct fb_videomode ok6410_lcd_timing = {
.left_margin = 2,
.right_margin = 2,
.upper_margin = 2,
.lower_margin = 2,
.hsync_len = 41,
.vsync_len = 10,
.xres = 480,
.yres = 272,
};
static struct map_desc ok6410_iodesc[] = {
{
/* LCD support */
.virtual = (unsigned long)S3C_VA_LCD,
.pfn = __phys_to_pfn(S3C_PA_FB),
.length = SZ_16K,
.type = MT_DEVICE,
},
};
2.然后将飞凌提供的Linux内核中的drviers/video/samsung目录拷贝到drviers/video/目录下
3.修改drviers/video/的Kconfig文件,在文件中加入:source "drivers/video/samsung/Kconfig"
4.修改修改drviers/video/的Makefie文件,再最后一行添加:obj-$(CONFIG_FB_S3C_EXT) += samsung/
5.在arch/arm/plat-samsung/include/plat/map-base.h里面添加:
#define S3C_VA_LCD S3C_ADDR(0x01100000) /* LCD */
6.把drivers/video/samsung/s3cfb_fimd4x.c里面的第1417行:
s3c6410_pm_do_save(s3c_lcd_save, ARRAY_SIZE(s3c_lcd_save));
改成
s3c_pm_do_save(s3c_lcd_save, ARRAY_SIZE(s3c_lcd_save));
第1438行
s3c6410_pm_do_restore(s3c_lcd_save, ARRAY_SIZE(s3c_lcd_save));
改成
s3c_pm_do_restore(s3c_lcd_save, ARRAY_SIZE(s3c_lcd_save));
7.把飞凌提供的Linux内核中arch/arm/plat-samsung/include/plat/ 目录下的 regs-fb.h , regs-fb-v4.h 拷贝到linux-3.12.16的相同目录下
8.把飞凌提供的Linux内核中arch/arm/mach-s3c64xx/include/mach/ 目录下的 regs-fb.h , regs-lcd.h 拷贝到linux-3.12.16的相同目录下
9.配置内核:
Device Drivers --->
Graphics support --->
<*> S3C Framebuffer Support (eXtended)(修改Kconfig之后才有这个选)
Select LCD Type (4.3 inch 480x272 TFT LCD) --->
(X) 4.3 inch 480x272 TFT LCD
<*> Advanced options for S3C Framebuffer
Select BPP(Bits Per Pixel) (16 BPP) --->
(4) Number of Framebuffers
[ ] Enable Virtual Screen
[*] Enable Double Buffering
<*> Support for frame buffer devices ---> (里面的都空选)
[ ] Backlight & LCD device support --->
Console display driver support --->
<*> Framebuffer Console support
[*] Bootup logo --->(显示小企鹅)
[*] Standard 224-color Linux logo
如果驱动移植成功,内核启动会应该会显示小企鹅。