├── Trial ├── text.txt ├── qemu-ifup ├── u-boot ├── run ├── qemu-crossCompiler-setenv.sh └── format-sd-loop-dev.sh ├── 2-Crosstool_Ng └── README.md ├── 3-Uboot ├── qemu-ifup └── README.md ├── Cmake ├── Example │ ├── include │ │ ├── port.hpp │ │ ├── dio.hpp │ │ └── ClassObject.hpp │ ├── library │ │ ├── dio.cpp │ │ ├── CMakeLists.txt │ │ └── port.cpp │ ├── main.cpp │ └── CMakeLists.txt ├── 03Variables.md ├── 04Programing.md ├── 01Overview.md ├── 05Configure.md └── 02BasicConcept.md ├── InitApp ├── deamonapp.c └── CMakeLists.txt ├── 8-Yocto ├── 3-Layer │ └── README.md ├── 5-BuildRecipe │ └── README.md ├── 4-Variables │ ├── Basic_Variables.md │ └── Variable_Assignment.md ├── 6-TaskBuild │ └── README.md ├── bitbake │ └── README.md ├── 2-FolderDescription │ └── README.md ├── 1-YoctoTerminology │ ├── WhatToEdit.md │ └── README.md └── README.md ├── README.md ├── ViEditor └── ViEditor.md ├── 1-Library └── README.md ├── 4-kernel └── README.md ├── 6-InitProcess └── README.md ├── 5-Busybox └── README.md ├── 7-BuildRoot └── README.md └── Github └── Github.md /Trial/text.txt: -------------------------------------------------------------------------------- 1 | fady 2 | -------------------------------------------------------------------------------- /2-Crosstool_Ng/README.md: -------------------------------------------------------------------------------- 1 | # EmbeddedLinux Course -------------------------------------------------------------------------------- /3-Uboot/qemu-ifup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ip a add 192.168.0.1/24 dev $1 3 | ip link set $1 up 4 | -------------------------------------------------------------------------------- /Trial/qemu-ifup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ip a add 192.168.0.1/24 dev $1 3 | ip link set $1 up 4 | -------------------------------------------------------------------------------- /Trial/u-boot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FadyKhalil/EmbeddedLinux/HEAD/Trial/u-boot -------------------------------------------------------------------------------- /Cmake/Example/include/port.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | void getPortValue(void); 4 | 5 | void setPortValue(void); -------------------------------------------------------------------------------- /Trial/run: -------------------------------------------------------------------------------- 1 | sudo qemu-system-arm -M vexpress-a9 -m 128M -nographic -kernel u-boot -sd ../3-uboot/sd.img -net tap,script=./qemu-ifup -net nic 2 | -------------------------------------------------------------------------------- /Trial/qemu-crossCompiler-setenv.sh: -------------------------------------------------------------------------------- 1 | PATH=${HOME}/x-tools/arm-cortexa9_neon-linux-musleabihf/bin/:$PATH 2 | export CROSS_COMPILE=arm-cortexa9_neon-linux-musleabihf- 3 | export ARCH=arm 4 | 5 | 6 | -------------------------------------------------------------------------------- /InitApp/deamonapp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) 5 | { 6 | while(1) 7 | { 8 | puts("\n Deamon is up and running \n"); 9 | sleep(4); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Cmake/Example/library/dio.cpp: -------------------------------------------------------------------------------- 1 | #include "dio.hpp" 2 | 3 | int getDioPin(char pin) 4 | { 5 | dio mydio; 6 | mydio.dio_getPin(pin); 7 | } 8 | 9 | void setDioPin(char pin) 10 | { 11 | dio mydio; 12 | mydio.dio_setPin(pin); 13 | } -------------------------------------------------------------------------------- /Cmake/Example/library/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # to make library shared put SHARED key word for static STATIC 3 | add_library(mcalLib STATIC 4 | dio.cpp 5 | port.cpp) 6 | 7 | target_include_directories(mcalLib PUBLIC ${CMAKE_HOME_DIRECTORY}/include) -------------------------------------------------------------------------------- /Cmake/Example/library/port.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "port.hpp" 3 | 4 | void getPortValue(void) 5 | { 6 | std::cout << "hello from port" << std::endl; 7 | } 8 | 9 | void setPortValue(void) 10 | { 11 | std::cout << "hello from set port value" << std::endl; 12 | } -------------------------------------------------------------------------------- /InitApp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.22) 2 | project(HELLODEAMON) 3 | add_executable(hellodeamon deamonapp.c) 4 | set(CMAKE_C_COMPILER "/home/fady/x-tools/arm-cortexa9_neon-linux-gnueabihf/bin/arm-cortexa9_neon-linux-gnueabihf-gcc") 5 | set(CMAKE_EXE_LINKER_FLAGS "-static") 6 | -------------------------------------------------------------------------------- /Cmake/Example/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ClassObject.hpp" 3 | #include "dio.hpp" 4 | #include "port.hpp" 5 | 6 | int main(void) 7 | { 8 | object myObject; 9 | lamp mylamp; 10 | myObject.printvalue(); 11 | 12 | lamp mylamp2(mylamp); 13 | 14 | mylamp.printvalue(); 15 | 16 | getDioPin(3); 17 | setDioPin(4); 18 | 19 | getPortValue(); 20 | setPortValue(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Cmake/Example/include/dio.hpp: -------------------------------------------------------------------------------- 1 | class dio 2 | { 3 | private: 4 | char* STATUS_REGISTER; 5 | char* PIN_REGISTER; 6 | 7 | public: 8 | dio() 9 | { 10 | STATUS_REGISTER = new char[1]; 11 | PIN_REGISTER = new char[1]; 12 | *STATUS_REGISTER = 1; 13 | *PIN_REGISTER = 2; 14 | } 15 | 16 | void dio_setPin(char pin) 17 | { 18 | *PIN_REGISTER = 1 << pin; 19 | } 20 | 21 | int dio_getPin(char pin) 22 | { 23 | return (*PIN_REGISTER | 1 << pin); 24 | } 25 | }; 26 | 27 | 28 | int getDioPin(char pin); 29 | void setDioPin(char pin); -------------------------------------------------------------------------------- /Cmake/Example/include/ClassObject.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | class object { 4 | 5 | protected: 6 | int privateValue; 7 | char* prPtr; 8 | 9 | public: 10 | object() 11 | { 12 | privateValue = 0; 13 | prPtr = new char[2]{1,2}; 14 | } 15 | 16 | virtual void printvalue() 17 | { 18 | std::cout << "my value " << privateValue << std::endl; 19 | std::cout << "my ptr value " << prPtr[0] << std::endl; 20 | } 21 | 22 | }; 23 | 24 | class lamp : object { 25 | private: 26 | int lampvalue = 1; 27 | 28 | public: 29 | lamp() 30 | { 31 | std::cout << "call constructor" << std::endl; 32 | lampvalue = 2; 33 | }; 34 | 35 | lamp(lamp& mySecondObject) 36 | { 37 | std::cout << "call copy constructor" <lampvalue; 39 | } 40 | 41 | void printvalue(void) override 42 | { 43 | std::cout << "call from child" << std::endl; 44 | } 45 | 46 | ~lamp() = default; 47 | 48 | }; -------------------------------------------------------------------------------- /8-Yocto/3-Layer/README.md: -------------------------------------------------------------------------------- 1 | # LAYERS 2 | 3 | In Yocto Project, a "layer" is a fundamental concept used to organize and manage the configuration, recipes, and other components needed to build an embedded Linux distribution. Layers provide a modular and flexible way to extend and customize the Yocto Project to meet the specific requirements of your embedded system. 4 | 5 | ## Layer priority 6 | 7 | In the Yocto Project, "layer priority" refers to the order in which Yocto Project layers are evaluated and applied when building an image or recipe. Layer priority plays a crucial role in determining which recipes and configurations take precedence when there are overlapping or conflicting definitions in multiple layers. It ensures that the desired behavior and components are included in the final image or recipe. 8 | 9 | ## Build a layer 10 | 11 | To create a layer we need to run the following command 12 | 13 | ```sh 14 | # create a layer 15 | bitbake-layers create-layer 16 | ``` 17 | 18 | entering to the new layer added we will find conf file it has the configuration of the the layer 19 | 20 | we also will see example recipe we can run it by the following command 21 | 22 | ```shell 23 | # run the example recipe 24 | bitbake example 25 | ``` 26 | 27 | To add the layer 28 | 29 | ```sh 30 | # Add the layer 31 | bitbake-layers add-layer 32 | ``` 33 | 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Embedded Linux Tutorial 2 | 3 | This repository contains the necessary components to build an embedded Linux system from scratch, including libraries, tools, and custom configurations. 4 | 5 | ## Components 6 | 7 | - **Crosstool-NG**: A toolchain generator for building cross-compiling toolchains. 8 | - **U-Boot**: A boot loader used in embedded systems. 9 | - **Kernel**: The Linux kernel for embedded systems. 10 | - **BusyBox**: A collection of Unix utilities in a single executable for embedded systems. 11 | - **Init Process**: The first process started during bootup, responsible for initializing the system. 12 | - **Buildroot**: A tool that automates building embedded Linux systems. 13 | - **Yocto**: A flexible build system for creating custom Linux distributions for embedded systems. 14 | 15 | ## Usage 16 | 17 | To use this repository, follow the steps below: 18 | 19 | 1. Clone the repository to your local machine. 20 | 2. Install the necessary dependencies for building the system, such as `gcc`, `make`, and `libssl-dev`. 21 | 3. Choose the appropriate tool for building the system, such as Buildroot or Yocto. 22 | 4. Follow the instructions in the tool's documentation to configure and build the system. 23 | 24 | ## Conclusion 25 | 26 | This repository provides a complete set of components for building an embedded Linux system, including libraries, tools, and custom configurations. By following the steps outlined above, you can easily build your own custom embedded Linux system. -------------------------------------------------------------------------------- /Cmake/Example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #minimum version required to start cmake 2 | cmake_minimum_required(VERSION 3.1...3.22) 3 | 4 | #project name 5 | project(HelloWorld) 6 | 7 | #to print a variable 8 | message(STATUS ${CMAKE_HOME_DIRECTORY}) 9 | 10 | #to set a variable 11 | set(SRC_FILE main.cpp) 12 | 13 | #to set compile flags 14 | set(COMPILE_C_FLAGS "-v -g") 15 | 16 | # read file content and display it 17 | file(READ ${SRC_FILE} MAIN_TEXT) 18 | message(${MAIN_TEXT}) 19 | 20 | # to change the compiler 21 | # set(CMAKE_CXX_COMPILER /home/fady/x-tools/arm-cortexa9_neon-linux-gnueabihf/bin/arm-cortexa9_neon-linux-gnueabihf-g++) 22 | 23 | #to create the executable 24 | add_executable(helloworld ${SRC_FILE}) 25 | 26 | #to run another cmake in another directory 27 | add_subdirectory(${CMAKE_HOME_DIRECTORY}/library) 28 | 29 | #include the files that the cpp needs 30 | target_include_directories(helloworld INTERFACE ${CMAKE_HOME_DIRECTORY}/include) 31 | 32 | #link the library 33 | target_link_libraries(helloworld PRIVATE mcalLib) 34 | 35 | #give option to the compiler 36 | target_compile_options(helloworld PRIVATE "-std=gnu++17") 37 | 38 | # Define the macro 39 | # replace the macro with function and see the difference. 40 | macro(print_message message) 41 | # Create a variable to hold the formatted message 42 | set(formatted_message "[Macro Message] ${message}") 43 | 44 | endmacro() 45 | 46 | 47 | # Example usage of the macro 48 | print_message("Hello, this is a custom message.") 49 | # Print the formatted message 50 | message(STATUS "helloo ${formatted_message}") -------------------------------------------------------------------------------- /8-Yocto/5-BuildRecipe/README.md: -------------------------------------------------------------------------------- 1 | # Build Recipe 2 | 3 | First, we need to create a layer like how we did in previous session, and create a recipe inside the layer. 4 | 5 | folder structure 6 | 7 | ```sh 8 | meta_mylayer --> recipes_example --> helloworld |--> files --> helloworld.c 9 | |--> helloworld.bb 10 | ``` 11 | 12 | ## Source file (helloworld.c) 13 | 14 | Implement a normal c code 15 | 16 | ```c 17 | #include 18 | 19 | int main(void) 20 | { 21 | printf("hello world!\n"); 22 | return 0; 23 | } 24 | ``` 25 | 26 | 27 | 28 | ## Recipe file (helloworld.bb) 29 | 30 | ```bash 31 | # A brief description of the Recipe 32 | SUMMARY = "Hello World Program" 33 | 34 | # Which Type of License are we going to use E.g MIT, GPL, BSD etc. 35 | LICENSE = "MIT" 36 | 37 | # License file location and its md5 checksum. 38 | LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420" 39 | 40 | # Source Files 41 | SRC_URI = "file://helloworld.c" 42 | 43 | # directory of output build 44 | S = "${WORKDIR}/build" 45 | 46 | # the compilation takes place. 47 | do_compile() { 48 | ${CC} ${CFLAGS} ${LDFLAGS} ${WORKDIR}/helloworld.c -o ${S}/helloworld 49 | } 50 | 51 | do_install() { 52 | install -d ${D}${bindir} 53 | install -m 0755 ${S}/helloworld ${D}${bindir}/ 54 | } 55 | ``` 56 | 57 | `bindir` represent a configuration variable that added in bitbake which represent that the binary will be installed in **/usr/bin** 58 | 59 | `sbindir` represent that the binaries will be installed in **/usr/sbin** 60 | 61 | 62 | 63 | ### How to Generate md5 Checksum 64 | 65 | ```bash 66 | # go to poky/meta 67 | md5sum COPYING.MIT 68 | ``` 69 | 70 | -------------------------------------------------------------------------------- /Trial/format-sd-loop-dev.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Format an sd card 4 | 5 | if [ $# -ne 1 ]; then 6 | echo "Usage: $0 [drive]" 7 | echo " drive is 'sdb', 'mmcblk0'" 8 | exit 1 9 | fi 10 | 11 | DRIVE=$1 12 | 13 | # Check the drive exists in /sys/block 14 | if [ ! -e /sys/block/${DRIVE}/size ]; then 15 | echo "Drive does not exist" 16 | exit 1 17 | fi 18 | 19 | # Check it is a flash drive (size < 32MiB) 20 | NUM_SECTORS=`cat /sys/block/${DRIVE}/size` 21 | if [ $NUM_SECTORS -eq 0 -o $NUM_SECTORS -gt 16000000 ]; then 22 | echo "Does not look like an SD card, bailing out" 23 | exit 1 24 | fi 25 | 26 | # Unmount any partitions that have been automounted 27 | if [ $DRIVE == "mmcblk0" ]; then 28 | sudo umount /dev/${DRIVE}* 29 | BOOT_PART=/dev/${DRIVE}p1 30 | ROOT_PART=/dev/${DRIVE}p2 31 | else 32 | sudo umount /dev/${DRIVE}[1-9] 33 | BOOT_PART=/dev/${DRIVE}1 34 | ROOT_PART=/dev/${DRIVE}2 35 | fi 36 | 37 | # Overwite existing partiton table with zeros 38 | sudo dd if=/dev/zero of=/dev/${DRIVE} bs=1M count=10 39 | if [ $? -ne 0 ]; then echo "Error: dd"; exit 1; fi 40 | 41 | # Create 2 primary partitons on the sd card 42 | # 1: FAT16, 64 MiB, boot flag 43 | # 2: Linux, 96 MiB 44 | sudo sfdisk --unit M /dev/${DRIVE} << EOF 45 | ,64,0x06,* 46 | ,96,L, 47 | EOF 48 | if [ $? -ne 0 ]; then echo "Error: sdfisk"; exit 1; fi 49 | 50 | # Format p1 with FAT32 and p2 with ext4 51 | sudo mkfs.vfat -F 16 -n boot ${BOOT_PART} 52 | if [ $? -ne 0 ]; then echo "Error: mkfs.vfat"; exit 1; fi 53 | sudo mkfs.ext4 -L rootfs ${ROOT_PART} 54 | if [ $? -ne 0 ]; then echo "Error: mkfs.ext4"; exit 1; fi 55 | 56 | # Create ext4 system with block size 4096, stride and stripe 512 KiB 57 | # (= 128 * 4096) 58 | 59 | #### sudo mkfs.ext4 -b 4096 -E stride=128,stripe-width=128 /dev/${DRIVE}1 60 | 61 | exit 0 62 | -------------------------------------------------------------------------------- /8-Yocto/4-Variables/Basic_Variables.md: -------------------------------------------------------------------------------- 1 | # Basic Variables 2 | 3 | ## Popular Variables 4 | 5 | - **PN** (Package Name) 6 | - **PV** (Package Version) 7 | - **PR** (Package Revision) 8 | - **WORKDIR** (Working Directory) 9 | - **S** (Source) 10 | - **D** (Destination) 11 | - **B** (Build Directory) 12 | 13 | 14 | 15 | ## How to Declare Recipe 16 | 17 | myrecipe_**0.1_r0**.bb 18 | 19 | The part of the name in bold, such as "0.1," indicates the specific version of the recipe, "r0" represent the package revision. 20 | 21 | 22 | 23 | ## How to Read Variable Value 24 | 25 | ``` 26 | bitbake -e | grep ^= 27 | ``` 28 | 29 | ## Package Name (PN) 30 | 31 | **PN** refers to a recipe name used by the Yocto build system as input to create a package. The name is extracted from the recipe file name. 32 | 33 | ## Package Version (PV) 34 | 35 | **PV** is the version of the recipe. The version is normally extracted from the recipe filename. 36 | 37 | ## Package Revision (PR) 38 | 39 | The revision of the recipe. The default value for this variable is “r0” 40 | 41 | ## Working Directory (WORKDIR) 42 | 43 | The **WORKDIR** is the pathname of the work directory in which the Yocto build system builds a recipe. This directory is located within the TMPDIR directory structure and is specific to the recipe being built and the system for which it is being built. 44 | 45 | ## Source (S) 46 | 47 | S is the location in the Build Directory where unpacked recipe source code resides. By default, this directory is WORKDIR/BPN-PV, where BPN is the base recipe name and PV is the recipe version. 48 | 49 | ## Destination (D) 50 | 51 | D is the destination directory. It is the location in the Build Directory where components are installed by the do_install task. This location defaults to WORKDIR/image. 52 | 53 | ## Build Directory (B) 54 | 55 | It is same as S. -------------------------------------------------------------------------------- /Cmake/03Variables.md: -------------------------------------------------------------------------------- 1 | # Variable and Cache 2 | 3 | 4 | 5 | ## Local Variables 6 | 7 | To set a local variable in Cmake 8 | 9 | ```CMake 10 | set(HELLO "value") 11 | ``` 12 | 13 | in order to access the following variables in another function provided by Cmake use `${}` meaning `${HELLO}` this will be replaced with `value` 14 | 15 | The local variable is only defined within the scope of CMakeList.txt file created or a scope of function created in cmake file (will discuss about function later). 16 | 17 | A variable can store list of values: 18 | 19 | ```cmake 20 | set(LIST "one" "two") 21 | # or 22 | set(LIST "one;two") 23 | ``` 24 | 25 | 26 | 27 | ## Cache Variables 28 | 29 | The cache is actually just a text file, `CMakeCache.txt`, that gets created in the build directory when you run CMake. This is how CMake remembers anything you set, so you don't have to re-list your options every time you rerun CMake 30 | 31 | If you want to set a variable from a command like how we use to do in Linux, Cmake offer `CACHE` keyword to make the variable in the cache. 32 | 33 | This will be like the variable initiate by Cmake such as `CMAKE_CXX_BUILD` 34 | 35 | ```cmake 36 | set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "Description of the variable") 37 | ``` 38 | 39 | If you want to use the value as global variable we can add `FORCE` 40 | 41 | ```cmake 42 | set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "Description of the variable" FORCE) 43 | ``` 44 | 45 | We can as well set option of value to be set as true or false called `BOOL` 46 | 47 | ```cmake 48 | option(MY_OPTION "This is settable from the command line" OFF) 49 | # ON OFF 50 | ``` 51 | 52 | See [cmake-variables](https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html) for a listing of known variables in CMake. 53 | 54 | 55 | 56 | ## Environment Variables 57 | 58 | in Cmake, you can as well set a variable as global by using the following commands 59 | 60 | ```cmake 61 | # to set an env variable 62 | set(ENV{variable_name} value) 63 | 64 | # to get the env variable 65 | $ENV{variable_name} 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /Cmake/04Programing.md: -------------------------------------------------------------------------------- 1 | # Programing Language 2 | 3 | 4 | 5 | ## Control flow 6 | 7 | Cmake is like any other programing language and it support if condition 8 | 9 | ```cmake 10 | f(variable) 11 | # If variable is `ON`, `YES`, `TRUE`, `Y`, or non zero number 12 | else() 13 | # If variable is `0`, `OFF`, `NO`, `FALSE`, `N`, `IGNORE`, `NOTFOUND`, `""`, or ends in `-NOTFOUND` 14 | endif() 15 | # If variable does not expand to one of the above, CMake will expand it then try again 16 | ``` 17 | 18 | here variable can be replace by many other case such as env variable and local variable discussed in previous chapters. 19 | 20 | ```cmake 21 | if("${variable}") 22 | # True if variable is not false-like 23 | else() 24 | # Note that undefined variables would be `""` thus false 25 | endif() 26 | ``` 27 | 28 | There are a variety of keywords as well, such as: 29 | 30 | - Unary: `NOT`, `TARGET`, `EXISTS` (file), `DEFINED`, etc. 31 | - Binary: `STREQUAL`, `AND`, `OR`, `MATCHES` (regular expression), `VERSION_LESS`, `VERSION_LESS_EQUAL` (CMake 3.7+), etc. 32 | - Parentheses can be used to group 33 | 34 | 35 | 36 | ## Macros and Functions 37 | 38 | You can define your own CMake [`function`](https://cmake.org/cmake/help/latest/command/function.html) or [`macro`](https://cmake.org/cmake/help/latest/command/macro.html) easily. The only difference between a function and a macro is scope. So, if you set a variable in a function and want it to be visible outside, you'll need `PARENT_SCOPE`. 39 | 40 | ```cmake 41 | function(functionName REQUIRED_ARG) 42 | message(STATUS "Simple arguments: ${REQUIRED_ARG}, followed by ${ARGN}") 43 | set(${REQUIRED_ARG} "From SIMPLE" PARENT_SCOPE) 44 | # without PARENT_SCOPE the variable won't be seen outside of the scope 45 | endfunction() 46 | 47 | functionName(This Foo Bar) 48 | message("Output: ${This}") 49 | ``` 50 | 51 | ```cmake 52 | # Define the macro 53 | macro(print_message message) 54 | # Create a variable to hold the formatted message 55 | set(formatted_message "[Macro Message] ${message}") 56 | 57 | endmacro() 58 | 59 | # Example usage of the macro 60 | print_message("Hello, this is a custom message.") 61 | 62 | # Print the formatted message 63 | message(STATUS ${formatted_message}) 64 | ``` 65 | 66 | We can see from macro from this example it will print the variable however we can see it's local but because cmake treated as text replacement not as function. 67 | 68 | if we did the same for function it won't work. -------------------------------------------------------------------------------- /Cmake/01Overview.md: -------------------------------------------------------------------------------- 1 | # CMake Overview 2 | 3 | ## What is CMake? 4 | 5 | [CMake](https://cmake.org/) is an open-source cross-platform build system designed to control the software building process. It allows developers to describe the build process in a platform-independent manner, and it generates native build files (such as Makefiles or project files for IDEs) based on the configuration provided. 6 | 7 | ## Key Concepts 8 | 9 | ### CMakeLists.txt 10 | 11 | The heart of CMake configuration is the `CMakeLists.txt` file. This file, typically located in the root of the project, contains instructions for CMake regarding how to build the project. It includes details like source files, dependencies, and build targets. 12 | 13 | ### Configure and Generate 14 | 15 | CMake operates in two main steps: configure and generate. During the configure step, CMake reads the `CMakeLists.txt` file and checks the system for necessary libraries, compilers, and other dependencies. In the generate step, CMake creates platform-specific build files based on the configuration. 16 | 17 | ### Build Directories 18 | 19 | CMake supports out-of-source builds, meaning the build files and the source code are in separate directories. This helps keep the source directory clean and facilitates building the same codebase with different configurations. (**use mkdir to create a directory build**) 20 | 21 | ## Basic Workflow 22 | 23 | 1. **Create CMakeLists.txt:** Start by creating a `CMakeLists.txt` file in your project directory. This file specifies project details, source files, and any dependencies. 24 | 25 | 2. **Configure:** Run `cmake` in the terminal, pointing it to the directory containing your `CMakeLists.txt` file. This step identifies the system environment and generates build files. 26 | 27 | ```bash 28 | cmake path/to/your/project 29 | ``` 30 | 31 | 3. **Generate:** After configuring, use the generated build files to compile your project. For Makefiles, run: 32 | 33 | ```bash 34 | make 35 | ``` 36 | 37 | 4. **Run and Test:** Execute the built executable or test files as needed. 38 | 39 | ## Example CMakeLists.txt 40 | 41 | ```cmake 42 | # minimum required version of cmake to run 43 | cmake_minimum_required(VERSION 3.12) 44 | 45 | # This is your project statement. You should always list languages; 46 | # Listing the version is nice here since it sets lots of useful variables 47 | project(MyProject VERSION 1.0 48 | DESCRIPTION "my first project" 49 | LANGUAGES CXX) 50 | 51 | # Add source files 52 | add_executable(my_executable main.cpp) 53 | ``` -------------------------------------------------------------------------------- /ViEditor/ViEditor.md: -------------------------------------------------------------------------------- 1 | # Vi Editor Cheat Sheet 2 | 3 | Vi is a powerful and widely used text editor in Linux. Below are some useful operations and commands to navigate and edit text in vi. 4 | 5 | ## Modes 6 | 7 | - **Normal Mode:** The default mode for navigation and executing commands. 8 | - **Insert Mode:** Allows you to insert and edit text. 9 | - **Visual Mode:** Enables text selection for copying or deleting. 10 | 11 | ## Navigation 12 | 13 | - `h` : Move cursor left. 14 | - `j` : Move cursor down. 15 | - `k` : Move cursor up. 16 | - `l` : Move cursor right. 17 | - `0` : Move to the beginning of the line. 18 | - `$` : Move to the end of the line. 19 | - `gg` : Move to the beginning of the file. 20 | - `G` : Move to the end of the file. 21 | - `Ctrl + b` : Move back one full screen. 22 | - `Ctrl + f` : Move forward one full screen. 23 | 24 | ## Editing 25 | 26 | ### Inserting and Appending 27 | 28 | - `i` : Enter insert mode before the cursor. 29 | - `I` : Enter insert mode at the beginning of the line. 30 | - `a` : Enter insert mode after the cursor. 31 | - `A` : Enter insert mode at the end of the line. 32 | - `o` : Open a new line below the current line and enter insert mode. 33 | - `O` : Open a new line above the current line and enter insert mode. 34 | 35 | ### Deleting 36 | 37 | - `x` : Delete the character under the cursor. 38 | - `dd` : Delete the current line. 39 | - `D` : Delete from the cursor position to the end of the line. 40 | 41 | ### Copying and Pasting 42 | 43 | - `yy` : Yank (copy) the current line. 44 | - `p` : Paste the yanked text after the cursor. 45 | - `P` : Paste the yanked text before the cursor. 46 | 47 | ### Undo and Redo 48 | 49 | - `u` : Undo the last change. 50 | - `Ctrl + r` : Redo the last undone change. 51 | 52 | ## Searching and Replacing 53 | 54 | - `/pattern` : Search forward for the specified pattern. 55 | - `?pattern` : Search backward for the specified pattern. 56 | - `n` : Move to the next occurrence of the search pattern. 57 | - `N` : Move to the previous occurrence of the search pattern. 58 | - `:s/old/new/g` : Replace all occurrences of "old" with "new" in the entire file. 59 | - `:n,ms/old/new/g` : Replace all occurrences in the range from line `n` to line `m`. 60 | 61 | ## Saving and Quitting 62 | 63 | - `:w` : Save changes to the file. 64 | - `:wq` or `:x` : Save changes and quit. 65 | - `:q!` : Quit without saving changes. 66 | 67 | Remember to press `Esc` to switch to normal mode before executing most commands. 68 | 69 | For more information, you can refer to the `vi` manual by typing `man vi` in the terminal. 70 | 71 | 72 | 73 | **Happy editing!** -------------------------------------------------------------------------------- /Cmake/05Configure.md: -------------------------------------------------------------------------------- 1 | # Configuration in Cmake 2 | 3 | 4 | 5 | ## Configure File 6 | 7 | If i want Cmake to generate a file that has some definition such as product_year, minor and major version, and those variable can printed in source file normally and be used. 8 | 9 | ```cmake 10 | set(PRODUCT_YEAR "2020") 11 | configure_file(config.h.in config.h) 12 | target_include_directories(targetname PUBLIC ${PROJECT_BINARY_DIR}) 13 | ``` 14 | 15 | In `config.h.in` 16 | 17 | ```cmake 18 | ##### this is configured within the configure file 19 | #define ProductType "value" 20 | 21 | #### this variable can be assigned in cmake file 22 | #define ProductYear "${PRODUCT_YEAR}" 23 | 24 | #### this to get importent variable 25 | #define MY_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ 26 | #define MY_VERSION_MINOR @PROJECT_VERSION_MINOR@ 27 | ``` 28 | 29 | 30 | 31 | 32 | 33 | ## Reading Files 34 | 35 | The other direction can be done too; you can read in something (like a version) from your source files. If you have a header only library that you'd like to make available with or without CMake, for example, then this would be the best way to handle a version. This would look something like this: 36 | 37 | ```cmake 38 | # Assuming the canonical version is listed in a single line 39 | # This would be in several parts if picking up from MAJOR, MINOR, etc. 40 | set(VERSION_REGEX "#define MY_VERSION[ \t]+\"(.+)\"") 41 | 42 | # Read in the line containing the version 43 | file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/My/Version.hpp" 44 | VERSION_STRING REGEX ${VERSION_REGEX}) 45 | 46 | # Pick out just the version 47 | string(REGEX REPLACE ${VERSION_REGEX} "\\1" VERSION_STRING "${VERSION_STRING}") 48 | 49 | # Automatically getting PROJECT_VERSION_MAJOR, My_VERSION_MAJOR, etc. 50 | project(My LANGUAGES CXX VERSION ${VERSION_STRING}) 51 | ``` 52 | 53 | Above, `file(STRINGS file_name variable_name REGEX regex)` picks lines that match a regex; and the same regex is used to then pick out the parentheses capture group with the version part. Replace is used with back substitution to output only that one group. 54 | 55 | 56 | 57 | ## Running a command at build time 58 | 59 | Build time commands are a bit trickier. The main complication comes from the target system; when do you want your command to run? Does it produce an output that another target needs? With this in mind, here is an example that calls a Python script to generate a header file: 60 | 61 | ```cmake 62 | add_custom_target(flash ALL 63 | DEPENDS main.elf 64 | COMMAND avr-objcopy -j .text -j .data -o ihex main.elf main.hex 65 | ) 66 | 67 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp DESTINATION include) 68 | ``` 69 | 70 | ALL here is used to run the command with make command. -------------------------------------------------------------------------------- /8-Yocto/6-TaskBuild/README.md: -------------------------------------------------------------------------------- 1 | # Task Build 2 | 3 | To build a recipe we need to run some tasks 4 | 5 | To list task inside a recipe we need to run 6 | 7 | ```sh 8 | bitbake -c listtasks 9 | ``` 10 | 11 | To clean the recipe 12 | 13 | ``` 14 | bitbake -c cleanall 15 | ``` 16 | 17 | The output of the task is list in alphabetics order. 18 | 19 | The most common tasks are: 20 | 21 | | Tasks | Description | 22 | | ---------------------------- | ------------------------------------------------------------ | 23 | | Fetch **(do_fetch)** | Fetches the source code | 24 | | Unpack **(do_unpack)** | unpacks the source code into a working directory | 25 | | Patch **(do_patch)** | Locates patch files and applies them to the source code | 26 | | configure **(do_configure)** | Configures the source by enabling and disabling any build-time and configuration options for the software being built | 27 | | Compile **(do_compile)** | Compiles the source in the compilation directory | 28 | | Install **(do_install)** | Copies files from the compilation directory to a holding area | 29 | 30 | 31 | 32 | ## Fetch Task 33 | 34 | Fetch task it fetches the package source from the local or remote repository. 35 | 36 | To fetch a package source you need to add the source in **SRC_URI** variable in the recipe. 37 | 38 | **SRCREV** describe if you want to fetch specific revision (Commit hash) 39 | 40 | to excute only the fetch task 41 | 42 | ```bash 43 | bitbake -c do_fetch 44 | ``` 45 | 46 | the output will be shown in download folder which is described in local.conf file. 47 | 48 | 49 | 50 | ## Unpack Task 51 | 52 | Unpack task unpacks the package that has been downloaded with Fetch task. 53 | 54 | the unpacking is stored in Working directory of the recipe, to show it 55 | 56 | ```shell 57 | bitbake -e | grep ^WORKDIR 58 | ``` 59 | 60 | in order to see the unpack what is does, first we set the variable **S** to the work directory of the recipe then run the following bitbake command 61 | 62 | ```bash 63 | bitbake -c do_unpack 64 | ``` 65 | 66 | the output will be show in work directory folder. 67 | 68 | 69 | 70 | ## Patch Task 71 | 72 | Patch task locates the patch files and applies the patches to the sources if any patch is available. 73 | 74 | This is optional task, executes if patch is available. 75 | 76 | A patch files provides some explicit changes for a specific file. That can be applied to that file. 77 | 78 | It can be defined in **SRC_URI** variable after the fetch or we can use **SRC_URI:append = ** 79 | 80 | to run the patch task 81 | 82 | ```bash 83 | bitbake -c do_patch 84 | ``` 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /8-Yocto/bitbake/README.md: -------------------------------------------------------------------------------- 1 | # Bitbake Cheat-sheet 2 | 3 | This all commands that you need to know in bitbake 4 | 5 | ## Basic Commands 6 | 7 | | Commands | Descriptions | 8 | | --------------------------------------------- | ------------------------------------------------------------ | 9 | | bitbake -vDDD | Verbose | 10 | | bitbake -s | List recipe add in the bblayer in conf file that will be executed | 11 | | bitbake -c listtasks | List task will be excuted by the recipe | 12 | | bitbake -c | Run specific task of the recipe | 13 | | bitbake | Run all task in the recipe | 14 | | bitbake -c cleanall | Delete the recipe from work directory | 15 | | bitbake -c devshell | To trigger a shell inside the work directory if you wan to configure something manually | 16 | | bitbake -c cleansstate | Clean the cashes of the recipe build | 17 | | bitbake -e \| grep | if you want to see a specific variable value in your recipe | 18 | | bitbake-getvar | if you want to list an environment variable in bitbake such as `LDFLAGS` | 19 | 20 | 21 | 22 | ## Bitbake-layers command 23 | 24 | | Commands | Description | 25 | | ------------------------------- | ------------- | 26 | | bitbake-layers | Add new layer | 27 | | bitbake-layers | Remove layer | 28 | | bitbake-layers | Show layers | 29 | | bitbake-layers | show recipes | 30 | 31 | 32 | 33 | ## Adding file into rootfs 34 | 35 | ```bash 36 | DESCRIPTION = "Install file into rootfs" 37 | 38 | LICENSE = "MTI" 39 | LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MTI-2.0;md5=0835ade698e0bcf8506ecda2f7b4f302" 40 | 41 | #to add extra directory to look at 42 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" 43 | 44 | #take file from files directory 45 | SRC_URI += "git://github.com/ \ 46 | file://file1 \ 47 | file://file2 \ 48 | " 49 | 50 | # Output of the fetch code 51 | S = "${WORKDIR}/git" 52 | 53 | 54 | do_install_append() { 55 | #create custom dir into rootfs 56 | install -d ${D}{bindir} 57 | #copy files inside 58 | install -m 0644 ${S}/file1 ${D}{bindir} 59 | install -m 0644 ${S}/file2 ${D}{bindir} 60 | } 61 | ``` 62 | 63 | 64 | 65 | # Increase Filesystem size of a .wic/.sdcard 66 | 67 | For example setting the RootFS to 2GB would require the following addition to the `local.conf` file: 68 | 69 | ```bash 70 | IMAGE_ROOTFS_SIZE = “2097152” 71 | IMAGE_OVERHEAD_FACTOR = “1.0” 72 | ``` -------------------------------------------------------------------------------- /8-Yocto/2-FolderDescription/README.md: -------------------------------------------------------------------------------- 1 | # Folder Descriptions 2 | 3 | ## LOCAL.CONF 4 | 5 | | Variable | Description | 6 | | -------------------- | ------------------------------------------------------------ | 7 | | MACHINE | Machine that you will use, you need to include the meta layer that has your machine that you will use. ---> Example **BeagleBone**: meta-yocto-bsp/conf/machine/beaglebone-yocto.conf | 8 | | SOURCES | | 9 | | DL_DIR | Download directory, contains all downloaded file needed to create our package and if we creating another image we will not need to download it from the beginning again | 10 | | SSTATE_DIR | contains the packaging build to get a binary, the use case is to not build a package again if it's already build | 11 | | TMPDIR | Specify the temporary file where in yocto it contains the deploy folder for the image | 12 | | DISTRO | specify name of the distribution, an a distribution is collection of software component and configuration files works together to create an image. This distro depend on the reference distribution that we will use. | 13 | | PACKAGE_CLASSES | mostly is how the yocto will make the package | 14 | | EXTRA_IMAGE_FEATURES | Some extra tools to add to the image such as debugging feature (refer to local.conf) | 15 | | USER_CLASSES | specify the time took to compile the package and build it | 16 | | PATCHRESOLVE | it can be assign to two variable **noop** (describe if we face issue during patch build will stop) **user** (open a terminal fix the patch no stopping the build) | 17 | | BB_DISK_DIRS | safety mechanism to track the size of the files TMP, DL, SSTATE directory to not consume full space as if so, the system may crash | 18 | | CONF_VERSION | The build system you will use it each build | 19 | | RM_OLD_IMAGE | if is set to **1** this will delete the image file before executing to save space and to avoid dependencies issue | 20 | | INHERIT | if it set to **rm_work**, after creating the package and already included to the image will delete the bin under the temp folder | 21 | 22 | 23 | 24 | ## BBLAYERS.CONF 25 | 26 | | Variable | Description | 27 | | -------------------------- | ------------------------------------------------------------ | 28 | | POKY_BBLAYERS_CONF_VERSION | This the configuration version | 29 | | BBLAYERS | All meta layer that poky reference will use to generate the image, inside meta layer there's recipes | 30 | | BBPATH | Path to find the meta layers folder | 31 | 32 | ### Bitbake command to add layer: 33 | 34 | ```shell 35 | # !!! enter build directory (MUST) 36 | 37 | # To show layers 38 | bitbake-layers show-layers 39 | 40 | # To add layers 41 | bitbake-layers add-layer ../meta* 42 | 43 | # To remove layers 44 | bitbake-layers remove-layer meta* 45 | ``` 46 | 47 | 48 | 49 | # Adding Package 50 | 51 | Suppose we intend to incorporate Git support into our image, necessitating the addition of Git-related packages. To initiate this process, we must first verify the package's availability on our system. This can be done as follows: 52 | 53 | ```shell 54 | # Display the layer where the Git package is located 55 | bitbake-layers show-recipes git 56 | ``` 57 | 58 | Next, proceed to the **local.conf** file and make the following modifications: 59 | 60 | ```sh 61 | # Add Git and Python3 to the IMAGE_INSTALL list 62 | IMAGE_INSTALL:append = "git" 63 | IMAGE_INSTALL:append = "python3" 64 | ``` 65 | 66 | Afterward, rebuild the image to implement these changes. 67 | -------------------------------------------------------------------------------- /Cmake/02BasicConcept.md: -------------------------------------------------------------------------------- 1 | # Basics Concept 2 | 3 | ## Minimum Version 4 | 5 | Here's the first line of every `CMakeLists.txt`, which is the required name of the file CMake looks for: 6 | 7 | ```cmake 8 | cmake_minimum_required(VERSION 3.1) 9 | 10 | # you can set a version from to by the following 11 | cmake_minimum_required(VERSION 3.1...3.12) 12 | ``` 13 | 14 | The `cmake_minimum_required` command in CMake is required to set the version of the current cmake file use. The `VERSION` is a special keyword for this function, and the version value follows the keyword. In this documentation, you can click on the command name to access the [official documentation](https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html). 15 | 16 | ## Create project 17 | 18 | Now, every top-level CMake file will have the next line: 19 | 20 | ```cmake 21 | project(MyProject VERSION 1.0 22 | DESCRIPTION "Very nice project" 23 | LANGUAGES CXX) 24 | ``` 25 | 26 | Here Version describe the version of the project, and you can give small description to describe the project following by the language used for the project to compile. 27 | 28 | ## Making an executable 29 | 30 | Although libraries are much more interesting, and we'll spend most of our time with them, let's start with a simple executable. 31 | 32 | ```cmake 33 | add_executable(hellobinary main.cpp header.h) 34 | ``` 35 | 36 | here the executable is used to create a executable binary file which will be named `hellobinary`, `hellobinary` can be described as target as well. then the other input are the folder to be compiled taking in count that cmake is smart to know that header file are only to be included in the cpp file and will only proceed with compiling the `main.cpp` file. you can add many input file as you want after the target. 37 | 38 | ## Making a Library 39 | 40 | Making a library is done with [`add_library`](https://cmake.org/cmake/help/latest/command/add_library.html), and is just about as simple: 41 | 42 | ```cmake 43 | add_library(operation STATIC operations.cpp operations.h) 44 | ``` 45 | 46 | with the following command cmake will create a library named operation which as well represent a target. We can see here a keyword static which mean that cmake will create the library static `.a` however, if you want to created as shared replace `STATIC` witch `SHARED` 47 | 48 | if you left it empty the library will be created by the value stored in the variable `BUILD_SHARED_LIBS` 49 | 50 | ## Usage of target 51 | 52 | in order to include more directory to let cmake look at we use the [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html) 53 | 54 | ```cmake 55 | target_include_directories(hellobinary INTERFACE include/) 56 | ``` 57 | 58 | here we are including `include` directory to the project to let cmake look at. `PUBLIC` explain that any target need target `hellobinary` must include the `include` file. 59 | 60 | `INTERFACE` here is used if nothing depends on the directory include, is usually used with header file, as header file are not part of the compilation process. 61 | 62 | [`target_link_libraries`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html) is used to link a library to the executable that will be created, example: 63 | 64 | ```cmake 65 | #link the library 66 | target_link_libraries(helloworld PUBLIC operation) 67 | ``` 68 | 69 | we will discuss later how we created the operation mentioned. 70 | 71 | # Quick Example 72 | 73 | ```cmake 74 | #version required 75 | cmake_minimum_required(VERSION 3.2) 76 | 77 | project(Calculator LANGUAGES CXX) 78 | 79 | add_library(operation STATIC src/operation.cpp include/calc/operation.hpp) 80 | target_include_directories(operation PUBLIC include) 81 | target_compile_features(operation PUBLIC cxx_std_11) 82 | 83 | add_executable(calc apps/calc.cpp) 84 | target_link_libraries(calc PUBLIC operation) 85 | ``` -------------------------------------------------------------------------------- /8-Yocto/1-YoctoTerminology/WhatToEdit.md: -------------------------------------------------------------------------------- 1 | # Recipes 2 | 3 | **Non-Yocto:** A recipe is a set of instructions that describe how to prepare or make something, especially a dish 4 | 5 | **Yocto:** A recipe is a set of instructions that is read and processed by the bitbake 6 | 7 | Extension of Recipe: **.bb** 8 | 9 | A recipe describes: 10 | 11 | - where you get source code 12 | - which patches to apply 13 | - Configuration options 14 | - Compile options (library dependencies) 15 | - Install 16 | - License 17 | 18 | **Examples of Recipes** 19 | 20 | - dhcp_4.4.1.bb 21 | - gstreamer1.0_1.16.1.bb 22 | 23 | # Configuration Files 24 | 25 | **Files which hold** 26 | global definition of variables 27 | user defined variables and 28 | hardware configuration information 29 | 30 | They tell the build system what to build and put into the image to support a particular platform 31 | 32 | - Extension: **.conf** 33 | 34 | 35 | Types 36 | -------- 37 | 38 | • Machine Configuration Options 39 | • Distribution Configuration Options 40 | • Compiler tuning options 41 | • General Common Configuration Options 42 | • User Configuration Options (local.conf) 43 | 44 | # Classes 45 | 46 | Class files are used to abstract common functionality and share it **amongst multiple recipe (.bb)** files 47 | 48 | To use a class file, you simply make sure **the recipe inherits the class** 49 | 50 | Eg. inherit classname 51 | 52 | - Extension: .**bbclass** 53 | 54 | 55 | They are usually placed in classes directory inside the **meta*** directory 56 | 57 | Example of classes 58 | ------------------- 59 | 60 | - **cmake.bbclass** - Handles cmake in recipes 61 | - **kernel.bbclass** - Handles building kernels. Contains code to build all kernel trees 62 | - **module.bbclass** - Provides support for building out-of-tree Linux Kernel Modules 63 | 64 | # Layers 65 | 66 | A collection of related recipes. 67 | 68 | or 69 | 70 | Layers are recipe containers (folders) 71 | 72 | Typical naming convention: **meta-** 73 | 74 | Poky has the following layers: 75 | 76 | meta, meta-poky, meta-selftest, meta-skeleton, meta-yocto-bsp 77 | 78 | Why Layers 79 | ----------- 80 | 81 | Layers provide a mechanism to isolate meta data according to functionality, for instance BSPs, distribution configuration, etc. 82 | 83 | You could have a BSP layer, a GUI layer, a distro configuration, middleware, or an application 84 | 85 | Putting your entire build into one layer limits and complicates future customization and reuse. 86 | 87 | **Example:** 88 | 89 | - meta-poky -- Distro metadata 90 | - meta-yocto-bsp -- BSP metadata 91 | 92 | Layers allow to easily to add entire sets of meta data and/or replace sets with other sets. 93 | meta-poky, is itself a layer applied on top of the OE-Core metadata layer, meta 94 | 95 | Command to find out which layers are present 96 | ---------------------------------------------- 97 | 98 | `$ bitbake-layers show-layers` 99 | 100 | Note: You can include any number of available layers from the Yocto Project 101 | 102 | Where to get other layers 103 | -------------------------- 104 | 105 | https://layers.openembedded.org/layerindex/branch/master/layers/ 106 | 107 | # Image 108 | 109 | An image is the top level recipe, it has a description, a license and inherits the core-image class 110 | 111 | It is used alongside the machine definition 112 | 113 | machine describes the hardware used and its capabilities 114 | 115 | image is architecture agnostic and defines how the root filesystem is built, with what packages. 116 | 117 | By default, several images are provided in Poky 118 | 119 | Command to check the list of available image recipes 120 | ---------------------------------------------------- 121 | 122 | ```bash 123 | `$ ls meta*/recipes*/images/*.bb` 124 | ``` 125 | 126 | # Packages 127 | 128 | **Non-Yocto:** Any wrapped or boxed object or group of objects. 129 | 130 | **Yocto:** A package is a binary file with name *.rpm, *.deb, or *.ipkg 131 | 132 | A single recipe produces many packages. All packages that a recipe generated are listed in the recipe variable 133 | 134 | ```bash 135 | $ vi meta/recipes-multimedia/libtiff/tiff_4.0.10.bb 136 | PACKAGES =+ "tiffxx tiff-utils" 137 | ``` 138 | 139 | -------------------------------------------------------------------------------- /1-Library/README.md: -------------------------------------------------------------------------------- 1 | # Library 2 | 3 | A library is a group of pre-compiled coded, called functions, to avoid repetition of code, package is created, called library. 4 | 5 | Note: Library is not an executable. 6 | 7 | ## Static Library and Building Process 8 | 9 | ### Introduction 10 | 11 | A **static library** is a collection of object files that are linked together during the compilation phase of a program. Unlike dynamic libraries, static libraries are linked with the program at compile time, resulting in a single executable file that contains the code from both the program and the library. 12 | 13 | ### Building a Static Library 14 | 15 | #### 1. Write Your Code 16 | 17 | Write the source code for your library. For example, let's create a simple library named `mylib` with a function `add_numbers`: 18 | 19 | ```c 20 | #ifndef MYLIB_H 21 | #define MYLIB_H 22 | 23 | int add_numbers(int a, int b); 24 | 25 | #endif 26 | ``` 27 | 28 | ```c 29 | #include "mylib.h" 30 | 31 | int add_numbers(int a, int b) { 32 | return a + b; 33 | } 34 | ``` 35 | 36 | #### 2. Compile the Source Files 37 | 38 | Compile the source files (`mylib.c` in this case) into object files using a compiler like `gcc`: 39 | 40 | ```bash 41 | gcc -c mylib.c -o mylib.o 42 | ``` 43 | 44 | #### 3. Create the Static Library 45 | 46 | Use the `ar` (archiver) command to create the static library (`libmylib.a`): 47 | 48 | ```bash 49 | ar rcs libmylib.a mylib.o 50 | ``` 51 | 52 | This command creates a static library (`libmylib.a`) and adds the object file (`mylib.o`) to it. 53 | 54 | #### 4. Use the Static Library in Your Program 55 | 56 | Now, you can use the static library in your main program. Create a program (`main.c`) that includes the library header and calls the library function: 57 | 58 | ```c 59 | // main.c 60 | #include 61 | #include "mylib.h" 62 | 63 | int main() { 64 | int result = add_numbers(5, 7); 65 | printf("Result: %d\n", result); 66 | return 0; 67 | } 68 | ``` 69 | 70 | #### 5. Compile Your Program with the Static Library 71 | 72 | Compile your program with the static library: 73 | 74 | ```bash 75 | gcc main.c -o my_program -L. -lmylib 76 | # OR 77 | gcc main.c -o my_program -L. libmylib 78 | ``` 79 | 80 | Here, `-L.` tells the linker to look for libraries in the current directory, and `-lmylib` links your program with `libmylib.a`. 81 | 82 | #### 6. Run Your Program 83 | 84 | Execute the compiled program: 85 | 86 | ```bash 87 | ./my_program 88 | ``` 89 | 90 | ## Dynamic Library and Building Process 91 | 92 | ### Introduction 93 | 94 | A **dynamic library** is a collection of compiled code that can be loaded into a program at runtime. Unlike static libraries, dynamic libraries are not embedded into the executable at compile time. Instead, they are linked at runtime, providing flexibility and modularity to the programs. 95 | 96 | ### Building a Dynamic Library 97 | 98 | #### 1. Write Your Code 99 | 100 | Similar to static libraries, write the source code for your library. For example, let's create a dynamic library named `mylib` with a function `add_numbers`: 101 | 102 | ```c 103 | // mylib.h 104 | #ifndef MYLIB_H 105 | #define MYLIB_H 106 | 107 | int add_numbers(int a, int b); 108 | 109 | #endif 110 | ``` 111 | 112 | ```c 113 | // mylib.c 114 | #include "mylib.h" 115 | 116 | int add_numbers(int a, int b) { 117 | return a + b; 118 | } 119 | ``` 120 | 121 | #### 2. Compile the Dynamic Library 122 | 123 | Compile the source file into a shared object (dynamic library) using the `-shared` flag: 124 | 125 | ```bash 126 | gcc -shared -fPIC -o libmylib.so mylib.c 127 | ``` 128 | 129 | The `-shared` flag indicates that you are creating a shared object, and `-fPIC` generates position-independent code, which is necessary for shared libraries. 130 | 131 | #### 3. Use the Dynamic Library in Your Program 132 | 133 | Create a program (`main.c`) that includes the library header and calls the library function: 134 | 135 | ```c 136 | // main.c 137 | #include 138 | #include "mylib.h" 139 | 140 | int main() { 141 | int result = add_numbers(5, 7); 142 | printf("Result: %d\n", result); 143 | return 0; 144 | } 145 | ``` 146 | 147 | #### 4. Compile Your Program with the Dynamic Library 148 | 149 | Compile your program with the dynamic library: 150 | 151 | ``` 152 | gcc main.c -o my_program -L. -lmylib 153 | ``` 154 | 155 | Here, `-L.` tells the linker to look for libraries in the current directory, and `-lmylib` links your program with `libmylib.so`. 156 | 157 | #### 5. Run Your Program 158 | 159 | Execute the compiled program: 160 | 161 | ```bash 162 | ./my_program 163 | ``` 164 | 165 | -------------------------------------------------------------------------------- /8-Yocto/1-YoctoTerminology/README.md: -------------------------------------------------------------------------------- 1 | # POKY 2 | 3 | Poky is a reference distribution of Yocto Project. The word "reference" is used to mean "example" in this context. 4 | 5 | Yocto Project uses Poky to build images (kernel, system, and application software) for targeted hardware. 6 | 7 | At the technical level it is a combined repository of the components 8 | • Bitbake 9 | • OpenEmbedded Core 10 | • meta-yocto-bsp 11 | • Documentation 12 | 13 | Note: Poky does not contain binary files,it is a working example of how to build your own custom Linux distribution from source. 14 | 15 | What is difference between poky and Yocto 16 | ----------------------------------------- 17 | 18 | The exact difference between Yocto and Poky is Yocto refers to the organization ( like one would refer to 'canonical', the company behind Ubuntu ), and Poky refers to the actual bits downloaded ( analogous to 'Ubuntu' ) 19 | 20 | # Metadata 21 | 22 | **Non Yocto:** A set of data that describes and gives information about other data 23 | 24 | **Yocto World:** 25 | Metadata refers to the build instructions, Commands and data used to indicate what versions of software are used Where they are obtained from Changes or additions to the software itself ( patches ) which are used to fix bugs or customize the software for use in a particular situation 26 | 27 | Metadata is collection of 28 | 29 | - ​ Configuration files (.conf) 30 | - ​ Recipes (.bb and .bbappend) 31 | - ​ Classes (.bbclass) 32 | - ​ Includes (.inc) 33 | 34 | # OpenEmbedded Project 35 | 36 | From http://www.openembedded.org/wiki/Main_Page 37 | 38 | OpenEmbedded offers a best-in-class cross-compile environment. It allows developers to create a complete Linux Distribution for embedded systems. 39 | 40 | What is the difference between OpenEmbedded and the Yocto Project? 41 | ------------------------------------------------------------------ 42 | 43 | The Yocto Project and OpenEmbedded share a core collection of **metadata** called **openembedded-core.** 44 | 45 | However, the two organizations remain separate, each with its own focus 46 | 47 | **OpenEmbedded** provides a comprehensive set of metadata for a wide variety of architectures, features, and applications 48 | 49 | Not a reference distribution 50 | Designed to be the foundation for others 51 | 52 | The **Yocto** Project focuses on providing powerful, easy-to-use, interoperable, well-tested tools, metadata, and board support packages (BSPs) for a core set of architectures and specific boards. 53 | 54 | 55 | OpenEmbedded-Core(oe-core) 56 | --------------------------- 57 | 58 | The Yocto Project and OpenEmbedded have agreed to work together and share a common core set of metadata(recipes, classes and associated files): oe-core 59 | 60 | # Bitbake 61 | 62 | - Bitbake is a core component of the Yocto Project. 63 | 64 | 65 | - It basically performs the same functionality as of **make**. 66 | 67 | 68 | - It's a task scheduler that parses **python** and **shell** **script** mixed code 69 | 70 | 71 | - The code parsed generates and runs **tasks**, which are basically a set of steps ordered according to code's dependencies. 72 | 73 | 74 | - It reads recipes and follows them by fetching packages, building them and incorporating the results into bootable images. 75 | 76 | 77 | - It keeps track of all tasks being processed in order to ensure completion, maximizing the use of processing resources to reduce build time and being predictable. 78 | 79 | # meta-yocto-bsp 80 | 81 | A Board Support Package (BSP) is a collection of information that defines how to support a particular **hardware device**, **set of devices**, or **hardware platform** 82 | 83 | The BSP includes information about the hardware features present on the device and kernel configuration information along with any additional hardware drivers required. 84 | 85 | The BSP also lists any additional software components required in addition to a generic Linux software stack for both essential and optional platform features. 86 | 87 | The meta-yocto-bsp layer in Poky maintains several BSPs such as the Beaglebone, EdgeRouter, and generic versions of both 32-bit and 64-bit IA machines. 88 | 89 | Machines supported 90 | ------------------- 91 | Texas Instruments BeagleBone (beaglebone) 92 | Freescale MPC8315E-RDB (mpc8315e-rdb) 93 | Intel x86-based PCs and devices (genericx86 and genericx86-64) 94 | Ubiquiti Networks EdgeRouter Lite (edgerouter) 95 | 96 | Note: To develop on different hardware, you will need to complement Poky with hardware-specific Yocto layers. 97 | 98 | # meta-poky 99 | 100 | meta-poky, which is Poky-specific metadata 101 | 102 | Documentation, which contains the Yocto Project source files used to make the set of user manuals. 103 | 104 | # Conclusion 105 | 106 | **Poky includes** 107 | some OE components(oe-core) 108 | bitbake 109 | demo-BSP's 110 | helper scripts to setup environment 111 | emulator QEMU to test the image -------------------------------------------------------------------------------- /8-Yocto/4-Variables/Variable_Assignment.md: -------------------------------------------------------------------------------- 1 | # Variable Assignment 2 | 3 | ## Types of Variable Assignments 4 | 5 | | Assignment | Description | 6 | | ---------- | ------------------------------------------------------------ | 7 | | ?= | This is used to assign the default value to varibale. It can be overridden. | 8 | | ??= | This is used to assign the default value to varibale. But it is a weak assignment. It can be overridden. If multiple assignments are done with this type, the the last one will be considered. | 9 | | = | This is a simple variable assignment. It requires " " and spaces are significant. But variables are expanded at the end. | 10 | | := | This is an immediate variable expansion. The value assigned is expanded immediately. | 11 | | += | This appends a value to a variable. The operator inserts **a space** between the current value and appended value. It takes effect immediately. | 12 | | =+ | This prepends a value to a variable, The operator inserts **a space** between the current value and prepended value. It takes effect immediately. | 13 | | .= | This appends a value to a variable. The operator inserts **no space** between the current value and appended value. It takes effect immediately. | 14 | | =. | This prepends a value to a variable. The operator inserts **no space** between the current value and prepended value. It takes effect immediately. | 15 | | :append | This appends a value to a variable. The operator inserts **no space** between the current value and appended value. The effects are applied at variable expansion time rather than being immediately applied. | 16 | | :prepend | This appends a value to a variable. The operator inserts **no space** between the current value and appended value. The effects are applied at variable expansion time rather than being immediately applied. | 17 | | :remove | This remove values from lists. Specifying a value for removal causes all occurrences of that value to be removed from the variable. | 18 | 19 | ### How to Read Variable Value 20 | 21 | ```sh 22 | bitbake -e | grep ^= 23 | ``` 24 | 25 | 26 | 27 | ## Assignment Type ?= 28 | 29 | ```sh 30 | TEST ?= "foo" 31 | TEST ?= "bar" 32 | TEST ?= "val" 33 | TEST ?= "var" 34 | 35 | # The final value is TEST="foo" 36 | ``` 37 | 38 | 39 | 40 | ## Assignment Type ??= 41 | 42 | ```sh 43 | TEST ??= "foo" 44 | TEST ??= "bar" 45 | TEST ??= "val" 46 | TEST ??= "var" 47 | 48 | # The final value is TEST="var" 49 | ``` 50 | 51 | 52 | 53 | ```sh 54 | TEST ??= "foo" 55 | TEST ?= "bar" 56 | TEST ?= "val" 57 | TEST ??= "var" 58 | 59 | # The final value is TEST="bar" 60 | ``` 61 | 62 | 63 | 64 | ## Assignment Type = 65 | 66 | ```sh 67 | # Override 68 | A ?= "foo" 69 | A = "bar" 70 | 71 | # The final value is A="bar" 72 | 73 | # Variable Expansion 74 | A = "foo" 75 | B = "${A}" 76 | A = "bar" 77 | 78 | # The final value is B="bar" 79 | ``` 80 | 81 | 82 | 83 | ## Assignment Type := 84 | 85 | ```shell 86 | # Override 87 | A ?= "foo" 88 | A := "bar" 89 | 90 | # The final value is A="bar" 91 | 92 | # Variable Expansion 93 | A = "foo" 94 | B := "${A}" 95 | A = "bar" 96 | # The final value is B="foo" 97 | ``` 98 | 99 | 100 | 101 | ## Assignment Type += and =+ 102 | 103 | ```bash 104 | # Spaces are added here 105 | 106 | # Append 107 | A = "foo" 108 | A += "bar" 109 | 110 | # The final value is A="foo bar" 111 | 112 | # Prepend 113 | B = "foo" 114 | B =+ "bar" 115 | 116 | # The final value is B="bar foo" 117 | 118 | # Append 119 | A ?= "val" 120 | A += "var" 121 | 122 | # The final value is A="var" 123 | 124 | # Prepend 125 | B ??= "val" 126 | B =+ "var" 127 | 128 | # The final value is B="var" 129 | ``` 130 | 131 | 132 | 133 | ## Assignment Type .= and =. 134 | 135 | ```shell 136 | # No Spaces are added here 137 | # Needs to add extra space 138 | 139 | # Append 140 | A = "foo" 141 | A .= "bar" 142 | 143 | # The final value is A="foobar" 144 | 145 | # Prepend 146 | B = "foo" 147 | B =. "bar" 148 | 149 | # The final value is B="barfoo" 150 | ``` 151 | 152 | 153 | 154 | ## Assignment Type :append, :prepend and :remove 155 | 156 | ```shell 157 | # No Spaces are added here 158 | # Needs to add extra space 159 | # Parsed at the end 160 | 161 | # Append 162 | A = "foo" 163 | A:append = "bar" 164 | # The final value is A="foobar" 165 | 166 | # Append 167 | A = "foo" 168 | A:append = "bar" 169 | A += "val" 170 | # The final value is A="foo valbar" 171 | 172 | # Append 173 | A = "foo" 174 | A:append = " bar" 175 | # The final value is A="foo bar" 176 | 177 | 178 | # Prepend 179 | A = "foo" 180 | A:prepend = "bar" 181 | # The final value is A="barfoo" 182 | 183 | # Prepend 184 | A = "foo" 185 | A:prepend = "bar" 186 | A =+ "val" 187 | # The final value is A="barval foo" 188 | 189 | # Prepend 190 | A = "foo" 191 | A:prepend = "bar " 192 | # The final value is A="bar foo" 193 | 194 | #remove 195 | 196 | A = "foo bar" 197 | A:remove = "foo" 198 | # The final value is A=" bar" 199 | 200 | A = "foo bar" 201 | A:remove = "var" 202 | A += "var" 203 | # The final value is A=" foo bar val" 204 | ``` 205 | 206 | 207 | 208 | ## Reference 209 | 210 | https://docs.yoctoproject.org/bitbake/2.2/bitbake-user-manual/bitbake-user-manual-metadata.html -------------------------------------------------------------------------------- /4-kernel/README.md: -------------------------------------------------------------------------------- 1 | # Linux Kernel 2 | 3 | The Linux kernel is the core component of the Linux operating system, responsible for managing system resources such as memory, processes, input/output (I/O), and device drivers. It is an open-source software project that was initially developed by Linus Torvalds in 1991 and is now maintained by a large community of developers around the world. 4 | 5 | ## Download Linux Kernel 6 | 7 | ### Vexpress (Qemu) 8 | 9 | ```bash 10 | git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git 11 | cd linux 12 | 13 | #configure the kernel to vexpress 14 | make ARCH=arm vexpress_defconfig 15 | 16 | # To indentify your kernel version 17 | make ARCH=arm kernelversion 18 | ``` 19 | 20 | ### Raspberry Pi 21 | 22 | ```bash 23 | git clone --depth=1 https://github.com/raspberrypi/linux 24 | cd linux 25 | 26 | #configure the kernel to rpi depends on the SoC number 27 | make bcmXXXX_defconfig 28 | ``` 29 | 30 | ### BeagleBone 31 | 32 | ```bash 33 | git clone --depth=1 https://github.com/beagleboard/linux.git 34 | cd linux 35 | 36 | #configure the kernel to beaglebone 37 | make bb.org_defconfig 38 | ``` 39 | 40 | ## Configure Kernel 41 | 42 | For all the next board this configuration must be checked 43 | 44 | - [ ] Enable **devtmpfs** 45 | - [ ] Change kernel compression to **XZ** 46 | - [ ] Change your kernel local version to your name and append on it -v1.0 47 | 48 | ### Vexpress (Qemu) 49 | 50 | ```bash 51 | #export the compiler 52 | export CROSS_COMPILE=PathToCompiler/arm-linux-cortexa9Compiler 53 | #export the architecture used 54 | export ARCH=arm 55 | 56 | #configure the kernel with the configuration discuss above 57 | make menuconfig 58 | 59 | #build the kernel 60 | make -j4 zImage modules dtbs 61 | ``` 62 | 63 | ### Raspberry PI 64 | 65 | ```bash 66 | #export the compiler 67 | export CROSS_COMPILE=arm-linux-gnueabihf- 68 | #export the architecture used 69 | export ARCH=arm 70 | 71 | #configure the kernel with the configuration discuss above 72 | make menuconfig 73 | 74 | #build the kernel 75 | make -j4 zImage modules dtbs 76 | ``` 77 | 78 | ### BeagleBone 79 | 80 | ```bash 81 | #export the compiler 82 | export CROSS_COMPILE=PathToCompiler/arm-linux-cortexa9Compiler 83 | #export the architecture used 84 | export ARCH=arm 85 | 86 | #configure the kernel with the configuration discuss above 87 | make menuconfig 88 | 89 | #build the kernel 90 | make -j4 zImage modules dtbs 91 | ``` 92 | 93 | ### Compiling modules and store them in rootfs 94 | 95 | The compiled modules have a .ko suffix and are generated in the same directory as the source code, meaning that they are scattered all around the kernel source tree. 96 | 97 | To install them into the staging area of your root filesystem (we will talk about root filesystems in the next chapter), provide the path using **INSTALL_MOD_PATH**: 98 | 99 | ```bash 100 | make -j4 ARCH=arm CROSS_COMPILE=arm-cortex_a8-linux-gnueabihf- INSTALL_MOD_PATH=$HOME/rootfs modules_install 101 | ``` 102 | 103 | Kernel modules are put into the directory /lib/modules/[kernel version], relative to the root of the filesystem. 104 | 105 | ## Boot from TFTP server 106 | 107 | ### Vexpress (Qemu) 108 | 109 | Copy the zImage and dtb file to the **tftp server** 110 | 111 | ```bash 112 | cp linux/arch/arm/boot/zImage /srv/tftp/ 113 | cp linux/arch/arm/boot/dts/*-ca9.dtb /srv/tftp/ 114 | ``` 115 | 116 | Start Qemu to boot on U-boot 117 | 118 | ```bash 119 | sudo qemu-system-arm -M vexpress-a9 -m 128M -nographic -kernel u-boot -sd sd.img -net tap,script=./qemu-ifup -net nic 120 | ``` 121 | 122 | Set the bootargs to 123 | 124 | ```bash 125 | setenv bootargs console=ttyAMA0 126 | saveenv 127 | ``` 128 | 129 | load kernel image `zImage` and DTB `vexpress-v2p-ca9.dtb` from TFTP into RAM 130 | 131 | ```bash 132 | tftp $kernel_addr_r zImage 133 | tftp $fdt_addr_r vexpress-v2p-ca9.dtb 134 | ``` 135 | 136 | boot the kernel with its device tree 137 | 138 | ```bash 139 | bootz $kernel_addr_r - $fdt_addr_r 140 | ``` 141 | 142 | ########## THE KERNEL WONT BOOT IT WILL **PANIC** ########### 143 | 144 | ### Raspberry PI 145 | 146 | Copy the zImage and dtb file to the **tftp server** 147 | 148 | ```bash 149 | cp linux/arch/arm/boot/zImage /srv/tftp/ 150 | cp linux/arch/arm/boot/dts/*-ca9.dtb /srv/tftp/ 151 | ``` 152 | 153 | **Plug the Power to RPI and make sure to stop at the U-Boot stage** 154 | 155 | Set the `bootargs` to 156 | 157 | ```bash 158 | setenv bootargs console=ttyXXX 159 | saveenv 160 | 161 | # get the console tty from cmdline 162 | ``` 163 | 164 | load kernel image `zImage` and DTB `vexpress-v2p-ca9.dtb` from TFTP into RAM 165 | 166 | ```bash 167 | tftp [Address RAM kernel] zImage 168 | tftp [Address RAM dtb] bcmXXXX-rpi-X.dtb 169 | 170 | #get this address from bdinfo 171 | ``` 172 | 173 | boot the kernel with its device tree 174 | 175 | ``` 176 | bootz [Address RAM kernel] - [Address RAM dtb] 177 | ``` 178 | 179 | ########## THE KERNEL WONT BOOT IT WILL **PANIC** ########### 180 | 181 | ### BeagleBone 182 | 183 | Copy the zImage and dtb file to the **tftp server** 184 | 185 | ```bash 186 | cp linux/arch/arm/boot/zImage /srv/tftp/ 187 | cp linux/arch/arm/boot/dts/*-ca9.dtb /srv/tftp/ 188 | ``` 189 | 190 | **Plug the Power to RPI and make sure to stop at the U-Boot stage** 191 | 192 | Set the `bootargs` to 193 | 194 | ```bash 195 | setenv bootargs console=ttyS0 196 | saveenv 197 | ``` 198 | 199 | load kernel image `zImage` and DTB `vexpress-v2p-ca9.dtb` from TFTP into RAM 200 | 201 | ```bash 202 | tftp 0x82000000 zImage 203 | tftp 0x88000000 am3356-bb-X.dtb 204 | 205 | # get this address from bdinfo 206 | ``` 207 | 208 | boot the kernel with its device tree 209 | 210 | ``` 211 | bootz 0x82000000 - 0x88000000 212 | ``` 213 | 214 | ########## THE KERNEL WONT BOOT IT WILL **PANIC** ########### -------------------------------------------------------------------------------- /8-Yocto/README.md: -------------------------------------------------------------------------------- 1 | # Yocto 2 | 3 | Yocto Project provides a flexible toolset and a development environment that allows embedded device developers across the world to collaborate through shared technologies, software stacks, configurations, and best practices used to create these tailored Linux images. 4 | 5 | To understand the outcome provided by the Yocto Project is set of instruction to give an output: 6 | 7 | Input: Set of data that describes what we want, that is our specification 8 | *(Kernel Configuration, Hardware Name, Packages/Binaries to be installed)* 9 | 10 | Output: Linux Based Embedded Product 11 | *(Linux Kernel, Root File System, Bootloader, Device Tree, Toolchain)* 12 | 13 | ## Setting up Build Machine 14 | 15 | 1. 50 Gb of free disk 16 | 2. Runs a supported linux distribution (example: Ubuntu, Fedora...) 17 | 3. Git 1.8.3.1 or greater 18 | 19 | tar 1.27 or greater 20 | 21 | Python 3.4.0 or greater. 22 | 23 | ## Setting Host Environment 24 | 25 | Need to download the following essential tool to build yocto project 26 | 27 | ```bash 28 | sudo apt-get install gawk wget git-core diffstat unzip texinfo gcc-multilib \ 29 | build-essential chrpath socat cpio python python3 python3-pip python3-pexpect \ 30 | xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \ 31 | pylint3 xterm 32 | ``` 33 | 34 | ## Download Yocto Project 35 | 36 | 1. Create a directory called `yocto` and change directory to it. 37 | 38 | ```bash 39 | mkdir yocto && cd yocto 40 | ``` 41 | 42 | 2. Clone Poky reference and change directory to poky and checkout to stable release by poky dunfell branch 43 | 44 | ```bash 45 | # Clone the repo 46 | git clone -b dunfell git://git.yoctoproject.org/poky.git 47 | 48 | # Change directory 49 | cd poky 50 | ``` 51 | 52 | ## Configuration Poky 53 | 54 | We need to source the oe-init-build-env to set the environment for poky 55 | 56 | ```bash 57 | source oe-init-build-env [Give folder name to be created] 58 | ``` 59 | 60 | Edit the tune of the parallelism of bitbake generator for fast execution and generation of project. 61 | 62 | ```bash 63 | # change directory to conf 64 | cd conf 65 | 66 | # edit the file local.conf 67 | vim local.com 68 | ``` 69 | 70 | Then we need to add the two line in the file 71 | 72 | ```bash 73 | ##### Please replace number of cores with your host cores and multiply it by the number next to it ##### 74 | BB_NUMBER_THREADS ?= "1.5 * Number of cores" 75 | PARALLEL_MAKE ?= "-j 2 * Number of cores" 76 | 77 | #### EXAMPLE ##### 78 | ## my machine has 4 cores ## 79 | BB_NUMBER_THREADS ?= "6" 80 | PARALLEL_MAKE ?= "8" 81 | 82 | ## NUMBER OF CORES MUST BE PAIR ## 83 | ``` 84 | 85 | ### Qemu build 86 | 87 | Poky the default setting is to build qemu so we only need to run bitbake 88 | 89 | ```bash 90 | # bitbake [options] [recipename/target ...] 91 | bitbake core-image-minimal 92 | ``` 93 | 94 | ### Raspberry Pi 95 | 96 | We need to download the meta layer for raspberry pi 97 | 98 | Check the following link for other meta layer required [OpenEmbedded Link](https://layers.openembedded.org/layerindex/branch/master/layers/) 99 | 100 | Any meta data downloaded make sure to check out to **Dunfell branch** 101 | 102 | ```bash 103 | # getting meta-raspberrypi 104 | git clone git://git.yoctoproject.org/meta-raspberrypi 105 | git checkout dunfell 106 | ``` 107 | 108 | We can also download of the layer that has many feature 109 | 110 | ```bash 111 | git clone git://git.openembedded.org/meta-openembedded 112 | git checkout dunfell 113 | ``` 114 | 115 | We need to add the layer in **bblayer.conf** 116 | 117 | ```bash 118 | # POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf 119 | # changes incompatibly 120 | POKY_BBLAYERS_CONF_VERSION = "2" 121 | 122 | BBPATH = "${TOPDIR}" 123 | BBFILES ?= "" 124 | 125 | BBLAYERS ?= " \ 126 | /home/ahmed/Documents/linux_amit/Embedded_linux/Linux-yocto-Excersises/yocto/building_Raspberrypi_image/poky/meta \ 127 | /home/ahmed/Documents/linux_amit/Embedded_linux/Linux-yocto-Excersises/yocto/building_Raspberrypi_image/poky/meta-poky \ 128 | /home/ahmed/Documents/linux_amit/Embedded_linux/Linux-yocto-Excersises/yocto/building_Raspberrypi_image/poky/meta-yocto-bsp \ 129 | /home/ahmed/Documents/linux_amit/Embedded_linux/Linux-yocto-Excersises/yocto/building_Raspberrypi_image/meta-raspberrypi \ 130 | " 131 | ``` 132 | 133 | Change the machine in **local.conf** to the require raspberry pi chosen 134 | 135 | ```bash 136 | ... 137 | # This sets the default machine to be qemux86-64 if no other machine is selected: 138 | #MACHINE ??= "qemux86-64" 139 | MACHINE = "raspberrypi" 140 | BB_NUMBER_THREADS = "6" 141 | PARALLEL_MAKE = "-j 8" 142 | ... 143 | 144 | ``` 145 | 146 | **Build the image** 147 | 148 | ```bash 149 | # bitbake [options] [recipename/target ...] 150 | bitbake core-image-minimal 151 | ``` 152 | 153 | ### BeagleBone 154 | 155 | Poky has the metadata bsp data layer for beaglebone we only need to change the support machine variable in **local.conf** 156 | 157 | ```bash 158 | # Comment the following line in local.conf 159 | #MACHINE ??= "qemux86" 160 | # Uncomment the following line 161 | MACHINE = "beaglebone" 162 | ``` 163 | 164 | Now we need to add the required layer for beaglebone 165 | 166 | ```bash 167 | # clone meta ti for beaglebone 168 | git clone git://git.yoctoproject.org/meta-ti 169 | ``` 170 | 171 | We include the layer in **bblayer.conf** 172 | 173 | ```bash 174 | # POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf 175 | # changes incompatibly 176 | POKY_BBLAYERS_CONF_VERSION = "2" 177 | 178 | BBPATH = "${TOPDIR}" 179 | BBFILES ?= "" 180 | 181 | BBLAYERS ?= " \ 182 | /home/ahmed/yocto-training/yocto/layers/poky/meta \ 183 | /home/ahmed/yocto-training/yocto/layers/poky/meta-poky \ 184 | /home/ahmed/yocto-training/yocto/layers/poky/meta-yocto-bsp \ 185 | /home/ahmed/yocto-training/yocto/layers/meta-ti \ 186 | ``` 187 | 188 | ## Yocto Build SD Card 189 | 190 | Add in **local.conf** 191 | 192 | ```bash 193 | IMAGE_FSTYPES +="[vendor]-sdimg" 194 | ``` 195 | 196 | -------------------------------------------------------------------------------- /6-InitProcess/README.md: -------------------------------------------------------------------------------- 1 | # Init Process 2 | 3 | The **init process** is the first process that is started by the kernel during the boot process. The init process has a process ID (PID) of 1 and is responsible for starting and managing all other processes on the system. 4 | 5 | ```bash 6 | # To show the process tree 7 | pstree -gn 8 | ``` 9 | 10 | In the following execices we will boot every time from NFS server, make sure to put all the folders for the root file system in 11 | 12 | `/etc/exports` 13 | 14 | then run `sudo exportfs -r` to update the nfs protocol with new folder added. 15 | 16 | ## Create the APP 17 | 18 | 1. Create a **simple application** just to see it running in initialization. 19 | 20 | 2. Compile the App with **specific compiler for the board** 21 | 22 | You can see the Folder **InitApp** in the Repo. 23 | 24 | ## BusyBox Init 25 | 26 | The **busybox init** process then reads the system configuration files and starts various system services, such as network interfaces, device drivers, and daemons, to bring the system to a functional state. 27 | 28 | ### Create Rootfs 29 | 30 | Using buildroot Or Busybox we set the configuration in filesystem to be **busybox init** 31 | 32 | then we edit the **bootargs** in uboot to boot on the busybox init filesystem 33 | 34 | ```bash 35 | setenv bootargs_busybox "setenv bootargs console=ttyS0,115200 root=/dev/nfs ip=192.168.7.100:::::eth0 nfsroot=192.168.7.1:/home/fady/rfs_bb,nfsvers=3,tcp rw init=/sbin/init" 36 | ``` 37 | 38 | then define bootcmd variable for busybox init 39 | 40 | ```bash 41 | setenv bootcmd_busybox 'run bootargs_busybox; tftp 0x80200000 zImage; tftp 0x82000000 am335x-boneblack.dtb; bootz 0x80200000 - 0x82000000' 42 | ``` 43 | 44 | ### Add the application 45 | 46 | We need to add the application into the init script so it run at startup. 47 | 48 | We need to modify two script: 49 | 50 | - `/etc/init.d/rcS1` 51 | 52 | ```bash 53 | echo "rsc1 is on" 54 | deamonapp & 55 | ``` 56 | 57 | - `/etc/init.d/rcK1` 58 | 59 | ```bash 60 | echo "shutdown deamon app" 61 | pkill -e deamonapp 62 | sleep 3 63 | ``` 64 | 65 | - Adding the script in inittab 66 | 67 | ```bash 68 | # mount proc and sys file system 69 | null::sysinit:/bin/mount -t proc proc /proc 70 | null::sysinit:/bin/mount -t sysfs sysfs /sys 71 | 72 | # Excute when the system start 73 | ::sysinit:/etc/init.d/rcS1 74 | 75 | # ask to enter to the shell 76 | console::adkfirst:-/bin/sh 77 | 78 | # Excute when the system will go down 79 | ::shutdown:/etc/init.d/rcK1 80 | ``` 81 | 82 | 83 | ## SystemV init 84 | 85 | The **BusyBox init** daemon just described is just a trimmed down version of System V init. Compared to the BusyBox init, System V init has two advantages: 86 | 87 | - The boot scripts are written in a well-known formal make it easier to add more packages or bin to run at boot time. 88 | - It has the concept of runlevels. 89 | 90 | ### Setup 91 | 92 | `/etc/init.d/deamonapp` 93 | 94 | take in count that **deamonapp** is a script inside the init.d 95 | 96 | ```sh 97 | #! /bin/sh 98 | case "$1" in 99 | start) 100 | echo "Starting deamonapp........." 101 | start-stop-daemon -S -n deamonapp -a /bin/deamonapp & 102 | ;; 103 | stop) 104 | echo "Stopping deamonapp........." 105 | start-stop-daemon -K -n deamonapp 106 | ;; 107 | *) 108 | echo "Usage: $0 {start|stop}" 109 | exit 1 110 | esac 111 | exit 0 112 | ``` 113 | 114 | **start-stop-daemon** is a helper function that makes it easier to manipulate background processes such as this. It originally came from the Debian installer package, dpkg, but most embedded systems use the one from BusyBox. It starts the daemon with the -S parameter, making sure that there is never more than one instance running at any one time. To stop a daemon, you use the -K parameter, which causes it to send a signal, SIGTERM by default, to indicate to the daemon that it is time to terminate. 115 | 116 | ### Usage of the app 117 | 118 | - Ask for Help 119 | 120 | ```sh 121 | /etc/init.d/deamonapp --help 122 | ``` 123 | 124 | - stop service 125 | 126 | ```sh 127 | /etc/init.d/deamonapp stop 128 | ``` 129 | 130 | - start service 131 | 132 | ```sh 133 | /etc/init.d/deamonapp start 134 | ``` 135 | 136 | - Then add this script to one of the `/etc/rc.d/` folders to specify on what run level we will start the application 137 | 138 | ```sh 139 | # from file system root we create a symbolic link to our application and place it in one of the rc folders(runlevel) 140 | ln -s ../init.d/deamonapp ./etc/rc5.d/S40deamonapp.sh 141 | # this simplic link file is named `S40`, S -> will call our script with `start` as argument, `40` order of execution 142 | ``` 143 | 144 | - To kill the application at when getting in specific runlevel we create similar symbolic link 145 | 146 | ```sh 147 | # Kill the process in runlevel 5 148 | ln -s ../init.d/deamonapp ./etc/rc5.d/K40deamonapp.sh 149 | # Kill the process in runlevel 4 150 | ln -s ../init.d/deamonapp ./etc/rc4.d/K40deamonapp.sh 151 | ``` 152 | 153 | to kill the application we execute 154 | 155 | ```sh 156 | telinit 4 # switching to runlevel 4 will kill the application 157 | ``` 158 | 159 | 160 | 161 | ## System D 162 | 163 | - we need to create in systemd filesystem `./etc/systemd/system/deamonapp.service` 164 | 165 | ```bash 166 | [Unit] 167 | Description=app server 168 | [Service] 169 | Type=simple 170 | ExecStart=/bin/deamonapp 171 | 172 | [Install] 173 | WantedBy=multi-user.target 174 | ``` 175 | 176 | 177 | 178 | then you can start and stop it using 179 | 180 | ```bash 181 | # start readapp program 182 | systemctl start deamonapp 183 | ``` 184 | 185 | but if you execute `ps ` command on terminal it will show that the application is running 186 | 187 | ```bash 188 | # stop readapp program 189 | systemctl stop deamonapp 190 | ``` 191 | 192 | but if you execute `ps ` command on terminal it will show that the application is **not** there 193 | 194 | using 195 | 196 | ```bash 197 | systemctl status deamonapp 198 | ``` 199 | 200 | to see the full log of our application we 201 | 202 | ```bash 203 | journalctl -u deamonapp.service 204 | #or for current boot only 205 | journalctl -u deamonapp.service -b 206 | ``` 207 | 208 | 209 | 210 | To make it **persistent**, **permanent** (application will boot for multiuser.target by default) we execute -------> **[Install]** section purpose 211 | 212 | ```bash 213 | systemctl enable deamonapp 214 | ``` 215 | 216 | 217 | 218 | ```bash 219 | reboot 220 | ps # not application is there Executing 221 | ``` 222 | 223 | **Note:** 224 | 225 | Now, you can see how services add dependencies without having to keep on editing target unit files. A target can have a directory named **.target.wants**, which can contain links to services. 226 | 227 | This is exactly the same as adding the dependent unit to the **[Wants]** list in the target. 228 | -------------------------------------------------------------------------------- /5-Busybox/README.md: -------------------------------------------------------------------------------- 1 | # BusyBox 2 | 3 | **BusyBox** is a software suite that provides a single binary executable file that contains many common Unix utilities. It is designed to be **small and efficient**, and is often used in **embedded systems** or other systems with limited resources. 4 | 5 | ## Download BusyBox 6 | 7 | ```bash 8 | git clone https://github.com/mirror/busybox.git 9 | cd busybox/ 10 | ``` 11 | 12 | ## Configure BusyBox 13 | 14 | ```bash 15 | make menuconfig 16 | ``` 17 | 18 | ## Compile BusyBox 19 | 20 | ```bash 21 | # export the compiler on the system 22 | # chose the right compiler that corespond to your board 23 | export CROSS_COMPILE=arm-cortexa9_neon-linux-musleabihf- 24 | export ARCH=arm 25 | 26 | # Configure busybox to be static build from menuconfig 27 | make menuconfig 28 | 29 | #build the busybox to get the minimal command 30 | make 31 | 32 | # generate the rootfs 33 | make install 34 | # this will create folder name _install has all binary 35 | ``` 36 | 37 | ## Create the Rootfs 38 | 39 | We need to copy the rootfs under folder `_install` under file name backwards of BusyBox directory 40 | 41 | ```bash 42 | # to go out from busybox directory 43 | cd .. 44 | 45 | # create directory rootfs 46 | mkdir rootfs 47 | 48 | # copy the content inside the _install into rootfs 49 | cp -rp ./busybox/_install/ ./rootfs 50 | 51 | # change directory to rootfs 52 | cd rootfs 53 | 54 | # create the rest folder for rootfs 55 | mkdir -p ./dev /etc 56 | 57 | #create folder inittab 58 | touch /etc/inittab 59 | ``` 60 | 61 | #### Configure Inittab 62 | 63 | We need to setup **inittab** file because it's the first thing that the **init** process look at 64 | 65 | ```bash 66 | # inittab file 67 | ::sysinit:/etc/init.d/rcS 68 | # Start an "askfirst" shell on the console (whatever that may be) 69 | ttyAMA0::askfirst:-/bin/sh 70 | # Stuff to do when restarting the init process 71 | ::restart:/sbin/init 72 | ``` 73 | 74 | # Mount rootfs Through NFS 75 | 76 | ## Install NFS 77 | 78 | ```bash 79 | # Install an NFS server 80 | sudo apt install nfs-kernel-server 81 | 82 | # Add exported directory to `/etc/exports` file, with target ip as follows 83 | /PathToDirectory/rootfs 192.168.0.100(rw,no_root_squash,no_subtree_check) 84 | 85 | # Ask NFS server to apply this new configuration (reload this file) 86 | sudo exportfs -r 87 | ``` 88 | 89 | ## Setup Bootargs in U-Boot 90 | 91 | ```bash 92 | setenv bootargs console=ttyXXX root=/dev/nfs ip=192.168.0.100:::::eth0 nfsroot=192.168.0.1:/home/fady/Documents/busybox/_install,nfsvers=3,tcp rw init=/sbin/init 93 | 94 | # make sure the console tty represet the machine you working on 95 | ``` 96 | 97 | # Mount rootfs through SD Card 98 | 99 | ```bash 100 | # mount the sd card to the host file system 101 | # No need to do this command if the sd card already mounted 102 | sudo mount /dev/mmblck /media/SDCARD 103 | 104 | # copy rootfs into the sd card 105 | cd rootfs 106 | cp -r * /media/SDCARD/rootfs 107 | 108 | # unmount the SD card 109 | sudo umount /media/SDCARD 110 | ``` 111 | 112 | ## Setup Bootargs in U-boot 113 | 114 | ```bash 115 | setenv bootargs 'console=ttyO0,115200n8 root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait init=/sbin/init' 116 | # console is set depends on the machine 117 | ``` 118 | 119 | # Creating initramfs 120 | 121 | `initramfs` (initial ramdisk filesystem) is a temporary, early root filesystem that is mounted before the real root filesystem becomes available during the Linux kernel's initialization process. It is commonly used in the boot process to perform tasks such as loading essential kernel modules, configuring devices, and preparing the system for the transition to the actual root filesystem. 122 | 123 | ## Sequence of instruction 124 | 125 | An initial RAM filesystem, or initramfs, is a compressed cpio archive. cpio is an old Unix archive format, similar to TAR and ZIP but easier to decode and so requiring less code in the kernel. You need to configure your kernel with **CONFIG_BLK_DEV_INITRD** to support initramfs. 126 | 127 | Make sure do not includes kernel modules in the initramfs as it will take much space. 128 | 129 | ```bash 130 | cd ~/rootfs 131 | find . | cpio -H newc -ov --owner root:root > ../initramfs.cpio 132 | cd .. 133 | gzip initramfs.cpio 134 | mkimage -A arm -O linux -T ramdisk -d initramfs.cpio.gz uRamdisk 135 | ``` 136 | 137 | ## Booting with initramfs 138 | 139 | Copy uRamdisk you created earlier in this section to the boot partition on the microSD card, and then use it to boot to point that you get a U-Boot prompt. Then enter these commands: 140 | 141 | ```bash 142 | # make sure the variable initramfs doesn't overwrite the dtb and zimage variables 143 | setenv initramfs [chose a value depends on bdinfo] 144 | 145 | fatload mmc 0:1 $kernel_addr_r zImage 146 | fatload mmc 0:1 $fdt_addr_r am335x-boneblack.dtb 147 | fatload mmc 0:1 $initramfs uRamdisk 148 | setenv bootargs console=ttyO0,115200 rdinit=/bin/sh 149 | 150 | bootz $kernel_addr_r $initramfs $fdt_addr_r 151 | ``` 152 | 153 | In bootargs variable you need to configure like this 154 | 155 | ### Qemu 156 | 157 | ```bash 158 | setenv bootargs "console=ttyAMA0 rdinit=/bin/sh" 159 | ``` 160 | 161 | ### BeagleBone 162 | 163 | ```bash 164 | setenv bootargs "console=ttyO0,115200 rdinit=/bin/sh" 165 | ``` 166 | 167 | ## NOTE about initramfs 168 | 169 | So far, we have created a compressed initramfs as a separate file and used the bootloader to load it into memory. Some bootloaders do not have the ability to load an initramfs file in this way. To cope with these situations, Linux can be configured to incorporate initramfs into the kernel image. To do this, change the kernel configuration and set **CONFIG_INITRAMFS_SOURCE** to the full path of the cpio archive you created earlier. If you are using menuconfig, it is in General setup | Initramfs source file(s). Note that it has to be the uncompressed cpio file ending in .cpio, not the gzipped version. Then, build the kernel. 170 | 171 | # System configuration and startup 172 | 173 | The first user space program that gets executed by the kernel is `/sbin/init` and its configuration 174 | file is `/etc/inittab`. in `inittab` we are executing `::sysinit:/etc/init.d/rcS`but this file doesn't exist. 175 | 176 | create `/etc/init.d/rcS` startup script and in this script mount `/proc` `/sys` filesystems: 177 | 178 | ```sh 179 | #!/bin/sh 180 | # mount a filesystem of type `proc` to /proc 181 | mount -t proc nodev /proc 182 | # mount a filesystem of type `sysfs` to /sys 183 | mount -t sysfs nodev /sys 184 | # you can create `/dev` and execute `mdev -s` if you missed the `devtmpfs` configuration 185 | ``` 186 | 187 | Note: `can't run '/etc/init.d/rcS': Permission denied` , use 188 | 189 | ```sh 190 | #inside `rootfs` folder 191 | chmod +x ./etc/init.d/rcS # to give execution permission for rcS script 192 | #restart 193 | ``` 194 | 195 | -------------------------------------------------------------------------------- /7-BuildRoot/README.md: -------------------------------------------------------------------------------- 1 | # BuildRoot 2 | 3 | ## Download Required Library 4 | 5 | ```bash 6 | sudo apt install sed make binutils gcc g++ bash patch \ 7 | gzip bzip2 perl tar cpio python unzip rsync wget libncurses-dev 8 | ``` 9 | 10 | ## Download BuildRoot 11 | 12 | ```bash 13 | git clone https://github.com/buildroot/buildroot.git 14 | cd buildroot 15 | 16 | #to Require help 17 | make help 18 | ``` 19 | 20 | ## Configuration 21 | 22 | To List all board configuration supported by Buildroot 23 | 24 | ```bash 25 | make list-defconfigs 26 | 27 | # Or you can list the files inside 28 | ls configs/ 29 | ``` 30 | 31 | ### Configure Beaglebone 32 | 33 | ```bash 34 | #configure beaglebone to buildroot 35 | make beaglebone_defconfig 36 | ``` 37 | 38 | ### Configure Raspberry Pi 39 | 40 | ```bash 41 | # listing the defconfigs you will find several rasberry Pi 42 | # Example 43 | make raspberrypi3_defconfig 44 | ``` 45 | 46 | ### Configure Qemu 47 | 48 | ```bash 49 | # configure qemu vexpress 50 | make qemu_arm_vexpress_defconfig 51 | ``` 52 | 53 | ### Configure buildroot 54 | 55 | ```bash 56 | # to configure the buildroot 57 | make menuconfig 58 | ``` 59 | 60 | In the configuration, configure the following **requirement**: 61 | 62 | - [ ] Init procecss to **System V** or **System D** or **Busybox init** 63 | 64 | `In case of using systemD increase the root file system size from build root configuartion` 65 | 66 | - [ ] Change **system host** 67 | - [ ] Change **system banner** 68 | - [ ] Appy **root password** 69 | 70 | #### Configure SSH 71 | 72 | In order to configure SSH and add the executable in rootfs in **buildroot** 73 | 74 | - [ ] Enable in **Network application** configure **dropbear** 75 | - [ ] Set **Root password** in **system configuration** 76 | 77 | ## Build the System 78 | 79 | ```bash 80 | # It will build the buildroot 81 | # Register the logs for debugging 82 | make 2>&1 | tee build.log 83 | 84 | #### WARNING it will take up to 2 hours #### 85 | ``` 86 | 87 | ## Configure Embedded Linux Component 88 | 89 | ### Configure Linux 90 | 91 | ```bash 92 | # to change configuration for linux 93 | make linux-menuconfig 94 | ``` 95 | 96 | ### Configure uboot 97 | 98 | ```bash 99 | # to configure uboot 100 | make uboot-menuconfig 101 | ``` 102 | 103 | ### Configure Busybox 104 | 105 | ```bash 106 | # to configure busybox 107 | make busybox-menuconfig 108 | ``` 109 | 110 | ## Boot The System 111 | 112 | ### Qemu 113 | 114 | ```bash 115 | # Run the system on Qemu 116 | qemu-system-arm -M vexpress-a9 -m 128M -sd output/image/sdcard.img -kernel output/image/u-boot.img -nograhic 117 | ``` 118 | 119 | ### BeagleBone 120 | 121 | ```bash 122 | # First we need to format the sd card 123 | dd if=/dev/zero of=/dev/mmcblk0 bs=1M 124 | #### warning it will take some time #### 125 | 126 | # Add the Sd image to the SD card 127 | dd if=output/images/sdcard.img of=/dev/mmcblk0 bs=1M 128 | ``` 129 | 130 | ### Raspberry Pi 131 | 132 | ```bash 133 | # First we need to format the sd card 134 | dd if=/dev/zero of=/dev/mmcblk0 bs=1M 135 | #### warning it will take some time #### 136 | 137 | # Add the Sd image to the SD card 138 | dd if=output/images/sdcard.img of=/dev/mmcblk0 bs=1M 139 | ``` 140 | 141 | # Create Buildroot Package 142 | 143 | Suppose you have a personalized package named "**simpleapp**" that you want to add to your Root File System (Root FS) that you are creating with buildroot. In the simplest scenario, this package would include a source file and a makefile. 144 | 145 | 1. Create folder under package as following 146 | 147 | ```bash 148 | mkdir -p ./package/simpleapp/src 149 | ``` 150 | 151 | 2. Create source file under **src** and write a simple code 152 | 153 | ```bash 154 | touch simpleapp && vim simpleapp 155 | # or for shortcut 156 | vim simpleapp 157 | ``` 158 | 159 | Inside the simple app write the following simple code 160 | 161 | ```c 162 | #include 163 | 164 | int main(void) { 165 | printf("Hi People\r\n"); 166 | } 167 | ``` 168 | 169 | 3. No we need to create the Makefile that buildroot will use it to compile the following app 170 | 171 | ```bash 172 | # under src directory create Makefile 173 | touch Makefile 174 | # edit the Makefile 175 | vim Makefile 176 | ``` 177 | 178 | Inside the Makefile write the following recipe 179 | 180 | ```makefile 181 | 182 | .PHONY: clean 183 | .PHONY: simpleapp 184 | 185 | simpleapp: simpleapp.c 186 | $(CC) -g -Wall $(CFLAGS) $(LDFLAGS) $< -o $@ 187 | 188 | clean: 189 | -rm simpleapp 190 | 191 | #### NOTE: Makefile requires a tab character for indentation. Spaces will not work. #### 192 | 193 | ``` 194 | 195 | 4. Create a package definition for this package in the buildroot source tree. 196 | 197 | ``` 198 | # under package/simpleapp create the following Makefile 199 | touch simpleapp.mk 200 | # and edit the makefile 201 | vim simpleapp.mk 202 | ``` 203 | 204 | Add the following script inside the makefile 205 | 206 | ```makefile 207 | ################################################################################ 208 | # 209 | # simpleapp package 210 | # 211 | ################################################################################ 212 | 213 | SIMPLEAPP_VERSION = 1.0 214 | SIMPLEAPP_SITE = package/simpleapp/src 215 | SIMPLEAPP_SITE_METHOD = local# Other methods like git,wget,scp,file etc. are also available. 216 | 217 | define SIMPLEAPP_BUILD_CMDS 218 | $(MAKE) CC="$(TARGET_CC)" LD="$(TARGET_LD)" -C $(@D) 219 | endef 220 | 221 | define SIMPLEAPP_INSTALL_TARGET_CMDS 222 | $(INSTALL) -D -m 0755 $(@D)/simpleapp $(TARGET_DIR)/usr/bin 223 | endef 224 | 225 | $(eval $(generic-package)) 226 | 227 | ``` 228 | 229 | Then create the configuration file that will be used by builroot to show the package in menuconfig 230 | 231 | ```bash 232 | touch Config.in && vim Config.in 233 | ``` 234 | 235 | Inside the file add the following configuration 236 | 237 | ```bash 238 | config BR2_PACKAGE_SIMPLEAPP 239 | bool "simpleapp" 240 | help 241 | simpleapp package. 242 | ``` 243 | 244 | 5. Add the new Config.in in the configuration for buildroot 245 | 246 | Under **package directory** 247 | 248 | ```bash 249 | vim ./package/Config.in 250 | ``` 251 | 252 | Add new menu under Target Package 253 | 254 | ```makefile 255 | menu "SIMPLEAPP Packages" 256 | source "package/simpleapp/Config.in" 257 | endmenu 258 | ``` 259 | 260 | 6. Enable the package in buildroot menuconfig 261 | 262 | ```bash 263 | # change directory to builroot 264 | cd builroot 265 | # configure the builroot 266 | make menuconfig 267 | 268 | # under target package you will find simpleapp 269 | # add it to the configuration 270 | ``` 271 | 272 | 7. Build builroot again 273 | 274 | After building the builroot the execution file for simple app will be add it to the rootfs 275 | 276 | ```bash 277 | # build the buildroot 278 | make -j8 279 | ``` 280 | 281 | # Tips and Tricks 282 | 283 | We can create a file to give U-Boot commands without setting the bootloader manually. 284 | 285 | ```bash 286 | # Create a folder and file in the `boot` partition: 287 | mkdir extlinux && touch extlinux/extlinux.conf 288 | ``` 289 | 290 | Add the following content in the file 291 | 292 | ```bash 293 | label buildroot 294 | kernel /zImage 295 | devicetree /am335x-boneblack.dtb 296 | append console=ttyO0,115200 root=/dev/mmcblk0p2 rootwait 297 | ``` 298 | 299 | -------------------------------------------------------------------------------- /Github/Github.md: -------------------------------------------------------------------------------- 1 | # Git Quick Overview 2 | 3 | ## Introduction 4 | 5 | Git is a distributed version control system widely used in software development to track changes in source code during the development process. It allows multiple contributors to collaborate on a project seamlessly. 6 | 7 | ## Basic Concepts 8 | 9 | - **Repository (Repo):** A folder or storage space where your project lives, containing all the files and their complete history. 10 | - **Commit:** A snapshot of your repository at a specific point in time. It records changes made to files. 11 | - **Branch:** A separate line of development. It allows you to work on features or fixes without affecting the main codebase. 12 | - **Merge:** Combining changes from different branches. 13 | - **Pull Request (PR):** Proposing changes and requesting them to be merged into a branch. 14 | 15 | ## Essential Commands 16 | 17 | - **`git init`:** Initializes a new Git repository in the current directory. 18 | - **`git clone [url]`:** Creates a local copy of a remote repository. 19 | - **`git add [file]`:** Stages changes for the next commit. 20 | - **`git commit -m "message"`:** Records changes to the repository with a descriptive message. 21 | - **`git status`:** Shows the status of changes as untracked, modified, or staged. 22 | - **`git log`:** Displays a log of commits. 23 | - **`git branch`:** Lists all branches, indicating the current one with an asterisk. 24 | - **`git checkout [branch]`:** Switches to a different branch. 25 | - **`git merge [branch]`:** Integrates changes from one branch into another. 26 | - **`git pull origin [branch]`:** Fetches changes from a remote repository and merges them into the current branch. 27 | - **`git push origin [branch]`:** Pushes changes to a remote repository. 28 | 29 | ## Workflow Example 30 | 31 | 1. **Initialize Repository:** 32 | 33 | ```bash 34 | git init 35 | ``` 36 | 37 | 2. **Create a Branch:** 38 | 39 | ```bash 40 | git branch feature-branch 41 | git checkout feature-branch 42 | ``` 43 | 44 | 3. **Make Changes:** 45 | 46 | ```bash 47 | # Make changes to files 48 | git add . 49 | git commit -m "Add new feature" 50 | ``` 51 | 52 | 4. **Merge Changes:** 53 | 54 | ```bash 55 | git checkout main 56 | git merge feature-branch 57 | ``` 58 | 59 | 5. **Push Changes:** 60 | 61 | ```bash 62 | git push origin main 63 | ``` 64 | 65 | This is a simplified overview of Git. 66 | 67 | 68 | 69 | # Downloading and Installing Git Bash 70 | 71 | ## Steps 72 | 73 | ### Step 1: Download 74 | 75 | 1. Visit the [Git official website](https://git-scm.com/). 76 | 2. Click on the "Download" button. 77 | 78 | ### Step 2: Choose Download Option 79 | 80 | Choose the appropriate version for your operating system (Windows in this case). 81 | 82 | ### Step 3: Run the Installer 83 | 84 | 1. Open the downloaded executable file (e.g., `Git-2.x.x-64-bit.exe` for a 64-bit system). 85 | 2. The installer will guide you through the setup process. 86 | 87 | ### Step 4 : Launch Git Bash 88 | 89 | 1. Once the installation is complete, find the Git Bash shortcut on your desktop or in the Start menu. 90 | 2. Open Git Bash. 91 | 92 | ### Step 5: Verify Installation 93 | 94 | Open Git Bash and enter the following command to verify the installation: 95 | 96 | ``` 97 | git --version 98 | ``` 99 | 100 | If Git is installed successfully, you should see the installed Git version. 101 | 102 | Congratulations! You've successfully downloaded and installed Git Bash on your Windows system. You can now use Git commands in the Git Bash terminal. 103 | 104 | # Configuring Git Author Information 105 | 106 | When working with Git, it's essential to configure your author name and email to associate your commits with your identity. This information is included in each commit and is visible in the project's version history. Here's how you can configure your author information: 107 | 108 | ## Step 1: Open Git Bash or Terminal 109 | 110 | Open Git Bash or your terminal on your local machine. 111 | 112 | ## Step 2: Use Git Config Command 113 | 114 | Git uses the `git config` command to set configuration options. Use the following commands to configure your author name and email: 115 | 116 | ```bash 117 | git config --global user.name "Your Name" 118 | git config --global user.email "your.email@example.com" 119 | ``` 120 | 121 | Replace "Your Name" with your actual name and "[your.email@example.com](mailto:your.email@example.com)" with your actual email address. 122 | 123 | - The `--global` flag sets these configurations globally, meaning they will be applied to all your Git repositories on this machine. 124 | 125 | ## Step 3: Verify Configuration 126 | 127 | To verify that your configuration changes were successful, you can use the following command: 128 | 129 | ```bash 130 | git config --global --get user.name 131 | git config --global --get user.email 132 | ``` 133 | 134 | These commands will display the configured name and email, respectively. 135 | 136 | 137 | 138 | # Topics to Discuss 139 | 140 | - [ ] Initialize local repo 141 | 142 | - ```bash 143 | git init 144 | ``` 145 | 146 | - [ ] Track and Untrack Files 147 | 148 | - ```bash 149 | git add 150 | ``` 151 | 152 | - [ ] Ignore file (.gitignore) 153 | 154 | - [ ] stage and commit 155 | 156 | - ```bash 157 | git commit -a -m "your commit message" 158 | ``` 159 | 160 | - [ ] Amend Commit 161 | 162 | - ```bash 163 | git commit -m "new commit message" --amend 164 | ``` 165 | 166 | - [ ] View Change in commits 167 | 168 | - ```bash 169 | git log -p 170 | ``` 171 | 172 | - [ ] change file and view differences 173 | 174 | - ```bash 175 | git diff 176 | ``` 177 | 178 | - [ ] Restore and rename files 179 | 180 | - ```bash 181 | git mv 182 | ``` 183 | 184 | - [ ] Commit History 185 | 186 | - [ ] Branches 187 | 188 | - [ ] Merge Branch 189 | 190 | - [ ] Merge Conflicts 191 | 192 | - [ ] Push local repo to GitHub 193 | 194 | - [ ] Pull Requests 195 | 196 | 197 | 198 | # Initializing a Repository on GitHub 199 | 200 | ## Overview 201 | 202 | Initializing a repository on GitHub involves creating a new repository to host your project. Here's a step-by-step guide to help you initialize a repository on GitHub. 203 | 204 | ### Step 1: Sign in to GitHub 205 | 206 | If you don't have a GitHub account, you'll need to sign up. If you already have an account, sign in to your GitHub account. 207 | 208 | ### Step 2: Create a New Repository 209 | 210 | 1. On the GitHub homepage, click on the "+" sign in the upper right corner. 211 | 2. From the dropdown, select "New repository." 212 | 213 | ### Step 3: Fill in Repository Details 214 | 215 | 1. **Repository Name:** Enter a name for your repository. This will also become the project's URL (e.g., `my-first-repo`). 216 | 2. **Description (optional):** Provide a brief description of your project. 217 | 3. **Public/Private:** Choose whether your repository will be public (visible to everyone) or private (accessible only to you and collaborators). 218 | 4. **Initialize this repository with a README:** You can choose to initialize your repository with a README file. This is optional but can be useful to provide information about your project. 219 | 220 | ### Step 4: Choose a License, .gitignore, or Template (Optional) 221 | 222 | - **License:** Choose a license for your project. This is optional, but it's good practice to specify the terms under which others can use, modify, and distribute your software. 223 | - **.gitignore:** Select a .gitignore file to determine which files and directories should be ignored by Git. This depends on your project type (e.g., Python, Node, Java). 224 | - **Template:** If your project fits a specific category (e.g., Python library, Node module), you can choose a template to initialize your repository with files and settings tailored to that category. 225 | 226 | ### Step 5: Create Repository 227 | 228 | Click the "Create repository" button to finalize the process. 229 | 230 | ### Step 6: Copy the Repository URL 231 | 232 | After creating the repository, you'll be redirected to its main page. Copy the repository URL from the "Quick setup" section. 233 | 234 | ### Step 7: Initialize a Local Git Repository 235 | 236 | 1. Open a terminal or Git Bash on your local machine. 237 | 238 | 2. Navigate to your project directory using the `cd` command. 239 | 240 | 3. Initialize a Git repository using the following commands: 241 | 242 | ``` 243 | git init 244 | git remote add origin 245 | ``` 246 | 247 | ### Step 8: Add, Commit, and Push 248 | 249 | 1. Add your files to the repository: 250 | 251 | ``` 252 | git add . 253 | ``` 254 | 255 | 2. Commit the changes: 256 | 257 | ``` 258 | git commit -m "Initial commit" 259 | ``` 260 | 261 | 3. Push the changes to GitHub: 262 | 263 | ``` 264 | git push -u origin main 265 | ``` 266 | 267 | (Note: If you initialized with a different branch name, replace `main`with your branch name.) -------------------------------------------------------------------------------- /3-Uboot/README.md: -------------------------------------------------------------------------------- 1 | # U-boot 2 | 3 | U-Boot is **the most popular boot loader in** **linux** **based embedded devices**. It is released as open source under the GNU GPLv2 license. It supports a wide range of microprocessors like MIPS, ARM, PPC, Blackfin, AVR32 and x86. 4 | 5 | ## Setup U-boot 6 | 7 | ### Download U-Boot 8 | 9 | ```bash 10 | git clone git@github.com:u-boot/u-boot.git 11 | cd u-boot/ 12 | git checkout v2022.07 13 | ``` 14 | 15 | ### Configure U-Boot Machine 16 | 17 | In this section we will **configure** u-boot for several Machine 18 | 19 | ```bash 20 | # In order to find the machine supported by U-Boot 21 | ls configs/ | grep [your machine] 22 | ``` 23 | 24 | #### Vexpress Cortex A9 (Qemu) 25 | 26 | In **U-boot directory** Assign this value 27 | 28 | ```bash 29 | # Set the Cross Compiler into the environment 30 | # To be used by the u-boot 31 | export CROSS_COMPILE=/arm-cortexa9_neon-linux-musleabihf- 32 | export ARCH=arm 33 | 34 | # load the default configuration of ARM Vexpress Cortex A9 35 | make vexpress_ca9x4_defconfig 36 | ``` 37 | 38 | #### Raspberry Pi 39 | 40 | First we need to download the **compiler** for the architecture set for **RPI** 41 | 42 | ```bash 43 | # update the package manager 44 | sudo apt-get update 45 | 46 | # the following compiler support 32 bit architecture 47 | sudo apt-get install gcc-arm-linux-gnueabihf- 48 | 49 | # in case of using architecture 64 Download the following compiler 50 | sudo apt-get install gcc-aarch64-linux-gnu 51 | ``` 52 | 53 | ##### Raspberry Pi 3 54 | 55 | In **U-boot directory** Assign this value 56 | 57 | ```bash 58 | # Set the Cross Compiler into the environment 59 | # To be used by the u-boot 60 | export CROSS_COMPILE=arm-linux-gnueabihf- 61 | export ARCH=arm 62 | 63 | # load the default configuration of rpi 3 64 | make rpi_3_defconfig 65 | ``` 66 | 67 | ##### Raspberry Pi 4 68 | 69 | In **U-boot directory** Assign this value 70 | 71 | ```bash 72 | # Set the Cross Compiler into the environment 73 | # To be used by the u-boot 74 | export CROSS_COMPILE=arm-linux-gnueabihf- 75 | export ARCH=arm 76 | 77 | # load the default configuration of rpi 3 78 | make rpi_4_32b_defconfig 79 | ``` 80 | 81 | **In case of 64 architecture** 82 | 83 | ```bash 84 | export CROSS_COMPILE=aarch64-linux-gnu- 85 | export ARCH=arm64 86 | 87 | # depends what raspberry pi in used 88 | make rpi_4_b_defconfig 89 | ``` 90 | 91 | #### Beaglebone 92 | 93 | In **U-boot directory** Assign this value 94 | 95 | ```bash 96 | # Set the Cross Compiler into the environment 97 | # To be used by the u-boot 98 | export CROSS_COMPILE=/arm-cortexa9_neon-linux-musleabihf- 99 | export ARCH=arm 100 | 101 | # load the default configuration of ARM Vexpress Cortex A9 102 | make am335x_evm_defconfig 103 | ``` 104 | 105 | ### Configure U-Boot 106 | 107 | In this part we need to configure some u-boot configuration for the specific board chosen up. 108 | 109 | ```bash 110 | make menuconfig 111 | ``` 112 | 113 | **The customer requirement are like following**: 114 | 115 | - [ ] Support **editenv**. 116 | - [ ] Support **bootd**. 117 | - [ ] Store the environment variable inside file call **uboot.env**. 118 | - [ ] Unset support of **Flash** 119 | - [ ] Support **FAT file system** 120 | - [ ] Configure the FAT interface to **mmc** 121 | - [ ] Configure the partition where the fat is store to **0:1** 122 | 123 | ## SD Card 124 | 125 | In this section it's required to have SD card with first partition to be FAT as pre configured in **U-boot Menuconfig**. 126 | 127 | ### ! ONLY FOR WHO WORK WITH QEMU ! 128 | 129 | In order to Emulate SD card to attached to Qemu following steps will be followed: (ONLY FOR NON PHYSICAL SD): 130 | 131 | ```bash 132 | # Change directory to the directory before U-Boot 133 | cd .. 134 | 135 | # Create a file with 1 GB filled with zeros 136 | dd if=/dev/zero of=sd.img bs=1M count=1024 137 | ``` 138 | 139 | ### ! ONLY FOR WHO WORK WITH HW ! 140 | 141 | Plug your SD card to the computer 142 | 143 | ```bash 144 | # To show where your sd card is mounted 145 | lsblk 146 | ``` 147 | 148 | `WARNING: The following command will completely erase all data on the specified SD card.` 149 | 150 | ```bash 151 | ### WARNING #### 152 | sudo dd if=/dev/zero of=/dev/mmblk bs=1M 153 | 154 | # is not always mmblck to make sure use the command lsblk 155 | 156 | # Assign the Block device as global variable to be treated as MACRO 157 | export DISK=/dev/mmblck 158 | ``` 159 | 160 | 161 | 162 | ### Configure the Partition Table for the SD card 163 | 164 | ```bash 165 | # for the VIRTUAL SD card 166 | cfdisk sd.img 167 | 168 | # for Physical SD card 169 | cfdisk /dev/mmblck 170 | ``` 171 | 172 | | Partition Size | Partition Format | Bootable | 173 | | :------------: | :--------------: | :-------: | 174 | | `200 MB` | `FAT 16` | ***Yes*** | 175 | | `300 MB` | `Linux` | ***No*** | 176 | 177 | **write** to apply changes 178 | 179 | ### Loop Driver FOR Virtual usage ONLY 180 | 181 | To emulate the sd.img file as a sd card we need to attach it to **loop driver** to be as a **block storage** 182 | 183 | ```bash 184 | # attach the sd.img to be treated as block storage 185 | sudo losetup -f --show --partscan sd.img 186 | 187 | # Running the upper command will show you 188 | # Which loop device the sd.img is connected 189 | # take it and assign it like down bellow command 190 | 191 | # Assign the Block device as global variable to be treated as MACRO 192 | export DISK=/dev/loop 193 | ``` 194 | 195 | ### Format Partition Table 196 | 197 | As pre configured from **cfdisk command** first partition is **FAT** 198 | 199 | ```bash 200 | # Formating the first partition as FAT 201 | sudo mkfs.vfat -F 16 -n boot ${DISK}p1 202 | ``` 203 | 204 | As pre configured from cfdisk Command second partition is linux 205 | 206 | ```bash 207 | # format the created partition by ext4 208 | sudo mkfs.ext4 -L rootfs ${DISK}p2 209 | ``` 210 | 211 | ## Test U-Boot 212 | 213 | Check the **u-boot** and the **sd card** are working 214 | 215 | ### Vexpress-a9 (QEMU) 216 | 217 | Start Qemu with the **Emulated SD** card 218 | 219 | ```bash 220 | qemu-system-arm -M vexpress-a9 -m 128M -nographic \ 221 | -kernel u-boot/u-boot \ 222 | -sd sd.img 223 | ``` 224 | 225 | ### Raspberry Pi 226 | 227 | Add all **close source** file provided my Raspberry depend for each version to the **SD card in FAT Partition** 228 | 229 | ``` 230 | 1. Bootcode.bin 231 | 2. Fixup.dat 232 | 3. cmdline.txt 233 | 4. config.txt 234 | 5. start.elf 235 | 6. u-boot.bin {generated from u-boot} 236 | ``` 237 | 238 | Edit file `config.txt` as following 239 | 240 | ``` 241 | kernel=u-boot.bin 242 | enable_uart=1 243 | ``` 244 | 245 | ### Beaglebone 246 | 247 | Add following file generated by U-Boot in the SD card FAT partition 248 | 249 | ``` 250 | 1. MLO 251 | 2. u-boot.bin 252 | ``` 253 | 254 | ## Initialize TFTP protocol 255 | 256 | ### Ubuntu 257 | 258 | ```bash 259 | #Switch to root 260 | sudo su 261 | #Make sure you are connected to internet 262 | ping google.com 263 | #Download tftp protocol 264 | sudo apt-get install tftpd-hpa 265 | #Check the tftp ip address 266 | ip addr `will be needed` 267 | #Change the configuration of tftp 268 | nano /etc/default/tftpd-hpa 269 | #write inside the file 270 | tftf_option = “--secure –-create” 271 | #Restart the protocal 272 | Systemctl restart tftpd-hpa 273 | #Make sure the tftp protocol is running 274 | Systemctl status tftpd-hpa 275 | #Change the file owner 276 | cd /srv 277 | chown tftp:tftp tftp 278 | #Move your image or file to the server 279 | cp [File name] /srv/tftp 280 | ``` 281 | 282 | ### Create Virtual Ethernet For QEMU 283 | 284 | This section for Qemu emulator users only **no need for who using HW** 285 | 286 | Create a script `qemu-ifup` 287 | 288 | ```bash 289 | #!/bin/sh 290 | ip a add 192.168.0.1/24 dev $1 291 | ip link set $1 up 292 | ``` 293 | 294 | #### Start Qemu 295 | 296 | In order to start Qemu with the new virtual ethernet 297 | 298 | ```bash 299 | sudo qemu-system-arm -M vexpress-a9 -m 128M -nographic \ 300 | -kernel u-boot/u-boot \ 301 | -sd sd.img \ 302 | -net tap,script=./qemu-ifup -net nic 303 | ``` 304 | 305 | ## Setup U-Boot IP address 306 | 307 | ```bash 308 | #Apply ip address for embedded device 309 | setenv ipaddr [chose] 310 | #Set the server ip address that we get from previous slide 311 | setenv serverip [host ip address] 312 | 313 | #### WARNING #### 314 | #the ip address should has the same net mask 315 | 316 | ``` 317 | 318 | ## Load File to RAM 319 | 320 | First we need to know the ram address by running the following commend 321 | 322 | ```bash 323 | # this commend will show all the board information and it start ram address 324 | bdinfo 325 | ``` 326 | 327 | ### Load from FAT 328 | 329 | ```bash 330 | # addressRam is a variable knowen from bdinfo commend 331 | fatload mmc 0:1 [addressRam] [fileName] 332 | ``` 333 | 334 | ### Load from TFTP 335 | 336 | ```bash 337 | # addressRam is a variable knowen from bdinfo commend 338 | tftp [addressRam] [fileName] 339 | ``` 340 | 341 | 342 | 343 | ## Write Script in U-boot 344 | 345 | ```bash 346 | setenv ifcondition "if mmc dev; then echo MmcExist; elif mtd list; then echo NoDeviceExist; else echo noDeviceExist; fi" 347 | ``` 348 | 349 | `setenv` >>> **T**o set a new variable 350 | 351 | `ifcondition` >>> **V**ariable name 352 | 353 | `if` >>> **F**irst condition 354 | 355 | `mmc dev` >>> **I**s command to check there's device available 356 | 357 | `then` >>> **D**o if condition **pass** 358 | 359 | `echo` >>> **P**rint on console 360 | 361 | `elif` >>> **Else if** 362 | 363 | `mtd` >>> **C**heck **if** any **nor flash** supported 364 | 365 | `then` >>> **E**xecute the else if 366 | 367 | `else` >>> **If** condition not **pass** and **elif** not pass execute **else** condition 368 | 369 | `fi` >>> **Y**ou need to end the condition with **fi** (same as linux bash script) 370 | 371 | --------------------------------------------------------------------------------