Uživatelské nástroje

Nástroje pro tento web


navody:linuxove_jadro

Linuxové jádro

Překlad

parametry pro překlad první dva identifikují jaké nástroje pro překlad se mají použít (VUT FIT merlin)

CC=x86_64-linux-gcc CROSS_COMPILE=x86_64-linux- ARCH=um SUBARCH=x86_64

vyčístí přeložené věci

make mrproper

použije jako konfigurační soubor .config

make oldconfig

Různé

spuštění jádra s imagem a umid

./vmlinux umid=debian ubd0=./image.lenny64.ext3

mirror jádra na VUT FIT serveru merlin http://merlin.fit.vutbr.cz/mirrors/kernel.org/linux/kernel/v3.x/ vyhledávání ve zdrojovém kódě jádra http://lxr.free-electrons.com/ident

Moduly

načtení modulu

mkdir -p /lib/modules/<verze jádra>/misc
cp <soubor.ko> /lib/modules/<verze jádra>/misc/<soubor.ko>
depmod -a
modprobe <soubor>

vypíše moduly

lsmod

vypíše informace o modulu

modinfo <modul>
modinfo </cesta/k/modulu.ko>

smaže modul

rmmod <modul>

Příklady kodu

ukázka makefile pro překlad jaderného modulu

# Makefile for mod-2.6.c
 
NAME = cdev-test
 
obj-m := $(NAME).o
 
default: $(NAME).c
	make -C ./linux-stable SUBDIRS=$(PWD) modules

překlad pro architekturu x86_64

ARCH=um SUBARCH=x86_64 make

modul, který vytvoří soubor /proc/test, který vypíše aktuální čas a datum

#include <linux/init.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <linux/time.h>
 
MODULE_LICENSE("GPL");
 
 
static struct proc_dir_entry * entry; /*struktura pro file v proc*/
 
 
static int show(struct seq_file *m, void *p)
{
    struct timespec s_timespec;
    struct tm s_tm;
 
    getnstimeofday(&s_timespec);
    time_to_tm(s_timespec.tv_sec, 0, &s_tm);
 
    seq_printf(m, "%ld-%02d-%02dT%02d:%02d:%02dZ\n", 1900+s_tm.tm_year, s_tm.tm_mon+1,
               s_tm.tm_mday, s_tm.tm_hour, s_tm.tm_min, s_tm.tm_sec);
 
    return 0;
}
 
static int my_open(struct inode *inode, struct file *file)
{
	return single_open(file, show, NULL);
};
 
 
static struct file_operations ct_file_ops =
{
	.owner   = THIS_MODULE,
	.open    = my_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = single_release
};
 
static int ct_init(void)
{
    entry = create_proc_entry("test",0, NULL);
    if (entry)
        entry->proc_fops = &ct_file_ops;
    return 0;
}
 
static void __exit ct_exit(void)
{
    remove_proc_entry("test", NULL);
}
 
module_init(ct_init);
module_exit(ct_exit);

modul, který vytvoří znakové zařízení test, které při zápisu počítá počet mezer a nových řádků a při čtení vypíše větu: X words written\n.

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <linux/slab.h>
 
MODULE_LICENSE("GPL");
 
    /* alloc major number from 120-127 */
#define MAJORNUMBER 120
 
#define DEV_NAME "test"
#define OUTPUT_MAX_SIZE 50
 
dev_t dev;
struct cdev *test_cdev;
 
int my_word_count = 0;
char my_output [OUTPUT_MAX_SIZE];
int my_output_size = 0;
int my_position = 0;
 
static ssize_t test_read(struct file *f, char *ch, size_t s, loff_t *o)
{
    int count_to_end = my_output_size - my_position;
    int result_size = s >= count_to_end ? count_to_end : s;
 
    printk(KERN_DEBUG "jsem ve funkci test_read\n");
 
    if(my_position < my_output_size)
    {
        if(copy_to_user(ch, my_output+my_position, result_size))
        {
            return -EFAULT;
        }
        my_position += result_size;
 
        return result_size;
    }
 
    return 0;
}
 
static ssize_t test_write(struct file *f, const char *ch, size_t s, loff_t *o)
{
    int i;
    char *buffer;
    printk(KERN_DEBUG "jsem ve funkci test_write\n");
 
    if((buffer = kmalloc(s, GFP_KERNEL)) == NULL)
    {
        return -ENOMEM;
    }
 
    if(copy_from_user(buffer, ch, s))
    {
        kfree(buffer);
        return -EFAULT;
    }
 
    for(i=0; i < s; i++)
    {
        if(buffer[i] == ' ' || buffer[i] == '\n')
        {
            my_word_count++;
        }
    }
 
    kfree(buffer);
    return s;
}
 
static int test_open(struct inode *i, struct file *f)
{
    printk(KERN_DEBUG "jsem ve funkci test_open\n");
 
    my_output_size = snprintf(my_output, OUTPUT_MAX_SIZE, "%d words written\n", my_word_count);
    my_position = 0;
 
    return 0;
}
 
static int test_release(struct inode *i, struct file *f)
{
    printk(KERN_DEBUG "jsem ve funkci test_release\n");
 
    return 0;
}
 
static loff_t test_lseek(struct file *file, loff_t offset, int orig)
{
    printk(KERN_DEBUG "jsem ve funkci test_lseek\n");
 
    my_position += offset;
 
    return my_position;
}
 
static struct file_operations test_fops =
{
    .owner = THIS_MODULE,
    .read = test_read,
    .write = test_write,
    .open = test_open, 
    .release = test_release,
    .llseek = test_lseek,
};
 
static int __init cdev_test_init(void)
{
    dev = MKDEV(MAJORNUMBER, 0);
 
    register_chrdev_region(dev, 1, DEV_NAME);
 
    test_cdev = cdev_alloc();
    test_cdev->owner = THIS_MODULE;
    test_cdev->ops = &test_fops;
 
    /* get entry in /sysfs */
    kobject_set_name(&test_cdev->kobj, DEV_NAME);
 
    cdev_add(test_cdev, dev, 1);
 
    return 0; 
}
 
static void __exit cdev_test_exit(void)
{
    cdev_del(test_cdev);
 
    unregister_chrdev_region(dev, 1);
}
 
module_init(cdev_test_init);
module_exit(cdev_test_exit);

zařízení je možné přidat příkazem

mknod /dev/test c 120 0

Systémová volání

tabulka systémových volání pro architekturu x86 se nachází v adresáři arch/x86/syscalls/ v souborech syscall_<architektura>.tbl (jádro 3.4.41).

Příklad

systémové volání, které vrátí součet dvou jeho argumentů:

do arch/x86/syscalls/syscall_32.tbl přidat řádek

223	i386	add	sys_add

do arch/x86/syscalls/syscall_64.tbl přidat řádek

312	64	add	sys_add

do include/linux/syscalls.h přidat řádek

asmlinkage long sys_add(int number1, int number2);

do kernel/Makefile přidat řádek

obj-y += add.o

vytvořit soubor kernel/add.c

#include <linux/kernel.h>
#include <linux/linkage.h>
 
asmlinkage long sys_add(int number1, int number2)
{
    return number1 + number2;
}

uml_mconsole

instalace Fedora

su -c "yum install uml_utilities"

spuštění s umid jádra

uml_mconsole <umid>
navody/linuxove_jadro.txt · Poslední úprava: 2013/04/30 09:43 autor: jules