Embedded Linux Kernel Porting Experiment

# ------------------------------------------------------------#                       【Note】# #              The following code needs to run on laboratory computers.# #     If you wish to run it on your own computer, you need to copy the following content from the laboratory virtual machine:# #    Linux kernel and compilation toolchain: /home/book/100ask_imx6ull-qemu/# qemu and linux ARM image: /home/book/ubuntu-18.04_imx6ul_qemu_system/# # -------------------------------------------------------------

Setting Up Embedded Software Cross Compilation Tools

# =================1. Setting Up Embedded Software Cross Compilation Tools=================export ARCH=armexport CROSS_COMPILE=arm-linux-gnueabihf-export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/binarm-linux-gnueabihf-gcc -v

Embedded Software Cross Compilation Process

# =================2. Embedded Software Cross Compilation Process=================# Assume /home/book/nfs_rootfs/test_06.c outputs "Hello, world!".echo '#include <stdio.h>int main(int argc, char const *argv[]){    printf("Hello, world!");    return 0;}' > /home/book/nfs_rootfs/test_06.ccd /home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/./arm-linux-gnueabihf-gcc /home/book/nfs_rootfs/test_06.c -o /home/book/nfs_rootfs/test_06# Format error because it is an arm architecture program/home/book/nfs_rootfs/test_06# Here you can see it is an arm architecture programfile /home/book/nfs_rootfs/test_06cd /home/book/ubuntu-18.04_imx6ul_qemu_system/./qemu-imx6ull-gui.sh# After the following content loads, first enter user root and hit enter, then continue to execute:mount -t nfs -o nolock,vers=3 10.0.2.2:/home/book/nfs_rootfs /mnt/mnt/test_06# Execute the following command to exit (you can also just close the window; the command below is for shutdown)shutdown -h now

Compiling Kernel and Device Tree

# =================3. Compiling Kernel and Device Tree=================# The environment variables set in question 1 are for question 3. However, the environment variables from question 1 seem to be undetectable during linux compilation. I speculate that the method used in question 1 is export to set environment variables, # which only work in the current terminal session and become invalid after exit. Since new terminal sessions are definitely involved in the compilation process, the variables set in question 1 are ineffective for compilation.# Therefore, the following code directly specifies the target for compilation and the cross-platform compiler, which takes precedence over environment variables. At the same time, soft links for the required dependencies are directly established in the /usr/bin/ directory.# ===================================================cd /home/book/100ask_imx6ull-qemu/linux-4.9.88/sudo make \        ARCH=arm \    mrproper# Here the target architecture is forcibly specified. If the original tutorial command applies, execute the original command as needed.# sudo make 100ask_imx6ull_qemu_defconfigsudo make \        ARCH=arm \    100ask_imx6ull_qemu_defconfig# Note: The tutorial image (PDF page 6 left) is incorrect; it shows x86 architecture compilation settings (see title).# This step will pop up a window. After taking a screenshot, select Exit to exit. Note, do not save, otherwise it will overwrite the default configuration loaded in the previous step, and subsequent compilations will pop up a bunch of options and settings.# Here the target architecture is forcibly specified. If the original tutorial command applies, execute the original command as needed.# sudo make menuconfigsudo make \        ARCH=arm \        menuconfig# Create links for required dependenciessudo ln -s \        /home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/* \        /usr/bin/# Note, the tutorial is incorrect here: there must be a space between -j and N, or use --jobs=N; both are equivalent.# Also, N must be a number representing the number of threads; here it is 4, N is just a placeholder.# Here the target architecture is forcibly specified. If the original tutorial command applies, execute the original command as needed.# sudo make zImage -j 4sudo make \        ARCH=arm \        CROSS_COMPILE=arm-linux-gnueabihf- \        zImage -j 4# Here the target architecture is forcibly specified. If the original tutorial command applies, execute the original command as needed.# sudo make dtbssudo make \        ARCH=arm \        CROSS_COMPILE=arm-linux-gnueabihf- \        dtbs

Experiment Assignment

Write a C language program where the parent process first creates a child process. When the parent process uses the function signal() to capture the interrupt signal sent from the keyboard (i.e., pressing ctrl+c), it will send a SIGUSR1 signal to the child process; the child process outputs the message “Child process is killed” after receiving the SIGUSR1 signal and terminates; the parent process outputs the message “Parent process is killed!” after waiting for the child process to terminate.

#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>#include <sys/wait.h>pid_t child_fork = -1;void signal_handler(int signo) {    if (signo == SIGINT) {        kill(child_fork, SIGUSR1);        wait(NULL);        const char string[] = "Parent process is killed!\n";        write(STDOUT_FILENO, string, sizeof(string));        raise(SIGKILL);    } else if (signo == SIGUSR1)    {        const char string[] = "Child process is killed!\n";        write(STDOUT_FILENO, string, sizeof(string));        raise(SIGKILL);    }    }int main(int argc, char const *argv[]){    signal(SIGUSR1, signal_handler);    signal(SIGINT, signal_handler);    int fd[2];    if (pipe(fd) == -1) {        perror("pipe");        exit(1);    }    pid_t forked_pid = fork();    if (forked_pid < 0) {        perror("fork");        exit(1);    } else if (forked_pid == 0) {        child_fork = getpid();        close(fd[0]);        write(fd[1], &child_fork, sizeof(int));        close(fd[1]);        pause();    } else {        close(fd[1]);        read(fd[0], &child_fork, sizeof(child_fork));        close(fd[0]);        pause();    }    return 0;} 

Leave a Comment