This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux: Linux-Device Drivers, BIOS, Bootloader, Initrd - initramfs



Tool/software: Linux

Hi,

I have few questions about Linux Kernel and Boot process.

1) BIOS: Upon PowerON, the first code that is on Processor startup address i.e. BIOS, is executed. BIOS detects hardware and conducts POST. then it loads first stage boot loader (from MBR) handover the control to it. Now the question is, if BIOS conduct POST or read MBR it means it should contains drivers to communicate with RAM, Keyboard, Harddisk, USB. i.e. isn't it necessary to have Device driver to Detect/communicate with these Hardware.... So

i) does BIOS contains any driver??

ii) How it DETECTS hardware and conducts POST or communicate with Hard disk, RAM etc.??

2) initrd - initramfs : I have heard that device drivers are packed inside the kernel. The kernel loads them on boot time. after the kernel is loaded, kernel mounts a temporary RAMDISK file system called initrd or initramfs to load device drivers and mount actual root rile system. Now if device drivers are packed into kernel, so when bootloader loads kernel image into RAM, doesn't it means the drivers that ware packed inside kernel are too loaded into RAM, if so, then why does the kernel need a temporary root file system to load drivers??

3) bootloader: If boot loader is loading kernel image into RAM from Hard drive, then it means it should contain the device driver for hard drive. then why kernel needs to load RAID controllers and drivers?? should bootloader handover the driver to kernel???

Regards,

  • Hi Aimal Khan,

    Since you have posted this query in TI forum, I will be discussing about TI based Embedded SOCs(System On Chips).
    i) does BIOS contains any driver??
    Me)Yes. Since this is TI forum, lets discuss specific to common TI chipsets like Davinci and Sitara SOC chipsets. They have RBL (Read only BootLoader, user/developer cannot write into it) similar to BIOS. It picks up the first stage bootloader(called MLO, SPL, xloader etc in TI SOC world) from a medium(like SDCard, NAND, eMMC, USB, Ethernet,UART) depending on a hardware switch, which can be changed to make it select one of the boot options. Coming back to the question, yes RBLs(BIOS) have a set of drivers(may not be a linux driver, but a piece of code to interact with hardware and make them work). TI has access to the RBL code that they use and I have seen in this forum, few TI people referring to the code internally and giving pointers. Also TRM(technical reference manual) details about few supported type of hardwares (like type of NAND etc)

    ii) How it DETECTS hardware and conducts POST or communicate with Hard disk, RAM etc.??
    Me)As I mentioned in previous answer, it reads a boot switch, which can be set by us. Then depending upon the medium set, like SDCard or NAND etc, it expects the first stage bootloader to be at specific offset(NAND at 0x00 address, though the list of supported NAND configurations will be specified in TRM) or format(in most TI cases, it can read a FAT32 partitioned SDCard that contains first stage bootloader ). So the NAND being connected or SDCard being used should have a predefined requirement(which most of NAND parts or SDCard types meet). Nothing specific to POST does the embedded SOCs do.

    iii)Now if device drivers are packed into kernel, so when bootloader loads kernel image into RAM, doesn't it means the drivers that ware packed inside kernel are too loaded into RAM, if so, then why does the kernel need a temporary root file system to load drivers??
    Me)Not always we use RAMDISK(temporary filesystems) in embedded world. But in generic uses like Desktop, it is possible that the medium from which root filesystems are mounted could be varied. So it will be difficult to make the kernel(it will bloat the kernel size) have all the drivers within it. So it uses initial ramdisk, which has tools and loadable modules to detect the medium in which root filesystems are present and load them. Since in a Desktop like environment, where the root filesystems could be stored in any of the plethora of media available, ramdisk plays a vital part. In embedded world, it helps in booting quickly and running applications from RAM since it would be faster than running from a root filesystems stored in a secondary storage.

    iv) bootloader: If boot loader is loading kernel image into RAM from Hard drive, then it means it should contain the device driver for hard drive. then why kernel needs to load RAID controllers and drivers?? should bootloader handover the driver to kernel???
    Me) Bootloader as its name suggests, is a piece of code that runs at the boot time to load the OS software. It is a piece of code that is more functional than the BIOS(RBL code). Actually since the peripherals connected could vary and the medium in which OS software stored could also vary, we need a bootloader to initialize enough peripherals and memory to load the OS. But it needs to be kept in mind that Bootloader cannot be very big and generic. It has to be specific to the Board(with given set of peripherals and memory). Coming back to the question of handing over the driver(though that seems a good idea), Bootloader is a simple code compared to say a linux kernel. The layering and abstraction and the APIs are different between kernel and bootloader. A driver code in Bootloader could be simple and it would not fit in and be full fledged as required by a more layered code like linux kernel. But initialization steps like setting clocks of peripherals like Video, Imaging subsystem etc and the pin muxing, can be once performed in Bootloader and need not be set again in linux kernel. Though having two sets of driver, one in bootloader and one in kernel seem to be redundant, but considering the above points of linux driver being generic, layered and also full fledged compared to a simple bootloader code, it seems to justify.
  • Thanks Dwarakesh.

    Your reply is indeed very comprehensive and informative. I just have one query... regarding your answer, i.e. initrd ramdisk... you said we can pack all the drivers in kernel but it will increase kernel size. but here what we are doing, we are reducing kernel size by keeping out the less important drivers and modules but we are packing them into another image initrd. so the net time to load one single large file (kernel) or one file divided into two images (kernel and initrd) wouldn't be the same???

    isn't it strange like mounting temporary file system (initrd) and then mounting real root file system. is it because we need drivers to load the root file system??? if so then from where the initrd is loaded?? not from the same disk??? if i the root file system is on the same harddrive as that of initrd, then don't you think we can skip the initrd, as we don't need any new driver to load root file system....

    can you elaborate a little bit the keyword you mentioned..."Boot switch"..

    Btw what exactly mounting is???? the root file system exists on secondary storage, and it stays there, then what it meant by mounting??? i am sure its not like coping the root file system (FHS) from secondary storage to RAM. i mean we are doing quite heavy job by copying and decompressing initrd JUST TO mount root file system. if mounting is just a linking files residing on Disk; to kernel then why is it so heavy and what mounting word suggests???
  • Hi Aimal,

    From what I understand, this initrd started as a concept in Desktop distribution, where they could have a single kernel image from the factory being used. Later could change the initrd accordingly to different hardware combination. But in embedded system, this is not of any significance.

    In case of embedded system, kernel and initrd can come from NOR flash(faster read speed and costlier and so small in size to just hold kernel and initrd) and the filesystems can come from NAND (cheaper, slower flash). This provides a way of quickening loading, since kernel and initrd can come from a different and faster medium like NOR.

    As far as reducing the size of kernel, I would agree with you that sum total of size is the same. But there is slight difference:

    There are two parts to starting quickly at the boot time. Loading and running(executing). Sum total of loading could remain the same since the size(of image to be loaded to achieve the same functionality) remains the same, but what makes the difference is the order of running(executing). The Applications(which define the major purpose of the software) are present in the user space whereas the kernel provides the administrative work. So without Applications, kernel alone is of no use for the end product. So for the Application to start, we need to load the kernel, mount a filesystem to access the userspace App and then run them(Thats how linux works. For that matter in linux everything is a file analogy inherited from Unix). Now reducing the size of kernel, helps one step in reducing the executing code(initializing code at boot time). Reduced kernel means reduced initialization at boot time. Next step would be to reduce the time taken to mount filesystems which are stored in secondary storage like NAND, SDCard, Hard disk etc.

    When there are lots of data(files) to store and access, to ease things out, filesystems are available. Filesystems provide a way to arrange the files and a way to access them. You can consider filesystems as structures stored in storage medium to easily locate and access required files quickly. Kernel is a single binary, but user space can have N number of binaries, daemons, files etc. And there are N number of filesystems for differrent purpose and for different medium of storage.

    Mounting is the step the kernel(on behalf and for userspace) does to evaluate the type of storage medium, type of filesystems present in the medium, the type of access of that medium etc. Kernel tries to maintain a copy of that filesystems in RAM(not the binaries or the files, but a small details of the filesystems). So kernel has a block driver(NAND driver or SDCard driver) to access the medium, then a filesystems driver to read/access files and then virtual filesystems(for abstraction) and then paging/caching for performance etc.

    Now having elaborated on the process of mounting and the filesystems, we will understand the ease that the ramdisk(ramfs) provides. First and foremost, RAM is faster access memory than secondary storage like NAND, Hard disk, SDCard etc. And next is, it eliminates the need of block driver, filesystems driver and its overhead. Only virtual filesystems and paging/caching mechanism is present. This provides a faster access to files and running them.

    Now if we have our application in ramfs, wont it be faster in accessing and then executing? So in embedded systems, other than having kernel drivers for mounting the root filesystems, ramfs can also have Application that can run ahead and faster.

    Later, once Application is running, remaining components of the kernel, can be loaded as modules. And rootfs mounted.

    boot switch is a jumper settings provided in many embedded hardware, to inform the RBL(BIOS) code to where to look for the first stage bootloader. It helps in boot strapping. It is a way of helping to reduce the complexity of RBL(BIOS) which can quickly identify the medium to load the first stage bootloader.