基于s5pv210的Linux内核裁剪--Linux内核篇

Linux内核裁剪

操作系统的内核是应用程序赖以运行的环境,内核可以说是操作系统的核心部分。因为Linux是开源的操作系统,可以将不需要的功能进行裁剪,所以本设计将需要的功能添加,不需要的功能将删除,本设计的内核采用Linux2.6.35版本。

本人的开发环境是window10、VMWare 12.5.2和Ubuntu 16.04,交叉编译器是arm-2009q3具体的裁剪如下:

1.修改Makefile为:

export KBUILD_BUILDHOST := $(SUBARCH)

ARCH            ?= arm

CROSS_COMPILE   ?=/usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-

CROSS_COMPILE   ?= $(CONFIG_CROSS_COMPILE:"%"=%)

2.进行配置生成.config文件

make smdkv210_android_defconfig

3.进一步配置, # make menuconfig

如果说你缺少ncurses libraries,则输入apt-get install ncurses-devc

串口配置,选择串口0

System Type  --->

         (0) S3C UART to use for low-level messages

Kernel hacking  --->

(0) S3C UART to use for low-level debug

4.确定机器码

vi arch/arm/tools/mach-types

在433行可以看出,SMDKV210评估板的机器码是2456(16进制是0x998):

433 smdkv210        MACH_SMDKV210           SMDKV210                2456

可在末行加入,在uboot那里set machid 270f,或者把上面那行注释掉,加入下面那行,然后机器码改成2456.

gec210              MACH_GEC210             GEC210                  9999

5.确定内核的加载地址与参数地址

vim arch/arm/mach-s5pv210/Makefile.boot

因为我们之前uboot的DDRch0内存 0x20000000~0x30000000,映射到了 0x30000000~0x40000000,所以我们要修改内核的加载地址和参数地址。

可以看出,内核的加载地址和参数地址分别为0x30008000和0x30000100,bootloader启动内核前应该将内核拷贝到0x30008000,并将参数放到0x30000100。

改为:

zreladdr-y   += 0x30008000

params_phys-y   := 0x30000100

6.移除max8698模块。Max8698是SMDKV210开发板上使用的电源管理芯片,而我们的开发板上并未使用。因此之前在移植uboot时我们屏蔽了该PMIC相关代码,现在移植kernel,也需要做相应处理,即在make menuconfig中去掉max8698模块。

make menuconfig

Device Drivers  --->

[*] Multifunction device drivers  --->

[ ]   Maxim Semiconductor MAX8698 PMIC Support

      [*] Voltage and Current Regulator Support  --->

         < >   Maxim 8698 voltage regulator

7.修改Nand分区

drivers\mtd\nand\s3c_nand.c定义好了NandFlash的分区表,需要修改drivers\mtd\nand\s3c_nand.c文件:

vi drivers/mtd/nand/s3c_nand.c

struct mtd_partition s3c_partition_info[] = {

         {

                   .name                = "uboot",

                   .offset                = 0,          /* for bootloader */

                   .size          = (1*SZ_1M),

                   .mask_flags     = MTD_CAP_NANDFLASH,

         },

         {

                   .name                = "recovery",

                   .offset                = MTDPART_OFS_APPEND,

                   .size          = (5*SZ_1M),

         },

         {

                   .name                = "kernel",

                   .offset                = MTDPART_OFS_APPEND,

                   .size          = (5*SZ_1M),

         },

         {

                   .name                = "ramdisk",

                   .offset                = MTDPART_OFS_APPEND,

                   .size          = (3*SZ_1M),

         },

         {

                   .name                = "rootfs",

                   .offset                = MTDPART_OFS_APPEND,

                   .size          = MTDPART_SIZ_FULL,

         },

};

我们把256MB的分成了以下几个区,每个分区用于存放不同的内容:

分区名

起始地址

结束地址

大小

Uboot

0x000000000000

0x000000100000

0x000000100000 1MB

Recovery

0x000000100000

0x000000600000

0x000000500000 5MB

Kernel

0x000000600000

0x000000b00000

0x000000500000 5MB

Ramdisk

0x000000b00000

0x000000e00000

0x000000300000 3MB

Root

0x000000e00000

0x000020000000

0x00001F200000 498MB

 

8.加入开发板GEC210

(1)复制mach-smdkc110.c为mach-gec210.c

cp arch/arm/mach-s5pv210/mach-smdkc110.c arch/arm/mach-s5pv210/mach-gec210.c

(2)修改机器型号

$vim arch/arm/mach-s5pv210/mach-gec210.c

将arch/arm/mach-s5pv210/mach-gec210.c文件的末尾修改成如下(就是将SMDKV210改成GEC210):

#ifdef CONFIG_MACH_SMDKC110

MACHINE_START(SMDKC110, "SMDKC110")

#elif CONFIG_MACH_GEC210

MACHINE_START(GEC210, "GEC210")

#endif

         /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */

         .phys_io   = S3C_PA_UART & 0xfff00000,

         .io_pg_offst     = (((u32)S3C_VA_UART) >> 18) & 0xfffc,

         .boot_params = S5P_PA_SDRAM + 0x100,

         .init_irq    = s5pv210_init_irq,

         .map_io             = smdkc110_map_io,

         .init_machine  = smdkc110_machine_init,

         .timer                = &s5p_systimer,

MACHINE_END

(3)添加机器码,上面已经做了。

(4)在KBuild系统中增加GEC210开发板的配置菜单

vi arch/arm/mach-s5pv210/Kconfig

在menu "S5PV210 Machines"下面加入:

config MACH_GEC210

        bool "GEC210"

        select CPU_S5PV210

        select ARCH_SPARSEMEM_ENABLE

        select S3C_DEV_WDT

        select HAVE_S3C2410_WATCHDOG

        select S3C_DEV_I2C1

        select S3C_DEV_I2C2

        select HAVE_PWM

        select S3C_DEV_HSMMC

        select S3C_DEV_HSMMC1 if !S5PV210_SD_CH0_8BIT

        select S3C_DEV_HSMMC3 if !S5PV210_SD_CH2_8BIT

        select S5PV210_SETUP_SDHCI

        select S5PV210_POWER_DOMAIN

        help

          Machine support for GEC210

(5)修改arch/arm/mach-s5pv210/Makefile文件

vi arch/arm/mach-s5pv210/Makefile

在“# machine support”下面加入:

obj-$(CONFIG_MACH_GEC210)       += mach-gec210.o smdkc110-rtc.o

选上下面一项,加入GEC210开发板的支持:

System Type  --->

Board selection (SMDKV210)  ---> 

[*] GEC210

9.修改内存物理地址

vi arch/arm/mach-s5pv210/include/mach/memory.h

修改第16行为:

#if defined(CONFIG_MACH_SMDKV210) || defined(CONFIG_MACH_GEC210)

#define PHYS_OFFSET             UL(0x30000000)

#else

#define PHYS_OFFSET             UL(0x30000000)

#endif

10.修改内存映射

vi arch/arm/mach-s5pv210/include/mach/map.h

修改第156行,增加GEC210

#if defined(CONFIG_MACH_SMDKV210) || defined(CONFIG_MACH_GEC210)

#define S5PV210_PA_SDRAM (0x30000000)

#else

#define S5PV210_PA_SDRAM (0x30000000)

#endif

11.添加LCD支持(如果不添加会导致启动时内核OOPS错误)

vi drivers/video/samsung/Kconfig

修改第77行,增加MACH_GEC210

config FB_S3C_LTE480WV

          bool "LTE480WV"

          depends on (MACH_SMDKV210 || MACH_SMDKC110 || MACH_GEC210)

          ---help---

            This enables support for Samsung LTE480WV 4.8\" WVGA LCD panel

然后 make menuconfig,确认driver中LTE480WV被选中。

Device Drivers  --->  

         Graphics support  --->

                   <*> Support for frame buffer devices  --->

                            Select LCD Type (LTE480WV)  --->

12.修改网卡配置

GEC210原理图中DM9000网卡芯片的部分原理图。重要的信息如下:

1、CS(37脚)连接了Xm0CSn1

2、CMD(32脚)连接了Xm0ADDR2

3、INT(34脚)连接了XEINT7

(1)修改网卡物理地址,对应上面1

vi arch/arm/mach-s5pv210/include/mach/map.h

改为:

#define S5PV210_PA_DM9000       (0x88000000)

(2)修改命令线和外部中断配置,分别对应上面2和3

vi arch/arm/plat-s5p/devs.c
static struct resource s5p_dm9000_resources[] = {

         [0] = {

                   .start = S5P_PA_DM9000,

                   .end   = S5P_PA_DM9000,

                   .flags = IORESOURCE_MEM,

         },

         [1] = {

#if defined(CONFIG_DM9000_16BIT)

                   //.start = S5P_PA_DM9000 + 2,

                   //.end   = S5P_PA_DM9000 + 2,

                   .start = S5P_PA_DM9000 + 8,

                   .end   = S5P_PA_DM9000 + 8,

                   .flags = IORESOURCE_MEM,

#else

                   .start = S5P_PA_DM9000 + 1,

                   .end   = S5P_PA_DM9000 + 1,

                   .flags = IORESOURCE_MEM,

#endif

         },

         [2] = {

                   //.start = IRQ_EINT9,

                   //.end   = IRQ_EINT9,

                   .start = IRQ_EINT7,

                   .end   = IRQ_EINT7,

                   .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,

         }

};

13.配置NFS服务 make menuconfig

(1)、配置网络部分,主要是使能CONFIG_IP_PNP以在2中能够看到Root file system on NFS选项

[*] Networking support

         Networking options

                   [*] TCP/IP networking

                            [*] IP: kernel level autoconfiguration

                                     [*] IP: DHCP support

                                     [*] IP: BOOTP support

(2)、配置开启nfs服务

File systems  --->  

         [*]Network File Systems  --->

                   <*> NFS client support

                   [*] NFS client support for NFS version 3                                 

[*] NFS client support for the NFSv3 ACL protocol extension

                   [*] NFS client support for NFS version 4 (EXPERIMENTAL)

                   [*] NFS client support for NFSv4.1 (DEVELOPER ONLY)

                   [*] Root file system on NFS

(3)在uboot下配置:

set bootcmd tftp 30008000 zImage\;bootm 30008000

set machid 270f

set bootargs root=/dev/nfs init=/linuxrc nfsroot=192.168.1.141:/workdir/rootfs ip=192.168.1.20:192.168.1.141:192.168.1.1:255.255.255.0::eth0:on console=ttySAC0,115200

save

14.LCD驱动移植

(1)修改LCD参数

# vi arch/arm/mach-s5pv210/mach-gec210.c

将#ifdef CONFIG_FB_S3C_LTE480WV(该宏在 676 行) 与 #endif 之间的代码改

成:

static struct s3cfb_lcd wvga_s70 = {

.width = 800,

.height = 480,

.p_width = 800,

.p_height = 480,

.bpp = 32,

.freq = 30,

.timing = {

.h_fp = 80,

.h_bp = 36,

.h_sw = 10,

.v_fp = 22,

.v_fpe = 1,

.v_bp = 15,

.v_bpe = 1,

.v_sw = 8,

},

.polarity = {

.rise_vclk = 0,

.inv_hsync = 1,

.inv_vsync = 1,

.inv_vden = 0,

},

};

static void lcd_cfg_gpio(struct platform_device *pdev)

{

int i;

for (i = 0; i < 8; i++) {

s3c_gpio_cfgpin(S5PV210_GPF0(i), S3C_GPIO_SFN(2));

s3c_gpio_setpull(S5PV210_GPF0(i), S3C_GPIO_PULL_NONE);

}

for (i = 0; i < 8; i++) {

s3c_gpio_cfgpin(S5PV210_GPF1(i), S3C_GPIO_SFN(2));

s3c_gpio_setpull(S5PV210_GPF1(i), S3C_GPIO_PULL_NONE);

}

for (i = 0; i < 8; i++) {

s3c_gpio_cfgpin(S5PV210_GPF2(i), S3C_GPIO_SFN(2));

s3c_gpio_setpull(S5PV210_GPF2(i), S3C_GPIO_PULL_NONE);

}

for (i = 0; i < 4; i++) {

s3c_gpio_cfgpin(S5PV210_GPF3(i), S3C_GPIO_SFN(2));

s3c_gpio_setpull(S5PV210_GPF3(i), S3C_GPIO_PULL_NONE);

}

/* mDNIe SEL: why we shall write 0x2 ? */

writel(0x2, S5P_MDNIE_SEL);

/* drive strength to max */

writel(0xaaaaaaaa, S5PV210_GPF0_BASE + 0xc);

writel(0xaaaaaaaa, S5PV210_GPF1_BASE + 0xc);

writel(0xaaaaaaaa, S5PV210_GPF2_BASE + 0xc);

writel(0x000000aa, S5PV210_GPF3_BASE + 0xc);

}

#define S5PV210_GPD_0_0_TOUT_0 (0x2)

#define S5PV210_GPD_0_1_TOUT_1 (0x2 << 4)

#define S5PV210_GPD_0_2_TOUT_2 (0x2 << 8)

#define S5PV210_GPD_0_3_TOUT_3 (0x2 << 12)

static int lcd_backlight_on(struct platform_device *pdev)

{

int err;

err = gpio_request(S5PV210_GPD0(3), "GPD0");

if (err) {

printk(KERN_ERR "failed to request GPD0 for "

"lcd backlight control\n");

return err;

}

gpio_direction_output(S5PV210_GPD0(3), 1);

s3c_gpio_cfgpin(S5PV210_GPD0(3), S5PV210_GPD_0_3_TOUT_3);

gpio_free(S5PV210_GPD0(3));

return 0;

}

static int lcd_backlight_off(struct platform_device *pdev, int onoff)

{

int err;

err = gpio_request(S5PV210_GPD0(3), "GPD0");

if (err) {

printk(KERN_ERR "failed to request GPD0 for "

"lcd backlight control\n");

return err;

}

gpio_direction_output(S5PV210_GPD0(3), 0);

gpio_free(S5PV210_GPD0(3));

return 0;

}

static int lcd_reset_lcd(struct platform_device *pdev)

{

int err;

err = gpio_request(S5PV210_GPH0(6), "GPH0");

if (err) {

printk(KERN_ERR "failed to request GPH0 for "

"lcd reset control\n");

return err;

}

gpio_direction_output(S5PV210_GPH0(6), 1);

mdelay(100);

gpio_set_value(S5PV210_GPH0(6), 0);

mdelay(10);

gpio_set_value(S5PV210_GPH0(6), 1);

mdelay(10);

gpio_free(S5PV210_GPH0(6));

return 0;

}

static struct s3c_platform_fb s5pv210_fb_data __initdata = {

.hw_ver = 0x62,

.nr_wins = 5,

.default_win = CONFIG_FB_S3C_DEFAULT_WINDOW,

.swap = FB_SWAP_WORD | FB_SWAP_HWORD,

.lcd = &wvga_s70,

.cfg_gpio = lcd_cfg_gpio,

.backlight_on = lcd_backlight_on,

.backlight_onoff = lcd_backlight_off,

.reset_lcd= lcd_reset_lcd,

};

在 static void __init smdkc110_machine_init(void)函数里修改

ifdef CONFIG_FB_S3C_LTE480WV(该宏定义在 1549 行) :

#ifdef CONFIG_FB_S3C_LTE480WV

s3cfb_set_platdata(&lte480wv_fb_data);

改成:

s3cfb_set_platdata(&s5pv210_fb_data);

#endif

(2)确认开机logo是否打开

为了检验LCD是否已正常工作,我们同时打开开机logo显示功能。这样只要开机能看到屏幕左上角的启动画面小企鹅,即可证明LCD已正常工作。

为了打开启动画面功能,需要在make menuconfig中做如下配置:

Device Drivers  --->

         Graphics support  ---> 

                   [*] Bootup logo  --->

                            [*]   Standard black and white Linux logo                                                 

            [*]   Standard 16-color Linux logo                                                        

            [*]   Standard 224-color Linux logo

15.在uboot那配置好后,检测ubantu的NFS和rootfs有没准备好,还有网络是否ping得通,都准备好启动就行了。

16.蜂鸣器修改(蜂鸣器一直响)

vim arch/arm/mach-s5pv210/mach-gec210.c
842 struct s3c_pwm_data pwm_data[] = {

843 {

844 #if 0

845 .gpio_no = S5PV210_GPD0(0),

846 .gpio_name = "GPD",

847 .gpio_set_value = S5PV210_GPD_0_0_TOUT_0,

848 }, {

849 #endif

 

17.让内核支持热插拔

General setup --->

[*] Configure standard kernel features (for small systems) --->

[*] Support for hot-pluggable devices

18.让内核支持USB设备

Device Drivers --->

[*] USB support --->

Support for Host-side USB-->

[*] USB verbose debug messages

[*] USB announce new devices

*** Miscellaneous USB options ***

[*] USB device filesystem (DEPRECATED)

[*] USB device class-devices (DEPRECATED) (NEW)

<*> USB Monitor

<*> EHCI HCD (USB 2.0) support

<*> USB Mass Storage support

SCSI device support --->

<*> SCSI device support

[*] Probe all LUNs on each SCSI device

[*] Block devices --->

<*> Low Performance USB Block driver

 

19.添加USB摄像头支持

Device Drivers -->

     <*>Multimedia support --->

          <*>Video For Linux

          <*>Video capture adapters --->

                <*>V4L USB devices --->

                       <*>USB Video Class

                              <*>UVC input events device support

 

20.TSC2007触摸屏驱动移植

Device Drivers -->

Input device spport-->

[*]Touchscreen driver

< >S3C touchscreen device //去掉S3C触摸屏驱动

<*>TSC2007 base touchscreens

23.修改arch/arm/mach-s5pv210/mach-gec210.c内容

$vi arch/arm/mach-s5pv210/mach-gec210.c

#include <linux/i2c/tsc2007.h>

#include <mach/irqs.h>

#include <plat/irqs.h>

#include <plat/gpio-cfg.h>

static int ts_get_pendown_state(void)

{

int val=0;

val=gpio_get_value(S5PV210_GPH1(6));

return val?0:1;

}

static struct tsc2007_platform_data tsc2007_info=

{

.model=2007,

.x_plate_ohms=180,

.get_pendown_state=ts_get_pendown_state,

};

 

修改i2c_board_info结构体,加入TS2007芯片的设备信息

static struct i2c_board_info i2c_devs2[] __initdata = {

{

#if defined(CONFIG_SMDKC110_REV03) || defined(CONFIG_SMDKV210_REV02)

/* The address is 0xCC used since SRAD = 0 */

I2C_BOARD_INFO("max8998", (0xCC >> 1)),

.platform_data = &max8998_pdata,

#else

/* The address is 0xCC used since SRAD = 0 */

I2C_BOARD_INFO("max8698", (0xCC >> 1)),

.platform_data = &max8698_pdata,

#endif

},

{

I2C_BOARD_INFO("ts2007",(0x48)),

.type="ts2007",

.platform_data=&tsc2007_info,

.irq=IRQ_EINT14,

},

};

修改drivers/input/touchscreen/tsc2007.c文件内容,在tsc2007_probe()函数中添加并修改以下内容。

添加部分

ts->client=client;

ts->irq = client->irq;

ts->input=input_dev;

client->flag & = ~ I2C_M_TEN;

修改部分


err = request_irq(ts->irq, tsc2007_irq, IRQF_TRIGGER_FALLING|IRQF_DISABLED,client->dev.driver->name, ts);

make //将arch/arm/boot/下的zImage拷贝到tftp的目录下(/tftpboot目录)

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值