Date: Mon, 24 Jan 2005 16:15:23 +0200 From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua> To: Anton W?llert <MethoD.EaglE@gmx.net> Cc: freebsd-hackers@freebsd.org Subject: Re: operation sequence of ioctl's Message-ID: <20050124141523.GA1038@pm514-9.comsys.ntu-kpi.kiev.ua> In-Reply-To: <11679.1106483210@www25.gmx.net> References: <11679.1106483210@www25.gmx.net>
next in thread | previous in thread | raw e-mail | index | archive | help
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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050124141523.GA1038>