smart-os is a small linux system. This project demonstrates how to quickly create a small and full-featured linux operating system. The project address is https://github.com/superconvert/smart-os.

  1. Support for mounting multiple hard disks
  2. Support network function
  3. Support DNS domain name resolution
  4. GCC compiler support
  5. Support qemu startup
  6. Support docker startup
  7. Minimal mode 64 M
  8. Support driver related demos
  9. Supports smart_rtmpd streaming server running https://github.com/superconvert/smart_rtmpd
  1. Teaching Operating System Principles
  2. cloud host system
  3. Streaming server customization
  4. Embedded device customization
  5. IoT scenario operating system customization
  1. Increase arm version
  2. Add GUI demo
  3. Support ISO production
  4. firewall

This script is done on Ubuntu 18.04. Other systems should not be changed much. Friends who need it can modify it by themselves.

  1. Prepare the system environment
    Since the kernel needs to be compiled, the environment required for kernel compilation needs to be installed. Since busybox needs to be compiled, install the required environment according to your needs.

    ./00_build_env.sh
    
  2. Compile source code (kernel, glibc, busyboxy, gcc, binutils)

    ./01_build_src.sh
    
  3. Make a system disk (important, this step installs the system into a system file)

    ./02_build_img.sh
    
  4. run smart-os system

    ./03_run_qemu.sh 或 ./04_run_docker.sh
    

Isn’t it easy to make an operating system!The disk space can be expanded arbitrarily, you can access the Internet, and you can expand the components you want according to your needs. I have successfully tested and run the streaming media server smart_rtmpd in smart-os.

+----------------------------------------------------------------+-----------------------------------------+-----------------------------------------+  
|                          Host                                  |              Container 1                |              Container 2                |  
|                                                                |                                         |                                         |  
|       +------------------------------------------------+       |       +-------------------------+       |       +-------------------------+       |  
|       |             Newwork Protocol Stack             |       |       |  Newwork Protocol Stack |       |       |  Newwork Protocol Stack |       |  
|       +------------------------------------------------+       |       +-------------------------+       |       +-------------------------+       |  
|               +                    +                           |                   +                     |                    +                    |
|...............|....................|...........................|...................|.....................|....................|....................|
|               +                    +                           |                   +                     |                    +                    |
|        +-------------+    +---------------+                    |           +---------------+             |            +---------------+            |
|        | 192.168.0.3 |    | 192.168.100.1 |                    |           | 192.168.100.6 |             |            | 192.168.100.8 |            |
|        +-------------+    +---------------+     +-------+      |           +---------------+             |            +---------------+            |
|        |     eth0    |    |      br0      |<--->|  tap0 |      |           |      eth0     |             |            |      eth0     |            |
|        +-------------+    +---------------+     +-------+      |           +---------------+             |            +---------------+            |
|               +                   +                 +          |                   +                     |                    +                    |
|               |                   |                 |          |                   |                     |                    |                    |
|               |                   +                 +------------------------------+                     |                    |                    |
|               |               +-------+                        |                                         |                    |                    |
|               |               |  tap1 |                        |                                         |                    |                    |
|               |               +-------+                        |                                         |                    |                    |
|               |                   +                            |                                         |                    |                    |
|               |                   |                            |                                         |                    |                    |
|               |                   +-------------------------------------------------------------------------------------------+                    |
|               |                                                |                                         |                                         |
|               |                                                |                                         |                                         |
+---------------|------------------------------------------------+-----------------------------------------+-----------------------------------------+
                +
     Physical Network  (192.168.0.0/24)
  1. Since smart-os installs the glibc dynamic library, this heavily relies on the dynamic library loader/linker ld-linux-x86-64.so.2, since the applications are all linked through dynamic compilation, when an application that requires dynamic linking When loaded by the operating system, the system must locate and load all the dynamic library files it needs. This work is done by ld-linux.so.2. When the program is loaded, the operating system will give control to ld-linux.so instead of the normal entry address of the program. ld-linux.so.2 will find and load all required library files before passing control to the application’s starting entry. ld-linux-x86-64.so.2 is actually the soft chain of ld-linux.so.2, it must exist under /lib64/ld-linux-x86-64.so.2, otherwise, we dynamically compiled busybox depends on the glibc library. The loading of the glibc library requires ld-linux-x86-64.so. If it does not exist in the /lib64 directory, it will causeWhen the system starts, it will panic directly, this issue needs special attention! ! !

  2. qemu generally has a small window after startup. Once an error occurs, there is basically no way to view the error log. Then you need to add console=ttyS0 to the grub startup item, and qemu-system-x86_64 adds serial port output to the file -serial file:. /qemu.log, so debugging is much more convenient, you need to remove console=ttyS0 after debugging, otherwise, the content in /etc/init.d/rcS may not be displayed.

  3. The version of glibc we compile is usually higher than the version that comes with the system. We can write a test program main.c to test whether glibc is compiled successfully. for example:

    #include <stdio.h>
    int main() {
        printf("Hello glibc\\n");
        return 0 ;
    }
    

    we compile

    gcc -o test main.c -Wl,-rpath=/root/smart-os/work/glibc_install/usr/lib64  
    

    The compilation is successful, we execute the ./test program, and usually report an error like this /lib64/libc.so.6: version `GLIBC_2.28′ not found or the program is segmented directly
    In fact, this is the reason why the dynamic library loader/linker and system environment are not specified. Usually, when we compile the glibc library, the compilation directory will automatically generate a testrun.sh script file, and we execute the program in the compilation directory.

    ./testrun.sh ./test  
    

    Usually this will execute successfully. We can also save the following sentence into a script, and it is also possible to execute the test.

    exec env /root/smart-os/work/glibc_install/lib64/ld-linux-x86-64.so.2 --library-path /root/smart-os/work/glibc_install/lib64 ./test
    
  4. How do we track which libraries are loaded by an executable program, we can use LD_DEBUG=libs ./test, we can preload the library by using LD_PRELOAD to force the preload library

  5. When we compile cairo, we usually encounter many problems. If there is a problem with cairo compilation, what should we do? Some error messages are difficult to find online.
    Be sure to look at the config.log file generated when it is compiled, the error message is very detailed!You can solve the problem according to the prompt information

  1. You need to install the apt install -y python-xcbgen library, which will generate the corresponding h file and c file according to the xml file provided by xcbproto
  2. Increase the variable export PKG_CONFIG_SYSROOT_DIR=”${xclient_dir}”, otherwise, the path to find the xml file during compilation is wrong
  3. Add the variable export PKG_CONFIG_PATH=”${xclient_dir}/usr/share/pkgconfig:${xclient_dir}/usr/lib/pkgconfig:${xclient_dir}/usr/local/lib/pkgconfig”, otherwise, pkg-config –variable =xcbincludedir xcb-proto won’t work
  4. Add the variable export XCBPROTO_XCBINCLUDEDIR=”${xclient_dir}/usr/share/xcb” this is the path where the correct xml file is located
  5. Add the variable export PYTHONPATH=”${xclient_dir}/usr/lib/python2.7/dist-packages” to configure the xcbgen module path
  6. Edit the file src/c_client.py of libxcb to solve the problem of UnicodeEncodeError ordinal not in range(128), the default character set of Python is ascii code sed -i “8 i reload(sys)” src/c_client.py sed -i “9 i sys.setdefaultencoding(‘utf8’)” src/c_client.py
  1. The compilation of xfce is equivalent to doing a whole cross compile of xfce, the workload is quite large, there are sequential relationships and dependencies between various components
  2. It will depend on many development kits and system tools. In theory, development kits all require source code compilation, and the workload is huge. Development kits and system tools have version requirements.
  3. Environment variable requirements, such as can’t find header files, can’t find tool path, undefined reference to XXX, all need to change environment variables and compile parameters for different attempts
  4. During the compilation process, there is a problem of multiple versions of the referenced library. This must be clarified which version to use. When compiling, the priority of the search path must be clarified.
  5. There are many new tools to be familiar with, such as: meson, g-ir-scanner, g-ir-compile, etc. These are tools, not development kits, and I don’t understand them at first. As a result, it took a long time to compile gobject-introspection
  6. Compilation with circular dependencies such as: freetype && harfbuzz && cairo For specific solutions, see the processing of the mk_xfce.sh script

The knowledge involved in this piece of knowledge is relatively large. There are relatively few domestic and foreign articles on the compilation and use of xfce4. I am also crossing the river by feeling the stones and trying to demonstrate this knowledge as clearly as possible. I will open a special chapter to explain this. , I am not very sure about porting xfce4 to smart-os, but I will try my best to do it and reveal the mystery of the graphics system to the Chinese. For details, please refer to xfce4.md

  • usr directory details usr = abbreviation for unix system resource, /lib library is a kernel-level library, /usr/lib is a system-level library, /usr/local/lib is an application-level library; /lib contains many /bin && / Libraries used by executable programs in sbin. /usr/lib Almost all libraries referenced by system executable programs are installed here, /usr/local/bin Many libraries referenced by application layer executable programs are placed here

  • ramfs:
    Ramfs is a very simple file system that directly utilizes the existing cache mechanism of the Linux kernel (so its implementation code is small, and for this reason, the ramfs feature cannot be masked by kernel configuration parameters, it is a natural attribute of the kernel) , Use the physical memory of the system to make a memory-based file system whose size can change dynamically, the system will not recycle it, only the root user uses it

  • tmpfs:
    tmpfs is a derivative of ramfs, on the basis of ramfs, it increases the capacity size limit and allows data to be written to the swap space (swap). Due to the addition of these two features, ordinary users can also use tmpfs. tmpfs occupies virtual memory, not all RAM, and the performance may not be as high as ramfs

  • ramdisk:
    A ramdisk is a technology that uses an area in memory as a physical disk. It can also be said that a ramdisk is a block device created in a memory area to store a file system. For users, the ramdisk can be used the same as the normal hard disk partition.When the system reads and writes, it will also store a corresponding cache in the memory, which pollutes the CPU cache and has poor performance. It needs corresponding driver support.

  • rootfs:
    rootfs is a specific instance of ramfs (or tmpfs, if tmpfs is enabled), which always exists in linux 2.6 systems. rootfs cannot be unmounted (rather than adding special code to maintain an empty linked list, it is better to always add the rootfs node, so it is convenient for kernel maintenance. rootfs is an empty instance of ramfs and takes up very little space). Most other filesystems are mounted on rootfs and then ignored. It is the kernel boot that initializes the root filesystem.

  • rootfs is divided into virtual rootfs and real rootfs.
    The virtual rootfs is created and loaded by the kernel itself, and only exists in memory (the subsequent InitRamfs is also implemented on this basis), and its file system is of tmpfs type or ramfs type.
    The real rootfs means that the root file system exists on the storage device. The kernel will mount the storage device on the virtual rootfs during the startup process, and then switch the / directory node to this storage device, so that the file system on the storage device is It will be used as the root file system (subsequent InitRamdisk is implemented on this basis), and its file system types are more abundant, which can be ext2, yaffs, yaffs2, etc., depending on the type of specific storage device.

  • Our boot file system is actually preparing files for rootfs and letting the kernel execute according to our wishes
    In early Linux systems, generally only hard disks or floppy disks were used as storage devices for the Linux root file system, so it was easy to integrate the drivers of these devices into the kernel. But now the embedded system may save the root file system to various storage devices, including scsi, sata, u-disk and so on. Therefore, it is obviously not very convenient to compile all the driver codes of these devices into the kernel.
    In the kernel module automatic loading mechanism udev, we see that the use of udevd can achieve automatic loading of kernel modules, so we hope that if the driver of the storage device that stores the root file system can also be automatically loaded, that’s fine. But there is a contradiction here, udevd is an executable file, it is impossible to execute udevd before the root file system is mounted, but if udevd is not started, it cannot automatically load the driver that stores the root file system device, and at the same time It is also impossible to create a corresponding device node in the /dev directory. In order to solve this contradiction, the initrd (bootloader initialized RAM disk) based on ramdisk appeared. Initrd is a compressed small root directory. This directory contains the necessary driver modules, executable files and startup scripts in the startup phase, as well as the udevd (demon that implements the udev mechanism) mentioned above. When the system starts, the bootloader will read the initrd file into the memory, and then pass the starting address and size of the initrd file in the memory to the kernel. The kernel will decompress the initrd file during the startup initialization process, then mount the decompressed initrd as the root directory, and then execute the /init script in the root directory (initrd in cpio format is /init, and initrd in image format < also called The initrd of the old block device or the initrd of the traditional file image format is /initrc), you can run the udevd in the initrd file system in this script to automatically load the driver for the realfs (real file system) storage device And create the necessary device nodes in the /dev directory. After udevd automatically loads the disk driver, you can mount the real root directory and switch to this root directory.

#smartos #Homepage #Documentation #Downloads #Operating #System #Building #Tutorial #News Fast Delivery

smart-os Homepage, Documentation and Downloads – Operating System Building Tutorial – News Fast Delivery

Leave a Comment

Your email address will not be published. Required fields are marked *