From owner-freebsd-hackers@FreeBSD.ORG Mon Jan 24 14:17:16 2005 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BBFD716A4CE for ; Mon, 24 Jan 2005 14:17:16 +0000 (GMT) Received: from comsys.ntu-kpi.kiev.ua (comsys.ntu-kpi.kiev.ua [195.245.194.142]) by mx1.FreeBSD.org (Postfix) with ESMTP id BEC9843D2F for ; Mon, 24 Jan 2005 14:17:12 +0000 (GMT) (envelope-from simon@comsys.ntu-kpi.kiev.ua) Received: from pm514-9.comsys.ntu-kpi.kiev.ua (pm514-9.comsys.ntu-kpi.kiev.ua [10.18.54.109]) (authenticated bits=0)j0OEJ1ob038348 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 24 Jan 2005 16:19:04 +0200 (EET) Received: by pm514-9.comsys.ntu-kpi.kiev.ua (Postfix, from userid 1000) id DFF44159; Mon, 24 Jan 2005 16:15:23 +0200 (EET) Date: Mon, 24 Jan 2005 16:15:23 +0200 From: Andrey Simonenko To: Anton W?llert Message-ID: <20050124141523.GA1038@pm514-9.comsys.ntu-kpi.kiev.ua> References: <11679.1106483210@www25.gmx.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <11679.1106483210@www25.gmx.net> User-Agent: Mutt/1.4.2.1i X-Spam-Status: No, score=-4.4 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.0.1 X-Spam-Checker-Version: SpamAssassin 3.0.1 (2004-10-22) on comsys.ntu-kpi.kiev.ua X-Virus-Scanned: ClamAV 0.80/676/Thu Jan 20 20:25:54 2005 clamav-milter version 0.80j on comsys.ntu-kpi.kiev.ua X-Virus-Status: Clean cc: freebsd-hackers@freebsd.org Subject: Re: operation sequence of ioctl's X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Jan 2005 14:17:17 -0000 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.