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