-->

Built-in kernel driver still need device tree?

2020-07-19 03:25发布

问题:

If I build a kernel driver as a module, it can be inserted into the kernel at run-time manually with insmod or modprobe, that i am clear. But are the following statements about device tree, correct?

  1. If I build a kernel driver as a module it will be auto inserted into the kernel at boot time, depending on whether it is listed in device tree or not
  2. If I build a kernel driver as a built-in, it will be auto inserted into kernel at boot time regardless of device tree

回答1:

Built-in kernel driver still need device tree? Yes. Concept of device tree is orthogonal to whether drivers are built-in or compiled as modules. Device tree contains information about the hardware. Platform bus passes that info to relevant drivers.

This is a good brief article about platform bus, and how things used to be before device tree: https://www.codeproject.com/tips/1080177/linux-platform-device-driver. Device tree factors out harware info otherwiese hard-coded in kernel code, making the code more portable.



回答2:

In 2, there is no insertion step; the builtin driver is statically part of the kernel (and there is no moment where it is not part of it)

You can configure then compile and use a fully static kernel with all useful drivers built-in (so without modules and without initrd). You'll set CONFIG_MODULES=n, you'll never use m in your kernel .config file, and you'll set to y all the stuff needed for your particular hardware and system (e.g. file systems). See also this unanswered question. I guess that many embedded systems using Linux have a kernel compiled that way and don't use any initrd.

You can use a driver (either a builtin one, or a module which has been loaded) without the device tree since you could mknod(2) the device into a file path anywhere.

See https://www.devicetree.org/ and notice that older Linux systems did not have any. The device tree is mostly a useful convenience (improving over udev and devfsd). And you can avoid it entirely: you could run a fully static kernel without any device tree, on a root file system populated with block and character devices, like Linux distros of 1995 did. Hence a built-in kernel driver don't need any device tree, even today.

Notice that old Unix systems (e.g. SunOS3 in the mid-1980s, or Linux 1.x kernels in the 1990s) did not have anything of the sort. At that time you just relinked statically the kernel with appropriate drivers then used device files: character devices or block devices (and their driver was a builtin part of the kernel). Most driver code had some initialization which probed the existence of the relevant hardware (and that did slow down the boot process).

BTW, your question is dependent of how the kernel is loaded, of the hardware, and of the firmware loading it. For example, you can build hardware with the Linux kernel embedded in its firmware (in ROM).

Maybe with recent UEFI some recent hardware requires a device tree. AFAIK, BIOS don't need any. You could configure and compile a static kernel and a special init program which don't even use any device tree, and use very few pre-existing device files. Of course you need some root file system providing them.

Look also on OSDEV, and into hobby OSes mentionned there. Or into FreeBSD etc.... They don't use (or at least can be configured to avoid) any device tree AFAIK.

I probably could boot a 1995 Linux distro on my PC (at least if I have a floppy disk unit) -at least with a recent fully static kernel tailored to my hardware- and it would work without any device tree (which at that time did not exist).

Read Operating Systems: Three Easy Pieces (freely downloadable).