operation sequence of ioctl's

Andrey Simonenko simon at comsys.ntu-kpi.kiev.ua
Mon Jan 24 06:17:17 PST 2005


On Sun, Jan 23, 2005 at 01:26:50PM +0100, "Anton W?llert" wrote:
> 
> my question is how a ioctl is called when i use int ioctl(fd ....) from
> userland. i think first, a trap is generated through the handler in
> exeption.S, that calls the routine for system-calls, and that calls via the
> syscall-vector-table the function sys_ioctl (? i think). by the way, where
> is this vector-table initialized?

You're right here: exception.S:int0x80_syscall -> trap.c:syscall,
and int0x80_syscall is registered in IDT.

Then, according to the syscall number, desired syscall is called,
p->p_sysent->sv_table[] array keeps pointers to syscall functions, 
Since p_sysent is a per process pointer, then each process can
have own ABI (for example for Linux compatibility regime).  Relevant
file sys/sysent.h.

p->p_sysent is initialized when process is created, and this vector table
is created for FreeBSD from kern/syscalls.master: kern/makesyscalls.sh
using kern/syscalls.master creates init_sysent.c.  "grep init_sysent
kern/Makefile" for more information.  For Linux compatibility regime
there is i386/linux/syscalls.master which is used in the same way.

> sys_ioctl handles then the copying of args
> etc. and calls then some kind of fd->some_what->ioctl(foo, bar, bla). so i
> think the function which is called, depends of the filedescriptor that is
> passed via ioctl. so am i right with the assumption that for example the
> kbd-driver adds via what? the /dev/kdb file-descriptor and if i want to
> control something from the keyboard, i have to do ioctl(open("/dev/kbd"),
> TURN_LED_ON, 0) (just as an meta-code example). 
May be I understand something wrong, because this is the first time I
tried to track 5.x for you question, but let me try...

When you call open -> kern_open -> vn_open -> vn_open_cred, namei()
is called.  Namei() calls lookup(), which calls VOP_LOOKUP for the
file system where searched file is placed.  As the result somewhere
in VOP_LOOKUP vp->v_op got pointer to vnode operation table for its
file system.

For example /dev/kdb is in /dev which is devfs.  The sys/fs/devfs/
devfs_vnops.c file has vnode operation vector for devfs.  And vp->v_op
for /dev/kbd should have pointers to entries for functions specified
in devfs_specop_entries[].  Well, this is not very correct, because
vnode operation vector is generated, try to understand how this
is done for stackable VFS...  Try to follow this path in the
sys/fs/devfs/devfs_vnops.c: devfs_lookup -> devfs_lookupx ->
devfs_allocv, check lines where DT_CHR is checked.

Next, when you call ioctl -> fo_ioctl -> vn_ioctl -> VOP_IOCTL is
called.  For devfs VOP_IOCTL calls spec_vnoperate, which calls spec_ioctl,
which calls d_ioctl for cdev for vp.  Check specfs/specfs_vnops.c:spec_ioctl
and devsw().  As the result for /dev/kdb function dev/kbd/kbd.c:genkbdioctl
is called.  This function is easy: select ioctl implementation of ioctl for
keyboard and run selected function.

> but what is with the stdin,
> stdout and stderr file-descriptors. what type do they have and where are

0, 1, and 2 descriptors can be anything.

> they initialized? so and last question, where is the function|macro
> VOP_IOCTL defined?

It is generated and you can find it in /usr/obj/.../vnode_if.h.

I think you understood why devfs calls spec_vnoperate for VOP_IOCTL,
if not, try to understand how stackable VFS works, start from the
kern/vfs_init.c file and vnode_if.h.

> 
> thanks in advance

If I made some error (because this is the first time I tracked such
path), please correct me.

Hope this will help.


More information about the freebsd-hackers mailing list