Padajici driver tty na 64 bit systemu
Petr Sremr
petr.sremr na hwserver.cz
Středa Listopad 18 10:17:02 CET 2009
Zdavim,
snazim se napsat modul do jadra, ktery bude simulovat seriovy port. A to
podobne jako se chovaji prevodniky USB-RS232, ktere vytvori zarizeni napr.
/dev/ttyUSB0. Prave z techto driveru jsem vysel. U me to ma byt zarizeni
/dev/ttyVSP0.
Na dvou 32 systemech my driver funguje dobre, alespon ta cast, kterou mam
hotovou. Bez problemu se pripojim minicomem a loguju zapisovana data.
(viz. prilozeny vypis dmesg.ok) Jde o systemy:
- Ubuntu s distribucnim jadrem 2.6.31-14-generic, gcc ver. 4.4.1.
Stejnym gcc
je kompilovano i jadro
- Debian s distribucnim jadrem 2.6.26-19, gcc ver. 4.3.2. Jadro je
kompilovano
gcc ver. 4.1.3
Ale na 64 bit systemu s dvojjadrovym procesorem Intel(R) Core(TM)2 CPU
E8500 mi pri otevreni portu minicomem driver spadne a system hlasi OOPS
(viz. prilozeny vypis dmesg.error). Jde o system:
- Ubuntu s distribucnim jadrem 2.6.26-25, gcc ver. 4.2.4. Stejnym gcc je
kompilovano i jadro
Prikladam hodne primitivni a orezany zdrojak ovladace vcetne makefilu a
debugovaci hlasky (trochu zkracene).
Prosim, poradte mi co delam spatne na tom 64 bitu?
Dekuju.
Petr Sremr
-----------------------------------------------------------------------------
-- dmesg.ok
-----------------------------------------------------------------
[ 346.487093] MYVSP driver v1.0myvsp: myvsp_init
[ 352.577278] myvsp: myvsp_open
[ 352.577320] myvsp: myvsp_ioctl
[ 352.577357] myvsp: myvsp_ioctl
[ 352.577364] myvsp: myvsp_tiocmget
[ 352.577371] myvsp: myvsp_tiocmset
[ 352.577377] myvsp: myvsp_ioctl
[ 352.577453] myvsp: myvsp_ioctl
[ 352.611779] myvsp: myvsp_tiocmget
[ 352.611789] myvsp: myvsp_ioctl
[ 353.614228] myvsp: myvsp_tiocmget
[ 353.614285] myvsp: myvsp_ioctl
[ 354.615673] myvsp: myvsp_tiocmget
[ 354.615684] myvsp: myvsp_ioctl
[ 358.788300] myvsp: myvsp_write
[ 358.788311] 61
[ 358.788316]
[ 358.788325] myvsp: myvsp_tiocmget
[ 358.788333] myvsp: myvsp_ioctl
[ 359.788221] myvsp: myvsp_write
[ 359.788236] 61
[ 359.788241]
[ 359.788249] myvsp: myvsp_tiocmget
[ 359.788256] myvsp: myvsp_ioctl
[ 359.796481] myvsp: myvsp_write
[ 359.796489] 73
[ 359.796493]
[ 374.312311] myvsp: myvsp_tiocmget
[ 374.312336] myvsp: myvsp_ioctl
[ 375.313056] myvsp: myvsp_tiocmget
[ 378.316892] myvsp: myvsp_tiocmget
[ 378.316900] myvsp: myvsp_ioctl
[ 379.540319] myvsp: myvsp_ioctl
[ 379.541010] myvsp: myvsp_close
-----------------------------------------------------------------------------
-- dmesg.err
----------------------------------------------------------------
[ 264.737770] MYVSP driver v1.0myvsp: myvsp_init
[ 274.104918] myvsp: myvsp_open
[ 274.104924] myvsp: myvsp_ioctl
[ 274.104927] myvsp: myvsp_ioctl
[ 274.104928] myvsp: myvsp_tiocmget
[ 274.104929] myvsp: myvsp_tiocmset
[ 274.104930] myvsp: myvsp_ioctl
[ 274.104942] myvsp: myvsp_ioctl
[ 274.104943] myvsp: myvsp_ioctl
[ 274.115982] myvsp: myvsp_tiocmget
[ 274.115997] Unable to handle kernel NULL pointer dereference at
0000000000000000 RIP:
[ 274.115999] [<0000000000000000>]
[ 274.116002] PGD 1f6844067 PUD 1fc25f067 PMD 0
[ 274.116004] Oops: 0010 [1] SMP
[ 274.116005] CPU 1
[ 274.116006] Modules linked in: myvsp af_packet i915 drm rfcomm l2cap
bluetooth
tun vboxnetadp vboxnetflt vboxdrv ppdev ipv6 cpufreq_powersave
cpufreq_stats
cpufreq_userspace cpufreq_ondemand cpufreq_conservative freq_table video
output
container sbs sbshc dock battery iptable_filter ip_tables x_tables ac lp
snd_hda_intel snd_pcm_oss snd_mixer_oss snd_pcm snd_page_alloc snd_hwdep
snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi snd_seq_midi_event
joydev
snd_seq snd_timer parport_pc iTCO_wdt iTCO_vendor_support evdev shpchp
pci_hotplug parport snd_seq_device intel_agp snd pcspkr soundcore button
reiserfs sg sr_mod cdrom sd_mod usbhid hid usb_storage libusual ata_piix
pata_jmicron ata_generic pata_acpi libata scsi_mod r8169 ehci_hcd uhci_hcd
usbcore thermal processor fan fbcon tileblit font bitblit softcursor fuse
[ 274.116039] Pid: 7287, comm: minicom Not tainted 2.6.24-25-generic #1
[ 274.116040] RIP: 0010:[<0000000000000000>] [<0000000000000000>]
[ 274.116041] RSP: 0018:ffff8101fc24f9e0 EFLAGS: 00010246
[ 274.116042] RAX: ffff8102246fea00 RBX: ffff8102266e6000 RCX:
0000000000000003
[ 274.116044] RDX: ffff810219e3d200 RSI: 0000000000000246 RDI:
ffff8102266e6000
[ 274.116045] RBP: 0000000000000000 R08: 0000000000000000 R09:
0000000000000004
[ 274.116046] R10: 0000000000000004 R11: 0000000000000246 R12:
0000000000000001
[ 274.116047] R13: ffff81022779d3c0 R14: ffff8101fc24faf8 R15:
0000000000000104
[ 274.116048] FS: 00007f3fa43ae6e0(0000) GS:ffff810228001800(0000)
knlGS:0000000000000000
[ 274.116050] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 274.116051] CR2: 0000000000000000 CR3: 00000001f6805000 CR4:
00000000000006e0
[ 274.116052] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 274.116053] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
0000000000000400
[ 274.116054] Process minicom (pid: 7287, threadinfo ffff8101fc24e000,
task ffff81021a7fc7f0)
[ 274.116055] Stack: ffffffff8039f63d 0000000000000086
ffff81022779d3c0 ffff8102266e6000
[ 274.116058] 0000000000000000 ffff8102266e6018 ffffffff8039a5e6
0000000000000008
[ 274.116060] ffff81022779d3c0 0000000000000003 0000000000000003
0000000000000000
[ 274.116062] Call Trace:
[ 274.116066] [<ffffffff8039f63d>] normal_poll+0x15d/0x190
[ 274.116069] [<ffffffff8039a5e6>] tty_poll+0x86/0xa0
[ 274.116072] [<ffffffff802c1d88>] do_select+0x2e8/0x580
[ 274.116078] [<ffffffff802c25b0>] __pollwait+0x0/0x130
[ 274.116082] [<ffffffff802340a0>] default_wake_function+0x0/0x10
[ 274.116085] [<ffffffff802340a0>] default_wake_function+0x0/0x10
[ 274.116088] [<ffffffff802340a0>] default_wake_function+0x0/0x10
[ 274.116091] [<ffffffff802340a0>] default_wake_function+0x0/0x10
[ 274.116096] [<ffffffff802cb667>] mntput_no_expire+0x27/0xb0
[ 274.116099] [<ffffffff802bd590>] __link_path_walk+0x210/0xe90
[ 274.116102] [<ffffffff8023e35e>] printk+0x4e/0x60
[ 274.116108] [<ffffffff80234663>] __wake_up+0x43/0x70
[ 274.116111] [<ffffffff802c2229>] core_sys_select+0x209/0x300
[ 274.116117] [<ffffffff802bf619>] open_namei+0x89/0x710
[ 274.116121] [<ffffffff8046b740>] do_page_fault+0x1d0/0x840
[ 274.116125] [<ffffffff802b134c>] do_filp_open+0x1c/0x50
[ 274.116130] [<ffffffff802c27b1>] sys_select+0xd1/0x1c0
[ 274.116134] [<ffffffff8020c39e>] system_call+0x7e/0x83
[ 274.116138]
[ 274.116139]
[ 274.116139] Code: Bad RIP value.
[ 274.116140] RIP [<0000000000000000>]
[ 274.116141] RSP <ffff8101fc24f9e0>
[ 274.116142] CR2: 0000000000000000
[ 274.116144] ---[ end trace 210586c307da1d97 ]---
-----------------------------------------------------------------------------
-- Makefile
-----------------------------------------------------------------
obj-m := myvsp.o
myvsp-objs := vsp_serial.o
KDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ *.ko *.mod.c Module.* *.order
-----------------------------------------------------------------------------
-- vsp_serial.c
-------------------------------------------------------------
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <asm/uaccess.h>
#define DRIVER_VERSION "v1.0"
#define DRIVER_AUTHOR "Author <name na domain.com>"
#define DRIVER_DESC "MYVSP driver"
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
#define MYVSP_TTY_MAJOR 240
#define MYVSP_TTY_MINORS 4
static int myvsp_open(struct tty_struct *tty, struct file *file)
{
printk("myvsp: %s\n", __FUNCTION__);
return 0;
}
static void myvsp_close(struct tty_struct *tty, struct file *file)
{
printk("myvsp: %s\n", __FUNCTION__);
}
static int myvsp_write(struct tty_struct *tty,
const unsigned char *buffer, int count)
{
int i;
printk(KERN_DEBUG "myvsp: %s ", __FUNCTION__);
for (i = 0; i < count; ++i)
printk(KERN_DEBUG "%02x ", buffer[i]);
printk(KERN_DEBUG "\n");
return count;
}
static int myvsp_write_room(struct tty_struct *tty)
{
// printk("myvsp: %s\n", __FUNCTION__);
return 255;
}
static void myvsp_set_termios(struct tty_struct *tty, struct ktermios *old)
{
printk("myvsp: %s\n", __FUNCTION__);
}
static int myvsp_tiocmget(struct tty_struct *tty, struct file *file)
{
printk("myvsp: %s\n", __FUNCTION__);
return 0;
}
static int myvsp_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
printk("myvsp: %s\n", __FUNCTION__);
return 0;
}
static int myvsp_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
printk("myvsp: %s\n", __FUNCTION__);
return 0;
}
static struct tty_operations serial_ops = {
.open = myvsp_open,
.close = myvsp_close,
.write = myvsp_write,
.write_room = myvsp_write_room,
.set_termios = myvsp_set_termios,
.tiocmget = myvsp_tiocmget,
.tiocmset = myvsp_tiocmset,
.ioctl = myvsp_ioctl,
};
static struct tty_driver *myvsp_tty_driver;
static int __init myvsp_init(void)
{
int retval;
int i;
myvsp_tty_driver = alloc_tty_driver(MYVSP_TTY_MINORS);
if (!myvsp_tty_driver)
return -ENOMEM;
myvsp_tty_driver->owner = THIS_MODULE;
myvsp_tty_driver->driver_name = "myvsp";
myvsp_tty_driver->name = "ttyVSP";
myvsp_tty_driver->major = MYVSP_TTY_MAJOR,
myvsp_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
myvsp_tty_driver->subtype = SERIAL_TYPE_NORMAL,
myvsp_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
myvsp_tty_driver->init_termios = tty_std_termios;
myvsp_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
CLOCAL;
tty_set_operations(myvsp_tty_driver, &serial_ops);
retval = tty_register_driver(myvsp_tty_driver);
if (retval) {
printk(KERN_ERR "myvsp: failed to register tty driver");
put_tty_driver(myvsp_tty_driver);
return retval;
}
for (i = 0; i < MYVSP_TTY_MINORS; ++i)
tty_register_device(myvsp_tty_driver, i, NULL);
printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
printk("myvsp: %s\n", __FUNCTION__);
return retval;
}
static void __exit myvsp_exit(void)
{
int i;
for (i = 0; i < MYVSP_TTY_MINORS; ++i)
tty_unregister_device(myvsp_tty_driver, i);
tty_unregister_driver(myvsp_tty_driver);
printk("myvsp: %s\n", __FUNCTION__);
}
module_init(myvsp_init);
module_exit(myvsp_exit);
Další informace o konferenci Linux