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