How to compile the driver statically into the kernel.

Source: Internet
Author: User
Tags strcmp

How to compile the driver statically into the kernel.

Development boards used: TQ210 's s5pv210 Development Board

Kernel version: linux-3.8.3

Compiler: ARM-LINUX-GCC 4.4.3

Relevant download Address:

First, ready to properly compile the source code to guide the Development Board (

How to achieve the correct configuration and compile a good kernel source of the link address; http://blog.csdn.net/girlkoo/article/details/8719828)

Second, under the driver directory of the kernel source kernel folder, create the Led_arm folder
mkdir Drivers/led_arm
C. Copy the driver of "led drive experiment" to the Led_arm directory (see the previous LED driver blog for details)

Copy the led.c below the folder

The following is the writing of the LED.C driver

#include <linux/init.h>

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <asm/gpio.h>

#include <plat/gpio-cfg.h>

#define LED_ON 0x100001

#define Led_off 0x100002

Hardware Resources

struct led_resource{

int Gpio; Gpio Port

Char *name; The device name. Show in/proc/devices/

};

static struct Led_resource led_info[] = {

[0] ={

. Gpio = s5pv210_gpc0 (3),

. Name = "LED1"

},

[1] ={

. Gpio = s5pv210_gpc0 (4),

. Name = "LED2"

}

};

Software Management

static dev_t Dev; Device number

struct Cdev led_cdev;//Creating a device class

static struct class *cls; To create a device class pointer

static int Led_open (struct inode *inode, struct file *file)

{

PRINTK ("%s\n", __func__);

return 0;

}

static int led_close (struct inode *inode, struct file *file)

{

PRINTK ("%s\n", __func__);

return 0;

}

static int led_ioctl (struct inode *inode, struct file *file,

unsigned int cmd, unsigned long arg)

static int led_ioctl (struct file *file,

unsigned int cmd, unsigned long arg)

{

int kindex;

Copy data to kernel space

Copy_from_user (&kindex,

(int *) arg, sizeof (KINDEX));

Switch (CMD) {

Case LED_ON:

Gpio_set_value (led_info[kindex-1].gpio,1);

Break

Case Led_off:

Gpio_set_value (led_info[kindex-1].gpio,0);

Break

Default

return-1;

}

return 0;

}

static struct File_operations Led_fops = {

. Owner = This_module,

. open = Led_open,

. Release = Led_close,

. Unlocked_ioctl = Led_ioctl

};

static int led_init (void)

{

int i;

1. Assigning Character devices

Alloc_chrdev_region (&dev, 0, 1, "LEDs");

2. Initialize the character device

Cdev_init (&led_cdev, &led_fops);

3. Registering a character device

Cdev_add (&led_cdev, Dev, 1);

4. Add a Device file

4.1 Main device class

The result is: sys/class/myleds

CLS = Class_create (This_module, "myleds");

4.2 Creating a Device file

Device_create (CLS, null, dev, null, "myleds");

5. Request a GPIO Resource

for (i=0; i < array_size (led_info); i++)

{

Gpio_request (Led_info[i].gpio, led_info[i].name);

Gpio_direction_output (Led_info[i].gpio, 0);

}

return 0;

}

static void Led_exit (void)

{

int i;

Deleting device files and device classes

Device_destroy (CLS, Dev);

Class_destroy (CLS);

1. Uninstalling Character Device objects

Cdev_del (&led_cdev);

2. Releasing Gpio resources

for (i=0; i< array_size (Led_info); i++)

{

Gpio_set_value (Led_info[i].gpio, 0);

Gpio_free (Led_info[i].gpio);

}

3. Release the device number

Unregister_chrdev_region (Dev, 1);

}

Module_init (Led_init);

Module_exit (Led_exit);

Module_license ("GPL");

Since Kconfig is the configuration menu corresponding to the kernel. If you want to add a new driver to the kernel source, you can modify the Kconfig to add to our drive configuration menu, so there is a way to choose our driver.

Each config menu item must have a type definition, bool: Boolean type, TriState: Built-in, module, remove, String: String, Hex: 16, Integer: Integer

For example, config Hello_module
BOOL "Hello Test module"

BOOL type can only be selected or unchecked, tristate type of menu items are compiled into kernel module options, if you choose to compile into a kernel module, you will generate a config_hello_module=m configuration in. CONFIG, if you choose built-in, is to compile directly into the kernel effect, a config_hello_module=y configuration is generated in. config.

Below are the following actions under Led_arm:

① Add a Kconfig file

[CPP] view plain copy

1. config myled

2. TriState "Myled"

3. Default N

4. Help

5. This is a LED driver


② Add a Makefile

[CPP] view plain copy

1. obj-$ (config_ledtest) +=LED.O


Iv. Add the driver support options we have written to the kernel configuration menu.
Go back to drivers and modify the Kconfig file in the drivers directory

Add a statement on the last line

[CPP] view plain copy

1. Source "Drivers/led_arm/kconfig"


V. Modification of drivers/makefile files
Add the following statement
obj-$ (config_ledtest) +=led_arm/
Six, reconfigure the kernel
Enter in the source root directory
#make Menuconfig
At the end of the menu, you can see our newly added myled option. Here you can choose the type of kernel to compile, * for static compilation drive to the kernel, m to compile the driver into a module driver, here we will drive statically compiled into the kernel.

Make Zimage

Download the arch/arm/boot/kernel/zimage to the Development Board for testing.

The following is the preparation of the LED_TEST.C program;

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#define LED_ON 0x100001

#define Led_off 0x100002

int main (int argc, char *argv[])

{

int FD;

int cmd;

if (ARGC < 3) {

printf ("usage:\n%s <on|off> <1|2>\n", argv[0]);

return-1;

}

Fd= Open ("/dev/myleds", O_RDWR);

if (FD < 0) {

printf ("Open LED device failed. \ n ");

return-1;

}

Cmd= Strtoul (argv[2], NULL, 10);

if (!strcmp (argv[1]), "on")

IOCTL (FD,LED_ON,&CMD);

else if (!strcmp (argv[1], "off"))

IOCTL (FD,LED_OFF,&CMD);

Close (FD);

return 0;

}

Summary of issues:

The following error occurs if the kernel used in the compilation process is a kernel version after linux-2.6.36 and the IOCTL is used in it.

Error:unknown field ' IOCTL ' specified in initializer

The problem is that the original IOCTL was removed after the 2.6.36 kernel and two new members were added, so an error occurred

Long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

Long (*compat_ioctl) (struct file *, unsigned int, unsigned long);

So the modification needs to be within the file_operations of the driver's source file. The IOCTL is changed to. compat_ioctl

OK, compile through, warn me to ignore

Kernel 2.6.35 and previous versions of the struct file_operations altogether had 3 IOCTL:

Ioctl,unlocked_ioctl and Compat_ioctl

It's only Unlocked_ioctl and Compat_ioctl.

In kernel 2.6.36, the IOCTL function pointers in struct file_operations have been completely removed and replaced by Unlocked_ioctl.

But the biggest effect after the pointer function has changed is that the inode is missing from the parameter,

In kernel 2.6.36, the IOCTL function pointers in struct file_operations have been completely removed and replaced by Unlocked_ioctl.

This pointer function changed after the biggest effect is the parameter is less inode, but this is not a problem, because the user program in the IOCTL corresponding system call interface does not change, so the user program does not need to change, everything to the kernel processing, if you want to unlocked_ The following methods can be used to obtain information such as Inode in the IOCTL:

struct Inode *inode = file->f_mapping->host;

struct Block_device *bdev = inode->i_bdev;

struct Gendisk *disk = bdev->bd_disk;

fmode_t mode = file->f_mode;

struct Backing_dev_info *bdi;

Parameter change reference file_operations this structure, the most important of which is the cmd parameter, this change is very large.

For example, the parameter settings written in our driver:

IOCTL parameters used prior to Linux-2.6.36

static int led_ioctl (struct inode *inode, struct file *file,

unsigned int cmd, unsigned long arg)

Parameters used after Linux-2.6.36

static int led_ioctl (struct file *file,

unsigned int cmd, unsigned long arg)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.