From owner-freebsd-hackers Mon Aug 12 7:58:35 2002 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 AE82937B400 for ; Mon, 12 Aug 2002 07:58:30 -0700 (PDT) Received: from snipe.mail.pas.earthlink.net (snipe.mail.pas.earthlink.net [207.217.120.62]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4DB7A43E6A for ; Mon, 12 Aug 2002 07:58:30 -0700 (PDT) (envelope-from tlambert2@mindspring.com) Received: from pool0043.cvx22-bradley.dialup.earthlink.net ([209.179.198.43] helo=mindspring.com) by snipe.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 17eGeB-0001F1-00; Mon, 12 Aug 2002 07:58:19 -0700 Message-ID: <3D57CCD5.B8B36F86@mindspring.com> Date: Mon, 12 Aug 2002 07:57:25 -0700 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: ouyang kai Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: How the kernel add the devices when the kernel start References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG ouyang kai wrote: > > Part 1.1 Type: Plain Text (text/plain) > Encoding: quoted-printable | When the kernel process this code to check the SI_SUB_DRIVERS, | it would find the registed 'fxp' device(fxp_probe), right? Not exactly. Let's expand the macros manually: -------------------------------------------------------------------------- DRIVER_MODULE(if_fxp, pci, fxp_driver, fxp_devclass, 0, 0); -> static driver_t *if_fxp_pci_driver_list[] = { &fxp_driver }; static struct driver_module_data if_fxp_pci_driver_mod = { 0, 0, "pci", if_fxp_pci_driver_list, (sizeof if_fxp_pci_driver_list) / (sizeof if_fxp_pci_driver_list[0]), &fxp_devclass }; static moduledata_t if_fxp_pci_mod = { "pci/if_fxp", driver_module_handler, &if_fxp_pci_driver_mod }; DECLARE_MODULE(if_fxp_pci, if_fxp_pci_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE) -> SYSINIT(if_fxp_pcimodule, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, module_register_init, &if_fxp_pci_mod) -> struct sysinit if_fxp_pcimodule_sys_init { SI_SUB_DRIVERS, SI_ORDER_MIDDLE, module_register_init, &if_fxp_pci_mod }; -> in init_main.c: module_register_init( &if_fxp_pci_mod); /-------------------------------------------------------------------------- So the answer is that it calls the function "module_register_init" with the address of the moduledata_t structure whose contents are: -------------------------------------------------------------------------- static moduledata_t if_fxp_pci_mod = { "pci/if_fxp", driver_module_handler, &{ 0, 0, "pci", if_fxp_pci_driver_list, 1, &fxp_devclass } }; /-------------------------------------------------------------------------- | If the 'fxp' device is exist, the kernel will try to attach | it(fxp_attach), right? This *eventually* calls the probe, and, if it finds a device, the attach, so yes, many function calls deep. | Another, If we do not compile the 'vr' device into the kernel | and we do not load the corresponding 'ko', so the kernel will | not check the device, that is to say, the 'vr' device does not | registe to kernel, right? Yes. Unless the .ko (kernel module) version gets loaded, a driver must be statically linked into the kernel, or it will not be called to try and probe for devices that it matches. | 1. When the kernel process the specified device, the 'func' | means what? For example: the member 'if_ioctl' of the | structure 'ifnet', when the kernel process the 'fxp' device, | I know it should call the function 'fxp_ioctl'. But I do not | the 'func' means what when it check SI_SUB_DRIVERS. In this case, the macros make it mean the function named module_register_init(). | 2. In NetBSD, I can find main() function in init_main.c, but | in FreeBSD, I could not find it, I am puzzled about the place | of the FreeBSD main process. This is not well documented, and it has changed recently, as people have gained an understanding for the boot process, and screwed around with the code there, so any documentation is out of date pretty quickly. That's the problem with documenting things: there is so little documentation that as soon as something is documented, people understand it and jump on it and change it because they now understand it. Unfortunately people can't seem to leave working code alone, expecially if it's the only code they understand (understanding broken code would be too much like work, I guess...). The short answer is: mi_startup(). The longer answer is: bootstrap code (boot0, boot1+boot2) -- this is the entry point from the BIOS btext() (in locore.s; called locorestart() on Alpha) -- this is the entry point from the bootstrap identify_cpu() create_pagetables() begin() (in relocated address space) mi_startup() -- this is the entrypoint to the machine independent startup code that will be the same no matter what type of machine you run FreeBSD on. Which one is really "main()" depends on your philosophy, and who has been rearranging the deck chairs in locore.s this week. 8-(. -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message