This shows you the differences between two versions of the page.
ass:laboratoare:02:tasks:01 [2023/07/19 16:17] radu.mantu |
ass:laboratoare:02:tasks:01 [2024/08/06 15:05] (current) florin.stancu [01. Preparing the Linux μImage] |
||
---|---|---|---|
Line 12: | Line 12: | ||
=== Task A - Linux kernel === | === Task A - Linux kernel === | ||
- | Clone the kernel from the official github repo. Since you've built U-Boot previously, you should be somewhat familiar with the Kbuild system. Generate the default ARM configuration file and compile the kernel. | + | Clone the kernel from the [[https://github.com/torvalds/linux/|official GitHub repo]], using the ''v6.6'' tag. |
+ | We recommend you to use [[https://stackoverflow.com/questions/1778088/how-do-i-clone-a-single-branch-in-git|this git cloning technique]] to avoid fetching the entire git history (requiring several GBs of disk space). | ||
- | Note that the kernel image you will be including in the FIP is called **Image**. Unlike **vmlinux** which is an ELF file (i.e.: contains useless sections, including //.debuginfo// if you want to debug the kernel), **Image** is a boot executable image, made specifically for you to jump straight in and start executing. After the build process finalizes, **find** the **Image** file within the Linux repo. | + | Since you've built U-Boot previously, you should be somewhat familiar with the Kbuild system. Start by generating the build configuration from its [[https://github.com/torvalds/linux/tree/v6.6/arch/arm64/configs|default configuration template]]. Optionally, run a ''menuconfig'' to inspect the Linux kernel options available. |
<note warning> | <note warning> | ||
You must set the ''ARCH'' argument to the appropriate architecture **AT ALL TIMES** when invoking linux's ''make''! \\ | You must set the ''ARCH'' argument to the appropriate architecture **AT ALL TIMES** when invoking linux's ''make''! \\ | ||
Check out the subdirectories in ''linux/arch/'' for possible values. \\ | Check out the subdirectories in ''linux/arch/'' for possible values. \\ | ||
- | Also, do not forget about the ''CROSS_COMPILE'' argument. | + | Also, do not forget about the ''CROSS_COMPILE'' environment variable (export it inside your Makefile & terminal). |
</note> | </note> | ||
+ | |||
+ | In order to build the kernel image, simply ''make'' with the required variables (see the warning above!). | ||
<note tip> | <note tip> | ||
- | Paralellize the build process using ''make -j'', unless you want to waste an hour for Linux to build. \\ | + | Paralellize the build process using ''make -j <num_CPUs>'', unless you want to waste an hour for Linux to build. \\ |
</note> | </note> | ||
+ | |||
+ | Note that the kernel image you will be including in the FIP is called **Image**. Unlike **vmlinux** which is an ELF file (i.e.: contains useless sections, including //.debuginfo// if you want to debug the kernel), **Image** is a boot executable image, made specifically for you to jump straight in and start executing. After the build process finalizes, find the **Image** file within the ''<linux-kernel-src>/arch/arm64/boot/'' output directory. | ||
+ | |||
+ | While waiting for the build, explore the Linux source using your favorite code editor (especially [[https://github.com/torvalds/linux/tree/v6.6/arch/arm64/boot/dts/freescale|the device trees]])! | ||
<note tip> | <note tip> | ||
Line 41: | Line 48: | ||
=== Task B - Flattened Device Tree === | === Task B - Flattened Device Tree === | ||
- | Luckily, the FDT for our platform is also included in Linux. It's name should be **imx8mq-pico-pi.dtb**. | + | Luckily, the FDT for our platform is also included in Linux. It's name should be ''imx8mq-pico-pi.dtb'' (generated from its source counterpart, [[https://github.com/torvalds/linux/blob/v6.6/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts|imx8mq-pico-pi.dts]]). |
If for some reason it wasn't built alongside the kernel Image, check out the ''dtbs'' make target. | If for some reason it wasn't built alongside the kernel Image, check out the ''dtbs'' make target. | ||
Line 53: | Line 60: | ||
Buildroot on the other hand is geared towards simplicity and ease of use. Being based on Kbuild and Makefile (same as Linux and U-Boot) makes it instantly familiar to most developers. And even if you are new to this, while Yocto requires you to read entire [[https://www.goodreads.com/search?q=yocto|books]] in order to utilize it properly, Buildroot can be summed up in a 1k LoC Makefile. | Buildroot on the other hand is geared towards simplicity and ease of use. Being based on Kbuild and Makefile (same as Linux and U-Boot) makes it instantly familiar to most developers. And even if you are new to this, while Yocto requires you to read entire [[https://www.goodreads.com/search?q=yocto|books]] in order to utilize it properly, Buildroot can be summed up in a 1k LoC Makefile. | ||
- | == Step 1: Download Buildroot == | + | == Download Buildroot == |
Clone the official [[https://github.com/buildroot/buildroot.git|Buildroot repo]]. | Clone the official [[https://github.com/buildroot/buildroot.git|Buildroot repo]]. | ||
- | == Step 2: Create the configuration == | + | == Create the configuration == |
Find an existing defconfig for our platform (the **imx8mq**) and take a look at what it contains. Notice how the following config options are enabled: | Find an existing defconfig for our platform (the **imx8mq**) and take a look at what it contains. Notice how the following config options are enabled: | ||
Line 68: | Line 75: | ||
Yes, Buildroot also integrates the bootloaders into its build system. However, keeping the components separate makes it easier to appply patches and debug problems. What we want from Buildroot is a minimal root filesystem and nothing more. So, after generating ''.config'', enter ''menuconfig'' and make a few changes: | Yes, Buildroot also integrates the bootloaders into its build system. However, keeping the components separate makes it easier to appply patches and debug problems. What we want from Buildroot is a minimal root filesystem and nothing more. So, after generating ''.config'', enter ''menuconfig'' and make a few changes: | ||
+ | |||
* Disable all components that we've already integrated in our build environment (starting with the ones above). | * Disable all components that we've already integrated in our build environment (starting with the ones above). | ||
- | * Use an **external, custom, pre-installed toolchain**. | + | * Use an **external, custom, pre-installed toolchain** (remember ''CROSS_COMPILE''? check the menu for it!). |
* Use **systemd** as the init system instead of **BusyBox**. | * Use **systemd** as the init system instead of **BusyBox**. | ||
- | * Make sure **systemd-logind** is included in the build; not selected by default! | + | * Make sure **systemd-logind** is included in the build, or you may have [[https://lore.kernel.org/all/b49c7676-1864-d838-fcf7-7a1208d6ba78@benettiengineering.com/T/|this problem]]. |
- | * Use **bash** as the default shell instead of **sh**. | + | * Choose **bash** as the default shell instead of **sh**. |
* Enable password login for the //root// user, then set a password. | * Enable password login for the //root// user, then set a password. | ||
- | * Include a text editor package (e.g.: **vim** or **nano**). | + | * Include a text editor PACKAGE (e.g.: **vim** or **nano**). |
+ | * Include the **coreutils** PACKAGE. | ||
* Generate an **uncompressed CPIO** image from the output file system (see the Note below). | * Generate an **uncompressed CPIO** image from the output file system (see the Note below). | ||
+ | |||
+ | <note> | ||
+ | Note how the the configuration variables are prefixed with ''BR2_'', packages with ''BR2_PACKAGE_'' and so on! | ||
+ | </note> | ||
<note> | <note> | ||
Line 155: | Line 168: | ||
</solution> | </solution> | ||
- | == Step 3: Build it! == | + | == Build & inspect the rootfs == |
Not much to it, really. Once everything's done, check out the ''output/'' directory. What does it contain? Where is your CPIO archive? | Not much to it, really. Once everything's done, check out the ''output/'' directory. What does it contain? Where is your CPIO archive? | ||
Line 213: | Line 226: | ||
fdt = "fdt"; | fdt = "fdt"; | ||
ramdisk = "initrd"; | ramdisk = "initrd"; | ||
- | loadables = "fdt", "ramdisk"; | ||
}; | }; | ||
}; | }; | ||
Line 250: | Line 262: | ||
$ mkimage -f linux.its linux.itb | $ mkimage -f linux.its linux.itb | ||
</code> | </code> | ||
+ |