diff --git a/web-ui/docs/.vuepress/public/img/banners/2022-CCF-AIOps.jpg b/web-ui/docs/.vuepress/public/img/banners/2022-CCF-AIOps.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6552b78774eba76f7c9ea862e452462eb54a4f11
Binary files /dev/null and b/web-ui/docs/.vuepress/public/img/banners/2022-CCF-AIOps.jpg differ
diff --git a/web-ui/docs/.vuepress/public/img/news/20220818/image01.jpg b/web-ui/docs/.vuepress/public/img/news/20220818/image01.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ba2ffc536b749e1999ed954668500b835edda339
Binary files /dev/null and b/web-ui/docs/.vuepress/public/img/news/20220818/image01.jpg differ
diff --git a/web-ui/docs/.vuepress/public/img/news/20220818/image02.jpg b/web-ui/docs/.vuepress/public/img/news/20220818/image02.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..966e46ca3ccaabb0a8dad4b81a6f6d29d030545f
Binary files /dev/null and b/web-ui/docs/.vuepress/public/img/news/20220818/image02.jpg differ
diff --git a/web-ui/docs/.vuepress/public/img/news/20220818/image03.jpg b/web-ui/docs/.vuepress/public/img/news/20220818/image03.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..43442c27d524d486d58cda7d8ad456d612c9a08b
Binary files /dev/null and b/web-ui/docs/.vuepress/public/img/news/20220818/image03.jpg differ
diff --git a/web-ui/docs/.vuepress/public/img/news/20220818/image04.jpg b/web-ui/docs/.vuepress/public/img/news/20220818/image04.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3ed7df7ce0fbf329fc8e0f16aebe03e70b2067fc
Binary files /dev/null and b/web-ui/docs/.vuepress/public/img/news/20220818/image04.jpg differ
diff --git a/web-ui/docs/.vuepress/public/img/news/20220818/image05.jpg b/web-ui/docs/.vuepress/public/img/news/20220818/image05.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..57ffb8d375d4834fa74f522ba1ef2b65c14f6267
Binary files /dev/null and b/web-ui/docs/.vuepress/public/img/news/20220818/image05.jpg differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-cli-main.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-cli-main.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc184dbf816ddfdf7824da9e475f7274892d0da7
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-cli-main.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-code-overview.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-code-overview.png
new file mode 100644
index 0000000000000000000000000000000000000000..23cae1615e2b0c1961e257572c0aeabb46a60ddc
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-code-overview.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-core.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-core.png
new file mode 100644
index 0000000000000000000000000000000000000000..b862f2cfd053de0a4bf4d6d43694d0c2b13d55fc
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-core.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-daemon-main.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-daemon-main.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8376ee609fa92215e2b0370fbcb75328d67eb1a
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-daemon-main.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-folder-overview.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-folder-overview.png
new file mode 100644
index 0000000000000000000000000000000000000000..3c01b9b879fb0738886c809ade57662a3711ea62
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-folder-overview.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-help-info.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-help-info.png
new file mode 100644
index 0000000000000000000000000000000000000000..57f55db79c998940cdb5595da4b7f698a68e7ac4
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-help-info.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-isula-logo.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-isula-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..a971e1365b25d7fe95f63f5c80111afa4edbca95
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-isula-logo.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-join-us.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-join-us.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f03e9b8c884c766a4b4016bd211e2bfbafd8167
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-join-us.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-make.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-make.png
new file mode 100644
index 0000000000000000000000000000000000000000..21f576312f3ef1e3a0da21ff8b2a6d93d0ba4873
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-make.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-makefile.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-makefile.png
new file mode 100644
index 0000000000000000000000000000000000000000..824f291b6f1b9ff599d3062d9b7492490f11a151
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-makefile.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-release.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-release.png
new file mode 100644
index 0000000000000000000000000000000000000000..94b572bf42968e570fb2e27c33dca9f1e551d0c4
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-release.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-struct-overview.png b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-struct-overview.png
new file mode 100644
index 0000000000000000000000000000000000000000..745986b5354b5038adabd85965891b263a2cac87
Binary files /dev/null and b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration-struct-overview.png differ
diff --git a/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration.md b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration.md
new file mode 100644
index 0000000000000000000000000000000000000000..1d5f5d9271b14f59eb48b24163fdbac92dea95e6
--- /dev/null
+++ b/web-ui/docs/en/blog/DCCooper/2020-09-15-isula-build-code-exploration.md
@@ -0,0 +1,149 @@
+---
+title: 'isula-build Code Analysis'
+category: blog
+date: 2020-09-15
+tags:
+ - iSulad
+ - container
+ - image creation
+archives: 2020-09
+author:
+ - Li Xiang
+summary: As a member of the iSulad ecosystem, isula-build provides multiple functions, such as image creation, management, and distribution.
+---
+
+
+This article analyzes the code of the container image build tool isula-build and provides a quick tutorial to get started with the open source project if you want to give suggestions or improvements on the tool.
+
+## isula-build Code Analysis
+
+Contents
+
+1. Introduction to isula-build
+
+2. Introduction to the code
+
+3. Introduction to isula-build community release process and how to join the community
+
+### What Is isula-build?
+
+As a member of the iSulad ecosystem, isula-build provides multiple functions, such as image creation, management, and distribution.
+
+
+
+iSulad is a general-purpose container engine developed by Huawei and open sourced on [Gitee](https://gitee.com/openeuler/iSulad). It uses a unified architecture design to meet various requirements in the CT and IT fields. Compared with Docker written in Golang, iSulad features a lightweight, fast, and flexible design that is not restricted by hardware specifications and architecture, has less memory overhead, and can be widely used in more scenarios.
+
+### What Can isula-build Do?
+
+- Quickly and securely creates container images and manages the images.
+- Quickly integrates with iSulad and Docker, facilitating deployment.
+- Creates, deletes, updates, and retrieves images.
+- Constitutes the full-stack container solution.
+
+### isula-build Architecture
+
+isula-build adopts the classic client-server (C-S) architecture, in which client `isula-build` communicates with server `isula-builder` through gRPC. You can run the `isula-build` commands to interact with `isula-builder` and initiate requests for image creation and management.
+
+
+
+### isula-build Code Overview
+
+Currently, isula-build, written in Golang, has more than 20,000 in-house lines of code.
+
+```bash
+--------------------------------------------------------------------------------
+Language files blank comment code
+--------------------------------------------------------------------------------
+Go 134 3293 2676 25038
+Markdown 9 486 0 1098
+Bourne Shell 15 95 225 499
+XML 9 0 0 419
+Protocol Buffers 2 41 97 193
+make 1 18 1 89
+Dockerfile 6 14 0 68
+Bourne Again Shell 1 8 4 31
+TOML 3 37 255 15
+JSON 1 0 0 8
+--------------------------------------------------------------------------------
+SUM: 181 3992 3258 27458
+--------------------------------------------------------------------------------
+```
+
+The following figure shows a series of folders with various functions involved in the isula-build project.
+
+
+
+The following figure shows the main functions of some folders.
+
+
+
+You may be confused by far. But relax, the following describes how to quickly understand the isula-build code.
+
+### Code Builder
+
+In my opinion, the fastest way to understand a project is not to dive into the code at the very beginning. Instead, you should build and run the software, and then get familiar with the entire project by mapping the external appearance to the internal logic.
+
+How do we run isula-build? If you didn't install the RPM package, you need to manually build the binary. First, find `Makefile`, which describes how to build the project.
+
+Open the file and locate the `isula-build` and `isula-builder` binaries. Then, you can find the beginning of the code, that is, the program entry.
+
+
+
+Build the files and see what happens.
+
+
+
+Two binaries are built in the **isula-build/bin** directory. You can run them.
+
+### Command Line Entries
+
+Each Go binary is generated by the `main.go` file. According to the isula-build code overview, the entry of `isula-build` is in `cmd/cli/main.go`, and the entry of `isula-builder` is in `cmd/daemon/main.go`.
+
+
+
+Enter `isula-build -h` and `isula-builder -h`.
+
+
+
+### External Appearance and Internal Logic
+
+Next, let's learn about the build process with a command used to build a container image and save it as a local TAR package.
+
+> Example command: `isula-build ctr-img build –f Dockerfile –o docker-archive:busybox.tar:busybox:latest`
+
+
+
+
+The preceding S-shaped process provides key points of the entire build process. You can find the required code and extend it.
+
+> Quiz: How many level-2 subcommands does isula-build have so far?
+
+### isula-build Community Development
+
+Up to this point, you may want to give suggestions or improvements on the tool. Let me walk you through how to participate in the open source community development.
+
+First, you need to know the code development and release process.
+
+
+
+As shown in the figure, as a user or developer, you can obtain the released isula-build RPM package or source code. If you have any doubts or want to improve the project, you need to submit an issue in the [source code repository](https://gitee.com/openeuler/isula-build).
+
+If the community accepts the issue, it will make a schedule based on the urgency and difficulty of the issue.
+
+Interested contributors will claim the issue and start coding. After the local code is finished and the functions are tested, the contributor can submit the code by creating a pull request in the code repository.
+
+However, it doesn't mean that the code can be merged directly. The code submitted will be reviewed manually by maintainers and automatically by the robot (ci-bot). After the code passes the review, it can be merged into the source code repository.
+
+Yet the process is not over. How does the code become an RPM package that allows users to install and run on their computers using `yum install isula-build`? This involves another repository, the [artifact repository](https://gitee.com/src-openeuler/isula-build).
+
+The isula-build code exists in the artifact repository in the form of a TAR package, which means that the source code is packaged. You can use the corresponding **spec** file to build an RPM package, which is then integrated into the openEuler release package. Alternatively, you can directly obtain the official [RPM package](https://build.openeuler.org/package/show/openEuler:Mainline/isula-build).
+
+So far, our introduction to the isula-build code architecture and process comes to an end. You are welcome to join us to learn more about isula-build.
+
+
+
+> isula-build source code repository: [https://gitee.com/openeuler/isula-build](https://gitee.com/openeuler/isula-build)
+>
+> isula-build artifact repository: [https://gitee.com/src-openeuler/isula-build](https://gitee.com/src-openeuler/isula-build)
+>
+> isula-build obs address: [https://build.openeuler.org/package/show/openEuler:Mainline/isula-build](https://build.openeuler.org/package/show/openEuler:Mainline/isula-build)
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-01.png b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-01.png
new file mode 100644
index 0000000000000000000000000000000000000000..3264c220012ba5aa17fbe4fba520fc0a2ad647ab
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-01.png differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-02.jpg b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-02.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4f9129755d7780af13e4b528fc4b17ced49ee402
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-02.jpg differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-03.jpg b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-03.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c37a0fb574d39a3718cd665f4ecc471bea8d4518
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-03.jpg differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-04.jpg b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-04.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..14adc3a792634f15b75af187e58990a4efd54fa6
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-04.jpg differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-05.png b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-05.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6776f6d4e071122d951c3b8ac709c17d1ec101f
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-05.png differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-06.png b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-06.png
new file mode 100644
index 0000000000000000000000000000000000000000..82a1663932f8706ddebd2cd0a1eee80e47acafbe
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-06.png differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-07.png b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-07.png
new file mode 100644
index 0000000000000000000000000000000000000000..99a47739c4c2467782c412e4283d0f469d45e50a
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-07.png differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-08.png b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-08.png
new file mode 100644
index 0000000000000000000000000000000000000000..b860eda5251f48cc44d05980fe27b6d0e99852fc
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-08.png differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-09.png b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-09.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d660ce8e0ea9b9cf1057f39125077fb45a3e585
Binary files /dev/null and b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture-09.png differ
diff --git a/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture.md b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture.md
new file mode 100644
index 0000000000000000000000000000000000000000..6cfcd05abb89b4347170d7fc4be4a05109623e18
--- /dev/null
+++ b/web-ui/docs/en/blog/lifeng2221dd1/2020-09-14-isulad-architecture.md
@@ -0,0 +1,747 @@
+---
+title: 'Features and Code Architecture of the iSulad Lightweight Container Engine'
+category: blog
+date: 2020-09-14
+tags:
+ - iSulad
+archives: 2020-09
+author:
+ - lifeng2221dd1
+summary: iSulad architecture analysis
+---
+
+Introduction to the author: Li Feng has years of experience in container and OS software development, as well as in-depth research and understanding of container engines and runtime. He extensively participates in open source container communities such as LXC and Containers, and is now the maintainer of the openEuler iSulad community.
+
+iSulad is a container engine written in the C/C++ programming language. It has been open-sourced in the openEuler community ([https://gitee.com/openeuler/iSulad](https://gitee.com/openeuler/iSulad)). Mainstream container engines, such as Docker, containerd, and CRI-O, are written in the GO language. With the emergence of embedded device scenarios such as edge computing and the Internet of Things (IoT), the demands for service containerization are increasing in resource-limited environments. The disadvantages in memory overhead of container engines written in high-level languages are becoming more and more prominent. In addition, thanks to the standardization of external interfaces of container engines, it is possible to rewrite container engines using C/C++. The following figure shows the overall architecture of iSulad.
+
+
+
+iSulad provides two types of external interfaces: command line interfaces (CLIs) and gRPC-based container runtime interfaces (CRIs). Its core service functions are image management and container management.
+
+The following figure shows the positioning of iSulad in the container ecosystem.
+
+
+
+This blog describes the features and overall architecture of iSulad.
+
+## iSulad Features
+
+### Client CLI for Container and Image Operations
+
+iSulad is in a typical client-server architecture model. It functions as the daemon server and provides a client command **isula** for users.
+
+The command parameters provided by iSulad cover most common application scenarios, including container operations, such as starting, stopping, deleting, and pausing containers, and image-related operations, such as downloading, importing, and deleting images.
+
+```
+$ sudo isula --help
+USAGE:
+ isula [args...]
+
+COMMANDS:
+ attach Attach to a running container
+ cp Copy files/folders between a container and the local filesystem
+ create Create a new container
+ events Get real time events from the server
+ exec Run a command in a running container
+ export export container
+ images List images
+ import Import the contents from a tarball to create a filesystem image
+ info Display system-wide information
+ inspect Return low-level information on a container or image
+ kill Kill one or more running containers
+ load load an image from a tar archive
+ login Log in to a Docker registry
+ logout Log out from a Docker registry
+ logs Fetch the logs of a container
+ pause Pause all processes within one or more containers
+ ps List containers
+ pull Pull an image or a repository from a registry
+ rename Rename a container
+ restart Restart one or more containers
+ rm Remove one or more containers
+ rmi Remove one or more images
+ run Run a command in a new container
+ start Start one or more stopped containers
+ stats Display a live stream of container(s) resource usage statistics
+ stop Stop one or more containers
+ tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
+ top Display the running processes of a container
+ unpause Unpause all processes within one or more containers
+ update Update configuration of one or more containers
+ version Display information about isula
+ wait Block until one or more containers stop, then print their exit codes
+```
+
+### Example
+
+If you are using an openEuler distribution, you can use iSulad as follows:
+
+Run the **yum** command to install iSulad.
+
+```
+[root@openeuler ~]# yum install -y iSulad
+```
+
+After the installation is complete, check the service running status.
+
+```
+[root@openeuler ~]# systemctl status isulad
+● isulad.service - iSulad Application Container Engine
+ Loaded: loaded (/usr/lib/systemd/system/isulad.service; enabled; vendor preset: disabled)
+ Active: active (running) since Mon 2020-09-14 15:53:43 CST; 4h 35min ago
+ Main PID: 1248 (isulad)
+ Tasks: 25
+ Memory: 88.3M
+ CGroup: /system.slice/isulad.service
+ ├─1248 /usr/bin/isulad
+```
+
+Modify the iSulad configuration file and add the image repository address.
+
+```
+[root@openeuler iSula]# vi /etc/isulad/daemon.json
+{
+ .......
+ "registry-mirrors": [
+ "hub.oepkgs.net"
+ ],
+ .......
+```
+
+Restart the iSulad service.
+
+```
+[root@openeuler iSula]# systemctl restart isulad
+```
+
+Run a container based on the openEuler 20.09 image.
+
+Create a container.
+
+```
+[root@openeuler iSula]# isula create -it openeuler/openeuler:20.09
+Unable to find image 'openeuler/openeuler:20.09' locally
+Image "openeuler/openeuler:20.09" pulling
+Image "8c788f4bfb7290e434b2384340a5f9811db6ed302f9247c5fc095d6ec4fc8f32" pulled
+e91e5359be653f534312bc2b4703dcc6c4ca0436ac7819e09e1ff0e75ee1d733
+```
+
+The created container cannot be found by running the **isula ps** command because it is not running.
+
+```
+[root@openeuler iSula]# isula ps
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+```
+
+You can run the **isula pa –a** command to find the created container.
+
+```
+[root@ecs-cdf3 ~]# isula ps -a
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+e91e5359be65 openeuler/openeuler:20.09 "/bin/bash" 8 seconds ago Created e91e5359be653f534312bc2b4703dcc6c4ca0436ac7819e09e1ff0e75ee1d733
+```
+
+Start the container.
+
+```
+[root@openeuler iSula]# isula start e91e5359be65
+```
+
+You can run the **isula ps** command to find the container because it is now running.
+
+```
+[root@openeuler iSula]# isula ps
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+e91e5359be65 openeuler/openeuler:20.09 "/bin/bash" 30 seconds ago Up 4 seconds e91e5359be653f534312bc2b4703dcc6c4ca0436ac7819e09e1ff0e75ee1d733
+```
+
+View the container system version information.
+
+```
+[root@ecs-cdf3 ~]# isula exec e91e5359be65 cat /etc/os-release
+NAME="openEuler"
+VERSION="20.09"
+ID="openEuler"
+VERSION_ID="20.09"
+PRETTY_NAME="openEuler 20.09"
+ANSI_COLOR="0;31"
+```
+
+The openEuler 20.09 container is successfully running on the openEuler 20.03 system.
+
+Suspend and resume a container.
+
+```
+[root@openeuler iSula]# isula pause e91e5359be65
+e91e5359be65
+[root@openeuler iSula]# isula unpause e91e5359be65
+e91e5359be65
+```
+
+Forcibly delete a running container.
+
+```
+[root@openeuler iSula]# isula rm -f 6c1d81467d33
+6c1d81467d3367a90dd6e388a16c80411d4ba76316d86b6f56463699306e1394
+```
+
+Delete an image.
+
+```
+[root@openeuler iSula]# isula rmi openeuler/openeuler:20.09
+Image " openeuler/openeuler:20.09" removed
+```
+
+### Support for the CRI Standard Protocol
+
+The Container Runtime Interface (CRI) is a plugin interface defined by Kubernetes for container engines to provide container and image services externally to Kubernetes. In general, it is used by container engines to access Kubernetes.
+
+The CRI is implemented based on gRPC. iSulad complies with the CRI specifications and implements the CRI gRPC server, including RuntimeService and ImageService, which provide the container runtime interface and image operation interface, respectively. The gRPC server of iSulad needs to listen to the local Unix sockets, and the kubelet component of Kubernetes runs as the gRPC client.
+
+
+
+### Support for the CNI Network Standard Protocol
+
+The Container Network Interface (CNI) is a container network standard protocol developed by Google and CoreOS. With the CNI protocol, iSulad communicates with specific network plugins through JSON files to implement network functions of containers. iSulad uses the C language to implement the clibcni interface module to enable corresponding functions.
+
+
+
+### OCI Standard Compliment
+
+OCI consists of two specifications: the **runtime specification and image format specification**.
+
+#### Support for the OCI Standard Image Format
+
+First, let's look at what is a container image. The root file system (rootfs) and some resource configurations required for container running are packaged into a specific data structure, which is called a container image. A container can easily run based on the image. The operating environment and applications are packaged into the container image, avoiding the environment dependency problem during application deployment. Each container image consists of one or more layers of data and a **config.json** configuration file. The multiple layers depend on each other. This dependency is called a parent-child relationship (the depended layer is the parent layer). Before a container runs, data at all layers is combined and mounted to the rootfs for the container to use, which is called the container layer. If the combined data conflicts, the data at the child layer overwrites the data with the same paths and names at the parent layer. The following figure shows the image structure.
+
+
+
+Image layering is used to solve the space occupation problem. If the current layer and all its recursively dependent parent layers have the same data, the data can be reused to reduce space occupation. The following figure shows the data reuse structure of two container images with the same layer 0 and layer 1.
+
+
+
+iSulad supports the OCI standard image format and image formats compatible with Docker. You can download container images from image repositories such as Docker Hub, or import image files exported from Docker to start containers.
+
+#### Support for the OCI Standard Runtime
+
+iSulad supports the standard OCI runtime operation interfaces for container life cycle management. iSulad not only supports mainstream container runtimes such as runc and kata, but also modifies the LXC written in the C language to make it a C language runtime that supports the OCI standard protocol to meet the low memory overhead requirement. This further reduces the memory overhead of the container engine infrastructure.
+The following uses iSulad to run a new container. You can view the processes generated during running and the persistent configurations to better understand the container running.
+
+To run a container, you need to download an image first. We use **openeuler/openeuler:20.09** mentioned above as the container image.
+
+Use the iSulad client command to download the image.
+
+```bash
+$ sudo isula pull openeuler/openeuler:20.09
+Image "openeuler/openeuler:20.09" pulling
+Image "c7c37e472d31c1685b48f7004fd6a64361c95965587a951692c5f298c6685998" pulled
+```
+
+Create a container and start it.
+
+```bash
+$ sudo isula run -itd openeuler/openeuler:20.09
+42fc2595f876b5a18f7729dfb10d0def29789fb73fe0f1327e0277e6d85189a1
+```
+
+After the container is started, you can view the persistent container configuration file through a local file.
+
+```bash
+# cd /var/lib/isulad/engines/lcr/42fc2595f876b5a18f7729dfb10d0def29789fb73fe0f1327e0277e6d85189a1
+# ls -al
+total 92
+drwxr-x--- 3 root root 4096 Jul 27 16:25 .
+drwxr-x--- 3 root root 4096 Jul 27 16:25 ..
+-rw-r----- 1 root root 4045 Jul 27 16:25 config
+-rw-r----- 1 root root 23878 Jul 27 16:25 config.json
+-rw-r----- 1 root root 2314 Jul 27 16:25 config.v2.json
+-rw-r----- 1 root root 0 Jul 27 16:25 console.log
+-rw-r----- 1 root root 101 Jul 27 16:25 hostconfig.json
+-rw-r--r-- 1 root root 10 Jul 27 16:25 hostname
+-rw-r--r-- 1 root root 183 Jul 27 16:25 hosts
+drwx------ 3 root root 4096 Jul 27 16:25 mounts
+-rw-r----- 1 root root 5 Jul 27 16:25 ocihooks.json
+-rw-r--r-- 1 root root 707 Jul 27 16:25 resolv.conf
+-rw-r----- 1 root root 26140 Jul 27 16:25 seccomp
+```
+
+The **config.json** file is the container configuration file that complies with the OCI standard protocol. It contains the configuration information required for starting the container.
+
+```bash
+# cat config.json
+{
+ "ociVersion": "1.0.1",
+ "hooks": {
+
+ },
+ "hostname": "localhost",
+ "mounts": [
+ {
+ "source": "tmpfs",
+ "destination": "/dev",
+ "options": [
+ "nosuid",
+ "strictatime",
+ "mode=755",
+ "size=65536k"
+ ],
+ "type": "tmpfs"
+ },
+ {
+ "source": "mqueue",
+ "destination": "/dev/mqueue",
+ "options": [
+ "nosuid",
+ "noexec",
+ "nodev"
+ ],
+ "type": "mqueue"
+ },
+ ...
+```
+
+The **config.v2.json** file contains information about container persistence maintenance and management of iSulad, including basic container configurations, creation time, startup time, container PID, and running startup time.
+
+```bash
+# cat config.v2.json
+{
+ "CommonConfig": {
+ "Path": "sh",
+ "Config": {
+ "Hostname": "localhost",
+ "User": "",
+ "Tty": true,
+ "OpenStdin": true,
+ "Env": [
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+ ],
+ "Cmd": [
+ "sh"
+ ],
+ "WorkingDir": "",
+ "LogDriver": "json-file"
+ },
+ "Created": "2020-07-27T16:25:16.170149428+08:00",
+ "Image": "openeuler/openeuler:20.09",
+ "ImageType": "oci",
+ "Name": "42fc2595f876b5a18f7729dfb10d0def29789fb73fe0f1327e0277e6d85189a1",
+ "id": "42fc2595f876b5a18f7729dfb10d0def29789fb73fe0f1327e0277e6d85189a1"
+ },
+ "Image": "sha256:c7c37e472d31c1685b48f7004fd6a64361c95965587a951692c5f298c6685998",
+ "State": {
+ "FinishedAt": "0001-01-01T00:00:00Z",
+ "Pid": 19232,
+ "PPid": 19229,
+ "StartTime": 2731408,
+ "PStartTime": 2731402,
+ "Running": true,
+ "StartedAt": "2020-07-27T16:25:16.286812971+08:00"
+ }
+}
+```
+
+## Performance
+
+### Performance Comparison with Other Container Engines
+
+#### Test Environment
+
+| Configuration | Information |
+| ------------- | -------------------------------------------- |
+| OS | Fedora32 X86_64 |
+| Kernel | linux 5.7.10-201.fc32.x86_64 |
+| CPU | 48 cores, Intel Xeon CPU E5-2695 v2 @ 2.4GHZ|
+| Memory | 132 GB |
+
+#### Test Software
+
+| Name | Version |
+| --------- | --------------------------------------------------------------------- |
+| iSulad | Version: 2.0.3, Git commit: 3bb24761f07cc0ac399e1cb783053db8b33b263d |
+| docker | Version: 19.03.11, Git commit: 42e35e6 |
+| podman | Version: 2.0.3 |
+| CRI-O | v1.15.4 |
+| kubelet | v1.15.0 |
+| cri-tools | v1.15.0 |
+
+#### Single-Container Operations
+
+Execution Time Using a Client (in Milliseconds)
+
+| Operator| Docker | Podman | iSulad | vs. Docker | vs. Podman |
+| ------------- | ------ | ------ | ------ | --------- | --------- |
+| create | 287 | 180 | 87 | -69.69% | -51.67% |
+| start | 675 | 916 | 154 | -77.19% | -83.19% |
+| stop | 349 | 513 | 274 | -21.49% | -46.59% |
+| rm | 72 | 187 | 60 | -16.67% | -67.91% |
+| run | 866 | 454 | 195 | -77.48% | -57.05% |
+
+Execution Time Using the CRI (in Milliseconds)
+
+| Operator| Docker | CRI-O | iSulad | vs. Docker | vs. Podman |
+| ------------- | ------ | ---- | ------ | --------- | --------- |
+| runp | 681 | 321 | 186 | -72.69% | -42.06% |
+| stopp | 400 | 356 | 169 | -57.75% | -52.53% |
+
+#### Concurrent 100-Container Operations
+
+Execution Time Using a Client (in Milliseconds)
+
+| Operator| Docker | Podman | iSulad | vs. Docker | vs. Podman |
+| ------------- | ------ | ------ | ------ | --------- | --------- |
+| 100 \* create | 4995 | 3993 | 829 | -83.40% | -79.24% |
+| 100 \* start | 10126 | 5537 | 1425 | -85.93% | -74.26% |
+| 100 \* stop | 8066 | 11100 | 2273 | -71.82% | -79.52% |
+| 100 \* rm | 3220 | 4319 | 438 | -86.40% | -89.86% |
+| 100 \* run | 9822 | 5979 | 2117 | -78.45% | -64.59% |
+
+Execution Time Using the CRI (in Milliseconds)
+
+| Operator| Docker | CRI-O | iSulad | vs. Docker | vs. Podman |
+| ------------- | ------ | ---- | ------ | --------- | --------- |
+| 100 \* runp | 13998 | 4946 | 2825 | -79.82% | -42.88% |
+| 100 \* stopp | 8402 | 4834 | 4543 | -45.93% | -6.02% |
+
+## iSulad Code Architecture
+
+We have introduced the main features of iSulad. Now, let's go to the iSulad code to understand its organizational architecture.
+
+### **DDD Layered Architecture Design**
+
+iSulad adopts the Domain Driven Design (DDD) to organize the architecture by layer. The layers are as follows:
+
+
+
+The logical layers and their responsibilities are as follows:
+
+| **Layer** | **Function** |
+| ---------- | -------------------------------------------------------------------------------------- |
+| User interface layer | Displays information and interprets user commands. |
+| API layer | Defines and implements the client-server communication interface and the CRI. |
+| Application layer | Calls interfaces at the domain layer to implement corresponding service applications. |
+| Domain layer | Contains domain information, which is the core of the iSulad software. It has multiple modules and is the actual execution layer of the service logic.|
+| Infrastructure layer| Serves as the support library of other layers, and provides various tool functions for other layers to call. |
+
+According to the preceding logical layering design, the architecture of iSulad source code directories is organized as follows:
+
+
+
+The **api** directory contains the .proto file of the gRPC service provided by iSulad for external systems. During compilation, gRPC is used to generate the corresponding client and server code.
+
+### Organizational Structure of Code at Each Layer
+
+#### User Interface Layer
+
+Code of the user interface layer is stored in the **src/cmd** directory, which contains the command line interfaces provided by iSulad for external systems. The **cmd** directory contains interpretations and parameters of the `isula` (client), `isulad` (server), and `isulad-shim` commands. The code structure is as follows:
+
+```bash
+├── CMakeLists.txt
+├── command_parser.c
+├── command_parser.h
+├── isula # Definitions of the client commands and subcommands
+│ ├── base # Basic container operation commands, such as those for creating, starting, and deleting containers
+│ ├── client_arguments.c
+│ ├── client_arguments.h
+│ ├── CMakeLists.txt
+│ ├── extend # Extended commands for container operations, such as the update command for updating container resources and the events command for viewing container event logs.
+│ ├── images # Image-related operation commands, such as those for downloading, importing, and deleting images
+│ ├── information # Commands for querying container information, such as inspect and info
+│ ├── isula_commands.c
+│ ├── isula_commands.h
+│ ├── main.c
+│ └── stream # Persistent connection commands, such as cp, attach, and exec that require persistent connection with the server
+├── isulad # Definitions of the server commands and parameters
+│ ├── CMakeLists.txt
+│ ├── isulad_commands.c
+│ ├── isulad_commands.h
+│ └── main.c
+└── isulad-shim # Definitions of the isulad-shim commands and parameters
+│ ├── CMakeLists.txt
+│ ├── common.c
+│ ├── common.h
+│ ├── main.c
+│ ├── process.c
+│ ├── process.h
+│ ├── terminal.c
+│ └── terminal.h
+└── options # Common parameter parsing method
+│ ├── CMakeLists.txt
+│ ├── opt_log.c
+│ ├── opt_log.h
+│ ├── opt_ulimit.c
+│ └── opt_ulimit.h
+
+
+```
+
+#### API Layer
+
+Code of the API layer of iSulad is stored in the **src/daemon/entry** directory, which provides definitions of the client-server communication interface and the CRI.
+
+This layer is used to process client and CRI requests.
+
+In the **cri** directory, iSulad implements two types of services: image and runtime.
+
+```bash
+├── CMakeLists.txt
+├── connect # Client request processing
+│ ├── CMakeLists.txt
+│ ├── grpc # gRPC request interface processing
+│ ├── rest # RESTful request interface processing
+│ ├── service_common.c
+│ └── service_common.h
+└── cri # CRI request processing
+ ├── checkpoint_handler.cc
+ ├── checkpoint_handler.h
+ ├── CMakeLists.txt
+ ├── cni_network_plugin.cc
+ ├── cni_network_plugin.h
+ ├── cri_container.cc # Processing of container-related operation requests in the CRI
+ ├── cri_container.h
+ ├── cri_image_service.cc # Processing of image-related operation requests in the CRI
+ ├── cri_image_service.h
+ ├── cri_runtime_service.cc # Processing of runtime-related operation requests in the CRI
+ ├── cri_runtime_service.h
+ ├── cri_sandbox.cc # Processing of pod-related operation requests in the CRI
+ ├── cri_sandbox.h
+ ├── cri_security_context.cc # CRI security configuration processing
+ ├── cri_security_context.h
+ └── websocket # Processing of CRI streaming service requests using the WebSocket service
+```
+
+#### Application Layer
+
+Code of the application layer of iSulad is stored in the **src/daemon/executor** directory. It is used to call APIs at the domain layer to implement corresponding service applications. The application layer is a service scheduling layer. According to the folder names, the application layer implements two service modules: image and runtime.
+
+```bash
+├── callback.c
+├── callback.h
+├── CMakeLists.txt
+├── container_cb # Container service module
+│ ├── CMakeLists.txt
+│ ├── execution.c
+│ ├── execution_create.c
+│ ├── execution_create.h
+│ ├── execution_extend.c
+│ ├── execution_extend.h
+│ ├── execution.h
+│ ├── execution_information.c
+│ ├── execution_information.h
+│ ├── execution_network.c
+│ ├── execution_network.h
+│ ├── execution_stream.c
+│ ├── execution_stream.h
+│ ├── list.c
+│ └── list.h
+└── image_cb # Image service module
+ ├── CMakeLists.txt
+ ├── image_cb.c
+ └── image_cb.h
+```
+
+#### Domain Layer
+
+The domain layer contains domain information, which is the core of the iSulad software. It contains all service modules and is the execution layer of the service logic. Its code is stored in **src/daemon/modules**.
+
+```bash
+├── api # Header files provided by the domain layer, which are used by the application layer
+│ ├── CMakeLists.txt
+│ ├── container_api.h
+│ ├── events_collector_api.h
+│ ├── events_sender_api.h
+│ ├── event_type.h
+│ ├── image_api.h
+│ ├── io_handler.h
+│ ├── log_gather_api.h
+│ ├── plugin_api.h
+│ ├── runtime_api.h
+│ ├── service_container_api.h
+│ ├── service_image_api.h
+│ └── specs_api.h
+├── CMakeLists.txt
+├── container # Container module, which maintains the full life cycle and status of a container
+│ ├── CMakeLists.txt
+│ ├── container_events_handler.c
+│ ├── container_events_handler.h
+│ ├── container_gc
+│ ├── containers_store.c
+│ ├── containers_store.h
+│ ├── container_state.c
+│ ├── container_state.h
+│ ├── container_unix.c
+│ ├── container_unix.h
+│ ├── health_check
+│ ├── restart_manager
+│ ├── restore
+│ └── supervisor
+├── events # Event collection module, which collects container and image events generated during iSulad running
+│ ├── CMakeLists.txt
+│ ├── collector.c
+│ ├── monitord.c
+│ └── monitord.h
+├── events_sender # Event sending module, which provides an interface for sending events to the event collection module
+│ ├── CMakeLists.txt
+│ └── event_sender.c
+├── image # Image management module
+│ ├── CMakeLists.txt
+│ ├── embedded # Management of images in embedded format
+│ ├── external # Management of images in external format
+│ ├── image.c
+│ ├── image_rootfs_handler.c
+│ ├── image_rootfs_handler.h
+│ └── oci # Management of images in OCI format
+├── log # Log collection module
+│ ├── CMakeLists.txt
+│ └── log_gather.c
+├── plugin # Plugin mechanism module
+│ ├── CMakeLists.txt
+│ ├── plugin.c
+│ ├── pspec.c
+│ └── pspec.h
+├── runtime # Container runtime module
+│ ├── CMakeLists.txt
+│ ├── engines # LXC-based lightweight runtime interconnection interface
+│ ├── isula # Standard OCI runtime interconnection interface
+│ └── runtime.c
+├── service # Service module, including the implementation of collaborative calls to multiple modules
+│ ├── CMakeLists.txt
+│ ├── io_handler.c
+│ ├── service_container.c # Container service operation interface
+│ └── service_image.c # Image service operation interface
+└── spec # OCI specification configuration module, which provides functional interfaces such as OCI specification combination and verification
+ ├── CMakeLists.txt
+ ├── specs.c
+ ├── specs_extend.c
+ ├── specs_extend.h
+ ├── specs_mount.c
+ ├── specs_mount.h
+ ├── specs_namespace.c
+ ├── specs_namespace.h
+ ├── specs_security.c
+ ├── specs_security.h
+ ├── verify.c # Interface for configuring the verification function
+ └── verify.h
+```
+
+#### Infrastructure Layer
+
+The infrastructure layer is located in the **src/utils** directory. It functions as the support library of other layers, and provides various tool functions for other layers to call.
+
+```bash
+├── buffer # Buffer tool functions
+│ ├── buffer.c
+│ ├── buffer.h
+│ └── CMakeLists.txt
+├── CMakeLists.txt
+├── console # I/O terminal processing tool functions
+│ ├── CMakeLists.txt
+│ ├── console.c
+│ └── console.h
+├── cpputils # Tool functions used by C++, including basic character string processing, URL, and thread tools
+│ ├── CMakeLists.txt
+│ ├── cxxutils.cc
+│ ├── cxxutils.h
+│ ├── stoppable_thread.cc
+│ ├── stoppable_thread.h
+│ ├── url.cc
+│ └── url.h
+├── cutils # Tool functions used by C, including basic character string processing, data type conversion, file processing, and regular expression tools
+│ ├── CMakeLists.txt
+│ ├── util_atomic.c
+│ ├── util_atomic.h
+│ ├── utils_aes.c
+│ ├── utils_aes.h
+│ ├── utils_array.c
+│ ├── utils_array.h
+│ ├── utils_base64.c
+│ ├── utils_base64.h
+│ ├── utils.c
+│ ....
+├── http # HTTP processing tool functions, including HTTP request, parsing, and authentication tools
+│ ├── certificate.c
+│ ├── certificate.h
+│ ├── CMakeLists.txt
+│ ├── http.c
+│ ├── http.h
+│ ├── mediatype.h
+│ ├── parser.c
+│ ├── parser.h
+│ ├── rest_common.c
+│ └── rest_common.h
+├── sha256 # sha256 tool functions, which are used to calculate SHA-256 hash values.
+│ ├── CMakeLists.txt
+│ ├── sha256.c
+│ └── sha256.h
+└── tar # File compression and decompression tool function
+ ├── CMakeLists.txt
+ ├── isulad_tar.c
+ ├── isulad_tar.h
+ ├── util_archive.c
+ ├── util_archive.h
+ ├── util_gzip.c
+ └── util_gzip.h
+```
+
+### Calling Process
+
+You can use the **Structure101** code analysis tool to sort out the calling dependencies between iSulad code directories.
+
+
+
+As the top layer, the user interface layer (**cmd**) only calls interfaces of other modules and is not depended by other modules. **cmd** calls the functions in the **client** directory to communicate with the daemon service. The **cmd** directory contains the `daemon` command of iSulad. Therefore, it depends on the function definitions in the **daemon** directory.
+
+The **daemon** directory is the top-level directory of the server code, including the code of the API layer (**entry**), application layer (**executor**), and domain layer (**modules**). As the entry for calling the daemon service, the API layer needs to call functions at other layers for service scheduling. Other layers do not depend on this layer. The application layer needs to call the interfaces of each module at the domain layer (**modules**) to implement specific services.
+
+With the core code of iSulad at the domain layer, the **modules** directory contains the implementation of every sub-function module. Take the **image** module as an example. The **image_api.h** file is provided in **src/daemon/modules/api** to shield the differences between different image formats and implement a unified image operation function interface.
+
+```c
+int image_module_init(const isulad_daemon_configs *args);
+
+void image_module_exit();
+
+int im_list_images(const im_list_request *request, im_list_response **response);
+
+int im_rm_image(const im_rmi_request *request, im_remove_response **response);
+
+int im_tag_image(const im_tag_request *request, im_tag_response **response);
+
+int im_inspect_image(const im_inspect_request *request, im_inspect_response **response);
+
+int im_import_image(const im_import_request *request, char **id);
+
+int im_load_image(const im_load_request *request, im_load_response **response);
+
+int im_pull_image(const im_pull_request *request, im_pull_response **response);
+
+char *im_get_image_type(const char *image, const char *external_rootfs);
+
+bool im_config_image_exist(const char *image_name);
+
+int im_login(const im_login_request *request, im_login_response **response);
+
+int im_logout(const im_logout_request *request, im_logout_response **response);
+
+int im_container_export(const im_export_request *request);
+
+void free_im_export_request(im_export_request *ptr);
+
+```
+
+Inside the image management module, image operations in different formats are distinguished.
+
+```c
+static const struct bim_type g_bims[] = {
+#ifdef ENABLE_OCI_IMAGE
+ {
+ .image_type = IMAGE_TYPE_OCI,
+ .ops = &g_oci_ops,
+ },
+#endif
+ { .image_type = IMAGE_TYPE_EXTERNAL, .ops = &g_ext_ops },
+#ifdef ENABLE_EMBEDDED_IMAGE
+ { .image_type = IMAGE_TYPE_EMBEDDED, .ops = &g_embedded_ops },
+#endif
+};
+```
+
+Other modules are designed in a similar way. The detailed analysis of each module will be analyzed in subsequent blogs.
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-1.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-1.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..fc75cfa0853e44c4058642c0bf36d9f0e183543d
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-1.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-10.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-10.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..242aa4049fe845792482628182b7460eb5c00401
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-10.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-11.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-11.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..1f402689d79f9784cc3a8d41a99c49a2c595e7fb
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-11.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-12.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-12.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..e309e58bda3320248d1e2cf8240686e526ab6ad2
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-12.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-13.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-13.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..1a559ea00b603b48a533ccc4aceed9e455dc3fc6
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-13.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-2.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-2.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..8aa50cc47c5e5e412bc14ae7a9b352f04ed741fe
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-2.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-3.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-3.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..cb66c5f3047d716a35a7c4d1917b8466bed44522
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-3.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-4.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-4.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..87a25cc2e31bf564039058b22a1ee00a9348aaa4
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-4.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-5.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-5.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..bfe2ddac3dabf68ceb349692e4c7f37d84cc23dd
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-5.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-6.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-6.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..2ba9afce32f9d393da9f2175759e625b74efb27d
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-6.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-7.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-7.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..a7cf0b9b4baf6ced67aae68d38d55f233c724bc2
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-7.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-8.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-8.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..ee2194ac991b1a04aefe753d3c270d8684977f0c
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-8.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-9.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-9.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..ce9a5f435179b6415f2bb3e57a5126f5b69f0689
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220-9.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220.md" "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220.md"
new file mode 100644
index 0000000000000000000000000000000000000000..404cea0b041ab66eba5af7e6668d28f760794577
--- /dev/null
+++ "b/web-ui/docs/en/blog/lijia128/2020-11-03-ELF\346\226\207\344\273\266\346\240\274\345\274\217\350\247\243\346\236\220.md"
@@ -0,0 +1,159 @@
+---
+title: 'ELF File Format Analysis'
+category: blog
+date: 2020-11-02
+tags:
+ - ELF
+ - executable file format
+archives: 2020-11
+author:
+ - Jiajie Li
+summary: ELF file format analysis
+---
+
+# ELF File Format Analysis
+A compiler can compile and convert the source code to an object file. In terms of structure, an object file is the same as an executable file. The only difference is that the object file isn't linked, and some symbols and addresses isn't adjusted.
+
+Executable file formats cover all aspects of program compilation, linking, loading, and execution. Understanding the executable file format helps understand the operating system and the mechanism behind program execution.
+
+Currently, the executable file format for the Linux platform is Executable and Linkable Format (ELF), which is similar to the EXE file format for the Windows platform.
+
+
+Example Program
+====
+To facilitate understanding, a simple C language program is used as an example to describe each part of the ELF.
+```c
+#include
+
+void say_hello(char *who)
+{
+ printf("hello, %s!\n", who);
+}
+
+char *my_name = "wb";
+
+int main()
+{
+ say_hello(my_name);
+ return 0;
+}
+```
+Compile it to generate an executable program named **app** and run it.
+```shell
+linux-XqAfQZ:~/tmp_analyze_elf # gcc -o app main.c
+linux-XqAfQZ:~/tmp_analyze_elf # ./app
+hello, wb!
+```
+
+ELF Layout
+====
+The ELF format can express four types of binary object files:
+ 1. Relocatable file (.o file)
+ 2. Executable file (for example, the app file generated by the preceding example code)
+ 3. Shared object file (.so file, used for dynamic linking)
+ 4. Core dump file
+
+Relocatable files are used in the building and linking phase. Executable files are used in the program execution phase. Shared object files are used in both phases. We can understand the ELF from different perspectives in different phases. The following figure shows the overall layout.
+
+
+
+As shown in the preceding figure, an ELF file consists of four parts:
+ * An ELF header defines global information.
+ * A program header table is an array of structures, each describing a segment. Executable files usually contain a program header table. Relocatable files usually don't contain one, but they could.
+ * A segment consists of several sections. Segments are loaded into the process address space during execution and are contained in executable files. A section is a unit of a segment and is contained in executable files and relocatable files.
+ * A section header table is an array of structures, each describing a section. Relocatable files usually contain a section header table. Executable files usually contain one, but they don't need it.
+
+
+
+ELF Header
+====
+The fields in the ELF header are defined as follows:
+
+
+
+Run the **readelf -h** command to view the ELF header content in the example program **app**. The command output is as follows:
+
+
+
+ * **e_ident** contains the first 16 bytes and can be further divided into fields such as class, data, and version. You only need to know that the file is in ELF format if the first four bytes contain the keyword "ELF".
+ * **e_type** indicates the ELF type, which can be the relocatable file, executable file, or shared library file. **e_machine** indicates the machine platform where the file is executed, which is x86_64 in the example.
+ * **e_version** indicates the file version. The value **1** indicates the initial version.
+ * **e_entry** indicates the entry point address. It is the program entry function address and is expressed as an address in the process virtual address space (0x400440 in the example).
+ * **e_phoff** indicates the start of program headers, that is, the offset of the program header table in the file. In the example, **e_phoff** starts from byte 64 (assuming that the initial byte is byte 0).
+ * **e_shoff** indicates the start of section headers, that is, the offset of the section header table in the file. In the example, **e_shoff** starts from byte 4472, which is close to the end of the file.
+ * **e_flags** indicates information related to the CPU architecture and is zero in the example.
+ * **e_ehsize** indicates the size of this header. The size is 64 bytes in the example. The value of **e_phoff** is also 64, which means that the ELF header is followed by the program header table.
+ * **e_phentsize** indicates the size of program headers, that is, the size of each element in the program header table. In this example, the size is 56 bytes.
+ * **e_phnum** indicates the number of program headers, that is, the number of elements in the program header table. In this example, the number is 9.
+ * **e_shentsize** indicates the size of section headers, that is, the size of each element in the section header table. In this example, the size is 64 bytes.
+ * **e_shnum** indicates the number of section headers, that is, the number of elements in the section header table. In this example, the number is 30.
+ * **e_shstrndx** indicates the section header string table index, that is, the subscript of the section name string table in the section header table. For details, see the description of the string table in the following sections.
+
+Program Header Table
+====
+The program header table is an array. Each array element is called a program header. The structure of the program header table is defined as follows:
+
+
+
+Run the **readelf -l** command to view the program header table of the example program.
+
+
+
+The preceding figure shows the first part of the command output. The following analyzed only some headers:
+ * **PHDR**: This header element describes the information about the program header table. The offset of the program header table of the example program in the file is 0x40, that is, 64 bytes, and the virtual address (**VirtAddr**) of the process space to which the segment is mapped is 0x400040. **PhysAddr** is the same as **VirtAddr** but not used currently. The file size occupied by **PhysAddr** is 00x1f8. The size of the process space occupied by **PhysAddr** is also 0x1f8. **Flags** indicates the read and write permissions of the segment. **R E** indicates that the segment is readable and executable, which means that the segment is a code segment. **Align** is 8, indicating that the segment is 8-byte aligned.
+ * **INTERP**: This header element describes a special memory segment that records the access path string of the dynamically loaded interpreter. In the example program, the memory segment is located at the file offset 0x238, following the program header table. The mapped process virtual address space's address is 0x400238. The file length and memory-mapped file length are both 0x1c, that is, 28 characters. The specific path is **/lib64/ld-linux-x86-64.so.2**. The segment is read-only and aligned by byte.
+ * **LOAD**: This header element describes the code segment or data segment that can be loaded to the process space. The first **LOAD** element is a code segment. The file offset is 0 and the mapped process address is 0x400000. The length of the code segment is 0x764 bytes. The segment is read-only and executable. The segment address is aligned to a 2M boundary. The second **LOAD** segment is a data segment. The file offset is 0xe10. The data segment is mapped into the process address at 0x600e10 (2M aligned). The file size is 0x230 and the memory size is 0x238 (because there is an 8-byte BSS segment, that is, an uninitialized data segment, which does not occupy the file space, but needs to be allocated space and cleared during running). The segment is readable and writable, and the segment address is also aligned to a 2M boundary.
+ * **DYNAMIC**: This header element describes the dynamically loaded segment, which usually contains a dynamically loaded section named **.dynamic**. This segment is also an array. Each array element describes information related to dynamic loading, which will be described in dynamic loading. This segment starts from the file offset 0xe28, has a length of 0x1d0, and is mapped to 0x600e28 of the process. Therefore, this segment overlaps with the previous data segment.
+
+The second part of the **readelf** command output shows the include relationship between segments and sections, as shown in the following figure. The **INTERP** segment contains only the **.interp** section. The code segment contains the **.interp**, **.plt**, and **.text** sections. The data segment contains the **.dynamic**, **.data**, and **.bss** sections. The **DYNAMIC** segment contains the **.dynamic** section. As we can see, some sections are included in multiple segments.
+
+
+
+Section Header Table
+====
+The section header table describes file sections. The definition of each element in the array is as follows:
+
+
+
+Run the **readelf -S** command to view the content of the section header table in the example program, as shown in the following figure. There are 30 sections in the example program. **Name** indicates the section name. **Type** indicates the section function. **Address** indicates the virtual address of each section. **Offset** indicates the offset in the file. **Size** indicates the section size. **EntSize** indicates the size of each element in a section (if the section isn't an array, the value is 0). **Flags** indicates the section attribute. **Link** and **Info** record the information about different types of sections (for details, see the specifications). **Align** indicates the alignment unit of the section.
+
+
+
+String Table
+====
+In the preceding section header table example, there is a section type of STRTAB (subscripts 6, 27, and 29 in the section header table). This section is called a string table, which records all character string information. When other sections need to use character strings, only the offset of the start address of the character string in the string table needs to be recorded. The entire character string content doesn't need to be included.
+
+Run the **readelf -x** command to output the detailed information in the subscript-27 section.
+
+
+
+The content in the red box is the actual content of the section, the left part is the offset address of the section, and the right part is the character representations. We can see that there are a bunch of character strings, which correspond to the section names. Therefore, the name field of each element in the section header table is the index of the string table. The value of **e_shstrndx** in the ELF header is 27, pointing to the current string table.
+
+Similarly, let's look at the content in section 29, as shown in the following figure. We can see the **main** and **say_hello** character strings, which are symbols defined in the source code in the example. Therefore, section 29 is the string table of the application, which records the character strings used by the application.
+
+
+
+Symbol Table
+====
+In the section header table, there is another section type of SYMTAB (DYNSYM), which is called a symbol table. Each element in the symbol table corresponds to a symbol and records the actual value of the symbol. The symbol table is usually used in a relocation or a problem location process. The process execution doesn't load the symbol table. These elements are defined as follows: **name** indicates a source code string corresponding to a symbol, and is an index to a string table; **value** indicates the symbol value; **size** indicates a space occupied by the symbol; **info** indicates related information of the symbol, for example, a symbol type (variable symbol or function symbol); **shndx** indicates an index of the section related to the symbol, for example, a function symbol is related to a code section.
+
+
+
+Run the **readelf -s** command to output the symbol table in the example program, as shown in the following figure. The value corresponding to the **main** function symbol defined in the example program is 0x400554, the type is FUNC, the size is 26 bytes, and the index of the corresponding code section in the section header table is 13. The value corresponding to the **say_hello** function symbol is 0x400530, the type is FUNC, the size is 36 bytes, and the corresponding code section is 13.
+
+
+
+Code Segment
+====
+After understanding the functions of the string table and symbol table, we use **objdump** to disassemble a file to understand the **.text** code segment.
+
+
+
+We can see that a function is defined at 0x400530 and 0x400554 respectively. The symbols of the functions are **say_hello** and **main** respectively. The information is obtained by resolving the symbol table. In an instruction involving a memory address, except that a reference to a data segment address is performed by using an absolute address, a reference to a code segment address is performed by using a relative address. An advantage of doing so is that in a relocation process of a binary file, we don't need to change the address of the instruction (because the relative address remains unchanged). The access to the library function **printf** points to the code segment address 0x400410. Is the **printf** function stored at this address? The answer involves dynamic linking, which we will discuss in future.
+
+Summary
+====
+The preceding definitions and examples can help you understand the basics of the ELF file format. If you want to further explore the ELF files in detail, you can visit the following links:
+1. [https://en.wikipedia.org/wiki/Executable_and_Linkable_Format](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format)
+2. [https://linux-audit.com/elf-binaries-on-linux-understanding-and-analysis/](https://linux-audit.com/elf-binaries-on-linux-understanding-and-analysis/)
+3. [https://refspecs.linuxfoundation.org/elf/elf.pdf](https://refspecs.linuxfoundation.org/elf/elf.pdf)
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245-1.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245-1.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..ddd7dfbc8140a03cdc264f8891c8e7f27cdf6e04
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245-1.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245-2.jpg" "b/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245-2.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..e76c66b009899459835d5d174f80f0f01a7c894a
Binary files /dev/null and "b/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245-2.jpg" differ
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245.md" "b/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245.md"
new file mode 100644
index 0000000000000000000000000000000000000000..51d83c844ab0176172f6e4ccd965dcc52f977224
--- /dev/null
+++ "b/web-ui/docs/en/blog/lijia128/2020-11-09-\351\235\231\346\200\201\351\223\276\346\216\245\344\270\216\345\212\250\346\200\201\351\223\276\346\216\245.md"
@@ -0,0 +1,141 @@
+---
+title: 'Static Linking and Dynamic Linking'
+category: blog
+date: 2020-11-09
+tags:
+ - Static linking
+ - Dynamic linking
+ - Knowledge graph
+archives: 2020-11
+author:
+ - Jiajie Li
+summary: Introduction to the general process of static linking and dynamic linking.
+---
+
+# Static Linking and Dynamic Linking
+Top-Down Thinking Logic
+----
+The article "ELF File Format Analysis" provides some basics about executable and linking format (ELF) target files. Here comes a question: How do we link multiple compiled target files into an executable file?
+
+Because each instruction in an executable file requires a clear address, the objective of linking is to determine these addresses for executable files. From this point of view, it is clear that the main tasks of the linker are:
+
+ 1. Allocating addresses and space to multiple target files
+ 2. Understanding the definition and reference of each symbol
+ 3. Modifying instructions whose addresses need to be updated
+
+The three tasks actually correspond to **address and spatial allocation**, **symbol resolution**, and **symbol relocation** in a linking process. Symbol resolution and relocation are usually completed together. Therefore, this set of processing logic is also called **two-pass linking**.
+
+
+According to the mode of allocating addresses and space to the target file, the linking mode can be classified into static linking and dynamic linking. The following discusses the details of the two modes.
+
+Static Linking
+----
+Static linking means that before a program runs, the linker completes all relocation operations based on the relocation table in the object file and forms a program that does not need to load and relocate dependencies during program running in that all dependencies are linked to the program before running.
+
+The following figure shows the process of obtaining an executable file through static linking. Find the target file **printf.o** in **libc.a** based on the header files included by the source file and the library functions used in the program, for example, the **printf()** function defined in **stdio.h**. (The dependency of the **printf()** function is not considered here.) Then statically link the target file to the **hello.o** file to obtain the executable file.
+
+
+
+Static linking enables developers and teams to develop and test their own program modules independently, which greatly improves the program development efficiency. In addition, because static linking allows the executable file to have all conditions for program running, the program runs quickly during execution.
+
+However, static linking wastes memory and drive space of a computer. For a multi-process operating system, each process uses many functions in public static libraries, such as the **printf()** and **scanf()** functions. As a result, duplicate public library function target files exist in the system memory and drive space.
+
+Another problem lies in the difficulty of updating and upgrading programs. After a target file required by an executable file is updated, the entire executable file needs to be relinked, which is inconvenient.
+
+To solve the preceding two problems, the easiest way is to separate modules required by a program and link the modules when the program is running, which is the basic idea of dynamic linking.
+
+Dynamic Linking
+----
+Dynamic linking refers to the reference of the main program to symbols in dynamic shared libraries or objects, which are loaded and relocated when the program runs. The main program still uses static links. These links do not link the dependent dynamic shared libraries or objects to the main program.
+
+Dynamic linking involves runtime linking and loading of multiple files. These operations must be supported by the operating system. Currently, mainstream operating systems support dynamic linking. In Linux, ELF dynamic link files are called dynamic shared objects (DSOs), and the file name extension is **.so**. In Windows, dynamic link files are called dynamic linking libraries (DLLs), and the file name extension is **.dll**.
+
+The following illustrates the general process of dynamic linking in Linux. Three source files are required: **hello.c**, **lib.c**, and **lib.h**.
+
+```c++
+/* hello.c file */
+#include "lib.h"
+int main(){
+ printInLib(1);
+ return 0;
+}
+```
+
+```c++
+/* lib.c file */
+#include
+void printInLib(int i){
+ printf("Hello from lib %d\n", i);
+ return 0;
+}
+```
+
+```c++
+/* lib.h file */
+#inndef LIB_H
+#define LIB_H
+
+void printInLib(int i);
+
+#endif
+```
+
+The demo program is simple. **hello.c** invokes the **printInLib** function in **lib.c** to print an input number. Run the following command to compile **lib.c** and **lib.h** into a DSO:
+
+```shell
+gcc -fPic -shared -o Lib.so lib.c
+```
+
+After obtaining the **Lib.so** file, run the following command to compile the **hello.c** file:
+```shell
+gcc -o hello hello.c ./Lib.so
+```
+
+In this way, an executable file **hello** is obtained. The following figure shows the compilation and linking process.
+
+
+
+As you can see, when **hello.c** is compiled to **hello.o**, the linker requires the address of **printInLib**. Therefore, the linker needs **Lib.so** as input to provide complete symbol information for **hello**.
+
+Note that the linker mentioned here refers to a static linker, not a dynamic linker required for program running.
+
+Through this example, we've got a basic understanding of the concept of dynamic linking. Here is a problem: how do we determine the address of a DSO when the target program runs?
+
+Early operating systems use static shared libraries. That is, shared libraries of all programs are managed by the operating system, and the operating system allocates an address for each library at a specific address and then performs symbol relocation according to the address.
+
+However, this method brings a serious problem: address conflict. Consider the following scenario. Program A requires the system to load the shared libraries 1 and 2 to addresses 0x1000-0x2000 and 0x2000-0x3000. Program B requires the system to load the shared libraries 1 and 3 to addresses 0x1000-0x2000 and 0x2000-0x3000. As a result, if programs A and B are executed at the same time, either of the shared libraries 2 and 3 will fail to be loaded to the address 0x2000-0x3000. This situation becomes increasingly serious as the number of programs and shared libraries increases, and there is almost no probability for reasonable allocation.
+
+To solve this problem, we need to think about how to load DSOs at any address. In this case, we can refer to the relocation operation in static linking. That is, do not relocate any reference to an absolute address. After the target program is loaded, modify the absolute addresses. Relocation during static linking is called link-time relocation, and relocation during program loading is called load-time relocation.
+
+Load-time relocation can solve the problem of address conflict, but it has a great disadvantage: some instructions that need to be modified in a DSO cannot be shared among multiple processes, which loses the memory-saving advantage of dynamic linking. To solve this problem, a solution called position-independent code (PIC) emerges.
+
+The core idea of PIC is to separate the instructions that need to be modified in a DSO and place them together with data. The instructions that do not need to be modified remain unchanged, and the instructions that need to be modified and data can have a copy in each process. How can this be achieved? The access to variables and functions in a module is simple. Relative addresses and jumps can be used.
+
+But what about access to variables and functions across modules? "Any problem in computer science can be solved with another layer of indirection." In this case, we can create a global offset table (GOT) for these variables and functions and jump through the GOT to implement PIC. So far, dynamic linking has basically achieved the advantages we expected: more flexible, less memory and drive space usage, and more convenient for upgrade and maintenance.
+
+Summary
+----
+The compiler generates a target file in assembly language by performing lexical analysis, syntax analysis, semantic analysis, intermediate code optimization, target code generation, and target code optimization on its source file in a high-level programming language.
+
+The linker integrates the symbol information of each target file, allocates addresses and space, parses and relocates symbols, and finally generates an executable program. Links can be classified into static links and dynamic links according to processing methods during the link process.
+
++ Advantages of static linking
+ + Code is loaded quickly, and the execution speed is slightly faster than that in dynamic linking.
+ + We only need to ensure that correct LIB files exist on our computer. When releasing programs as binaries, we do not need to consider whether the LIB files exist on users' computers or the versions of the LIB files are consistent. This avoids the DLL Hell problem.
++ Disadvantages of static linking
+ + Executable files generated in static linking are large in size and contain the same public code, wasting memory and drive space.
+
++ Advantages of dynamic linking
+ + It saves memory and reduces page swapping.
+ + DLL files are independent of EXE files. As long as output interfaces remain unchanged (that is, the names, parameters, return value types, and invoking conventions are not changed), replacing DLL files does not affect the EXE files, greatly improving maintainability and scalability.
+ + Programs written in different programming languages can invoke the same DLL function as long as they comply with the function invoking conventions.
+ + It is suitable to large-scale software development, which makes the development process independent and loosely coupled, facilitating development and testing for developers and teams.
++ Disadvantages of dynamic linking
+ + Executable files run slightly slower than those in static linking.
+ + Applications that use DLLs are not self-complete. If a DLL required by an executable file does not exist, the program cannot be executed correctly.
+
+References
+----
+1. Programmer's self-cultivation - link, load and library
+2. [https://en.wikipedia.org/wiki/Static_library](https://en.wikipedia.org/wiki/Static_library)
+3. [https://en.wikipedia.org/wiki/Dynamic-link_library](https://en.wikipedia.org/wiki/Dynamic-link_library)
diff --git "a/web-ui/docs/en/blog/lijia128/2020-11-10-\345\212\250\346\200\201\351\223\276\346\216\245\344\270\255\347\232\204PLT\344\270\216GOT.md" "b/web-ui/docs/en/blog/lijia128/2020-11-10-\345\212\250\346\200\201\351\223\276\346\216\245\344\270\255\347\232\204PLT\344\270\216GOT.md"
new file mode 100644
index 0000000000000000000000000000000000000000..112161588d3c4ff808437f5e44513ff99a67422b
--- /dev/null
+++ "b/web-ui/docs/en/blog/lijia128/2020-11-10-\345\212\250\346\200\201\351\223\276\346\216\245\344\270\255\347\232\204PLT\344\270\216GOT.md"
@@ -0,0 +1,143 @@
+---
+title: 'PLT and GOT Workflow in Dynamic Linking'
+category: blog
+date: 2020-11-10
+tags:
+ - Dynamic linking
+ - PLT
+ - Lazy binding
+ - Knowledge graph
+archives: 2020-11
+author:
+ - Jiajie Li
+summary: Introduction to the PLT and GOT workflow in dynamic linking.
+---
+
+# PLT and GOT Workflow in Dynamic Linking
+About This Document
+----
+In article "Static Linking and Dynamic Linking", the advantages and disadvantages of the two linking modes are introduced. One of the disadvantages of dynamic linking is that the program execution is slightly slower than that in static linking.
+
+The reason is that an executable program in dynamic linking needs to perform indirect jumps using a global offset table (GOT) to access variables and functions across modules. As a result, the program running slows down.
+
+Another reason is that the dynamic linking process is completed when the program is running. That is, before the program execution, the dynamic linker searches for and loads dynamic shared objects (DSOs) required by the program, and then completes symbol relocation, which slows down the program startup.
+
+In this case, a solution called **lazy binding** emerges. The core idea of lazy binding is that symbol relocation of all function calls across modules is not completed when the program is started. Address binding (symbol lookup and relocation) is performed only when the target program needs to invoke functions of other modules.
+
+To achieve this objective, the ELF file adopts the **procedure linkage table (PLT)** structure, which contains some exquisite instruction sequences, which are described in the following sections.
+
+General Logic
+----
+Before looking into the details of the PLT, we can think about how to complete the task from a top-down perspective. Assume that the target program needs to invoke the **foo()** function in **liba.so**. When the function is invoked for the first time, the dynamic linker needs a lookup function for searching for the address of the **foo()** function to complete the binding.
+
+So what information does this lookup function need? Typically, the module where the binding behavior occurs (for example, in the main module of the target program) and the function to be bound (for example, the **foo()** function) are required. In glibc, the lookup function is **_dl_runtime_resolve()**. This process is described in pseudocode as follows:
+
+```c++
+ void DSOFunction@plt()
+ {
+ if (DSOFunction@got[index] ! = RELOCATED) {
+ // If the function is invoked for the first time, the GOT does not contain the address of the function.
+ The lookup function obtains the address of the invoked function based on the module ID and the ID of the invoked function, and fill it in the corresponding entry in the GOT.
+ DSOFunction@got[index] = RELOCATED;
+ }
+ else{
+ // The function address already exists in the GOT. Jump to the function address directly.
+ jmp *DSOFunction@got[index];
+ }
+ }
+```
+
+This segment of pseudocode corresponds to an out-of-module PLT entry. After sorting out the pseudocode, we can obtain the contents of the PLT entry in assembly language as follows:
+
+```asm
+ foo@plt
+ jmp *(foo@got)
+ push n
+ push moduleID
+ jmp _dl_runtime_resolve
+```
+
+The first instruction is to jump to the GOT entry of the **foo()** function. If the GOT entry has been bound, the correct function address can be directly jumped to. If this function is invoked for the first time, the content in the GOT entry is the address in the second instruction **push n**. In this step, the **if** judgment in the pseudocode is implemented.
+
+The second instruction is to push the **foo()** function ID into the stack. The ID is the subscript of the **foo()** function in the relocation table. The third instruction is to push the module ID into the stack, and the fourth instruction is to jump to the lookup function **_dl_runtime_resolve()**. After performing a series of searches, **_dl_runtime_resolve()** fills the absolute address of the **foo()** function in the corresponding entry in the GOT, and then transfers the control flow to the **foo()** function.
+
+After the **foo()** function address is successfully bound, invoking the PLT entry of the **foo()** function is achieved by jumping to the correct address through the GOT entry. The above is the general logic of GOT and PLT. The following discusses the specific workflow.
+
+
+Workflow
+----
+The ELF file divides a GOT into two parts: **.GOT** and **.GOT.PLT**. **.GOT** is used to store global variables, and **.GOT.PLT** is used to store reference addresses of functions in DSOs. Note that the PLT is located in the code segment of an executable program and is readable but not writable, and the GOT is located in the data segment of an executable program and is readable and writable. In addition, the first three entries of **.GOT.PLT** have specific meanings:
+
+1. The first entry stores the address of the **.dynamic** segment, which describes the information about dynamic links of the current module.
+2. The second entry stores the ID of the current module.
+3. The third entry stores the address of the **_dl_runtime_resolve** function.
+
+These are the beauty of the linker. It extracts the common content of each PLT entry to form a reusable public instruction sequence.
+
+Therefore, the assembly code structure of the PLT is as follows:
+```asm
+ plt[0]
+ push *got[1]
+ push *got[2]
+
+ ···
+
+ foo@plt
+ jmp *(foo@got)
+ push n
+ jmp plt[0]
+```
+
+After understanding the general logic, see the following example. It is the PLT and GOT of a simple helloworld executable file.
+
+```asm
+ Disassembly of section .plt:
+
+ 00000000004003f0 <.plt>:
+ 4003f0: ff 35 12 0c 20 00 pushq 0x200c12(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
+ 4003f6: ff 25 14 0c 20 00 jmpq *0x200c14(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
+ 4003fc: 0f 1f 40 00 nopl 0x0(%rax)
+
+ 0000000000400400 :
+ 400400: ff 25 12 0c 20 00 jmpq *0x200c12(%rip) # 601018
+ 400406: 68 00 00 00 00 pushq $0x0
+ 40040b: e9 e0 ff ff ff jmpq 4003f0 <.plt>
+
+ 0000000000400410 <__libc_start_main@plt>:
+ 400410: ff 25 0a 0c 20 00 jmpq *0x200c0a(%rip) # 601020 <__libc_start_main@GLIBC_2.2.5>
+ 400416: 68 01 00 00 00 pushq $0x1
+ 40041b: e9 d0 ff ff ff jmpq 4003f0 <.plt>
+ ...
+
+
+ Disassembly of section .got:
+
+ 0000000000600ff8 <.got>:
+ ...
+
+
+ Disassembly of section .got.plt:
+
+ 0000000000601000 <_GLOBAL_OFFSET_TABLE_>:
+ ...
+```
+
+By referring to the preceding code after disassembly, we can see that the PLT has three entries:
+
+1. **.plt[0]**: Pushes the second entry in the GOT (that is, **.GOT.PLT[1]**) into the stack and then jumps to **.GOT.PLT[2]**. The last **nop** instruction does nothing.
+2. **.plt[1]**: Jumps to **.GOT.PLT[3]**, pushes **0x0** into the stack, and then jumps back to **.plt[0]**.
+3. **.plt[2]**: Jumps to **.GOT.PLT[4]**, pushes **0x1** into the stack, and then jumps back to **.plt[0]**.
+
+As shown in the code, the logic is the same as that we have analyzed above. After the related functions are executed, the addresses of the invoked functions are filled in the GOT, and the program control flow is transferred to the invoked functions to run the program.
+
+Summary
+----
+In short, the PLT and GOT workflow is as follows:
+
+1. During compilation, compilation relocation is performed to reference a required function outside the module to the corresponding PLT entry, and the address in the second instruction in the PLT entry is used to initialize the corresponding GOT entry.
+2. When the program is started, the dynamic linker obtains the permission from the kernel and updates the module ID and address of the **_dl_runtime_resolve** function in the GOT.
+3. When a function outside the module is invoked, the program jumps to the corresponding PLT entry, and then jumps to the corresponding GOT entry.
+4. If the GOT entry is a function address, the function is directly invoked, and the program control flow is transferred to the invoked function.
+5. If the GOT entry is invoked for the first time, the program jumps to the second instruction of the PLT entry. Then, the function ID and module ID are pushed into the stack and input to **_dl_runtime_resolve** as parameters. After **_dl_runtime_resolve** is executed, the address of the invoked function is filled in the corresponding GOT entry, the program control flow is then transferred to the invoked function.
+
+Dynamic linking improves the startup speed of programs through lazy binding and the PLT structure, accelerating executable program running. The above is the general logic and workflow of PLT and GOT. I hope this article is helpful.
diff --git a/web-ui/docs/en/blog/zihao/Brief Introduction to Edge Computing.md b/web-ui/docs/en/blog/zihao/Brief Introduction to Edge Computing.md
index 32731940340a29095ac857eaad20c0b163f18636..fe5c0ea084bc6272024e4b03de1df633f1cbb85a 100644
--- a/web-ui/docs/en/blog/zihao/Brief Introduction to Edge Computing.md
+++ b/web-ui/docs/en/blog/zihao/Brief Introduction to Edge Computing.md
@@ -1,3 +1,15 @@
+---
+title: 'Brief Introduction to Edge Computing'
+category: blog
+date: 2022-08-10
+tags:
+ - edge computing
+archives: 2020-08
+author:
+ - zihao
+summary: Brief introduction to edge computing.
+---
+
# Brief Introduction to Edge Computing
Edge computing is a new computing mode that works at the network edge. It processes data through downstream cloud services and upstream device applications. Edge computing allocates computing and storage resources to edge nodes, which are closer to users. The nodes analyze data from nearby users and upload only important information such as computing results to the cloud, greatly releasing server pressure.
diff --git a/web-ui/docs/en/blog/zihao/Introduction to the openEuler Network Subsystem.md b/web-ui/docs/en/blog/zihao/Introduction to the openEuler Network Subsystem.md
index 8172171d6d906d60551f92e303ddeba329049615..0960d44ad4ae7eeefec7f14339b812a8913c7485 100644
--- a/web-ui/docs/en/blog/zihao/Introduction to the openEuler Network Subsystem.md
+++ b/web-ui/docs/en/blog/zihao/Introduction to the openEuler Network Subsystem.md
@@ -1,3 +1,16 @@
+---
+title: 'Introduction to the openEuler Network Subsystem'
+category: blog
+date: 2022-08-10
+tags:
+ - openEuler
+ - network subsystem
+archives: 2020-08
+author:
+ - zihao
+summary: Introduction to the openEuler network subsystem.
+---
+
# Introduction to the openEuler Network Subsystem
Interconnection between computers is key to the computer network for ensuring information transmission and sharing. As bottom-layer software, the OS plays an important role in communication.
diff --git a/web-ui/docs/en/blog/zihao/TBOX Installation and Operation on openEuler.md b/web-ui/docs/en/blog/zihao/TBOX Installation and Operation on openEuler.md
index 8e30f805766932e0b1a1527d82f48b3c7a28320e..0799bce2e5401a2b5528cda499bd45da708aa5df 100644
--- a/web-ui/docs/en/blog/zihao/TBOX Installation and Operation on openEuler.md
+++ b/web-ui/docs/en/blog/zihao/TBOX Installation and Operation on openEuler.md
@@ -1,3 +1,16 @@
+---
+title: 'TBOX Installation and Operation on openEuler'
+category: blog
+date: 2022-08-10
+tags:
+ - openEuler
+ - TBOX
+archives: 2020-08
+author:
+ - zihao
+summary: TBOX installation and operation on openEuler.
+---
+
# TBOX Installation and Operation on openEuler
This blog describes how to install TBOX on openEuler and test and use its modules.
diff --git a/web-ui/docs/en/news/20220801-openueuler08.md b/web-ui/docs/en/news/20220801.md
similarity index 100%
rename from web-ui/docs/en/news/20220801-openueuler08.md
rename to web-ui/docs/en/news/20220801.md
diff --git a/web-ui/docs/zh/blog/20220628-em-duoos/embedded-duoos.md "b/web-ui/docs/zh/blog/20220628-em-duoos/embedded-sig-\345\244\232os\346\267\267\345\220\210\351\203\250\347\275\262\346\241\206\346\236\266.md"
similarity index 100%
rename from web-ui/docs/zh/blog/20220628-em-duoos/embedded-duoos.md
rename to "web-ui/docs/zh/blog/20220628-em-duoos/embedded-sig-\345\244\232os\346\267\267\345\220\210\351\203\250\347\275\262\346\241\206\346\236\266.md"
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Amount-of-spills-of-the-LLVM-register-allocators.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Amount-of-spills-of-the-LLVM-register-allocators.png"
new file mode 100644
index 0000000000000000000000000000000000000000..facf908831bb9b5c85bff36ed26ca007f98d719d
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Amount-of-spills-of-the-LLVM-register-allocators.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Compile-time-in-seconds-of-the-LLVM-register-allocators.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Compile-time-in-seconds-of-the-LLVM-register-allocators.png"
new file mode 100644
index 0000000000000000000000000000000000000000..bcc2b3047258868a4599d63945c17e9968d2bd95
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Compile-time-in-seconds-of-the-LLVM-register-allocators.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Runtime-in-seconds-for-each-program-using-different-allocators.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Runtime-in-seconds-for-each-program-using-different-allocators.png"
new file mode 100644
index 0000000000000000000000000000000000000000..952ef9601f84e68e155dbbe53e35c154872dd7af
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/Runtime-in-seconds-for-each-program-using-different-allocators.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714202443857-16578014861342.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714202443857-16578014861342.png"
new file mode 100644
index 0000000000000000000000000000000000000000..b1f0f68aa51bf4f52428d1cc1e8f80e214d309bc
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714202443857-16578014861342.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714202443857.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714202443857.png"
new file mode 100644
index 0000000000000000000000000000000000000000..b1f0f68aa51bf4f52428d1cc1e8f80e214d309bc
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714202443857.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714203130753.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714203130753.png"
new file mode 100644
index 0000000000000000000000000000000000000000..a42743043d20e4a50b077980f50f5d4fd8f3682e
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714203130753.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714203520309.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714203520309.png"
new file mode 100644
index 0000000000000000000000000000000000000000..374cd9d6996d4a3c5823401547dc7e7ecde660c3
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220714203520309.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715104033715.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715104033715.png"
new file mode 100644
index 0000000000000000000000000000000000000000..d6a6a96ae250a516e26037d66b99fd2955f578eb
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715104033715.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715105935155.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715105935155.png"
new file mode 100644
index 0000000000000000000000000000000000000000..d3fce4ab1b9a275722860f451f8828cab3389c87
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715105935155.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715105948889.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715105948889.png"
new file mode 100644
index 0000000000000000000000000000000000000000..929271b83d64f65e3fd9d2cfaca9b3295f44f327
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715105948889.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110001572.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110001572.png"
new file mode 100644
index 0000000000000000000000000000000000000000..8fee2741abfaa466f5fcb763f8e23056638e4cdd
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110001572.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110019461.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110019461.png"
new file mode 100644
index 0000000000000000000000000000000000000000..ef2beca9e2044079d6e954cfcec633c9188b7983
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110019461.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110035049.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110035049.png"
new file mode 100644
index 0000000000000000000000000000000000000000..c29982223c1b007be4c8ddf54efe43f59a322a68
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110035049.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110050386.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110050386.png"
new file mode 100644
index 0000000000000000000000000000000000000000..db86c98150ec9eef3700a60195e1ba87e1c7a0d9
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715110050386.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112348983.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112348983.png"
new file mode 100644
index 0000000000000000000000000000000000000000..73b325a894f6e19d7ac50bed83911f506574718c
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112348983.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112359881.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112359881.png"
new file mode 100644
index 0000000000000000000000000000000000000000..8de9abbaab9ba33770aa2cea46b73be5d71c0cc2
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112359881.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112411756.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112411756.png"
new file mode 100644
index 0000000000000000000000000000000000000000..9a8f3b1c734f5470aa95c8da3ee87d54213f9dd3
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112411756.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112422565.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112422565.png"
new file mode 100644
index 0000000000000000000000000000000000000000..0d09bf7a56970b1fdddb5b4349c8ceb5a1b2bea1
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112422565.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112431837.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112431837.png"
new file mode 100644
index 0000000000000000000000000000000000000000..ae0cda70609ce6d036e6db4e7ca0c0b31c2a4eb8
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112431837.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112441587.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112441587.png"
new file mode 100644
index 0000000000000000000000000000000000000000..e2d14b175be8172faf07310ab9e79cf4ec58681d
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112441587.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112557567.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112557567.png"
new file mode 100644
index 0000000000000000000000000000000000000000..58e00fe40ff8895482a90216fa8dcf0f251124bb
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715112557567.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715114021046.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715114021046.png"
new file mode 100644
index 0000000000000000000000000000000000000000..f5e5cd8af1cf7142caa47ba4ace17232df04fe7c
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715114021046.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715114451951.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715114451951.png"
new file mode 100644
index 0000000000000000000000000000000000000000..e3fea65564a3e9b95739bd818ae605622cad34f7
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715114451951.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715115152697.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715115152697.png"
new file mode 100644
index 0000000000000000000000000000000000000000..240411920a2059f68e29c375e72fee6a6a691634
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715115152697.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162518234.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162518234.png"
new file mode 100644
index 0000000000000000000000000000000000000000..955ab51e1e6e4180ea2da9e28224703af12154c9
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162518234.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162555465.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162555465.png"
new file mode 100644
index 0000000000000000000000000000000000000000..3168daab7ae431b84f7479bc016a600b3fbaacc6
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162555465.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162701015.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162701015.png"
new file mode 100644
index 0000000000000000000000000000000000000000..1ba70c8c7cfb57c13ff79a95393cfe822b575285
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162701015.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162828383.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162828383.png"
new file mode 100644
index 0000000000000000000000000000000000000000..31fd5ad4134a411540a6179631bdae2e2855c426
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162828383.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162848097.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162848097.png"
new file mode 100644
index 0000000000000000000000000000000000000000..31fd5ad4134a411540a6179631bdae2e2855c426
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715162848097.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715175352641.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715175352641.png"
new file mode 100644
index 0000000000000000000000000000000000000000..46e84948736602c661d069ca1f62d63d6fdb0d36
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220715175352641.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220718101616852.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220718101616852.png"
new file mode 100644
index 0000000000000000000000000000000000000000..5317e0166e5c9a7db1cdd441101d17e7f25ccaca
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/image-20220718101616852.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/live.png" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/live.png"
new file mode 100644
index 0000000000000000000000000000000000000000..4160fe0e88258a5cb15cd49ab4c1942f6dd02c99
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.assets/live.png" differ
diff --git "a/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.md" "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.md"
new file mode 100644
index 0000000000000000000000000000000000000000..0f52b5e55d37fbbe9b4e9e4a3228b03b2d218327
--- /dev/null
+++ "b/web-ui/docs/zh/blog/20220822-\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215/\345\257\204\345\255\230\345\231\250\345\210\206\351\205\215.md"
@@ -0,0 +1,382 @@
+---
+title: '编译器优化那些事儿(5):寄存器分配'
+category: blog
+date: 2022-08-22
+tags:
+ - 毕昇
+ - 寄存器
+archives: 2022-08
+author:
+ - 王博洋
+summary: 本文首先会简述用到的基本概念,然后借助一个例子介绍活跃变量分析和图着色算法,最后会介绍线性扫描算法及其llvm12中实现
+---
+
+
+0. 引言
+1. 概念介绍
+2. 活跃变量分析与图着色算法
+3. 线性扫描
+4. llvm中实现
+5. 参考
+
+## 引言
+
+本文首先会简述用到的基本概念,然后借助一个例子介绍活跃变量分析和图着色算法,最后会介绍线性扫描算法及其llvm12中实现。
+
+## 概念介绍
+
+在介绍算法之前,我们回顾下基本概念:
+- |X|:X的度数,(无向图中)节点的邻居个数。
+
+- CFG:控制流图。
+
+- successor:本文指CFG中基本块的后继。
+
+- 四元式:(op,result,arg1,arg2),比如常见的`a=b+c`就可以看作四元式(+,a,b,c)。
+
+- SSA(Static Single Assignment):静态单赋值。
+
+- use/def:举个例子,对于指令`n: c <- c+b`来说 use[n]={c,b},def[n]={c}。
+
+- live-in:当以下任一条件满足时,则称变量a在节点n中是live-in的,写作a∈in[n]。节点n本文中代表指令。
+
+ 1. a∈use[n];
+ 2. 存在从节点n到其他节点的路径使用了a且不包括a的def。
+
+- live-out: 变量a在节点n的任一后继的live-in集合中。写作a∈out[n]
+ $$
+ in[n] = use[n]\cup(out[n]-def[n])\\
+ out[n] = in[s_1]\cup in[s_2]\cup ...\cup in[s_n], where\ s_1,...,s_n are\ all\ successors\ of\ n
+ $$
+
+- 干涉:在某一时刻,两个变量在同一`live-in`集合中。
+
+- RIG(Register Interfere Graph): 无向图,其点集和边集构成如下:
+
+ - 节点:变量
+ - 边:如果两节点存在干涉,那么这两节点之间就有一条干涉边
+
+- k-着色:给定无向图G=(V,E),其中V为顶点集合,E为边集合。将V分为k个组,每组中没有相邻顶点,可称该图G是k着色的。当然可着色前提下,k越小越好。
+ 需要注意的是,我们后续的算法会作用在最普通的四元式上,而不是SSA。在介绍寄存器分配算法之前,我们需要活跃变量分析来构建干涉图。
+
+## 活跃变量分析与图着色算法
+
+### 活跃变量分析
+
+简单来说,就是计算每个点上有哪些变量被使用。
+
+算法描述如下[1]:
+
+```mathematica
+input: CFG = (N, E, Entry, Exit)
+begin
+// init
+for each basic block B in CFG
+ in[B] = ∅
+// iterate
+do{
+ for each basic block B other than Exit{
+ out[B] = ∪(in[s]),for all successors s of B
+ in[B] = use[B]∪(out[B]-def[B])
+ }
+}until all in[] do't change
+```
+> 活跃变量分析还有孪生兄弟叫Reaching Definitions,不过实现功能类似,不再赘述。
+
+
+举个例子:对图1的代码进行活跃变量分析
+
+
+
+> 图1,参考[2]画的
+
+可以得到每个点的活跃变量如图2所示:
+
+
+> 图2
+
+过程呢?限于篇幅,仅仅计算第一轮指令1的结果,剩余部分读者可自行计算。
+
+| 步骤 | 下标 | out | in |
+| ---- | ------------- | - | - |
+| 第一次迭代 | 1 | {} | {b,c} |
+| ...| ... | ... | ... |
+
+可画出RIG如图3:
+
+
+
+> 图3
+
+### 图着色
+
+经过上文的活跃变量分析,我们得到了干涉图,下一步对其进行上色。
+
+但是图着色是一个NP问题,我们会采用**启发式**算法对干涉图进行着色。
+基本思路是:
+
+1. 找到度小于k的节点;
+2. 从图中删除;
+3. 判断是否为可着色的图;
+4. 迭代运行前3步直到着色完成。
+
+算法描述[3]:
+
+```mathematica
+input: RIG, k
+// init
+stack = {}
+// iterate
+while RIG != {} {
+ t := pick a node with fewer than k neighbors from RIG // 这里RIG可以先按度数排序节点再返回
+ stack.push(t)
+ RIG.remove(t)
+}
+// coloring
+while stack != {} {
+ t := stack.pop()
+ t.color = a color different from t's assigned colored neighbors
+}
+```
+
+对于例子1,假设有4个寄存器r1、r2、r3、r4可供分配。
+
+| 步骤 | stack | RIG |
+| ---- | ------------- | ------------------------------------------------------------ |
+| 0 | {} |  |
+| 1 | {a} |  |
+| 2 | {d,a} |  |
+| 3 | {c,d,a} |  |
+| 4 | {b,c,d,a} |  |
+| 5 | {e,b,c,d,a} |  |
+| 6 | {f,e,b,c,d,a} | |
+
+
+
+| 寄存器分配 | stack |
+| ------------------------------------------------------------ | ----------- |
+|  | {e,b,c,d,a} |
+|  | {b,c,d,a} |
+|  | {c,d,a} |
+|  | {d,a} |
+|  | {a} |
+|  | {} |
+
+所以图3中的RIG是`4-着色`的。但如果只有三种颜色可用,怎么办呢?
+
+没关系,我们还有大容量的内存,虽然速度慢了那么一点点。着色失败就把变量放在内存里,用的时候再取出来。
+
+依然是上例,但是k=3,只有三个颜色。
+
+| 步骤 | stack | RIG |
+| ---- | ----- | ------------------------------------------------------------ |
+| 0 | {} |  |
+| 1 | {a} |  |
+| 2 | 没有度数小于3的节点了,需要溢出变量了 | / |
+
+如果f的邻居是2-着色的就好了,但不是。那就只能选一个变量存入内存了。
+这里我们选择将变量`f`溢出至内存。溢出后的IR和RIG如图:
+
+
+
+> 图4:溢出后的IR
+
+
+
+> 图5:溢出后的RIG
+
+所以,溢出其实是分割了变量的生命周期以降低被溢出节点的邻居数量。
+溢出后的着色图如图6:
+
+
+> 图6:着色后的图5
+
+这里溢出变量`f`并不是明智的选择,关于如何优化溢出变量读者可自行查阅资料。
+
+至此,图着色算法基本介绍完毕。不过,如果代码中的复制指令,应该怎么处理呢?
+
+寄存器分配之前会有Copy Propagation和Dead Code Elimination优化掉部分复制指令,但是两者并不是全能的。
+
+比如:代码段1中,我们可以合并Y和X。但是代码段2中Copy Propagation就无能为力了,因为分支会导致不同的Y值。
+
+```txt
+// 代码段1
+X = ...
+A = 10
+Y = X
+Z = Y + A
+return Z
+
+// 代码段2
+X= A + B
+Y = C
+if (...) {Y = X}
+Z = Y + 4
+```
+
+
+所以,寄存器分配算法也需要对复制指令进行处理。如何处理?给复制指令的源和目标分配同一寄存器。
+
+那么如何在RIG中表示呢?如果把复制指令的源和目标看作**RIG中相同的节点**,自然会分配同一寄存器。
+
+- 相同节点?可以扩展RIG:新增虚线边,代表合并候选人。
+
+- 成为合并候选人的条件是:如果X和Y的生命周期不重合,那么对于`Y=X`指令中的X和Y是可合并的。
+
+- 为了保证合并合法且不造成溢出:合并后局部的度数
+
+ > 图7,图源[3]
+
+ 但明显图7可以合并成图8:
+
+ > 图8,图源[3]
+
+2. Brigg's 算法:X和Y可合并,如果X和Y中度数≥k的邻居个数<k。但是如果X的度数很大,算法效率就不高
+
+3. George's算法:X和Y可合并,如果对Y的每个邻居T,|T|
+
+ > 图9,图源[3]
+
+ 相对于Brigg算法、George算法不用遍历节点的邻居。注意,图着色时可以按节点度数从小到大依次访问。
+
+到此,图着色算法介绍完毕。
+
+## 线性扫描
+
+接下来介绍一种不同思路的算法:线性扫描。算法描述如下[4]:
+
+```txt
+LinearScanRegisterAllocation:
+ active := {}
+ for i in live interval in order of increasing start point
+ ExpireOldIntervals(i)
+ if length(avtive) == R
+ SpillAtInterval(i)
+ else
+ register[i] := a regsiter removed from pool of free registers
+ add i to active, sorted by increasing end point
+ExpireOldInterval(i)
+ for interval j in active, in order of increaing end point
+ if endpoint[j] >= startpoint[i]
+ return
+ remove j from active
+ add register[j] to pool of free registers
+SpillAtInterval(i)
+ spill := last interval in active
+ if endpoint[spill] > endpoint[i]
+ register[i] := register[spill]
+ location[spill] := new stack location
+ remove spill from active
+ add i to active, sorted by increasing end point
+ else
+ location[i] := new stack location
+```
+
+live interval其实就是变量的生命期,用活跃变量分析可以算出来。不过需要标识第一次出现和最后一次出现的时间点。
+
+举个例子:
+
+
+
+| 变量名 | live interval |
+| ------ | ------------- |
+| a | 1,2 |
+| d | 2,3,4,5 |
+| e | 3,4,5,6 |
+
+## llvm中实现
+
+在上文中介绍的算法都是作用在最普通的四元式上,但LLVM-IR是SSA形式,有PHI节点,但PHI节点没有机器指令表示,所以在寄存器分配前需要把PHI节点干掉,消除PHI节点的算法限于篇幅不展开,请自行查阅。
+
+llvm作为工业级编译器,有多种分配算法,可以通过llc的命令行选项`-regalloc=pbqp|greedy|basic|fast`来手动控制分配算法。
+
+不同优化等级默认使用算法也不同:O2和O3默认使用greedy,其他默认使用fast。
+
+fast算法的策略很简单,扫描代码并为出现的变量分配寄存器,寄存器不够用就溢出到内存。用途主要是**调试**。
+
+basic算法以linearscan为基础并对life interval设置了溢出权重而且用优先队列来存储life interval。
+
+greedy算法也使用优先队列,但特点是先为生命期长的变量分配寄存器,而短生命期的变量可以放在间隙中,详情可以参考[5]。
+
+pbqp算法全称是Partitioned Boolean Quadratic Programming,限于篇幅,感兴趣的读者请查阅[6]。
+
+至于具体实现,自顶向下依次是:
+
+- `TargetPassConfig::addMachinePasses`含有寄存器分配和其他优化
+- `addOptimizedRegAlloc`中是与寄存器分配密切相关的pass,比如上文提到的消除PHI节点
+- `addRegAssignAndRewriteOptimized`是实际的寄存器分配算法
+- 寄存器分配相关文件在lib/CodeGen下的RegAllocBase.cpp、RegAllocGreedy.cpp、RegAllocFast.cpp、RegAllocBasic.cpp和RegAllocPBQP.cpp等。
+- RegAllocBase类定义了一系列接口,重点是selectOrSplit和enqueue/dequeue方法,数据结构的重点是priority queue。
+ selectOrSplit方法可以类比上文中提到的SpillAtInterval。
+ priority queue类比active list。
+简要代码如下:
+```c++
+void RegAllocBase::allocatePhysRegs() {
+ // 1. virtual reg其实就是变量
+ while (LiveInterval *VirtReg = dequeue()) {
+
+ // 2.selectOrSplit 会返回一个可用的物理寄存器然后返回新的live intervals列表
+ using VirtRegVec = SmallVector;
+ VirtRegVec SplitVRegs;
+ MCRegister AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);
+ // 3.分配失败检查
+ if (AvailablePhysReg == ~0u) {
+ ...
+ }
+ // 4.正式分配
+ if (AvailablePhysReg)
+ Matrix->assign(*VirtReg, AvailablePhysReg);
+
+ for (Register Reg : SplitVRegs) {
+ // 5.入队分割后的liver interval
+ LiveInterval *SplitVirtReg = &LIS->getInterval(Reg);
+ enqueue(SplitVirtReg);
+ }
+ }
+}
+```
+
+至于这四种算法的性能对比,我们主要考虑三个指标:运行时间、编译时间和溢出次数。
+
+
+
+> 各算法的运行时间,图源[6], 横坐标是测试集,纵坐标是以秒为单位的运行时间
+
+
+
+> 各算法的编译时间,图源[6], 横坐标是测试集,纵坐标是编译时间
+
+
+
+> 各算法的溢出次数,图源[6]
+
+从这三幅图可以看出greedy算法在大多数测试集上都优于其他算法,因此greedy作为默认分配器是可行的。
+
+## 小结
+
+我们通过一个例子介绍了活跃变量分析和图着色算法。借助活跃变量分析,我们知道了变量的生命期,有了变量生命期建立干涉图,对干涉图进行着色。如果着色失败,可以选择某个变量溢出到内存中。之后在RIG的基础上介绍了寄存器合并这一变换。
+
+然后我们简单介绍了不同思路的寄存器分配算法:linearscan。最后介绍了llvm12中算法的实现并对比了llvm中四种算法的性能差异。
+
+## 参考
+
+1. [Introduction to Data Flow Analysis (cmu.edu)](http://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15745-s18/www/lectures/L5-Intro-to-Dataflow-pre-class.pdf)
+2. [register-allocation](http://web.cecs.pdx.edu/~mperkows/temp/register-allocation.pdf)
+3. [Register Allocation (cmu.edu)](http://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15745-s18/www/lectures/L12-Register-Allocation.pdf) 和 [Register Allocation: Coalescing (cmu.edu)](http://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15745-s18/www/lectures/L13-Register-Coalescing.pdf)
+4. [linearscan.pdf (ucla.edu)](http://web.cs.ucla.edu/~palsberg/course/cs132/linearscan.pdf)
+5. [greedy-register-allocation-in-llvm-30](http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html)
+6. T. C. d. S. Xavier, G. S. Oliveira, E. D. d. Lima and A. F. d. Silva, "A Detailed Analysis of the LLVM's Register Allocators," 2012 31st International Conference of the Chilean Computer Science Society, 2012, pp. 190-198, doi: 10.1109/SCCC.2012.29.
\ No newline at end of file
diff --git "a/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/001.jpg" "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/001.jpg"
new file mode 100644
index 0000000000000000000000000000000000000000..d305cdd94fced22000f14fd78f0ab6d3d33b1dbb
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/001.jpg" differ
diff --git "a/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-01.png" "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-01.png"
new file mode 100644
index 0000000000000000000000000000000000000000..a69879486323f7759496430b5bcf242531f380b3
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-01.png" differ
diff --git "a/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-02.png" "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-02.png"
new file mode 100644
index 0000000000000000000000000000000000000000..e87ac2f9d06157b91af70408f3da7e17e9598b9a
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-02.png" differ
diff --git "a/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-03.png" "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-03.png"
new file mode 100644
index 0000000000000000000000000000000000000000..6000d10e1fc881883abb2ef8889e08b0d7fde0cb
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-03.png" differ
diff --git "a/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-04.png" "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-04.png"
new file mode 100644
index 0000000000000000000000000000000000000000..f0fda84bd1964ef5e48dadfe677b3f09e7bac125
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler-04.png" differ
diff --git "a/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler.png" "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler.png"
new file mode 100644
index 0000000000000000000000000000000000000000..d3c719452b031baab9987d29813dee88c241a9e7
Binary files /dev/null and "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/maas-openeuler.png" differ
diff --git "a/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/use-canonical-maas-deploy-openeuler-test.md" "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/use-canonical-maas-deploy-openeuler-test.md"
new file mode 100644
index 0000000000000000000000000000000000000000..93ec85f38bc15114b5faae0f43e3bb848ea18ffd
--- /dev/null
+++ "b/web-ui/docs/zh/blog/20220823-\344\275\277\347\224\250 Canonical MAAS \351\203\250\347\275\262 openEuler \346\265\213\350\257\225/use-canonical-maas-deploy-openeuler-test.md"
@@ -0,0 +1,309 @@
+---
+title: 使用Canonical MAAS 部署openEuler测试
+category: blog
+date: 2022-08-23
+tags:
+ - Canonical MAAS
+ - openEuler
+archives: 2022-08
+author:
+ - Mao Zhanglei
+summary: 在本文的测试 中,展示了如何通过Packer 为 MAAS 构建 openEuler 映像并验证MAAS部署,可使用的临时解决方法以及如MAAS直接支持 openEuler时,cloud-init 和 curtin 可能的加强或修复方法。
+---
+
+
+Canonical的 [MAAS](https://maas.io/)(Metal as a Service)是一款用于服务器自动发现、配置的远程操作系统安装、部署工具,可以将物理服务器转换为类似于虛拟机资源,实现物理物理服务器的自助服务,远程访问。 MAAS目前支持 Ubuntu、CentOS、RHEL、Windows、ESXI 和自定义镜像的部署。当在数据中心管理成百上千的物理服务器,比如云、HPC 场景时,使用MAAS 是减少运维成本的最佳选择之一。
+
+在本文的测试 中,展示了如何通过Packer 为 MAAS 构建 openEuler 映像并验证MAAS部署,可使用的临时解决方法以及如MAAS直接支持 openEuler时,cloud-init 和 curtin 可能的加强或修复方法。
+
+## 测试环境要求
+
+Packer创建openEuler MAAS 映像:
+
+ - Ubuntu 18.04+,能够运行 KVM 虚拟机
+
+ - Packer 1.8.0+
+
+ - 外网访问[openEuler官网](https://openeuler.org)以下载 openEuler ISO 和 git 访问 packer-maas
+
+MAAS验证部署openEuler映像:
+
+ - MAAS 3.0+
+
+ - MAAS管理的物理服务器或KVM host
+
+此测试可在Ubuntu Desktop 20.04 的笔记本电脑上进行,其中 MAAS 3.1可安装在 lxd 虚拟机中,主机自身被添加为 KVM host。主机或虚拟机均可用于Packer创建 openEuler 镜像,但需要 20G 可用磁盘空间。在单机上使用MAAS的详细方法可参考附件的文档链接。
+
+## Packer构建 openEuler MAAS映像
+
+MAAS 仅在可用于节点的OS映像时才有用。您可以直接从 MAAS GUI 选择和同步Ubuntu、Centos映像。您还可以自己构建 RHEL、Windows、ESXi maas 映像然后上传到 MAAS。有两种方法可以构建要部署到 MAAS 机器的自定义映像:MAAS Image Builder 和 packer。在这个 测试 中,我们使用了packer 借用了rhel8模板。
+
+安装packer:
+
+```C
+curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
+sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
+sudo apt-get update && sudo apt-get install packer
+```
+
+安装依赖包
+
+```C
+sudo apt install qemu-system qemu-utils ovmf cloud-image-utils make
+```
+
+下载packer-maas模板:
+
+```C
+git clone https://github.com/canonical/packer-maas.git
+```
+
+因为packer-maas目前没有openeuler 模板,可以使用rhel8模板但需适配。如下直接下载已测试过的适用于openEuler 20.03/22.03 LTS的模板。如想直接查看内容,可浏览器访问。
+
+
+
+```C
+cd packer-maas
+git clone https:// git.launchpad.net/~zhanglei-mao/+git/packer-maas-openeuler openeuler
+```
+
+使用浏览器访问 下载openEuler ISO并上传到packer机器。
+
+```C
+make ISO=/PATH/TO/openeuler-22.03-LTS-x86_64-dvd.iso
+
+例如:
+ubuntu@vm-k8s-w2:~/packer-maas/openeuler$ ls /home/ubuntu/*.iso -lhs
+3.4G -rw-rw-r-- 1 ubuntu ubuntu 3.4G Jun 29 07:20 /home/ubuntu/openEuler-22.03-LTS-x86_64-dvd.iso
+4.2G -rw-r--r-- 1 ubuntu ubuntu 4.2G Jun 29 01:24 /home/ubuntu/openEuler-20.03-LTS-SP1-x86_64-dvd.iso
+ubuntu@vm-k8s-w2:~/packer-maas/ openeuler$ make ISO=/home/ubuntu/openEuler-22.03-LTS-x86_64-dvd.iso
+...
+==> qemu: Waiting 3s for boot...
+==> qemu: Connecting to VM via VNC (0.0.0.0:5976)
+...
+==> qemu: Waiting for shutdown…
+...
+2022/06/29 07:34:54 packer-builder-qemu plugin: VM shut down.
+==> qemu: Converting hard drive...
+...
+ qemu (shell-local): Mounting root partition...
+ qemu (shell-local): Creating MAAS image openeuler.tar.gz...
+...
+ubuntu@ vm-k8s-w2:~/packer-maas/openeuler$ ls openeuler.tar.gz -lhs
+690M -rw-r--r-- 1 root root 690M Jun 29 07:36 openeuler.tar.gz
+ubuntu@vm- k8s-w2:~/packer-maas/openeuler$ mv openeuler.tar.gz openeuler2203.tar.gz
+ubuntu@vm-k8s-w2:~/packer-maas/ openeuler$ make ISO=/home/ubuntu//home/ubuntu/openEuler-20.03-LTS-SP1-x86_64-dvd.iso
+...
+ubuntu@vm- k8s-w2:~/packer-maas/openeuler$ mv openeuler.tar.gz openeuler2003.tar.gz
+```
+
+openeuler.tar.gz 就是创建好的 MAAS 映像,需要上传到MAAS服务器以便导入。 packer输出中的vnc 端口可用于vnc访问,注意每次的端口号都不同。
+
+## 上传openEuler映像到MAAS和部署验证
+
+如下方法将镜像上传到MAAS:
+
+```C
+maas $PROFILE boot-resources create \
+name='rhel/rhel8' title='openEuler 22.03' architecture='amd64/generic' filetype='tgz' \ content@ =openeuler.tar.gz #
+
+#例如
+zlmao@p14s:~/tmp$ scp ubuntu@192.168.122.105:~/packer-maas/openeuler/*.gz ./
+Openeuler.tar.gz 100% 689MB 209.9MB/s 00 :03
+zlmao@p14s:~/tmp$ lxc file push openeuler.tar.gz maas2/home/ubuntu/
+zlmao@p14s:~/tmp$ lxc exec maas2 bash
+root@maas2:~# su - ubuntu
+ubuntu@maas2:~$ maas login root http://192.168.122.12:5240/maas/ $(sudo maas apikey --username root)
+ubuntu@maas2:~$ maas root boot-resources create name=rhel/8 title="openEuler 22.03 LTS" architecture=amd64/generic content@=openeuler2203.tar.gz
+ubuntu@maas2:~$ maas root boot-resources create name=rhel/8.2 title="openEuler 20.03 LTS" architecture=amd64/generic content@=openeuler2003.tar.gz
+```
+
+注意,如果你有更多的不同版本的openEuler映像,请使用不同的rhel/8.x。
+在 MAAS图形管理介面中,您可以找到上传的像已同步。
+
+
+
+
+部署,请从“Redhat Enterprise Linux”中选择操作系统,然后选择“openEuler 22.03 LTS”
+
+
+
+约4-10分钟后, 会显示”Deployed”部署成功。可找到所分配的 IP 地址用于ssh远程访问。
+
+
+
+注意对于openEuler 22.04,要使用默认的“openeuler”用户名和ssh密钥进行远程访问。对于openEuler 20.03默认用户为”openEuler”。
+
+```C
+zlmao@p14s:~$ ssh openeuler@192.168.122.106
+Authorized users only. All activities may be monitored and reported.
+Welcome to 5.10.0-60.18.0.50.oe2203.x86_64
+System information as of time: Wednesday, June 29, 2022 AM08:23:20 UTC
+System load: 0.05
+Processes: 97
+Memory used: 8.9%
+Swap used: 0%
+Usage On: 48%
+IP address: 192.168.122.106
+Users online: 1
+To run a command as administrator(user "root"),use "sudo ".
+[openeuler@vm-test3 ~]$ uname -a
+Linux vm-test3.maas 5.10.0-60.18.0.50.oe2203.x86_64 #1 SMP Wed Mar 30 03:12:24 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
+[openeuler@vm-test3 ~]$
+
+zlmao@p14s:~$ ssh openEuler@192.168.122.107
+```
+
+```C
+Authorized users only. All activities may be monitored and reported.
+Welcome to 4.19.90-2109.1.0.0108.oe1.x86_64
+System information as of time: Thu Jun 30 13:40:24 UTC 2022
+System load: 0.06
+Processes: 94
+Memory used: 6.8%
+Swap used: 0.0%
+Usage On: 31%
+IP address: 192.168.122.107
+Users online: 1
+[openEuler@vm-k8s-m1 ~]$ uname -a
+Linux vm-k8s-m1.maas 4.19.90-2109.1.0.0108.oe1.x86_64 #1 SMP Mon Sep 6 05:27:07 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
+[openEuler@vm-k8s-m1 ~]$
+```
+
+## 如何定制packer模板和发现的问题
+
+Packer在构建时,它读取配置文件(openeuler.js)并创建一个qemu-kvm虛拟机, 使用 ISO 引导及 http/openeuler.ks 的作为自动安装配置文件。一旦自动安装成功完成并关闭电源后,Packer就会调用脚本setup-nbd 和 tar-root 生成最终映像文件。
+
+对于所使用如下openeuler.js 模板,与 rhel8 的区别在于 console=tty0 和 vnc_ind_address, 以使虛拟机输出重定向到 vnc 客户端及可以从网络而不仅仅是本机(127.0.0.1)进行vnc访问。
+
+```C
+ubuntu@vm-k8s-w2:~/packer-maas/openeuler$ cat openeuler.json
+{
+ "variables":
+ {
+ "openeuler_iso_path": "{{env `OPENEULER_ISO_PATH`}}"
+ },
+ "builders": [
+ {
+ "type": "qemu",
+ "communicator": "none",
+ "iso_url": "{{user `openeuler_iso_path`}}",
+ "iso_checksum": "none",
+ "boot_command": [
+ " ",
+ "inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/openeuler.ks ",
+ "console=ttyS0 console=tty0 inst.cmdline",
+ ""
+ ],
+ "boot_wait": "3s",
+ "disk_size": "4G",
+ "headless": true,
+ "vnc_bind_address": "0.0.0.0",
+ "memory": 2048,
+ "http_directory": "http",
+ "qemuargs": [
+ [ "-serial", "stdio" ]
+ ],
+ "shutdown_timeout": "1h"
+ }
+ ],
+ "post-processors": [
+ {
+ "type": "shell-local",
+ "inline_shebang": "/bin/bash -e",
+ "inline": [
+ "source ../scripts/setup-nbd",
+ "OUTPUT=${OUTPUT:-openeuler.tar.gz}",
+ "source ../scripts/tar-root"
+ ]
+ }
+ ]
+}
+ubuntu@vm-k8s-w2:~/packer-maas/openeuler$
+```
+
+“http/ openeuler.ks”则基于“rhel8.ks”并删除那些在openeuler下会失败的配置。其中最重要修改如下:
+
+```C
+ubuntu@vm-k8s-w2:~/packer-maas/openeuler$ cat -n http/openeuler.ks
+ ...
+ 39 yum clean all
+ 40 echo "%rhel 8" >> /etc/rpm/ macros.dist
+ 41 sed -i s/\^ID=.*\$/ID=\"rhel\"/ /etc/os-release
+ 42 %end
+ ...
+```
+
+这是针对以下2个问题的临时解决方法,它会欺骗 curtin和 cloud-init正处理的是 rhel 操作系统从完成部署而不出错。
+
+## 部署openEuler时出现的错误及可能修复方法
+
+MAAS使用curtin 解压上传到 MAAS 的 openeuler 映像并在 MAAS 部署期间安装 grub程序等。cloud-init 则是在 MAAS 部署后的首次启动期间来初始化机器,比如机器名,网络地址,注入ssh pub key等。cloud-int所使用的user-data由MAAS管理及自动提供。如果没有上面的临时解决方法将openeuler 映像假装为rhel, 则在部署时会出现如下2个报错。更详细信息及问題跟踪可访问:
+
+```C
+# during deploy, the curtin failed with
+finish: cmd-install/stage-curthooks/builtin/cmd-curthooks: FAIL: curtin command curthooks
+Traceback (most recent call last):
+ File "/curtin/curtin/distro.py", line 120, in get_distroinfo
+ variant = name_to_distro(variant_name)
+ File "/curtin/curtin/distro.py", line 57, in name_to_distro
+ return DISTROS[DISTROS.index(distname)]
+ValueError: tuple.index(x): x not in tuple
+
+# after deploy, cloud-init failed with:
+2022-06-21 02:30:15,216 - stages.py[ERROR]: Unable to render networking. Network config is likely broken: No available network renderers found. Searched through list: ['eni', 'sysconfig', 'netplan']
+```
+
+以下对于 curtin 和 cloud-init 的代码的修改可以测试通过:
+
+```C
+#In curtin/curtin/distro.py
+DISTRO_NAMES = ['arch', 'centos', 'debian', 'fedora', 'freebsd', 'gentoo',
+ 'opensuse', 'redhat', 'rhel', 'sles', 'suse', 'ubuntu', 'openEuler']
+...
+OS_FAMILIES = {
+ DISTROS.debian: [DISTROS.debian, DISTROS.ubuntu],
+ DISTROS.redhat: [DISTROS.centos, DISTROS.fedora, DISTROS.redhat,
+ DISTROS.rhel, DISTROS.openEuler],
+
+#Make openEuler be detected as rhel8 (rpm -E "%rhel")
+echo "%rhel 8" >> /etc/rpm/macros.dist
+
+# In /usr/lib/python3.7/site-packages/cloudinit/net/sysconfig.py, change openEuler to openeuler
+KNOWN_DISTROS = ['centos', 'fedora', 'rhel', 'suse', 'openeuler']
+
+# In /usr/lib/python3.7/site-packages/cloudinit/util.py, add ‘openeuler’
+ 'arch', 'centos', 'debian', 'fedora', 'rhel', 'suse', 'openeuler'):
+```
+
+## 通过vnc来监控packer构建过程
+
+Packer 构建依赖于 kickstart配置文件并等待其所创建的虛拟机在完成安装之后自动关机,通过 vnc 来监控日志输出的错误对调试问题极其有用。如果有Ubuntu 桌面系统,可以使用 Remmina 等 VNC 客户端进行访问。 vnc 端口可以在packer构建的输出中找到。
+
+
+
+
+
+注意可以使用ctrl+b 1-5来切换tmux窗口。
+
+## 附录-参考文档
+
+- 如何在一台及其上测试MAAS
+
+ - [第1篇安装](https://cn.ubuntu.com/blog/ubuntu-maas-installation-tutorial)
+
+ - [第2篇初始化](https://cn.ubuntu.com/blog/ubuntu-maas-installation-tutorial-1)
+
+ - [第3篇 KVM POD/host](https://cn.ubuntu.com/blog/ubuntu-maas-installation-tutorial-2)
+
+- [MAAS安装(英文)](https://maas.io/docs/how-to-install-maas#heading--fresh-install-3-1-packages)
+
+- [增加VM host(英文)](https://maas.io/docs/how-to-manage-vm-hosts)
+
+- [MAAS官方手册(英文)](https://maas.io/docs)
+
+---
+
+本博文由Canonical的Senior Field Engineer: **Mao Zhanglei** 所写。
+
+原文链接:
diff --git a/web-ui/docs/zh/news/20220801-openueuler08.md b/web-ui/docs/zh/news/20220801.md
similarity index 100%
rename from web-ui/docs/zh/news/20220801-openueuler08.md
rename to web-ui/docs/zh/news/20220801.md
diff --git a/web-ui/docs/zh/news/20220818.md b/web-ui/docs/zh/news/20220818.md
new file mode 100644
index 0000000000000000000000000000000000000000..7614390cd3097ecb51148f9a02b648f6b1da7222
--- /dev/null
+++ b/web-ui/docs/zh/news/20220818.md
@@ -0,0 +1,70 @@
+---
+title: 'openEuler开源社区首次亮相CCF国际AIOps挑战赛,斩获季军'
+date: '2022-08-18'
+category: news
+tags:
+ - openEuler
+ - CCF
+banner: 'img/banners/2022-CCF-AIOps.jpg'
+author:
+ - openEuler
+summary: '2022年3月,第五届CCF国际AIOps挑战赛正式拉开帷幕,经过热身赛、初赛、复赛、决赛长达五个月的激烈角逐,由华为集团IT-UniAI产品与openEuler A-Tune团队共同组成的AeroSpaceX战队在比赛中脱颖而出,斩获季军!'
+---
+
+
+2022年3月,第五届CCF国际AIOps挑战赛正式拉开帷幕,经过热身赛、初赛、复赛、决赛长达五个月的激烈角逐,由华为集团IT-UniAI产品与openEuler A-Tune团队共同组成的**AeroSpaceX战队**在比赛中脱颖而出,斩获季军!
+
+
+
+## 关于挑战赛
+
+CCF国际AIOps挑战赛(以下简称挑战赛)是智能运维领域最具影响力的专业赛事,由中国计算机学会(CCF)和清华大学联合发起,面向全球开放。截止至2022年共计举办了五届,从第一届仅有100多支队伍参赛,到如今有超过400支战队,和来自国内外知名高校、科研院所以及银行、保险、能源、运营商、互联网等众多行业的近千名选手报名,挑战赛的规模不断壮大,今年决赛的在线直播观看人数更是高达4w+。
+
+本届大赛以“微服务架构电商系统下故障识别和分类” 为赛题,高度贴合现实世界中互联网大规模电商业务架构,模拟真实场景中电商企业面对海量业务数据冲击时需要解决的运维挑战。
+
+
+
+
+
+## 关于答题思路
+
+基于本次挑战赛的赛题,AeroSpaceX战队设计了具备自愈功能、主动监控的整体方案。该方案包含四大部分:整体监控模块、在线推理模块、离线训练模块和测试模块。
+
+监控模块负责监控所有的在线进程,包涵了自动调参模块和三个检测模块等;在线检测进程之间都是解耦的,如果某个检测发生错误导致崩溃,自动重启模块会在10秒内重新恢复检测。
+
+在线推理模块分为四个小模块:线上自适应调参模块可以在线学习线上流入的三种类型的数据模式,并利用openEuler A-Tune智能调优引擎 [1](#refer-anchor-1) 实现实时调参功能;在实时异常检测模块中,三个独立进程分别对三种不同数据进行检测,异常检测的结果作为根因定位模块的输入;当根因定位到异常的数据之后,便会对其相关的指标进行更详细的分析,最终故障分类模块会给出故障类型,并上报提交。
+
+参数离线训练模块和有监督故障分类模型模块是支撑在线推理模块高效准确运行的必不可少的组成部分。在离线训练时充分学习历史故障数据,设置奖惩策略,实现数据类型级、实例级的参数调优,减少误报和漏报。
+
+测试模块是本方案中的一个特色模块。该模块利用鲲鹏多核芯片和高性能openEuler系统实现离线并发测试,30分钟即可完成离线12天故障时段的数据测试。与此同时,团队在测试模块中利用全量离线数据,实现kafka数据生产者,1:1模拟线上评测系统,对线上检测性能进行摸底,保障运维系统线上功能稳定。
+
+
+
+
+
+## 关于AeroSpaceX团队
+
+AeroSpace的成员来自华为集团IT-UniAI产品和openEuler A-Tune团队。
+
+华为IT平台服务部-UniAI产品承载华为AI战略,专注实现企业场景AI,深耕销售、服务、供应、制造、财经等20+业务及颗粒化领域900+海量场景,基于“场景、算法、数据、算力”四位一体,建设企业AI解决方案及服务,联接开放生态,践行智能之道。
+
+openEuler A-Tune团队致力于操作系统智能调优、智能运维、智能安全方向的探索,通过机器学习、深度学习、时间序列、异常检测等方法实现操作系统的智能自治。当前团队还积极和海内外高校展开学术交流和访问,共同探索业界创新技术,构建国产基础软件核心竞争力。
+
+
+
+
+
+## 交流与合作
+
+> 祝贺2022 CCF国际AIOps挑战赛决赛暨AIOps研讨会成功举办,期待国际AIOps挑战赛与openEuler两大社区后续继续深入交流与合作!
+
+如果您对操作系统智能自治、A-Tune SIG等内容感兴趣,欢迎扫描文末小助手二维码,与我们一起探讨~
+
+
+相关信息:
+
+- A-Tune智能调优引擎:一款在openEuler开源社区孵化的基于 AI 的自动化、智能化性能调优引擎。它利用人工智能技术,对运行在操作系统上的业务精准建模,动态感知业务特征并推理出具体应用,根据业务负载情况动态调节并给出最佳的参数配置组合。通过调整系统和应用配置,充分发挥软硬件能力,从而提升业务性能。目前已在openEuler社区开源:
+
+- openEuler A-Tune小助手微信:
+
+
\ No newline at end of file