Tools: Complete Guide to Embedded Linux System Porting and Driver Design Based on Loongson 2K1000 (II)
3. Embedded Software System Porting
3.1 PMON Boot Process and Compilation
3.1.1 PMON Directory Structure and Main Commands
3.1.2 PMON Boot Process Analysis
3.1.3 PMON Compilation
3.2 Embedded Linux Kernel Porting
3.2.1 Linux Kernel Introduction
3.2.2 Linux Kernel Configuration and Compilation
3.3 Root Filesystem Creation
3.3.1 Linux Root Filesystem
3.3.2 Root Filesystem Creation This guide details the process of porting an embedded Linux system onto the Loongson 2K1000 processor, covering the critical stages of bootloader configuration, kernel compilation, and root filesystem creation. Readers will learn the specific steps and considerations for setting up a robust embedded Linux environment, including PMON bootloader analysis, Linux kernel customization, and Buildroot-based root filesystem generation. For an embedded system to function correctly, a complete and operational embedded software system is paramount. This system forms the foundational platform for all subsequent software development. Key components include the PMON bootloader, which initiates kernel booting; a fully functional embedded Linux kernel; and a root filesystem responsible for critical initialization tasks during the boot process. PMON (Processor Monitor) serves as the bootloader for the Loongson 2K1000, responsible for initializing the hardware and loading the Linux kernel. Understanding its structure and boot sequence is crucial for successful system porting. The PMON source code is organized to separate processor-specific code from general device drivers and board-specific configurations. The PMON directory structure, typically visualized in a table like Table 3-1, contains core processor-related code and fundamental device drivers. Within this structure, the Targets directory is particularly important as it houses detailed configuration files tailored for different development boards, allowing for flexible adaptation to various hardware platforms [39]. PMON provides a set of essential commands for system interaction and debugging. These include general instructions and specific commands for device operations. For example, ifaddr is used to configure the IP address of network interfaces, ping tests network connectivity, and devls lists available devices, providing a basic command-line interface for system management before the full operating system loads. The Loongson 2K1000 processor utilizes an SPI bus interface to connect to a NOR Flash memory, where the PMON image file is stored. The physical starting address of the NOR Flash is 0x1fc00000, which corresponds to the processor's SPI bus controller. However, since programs primarily execute from memory, this physical address is mapped to a virtual address starting at 0xbfc00000. Upon power-up, the processor directly begins executing the PMON code from this virtual address. The PMON bootloader is structured into two distinct parts. The initial section of the PMON image consists of uncompressed assembly code. This part executes immediately after power-on, as the system environment is not yet ready for C language execution. Its primary role is to perform fundamental initialization tasks for the processor, memory, and other essential devices. Once these preparatory steps are complete, this assembly code then decompresses and executes the second part, which consists of compressed C code [40]. As illustrated in Figure 3-1, the PMON boot process begins with the start.s assembly code, located at the virtual address 0xbfc00000. After completing initial setup tasks such as initializing registers, memory controllers, serial ports, and network interfaces, start.s is responsible for decompressing the second part of the PMON code (the C code) and relocating the entire PMON image into RAM for execution. Following this, control is transferred to the initmips function. The initmips function, found in the Targets\LS2K\ls2k\tgt_machdep.c file, performs further system initialization. It first executes tgt_cpufreq to detect the CPU frequency, then calls dbginit to initialize commands, the filesystem, executable handling, and environment variables. Subsequently, it initializes the PCI bus and its devices, loads drivers for various peripherals like serial ports, network interfaces, video interfaces, and USB interfaces, ultimately constructing a functional command-line interface for user interaction. Compiling PMON involves several steps, primarily focused on setting up the cross-compilation environment and building the bootloader image. Download and Extract PMON Source Code:
Obtain the PMON source package, typically from a vendor-specific repository, and extract it to your development environment. Acquire PMON Cross-Compiler (GCC):A MIPS-specific GCC cross-compiler toolchain is required to build PMON for the Loongson 2K1000. Ensure this toolchain is correctly installed and accessible. Install Necessary Build Dependencies:Install essential development tools and libraries required for the PMON build process on your host system (e.g., an Ubuntu machine). Next, navigate to the pmoncfg tool directory within the PMON source and compile it. This tool is often used for configuring PMON builds. Configure Environment Variables:To ensure the build system can locate the cross-compiler and its libraries, set the appropriate environment variables in your shell's configuration file, such as .bashrc. Open .bashrc with a text editor: Add the following lines to the end of the file, adjusting the paths to match your specific cross-compiler installation directory: After saving the changes, apply the new environment variables to your current shell session: Compile PMON:Navigate to the specific PMON source directory for the Loongson 2K1000 (e.g., zloader.ls2k) and initiate the compilation process. The make cfg command is crucial if you have modified any source files or parameters within the Targets/LS2K/conf/ls2k directory; it ensures these changes are recognized by the build system. For routine compilations without configuration changes, make cfg is not always necessary. The make all tgt=rom command compiles the PMON image for ROM. Finally, make dtb combines the Device Tree Blob (DTB) with the gzrom.bin image to produce gzrom-dtb.bin, which is often required for modern embedded systems to describe hardware. Upon successful compilation, as shown in Figure 3-2, the zloader.ls2k/ directory within your PMON source will contain the generated gzrom.bin and gzrom-dtb.bin files. These are the PMON bootloader images ready for deployment. The Linux kernel is the core of any Linux-based embedded system, acting as the intermediary between applications and hardware. Porting it to a new platform like the Loongson 2K1000 involves careful configuration and compilation. In an embedded system, the Linux kernel serves as the vital link between user applications and the underlying hardware devices, as depicted in Figure 3-3. It translates application requests and commands into low-level instructions that the hardware can execute, thereby enabling control and interaction with peripherals. The Linux kernel is functionally divided into five primary subsystems [41]: For the Loongson 2K1000 processor, the project utilizes official Loongson-supported embedded Linux source code, specifically tailored for the MIPS architecture. The kernel is then customized (trimmed) and cross-compiled within an Ubuntu virtual machine environment to ensure software interchangeability and portability. The main workflow is as follows: Obtain Linux Source Code:Download the compressed kernel source package from the official Loongson FTP server and extract it to create the kernel source directory. Configure Environment Variables:Similar to PMON compilation, set the cross-compiler path in your .bashrc file. Open .bashrc with a text editor: Add the absolute path to your cross-compilation toolchain at the end of the file: Then, apply the changes to your current shell: Kernel Trimming and Configuration:The Linux kernel provides a graphical interface tool for kernel configuration, allowing for customization without directly modifying the kernel's build files. Execute the following command from the kernel source directory: Running this command will launch the kernel configuration interface, as depicted in Figure 3-4. Since this project uses a Linux kernel maintained by Loongson, specific adjustments are needed to tailor the kernel to the actual hardware characteristics of the Loongson 2K1000 processor: Compile the Kernel:After configuring the kernel, initiate the compilation process using the following command: Upon successful compilation, as shown in Figure 3-5, two key files will be generated in the kernel directory: vmlinux (the uncompressed, portable Linux kernel image) and vmlinuz (the compressed, portable Linux kernel image). For embedded systems, which typically have limited resources, vmlinuz is the preferred choice as the system kernel image due to its smaller size. The root filesystem is a fundamental component of any Linux system, especially in embedded contexts. It provides the necessary files and directories for the operating system to boot and function. After the kernel starts, its first action is to mount the root filesystem. Beyond its standard role in storing and managing data, the root filesystem in Linux has unique responsibilities. It typically contains numerous initialization scripts and configuration files, often located in the /etc directory, which are crucial for performing system initialization tasks during the boot process. The root filesystem is mounted at the root directory (/) in the final stages of kernel startup, with other directories subsequently mounted underneath it [42]. While the root filesystem is responsible for the Linux kernel's initialization work, in embedded systems, it is generally kept separate from the kernel. This separation is strategic: the kernel handles fundamental operating system tasks such as process scheduling, which are largely consistent across different processor platforms. In contrast, the root filesystem is responsible for configuration, and the specific configuration methods and content vary significantly between different processors. By decoupling the root filesystem from the kernel, the overall portability of the embedded software system is greatly enhanced, allowing for easier adaptation to diverse hardware. Common tools for creating root filesystems include BusyBox and Buildroot [43]. For this project, Buildroot is chosen over BusyBox due to its comparative ease of use. Buildroot is a comprehensive toolchain that includes Makefiles and Kconfig, capable of building the kernel, bootloader, and root filesystem. In embedded development, it is primarily used for constructing the root filesystem. The steps to create a root filesystem image using Buildroot are as follows: Download and Configure Buildroot:First, download and extract the Buildroot source package. Then, replace the default configuration file with the one specifically tailored for the Loongson 2K1000 processor. Create an Automatic Compilation Script:To simplify the compilation process and reduce manual steps, create an executable script that encapsulates the commands for building the root filesystem. Add the following content to cmd.sh: Make the script executable: Configure Buildroot using the Graphical Interface:Launch Buildroot's graphical configuration interface to customize the root filesystem. The Buildroot graphical configuration interface, similar to Figure 3-6, allows for detailed customization. Follow these specific configuration steps: Compile Buildroot:
Execute the automatic compilation script from the top-level Buildroot directory to start the build process: Upon successful compilation, as illustrated in Figure 3-7, the buildroot/output/images/ directory will contain various types of root filesystem images, including cpio, cpio.gz, ubi, ubifs, and yaffs2. Since the system uses an SSD card as the storage medium, choose a filesystem format other than ubifs, which is typically designed for NAND flash. This article was translated from Chinese to English with AI assistance and a light human review. The original is published at Sienovo Blog. The original Chinese source is at CSDN. Learn more about Sienovo edge AI computing. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse