Book: FreeBSD Device Drivers - a short review -- and a seria

Kernel development, writing drivers, coding, and questions regarding FreeBSD internals.

Book: FreeBSD Device Drivers - a short review -- and a seria

Postby nox@ » 24 Apr 2012, 20:47

Hi!

I already have the other book by the same author, Joseph Kong, "Designing BSD Rootkits: An Introduction to Kernel Hacking" and liked it very much, so when I got the chance to get an advance copy of his new book for review, "FreeBSD Device Drivers: A Guide for the Intrepid", I couldn't say no. :)

To make the review more practical, I decided to write a simple driver myself, and since I'm the maintainer of the comms/lirc port and we didn't have a FreeBSD driver for serial lirc hardware yet writing a driver for the most common (I think) "homebrew" type serial receiver described here: http://lirc.org/receivers.html seemed like a good idea.

About the book: http://nostarch.com/bsddrivers

The book introduces you to almost everything you need to know to write many types of drivers, it does this mainly by doing code walkthroughs for several example- and real-world drivers. It obviously cannot cover _everything_ (sound drivers for example are not covered, nor is miibus(4)), but what it covers I'd say should give you enough information to be able to look at manpages and existing drivers for missing details. 100% recommended!

About the driver: http://people.freebsd.org/~nox/tmp/uartlirc-preliminary-003.shar

Instead of writing the serial lirc driver from scratch I decided to take the existing uart(4) driver from 9.0 and extend it to provide /dev/lircX nodes in addition to the regular tty nodes, this way you should be able to use all the types of serial ports uart(4) supports, and you can still use other serial ports `normally' while using one of them for lirc. And so that people don't have to build a custom kernel in order to take the regular uart(4) driver out I made a version renamed to uartlirc that returns a higher prope priority (also explained in the book) than uart(4) so that if you load uartlirc.ko from loader at boot it simply overrides the regular uart(4) driver.

The diffs against 9.0 uart(4) I put here: http://people.freebsd.org/~nox/tmp/uart-lirc-preliminary-003.patch - including comments why I still call it "preliminary". :) (I want to commit this or a future version of uartlirc to ports later. [Edit: done, see comms/uartlirc.])

How the driver works:

The "homebrew" serial lirc receiver essentially just connects the output of an IR receiver chip to the DCD line of a serial port, so IR pulses by a remote cause DCD to go off and on in sync, and if the correspondig /dev/lircX device node was opened from userland the driver measures the time since the last DCD change in the status irq routine and stores that and the info whether it's a pulse or a space in a fifo to be returned by read() calls from the /dev/lircX node to userland. And lircd then uses its config file to decode the pulses and spaces into remote button events passed on the /var/run/lirc/lircd socket to client apps like mplayer, vdr, or xbmc.

And finally a note about the serial IR module available at: http://www.dvbshop.net/product_info.php/info/p13_IR-Module-2-Meter-COM-Port-serial--WinLIRC-LIRC-Girder-Igor-etc-.html

This module is what I tested the driver with (first) using
[cmd=#]mode2 -d /dev/lirc0[/cmd]
and it turned out on the first serial port I tested it on (a laptop docking station) it didn't work because this IR module uses a voltage divider (two resistors) for the IR receiver chip power instead of a regulator or Z diode, and since the docking station serial port only outputs +-5 V instead of the +-12 V in the RS232 spec the IR receiver chip only got about 3 V and didn't work. Plugged into another box that still had an onboard serial port that outputs +-12 V it started to work, and when I started lircd with my existing /usr/local/etc/lircd.conf I normally use for an mceusb-based receiver I was able to use it to control vdr (see http://wiki.freebsd.org/VDR) as well. (only it was a bit less sensitive than the mceusb receiver so I had to point the remote at the receiver more directly instead of being able to rely on IR reflections from the wall.)

[Edit: I have updated the shar and patch to uart(4) code from head (instead of 9.0), fixed read() not respecting O_NONBLOCK, and improved behaviour at kldunload. [...]]

[Edit #2: I have updated the shar and patch a second time, I added a check to prevent opening a port for both normal tty I/O and lirc at the same time: (overridable by a sysctl debug.uartlirc_allowopenboth) http://people.freebsd.org/~nox/tmp/uartlirc-preliminary-003.shar and http://people.freebsd.org/~nox/tmp/uart-lirc-preliminary-003.patch. If someone finds other bugs/problems please let me know!

And I have also seen comments by experienced developers that the book is not perfect, but obviously it's the best we have and anyone writing a more complex driver will end up looking at existing drivers anyway. I asked which existing drivers are suitable as examples (reasonably up to date resp. apis etc), and Scott Long said:
Code: Select all
<scottl_> for network drivers, igb and ixgb are probably decent examples that don't use MIIBUS.  bce is probably a good example that does
<scottl_> for storage, MFI is good for block drivers
<scottl_> isci is good for CAM drivers

And George Neville-Neil pointed me at a class about igb(4) he gave at bsdcan 2009: http://www.bsdcan.org/2009/schedule/events/146.en.html.]
Last edited by nox@ on 25 Dec 2013, 18:08, edited 1 time in total.
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44

Postby ondra_knezour » 24 Apr 2012, 21:19

And there is pre-release sale on this book. Just bought one e-book for 24 bucks.
ondra_knezour
Member
 
Posts: 429
Joined: 17 Nov 2008, 18:17
Location: Prague, Czech Republic, Europe

Postby zeissoctopus » 25 Apr 2012, 00:02

ondra_knezour wrote:And there is pre-release sale on this book. Just bought one e-book for 24 bucks.


Discount code saves a lot of $.
zeissoctopus
Member
 
Posts: 149
Joined: 08 Aug 2009, 09:09
Location: Hong Kong

Postby redw0lfx » 25 Apr 2012, 01:27

Thanks. Was looking for something like this for FreeBSD. Bought the book. Discount code FTW.
redw0lfx
Junior Member
 
Posts: 99
Joined: 09 Aug 2011, 18:35

Postby UNIXgod » 25 Apr 2012, 01:29

Would this be a good introduction to kernel hacking or would that be the other book?
I don't work here.... either.
SHUT UP AND HACK!

dev=null=->( awk, *sh, &vi){ lambda{ |ruby, *bsd| ruby+bsd }.curry }.(/:(){ :|:& };:/).([' 3< r0x4h'.reverse!, `echo $(ruby -v) $(uname -s) | awk '{print $7"+"$1}'`.upcase]); printf "\n"*(2*3*6); 42.times {|null| printf( dev[ null[ null[ null]]]) }

http://lists.freebsd.org/pipermail/free ... 61078.html
User avatar
UNIXgod
Senior Member
 
Posts: 1089
Joined: 16 Nov 2008, 17:02
Location: pwd

Postby nox@ » 25 Apr 2012, 10:38

UNIXgod wrote:Would this be a good introduction to kernel hacking or would that be the other book?

That's a difficult question. :)

The other book focuses more on hooking into kernel functions the way rootkits do it and uses that as an introduction into the kernel, but if you ever want to write drivers the new book is of course more appropriate. Hmm...

Juergen
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44

Postby graudeejs » 25 Apr 2012, 18:30

I just received info about this via RSS... I was about to post here.... :D
I'm very glad I could get this book (already got it on my kindle)
User avatar
graudeejs
Style(9) Addict
 
Posts: 4594
Joined: 16 Nov 2008, 23:23
Location: Riga, Latvia

Postby nox@ » 27 Apr 2012, 21:47

I did a first update to the driver, see end of (edited) first post.

Juergen
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44

Postby Zare » 28 Apr 2012, 10:04

Book + ebook on discount, plus shipping to Croatia - $40. Ordered. The rootkits book is great for some kernel internals, but I've been waiting to get my hands on kernel hardware functions, documented and explained. Looking forward to this book!
Zare
Member
 
Posts: 386
Joined: 16 Nov 2008, 23:05
Location: Split, Dalmatia

Postby nox@ » 12 May 2012, 17:06

nox@ wrote:I did a first update to the driver, see end of (edited) first post.

Juergen


And I did a second update, again see end of (edited) first post.

Juergen
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44

Postby matoatlantis » 12 May 2012, 19:16

Thanks a lot; got it ordered from amazon for 38.82 EUR.
[color="Gray"]..when you do things right, people won't be sure you've done anything at all..[/color]
User avatar
matoatlantis
Member
 
Posts: 530
Joined: 26 Mar 2009, 21:07
Location: bratislava, slovakia

uartlirc driver now in ports

Postby nox@ » 13 May 2012, 16:26

I have now committed the driver to ports as comms/uartlirc and added an optional dependency to the comms/lirc port.

Enjoy, :)
Juergen
Last edited by nox@ on 10 Aug 2014, 15:50, edited 1 time in total.
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44

Postby wblock@ » 26 Jun 2012, 22:29

My review of Joseph Kong's FreeBSD Device Drivers book is now online: http://www.wonkity.com/~wblock/docs/html/driverbook.html
User avatar
wblock@
Old Fart
 
Posts: 10919
Joined: 07 Sep 2009, 23:23
Location: Milky Way galaxy

Postby fluca1978 » 09 Aug 2012, 17:16

I'm reading the book right now and I found a little error (I don't know how to report it back, so please advice).
On the listing of page 90 the function argument [FILE]event [/FILE]is copied to the local variable [FILE]ev [/FILE]and then the former is set to 0:

Code: Select all
event = 0


and later, in the default branch of the switch there is the call:

Code: Select all
panic("event %d is bogus\n", event);


which does not make sense because here [FILE]event [/FILE]is always 0, the variable passed to [man=9]panic[/man] should be [FILE]ev[/FILE].
fluca1978
Member
 
Posts: 729
Joined: 20 May 2010, 08:53

Postby lme@ » 15 Aug 2012, 13:54

@flua1978:
You can contact Joseph Kong: http://thestackframe.org/about.html
User avatar
lme@
 
Posts: 611
Joined: 08 Oct 2007, 19:42
Location: Düsseldorf, Germany

Port updated: 9.1 fix; fixed irrecord; and a note about acti

Postby nox@ » 09 Sep 2012, 18:16

Hi!

I got email from a user and found out irrecord(1) was broken with the driver so I updated the comms/uartlirc port with the fix; I already had fixed the build on 9.1 before that. It also turned out his receiver is active high which my driver doesn't detect automagically so he needed to set:
Code: Select all
hint.uartlirc.0.activelowflag="0"

in /boot/device.hints to get lirc working. (This kernel tunable defaults to 1, and the first zero is the device index so for /dev/lirc1 it would be 1.) I've also updated the notes in the wiki page http://wiki.freebsd.org/WebcamCompat.

HTH, :)
Juergen
Last edited by nox@ on 10 Aug 2014, 15:51, edited 1 time in total.
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44

Postby Mur77 » 01 Dec 2012, 17:53

Hi!

After I've connected my homebrew IR receiver (http://www.lirc.org/receivers.html) to COM-port and got no results, I descovered that voltage on RTS pin is -12V. I think it should be +12V.

How can I change it?

Here's my system:

> uname -smr
FreeBSD 9.0-RELEASE i386


> kldstat
Id Refs Address Size Name
1 26 0xc0400000 c9218c kernel
2 1 0xc1093000 331c splash_bmp.ko
3 1 0xc1097000 6f5c vesa.ko
4 1 0xc115f000 30d4 coretemp.ko
5 1 0xc1163000 13054 uartlirc.ko
6 2 0xc2bb3000 7a000 osscore.ko
7 1 0xc2c35000 29000 oss_hdaudio.ko
8 1 0xc2ce5000 9000 i915.ko
9 1 0xc2cfd000 16000 drm.ko


> ps ax | grep lirc
1520 ?? Is 0:00,00 /usr/local/sbin/lircd -d /dev/lirc0 -H default /usr/lo
Mur77
Junior Member
 
Posts: 16
Joined: 30 Nov 2012, 19:01

Postby nox@ » 26 Dec 2012, 13:21

Mur77 wrote:Hi!

After I've connected my homebrew IR receiver (http://www.lirc.org/receivers.html) to COM-port and got no results, I descovered that voltage on RTS pin is -12V. I think it should be +12V.
[...]


Hm yes it should be +12V, that is weird. Does /dev/lirc0 exist? Was it opened before you checked the RTS voltage? Did you load uartlirc.ko from [man]loader.conf(5)[/man]?

Juergen

PS: Sorry for the late answer, I somehow check email more often than forum threads... :)
Last edited by nox@ on 10 Aug 2014, 15:52, edited 1 time in total.
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44

Postby Mur77 » 30 Dec 2012, 14:34

Hello,

Yes, /dev/lirc0 is exist. And I load [FILE]uartlirc.ko[/FILE] from the [FILE]loader.conf[/FILE]

My [FILE]lircd[/FILE] command line is:
Code: Select all
 ps axw | grep lirc
 1873  ??  Is    0:00,00 /usr/local/sbin/lircd -d /dev/lirc0 -H default /usr/local/etc/lirc/lircd.conf


After I start [FILE]irw[/FILE], the voltage on RTS pin become +1.8V, but it is too little to drive IR receiver!
Mur77
Junior Member
 
Posts: 16
Joined: 30 Nov 2012, 19:01

Postby Mur77 » 30 Dec 2012, 15:57

After I get power from somewhere else, IR receiver strat working, [FILE]mode2[/FILE] showed some output, but I couldn't learn any of remotes I have.

Some output from [FILE]irrecord[/FILE]:
Code: Select all
>sudo irrecord -n -H default -d /dev/lirc0 pioneer_DVR.conf

irrecord -  application for recording IR-codes for usage with lirc

Copyright (C) 1998,1999 Christoph Bartelmus(lirc@bartelmus.de)

This program will record the signals from your remote control
and create a config file for lircd.

...

Now start pressing buttons on your remote control.

It is very important that you press many different buttons and hold them
down for approximately one second. Each button should generate at least one
dot but in no case more than ten dots of output.
Don't stop pressing buttons until two lines of dots (2x80) have been
generated.

Press RETURN now to start recording.
................................................................................
Found gap: 9053
Please keep on pressing buttons like described above.
................................................................................
Space/pulse encoded remote control found.
Signal length is 87.
Found possible header: 4478 581
No trail pulse found.
No repeat code found.
Signals are pulse encoded.
Signal length is 43
Now enter the names for the buttons.

Please enter the name for the next button (press <ENTER> to finish recording)
KEY_POWER

Now hold down button "KEY_POWER".
Something went wrong. Please try again. (9 retries left)
Something went wrong. Please try again. (8 retries left)
Something went wrong. Please try again. (7 retries left)
Something went wrong. ^C>
Mur77
Junior Member
 
Posts: 16
Joined: 30 Nov 2012, 19:01

Postby Mur77 » 30 Dec 2012, 16:04

The powering problem was solved (wiring mistake), but I still couldn't learn IR codes.

Update: Everything works fine now after changing:
Code: Select all
hint.uartlirc.0.activelowflag="0"

to
Code: Select all
hint.uartlirc.0.activelowflag="1"

in [FILE]device.hints[/FILE].

Thanks! )
Mur77
Junior Member
 
Posts: 16
Joined: 30 Nov 2012, 19:01

Postby nox@ » 31 Dec 2012, 18:20

Mur77 wrote:The powering problem was solved (wiring mistake), but I still couldn't learn IR codes.

Update: Everything works fine now after changing:
Code: Select all
hint.uartlirc.0.activelowflag="0"

to
Code: Select all
hint.uartlirc.0.activelowflag="1"

in device.hints.

Thanks! )

Yes most receiver circuits are active low which is why I made it the default.

Glad you got it working! :)

Juergen
nox@
Junior Member
 
Posts: 75
Joined: 20 Feb 2008, 22:44


Return to FreeBSD Development

Who is online

Users browsing this forum: No registered users and 1 guest