👋 欢迎来到zhumouren的博客!
- 这个博客主要是用来记录我工作、学习中遇到的一些问题、解决方法以及学习到的内容,希望这些内容对见到的人有所帮助。
👋 欢迎来到zhumouren的博客!
1. 进程环境 #include <stdlib.h> void exit(int status); exit(0) 与 return 0 是等价的。 2. 进程标识和创建子进程 每个进程都有一个非负整型表示的唯一进程ID,但进程ID是可以被复用的。当一个进程终止后进程ID会进入候选池,并且一般新的进程不会使用最近终止进程的进程ID。 #include <unistd.h> pid_t getpid(void); // 返回值: 调用进程的进程ID pid_t getppid(void); // 返回值: 调用进程的父进程ID fork() 函数可以创建一个新进程,子进程和父进程继续执行fork调用之后的指令。子进程是父进程的副本。例如,子进程获得父进程数据空间、堆和栈的副本。并且在修改时使用了写时复制(Copy-On-Write,COW)技术。 #include <unistd.h> pid_t fork(void); // 返回值: 子进程返回0, 父进程返回子进程ID,若出错返回-1 以下是一个示例代码,用于创建一个子进程并展示父进程和子进程的ID与父进程ID,以及如何通过信号避免僵尸进程。 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/wait.h> #include <sys/types.h> void sigchld_handler(int sig) { int status; pid_t id = waitpid(-1, NULL, WNOHANG); if (WIFEXITED(status)) { printf("remove proc id: %d \n", id); printf("Child send: %d \n", WEXITSTATUS(status)); } } int main(int argc, char *argv[]) { struct sigaction sa; sa.sa_handler = sigchld_handler; sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; // 初始化信号屏蔽集,确保不阻塞任何额外信号 sigemptyset(&sa.sa_mask); // 注册 SIGCHLD 信号处理 sigaction(SIGCHLD, &sa, NULL); pid_t pid; int val = 24; if ((pid = fork()) < 0) { fprintf(stderr, "fork err: %d\n", pid); exit(1); } else if (pid == 0) { val++; printf("child: pid = %d, ppid = %d\n", getpid(), getppid()); printf("child: val = %d\n", val); _exit(0); } else { sleep(5); printf("root: pid = %d, ppid = %d, child_pid = %d\n", getpid(), getppid(), pid); printf("root: val = %d\n", val); sleep(5); } exit(0); } 以下是执行程序后的结果,一个有意思点是程序的父进程ID是bash,子进程修改的数据并不会影响到父进程的数据。 ...
1. 关于补丁 在OpenWrt中,补丁的功能使用一个名为quilt的工具完成的。这个工具由OpenWrt下载编译了,就在/home/buildbot/openwrt/staging_dir/host/bin/quilt。 如果我们要使用quilt首先要配置quilt的配置文件,然后配置环境变量。注意,下面的EDITOR="nano"时指quilt默认的编辑环境,想用vi的可以替换成EDITOR="vi" cat << EOF > ~/.quiltrc QUILT_DIFF_ARGS="--no-timestamps --no-index -p ab --color=auto" QUILT_REFRESH_ARGS="--no-timestamps --no-index -p ab" QUILT_SERIES_ARGS="--color=auto" QUILT_PATCH_OPTS="--unified" QUILT_DIFF_OPTS="-p" EDITOR="nano" EOF export PATH=/home/buildbot/openwrt/staging_dir/host/bin:$PATH 配置完成后,输入以下命令就可以看到quilt的版本。 quilt --version 2. 使用补丁添加新文件 2.1 准备补丁代码 在创建补丁之前,需要准备补丁源码环境 cd /home/buildbot/openwrt make package/helloopenwrt/{clean,prepare} QUILT=1 请注意,当执行make指定参数QUILT=1时,build_dir下的软件包不用于构建最终包,并且该参数会在构建目录中创建额外的文件夹和文件。 最后到补丁源码目录,确保提交所有现有的补丁: cd /home/buildbot/openwrt/build_dir/target-x86_64_musl/helloopenwrt-1.0 quilt push -a 现在执行quilt push -a时不会执行任何操作,因为这个示例包中还没有任何补丁。但时在处理由多人编写的软件包时,最好执行这条命令,因为不知道其他人是否提交了补丁。 2.2 创建一个补丁 现在开始创建第一个补丁 quilt new 100-add_functions_files.patch 补丁的命令最好遵循OpenWrt的构建约定,名称通常以数字开始,后跟其功能的简短描述。数字一般有特殊含义 0xx - 上游补丁 1xx - 代码等待上游合并 2xx - 内核构建、配置、头补丁 3xx - 特定架构的补丁 4xx - mtd相关的补丁(子系统和驱动) 5xx - 文件系统相关的补丁 6xx - 通用网络补丁 7xx - 网络层/物理层驱动补丁 8xx - 其他驱动 9xx - 未分类的其他补丁 我们要在helloopenwrt中增加两个文件,首先用quilt追踪这两个文件 ...
1. 创建Makefile 在上一章中我们是在包清单文件中定义如何编译helloopenwrt,以下是上一章中的包清单文件 # Package build instructions; invoke the target-specific compiler to first compile the source file, and then to link the file into the final executable define Build/Compile $(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/helloopenwrt.o -c $(PKG_BUILD_DIR)/helloopenwrt.c $(TARGET_CC) $(TARGET_LDFLAGS) -o $(PKG_BUILD_DIR)/$1 $(PKG_BUILD_DIR)/helloopenwrt.o endef 由于这是一个示例项目,只有一个源文件,编译命令比较简单。根据关注点分离原则,一个程序如何编译应该又要在源码中给出。 cd /home/buildbot/helloopenwrt touch Makefile 将以下内容复制进入Makefile include $(TOPDIR)/rules.mk # Name, version and release number # The name and version of your package are used to define the variable to point to the build directory of your package: $(PKG_BUILD_DIR) PKG_NAME:=helloopenwrt PKG_VERSION:=1.0 PKG_RELEASE:=1 # Source settings (i.e. where to find the source codes) # This is a custom variable, used below SOURCE_DIR:=/home/buildbot/helloopenwrt include $(INCLUDE_DIR)/package.mk # Package definition; instructs on how and where our package will appear in the overall configuration menu ('make menuconfig') define Package/helloopenwrt SECTION:=examples CATEGORY:=Examples TITLE:=Hello, OpenWrt! endef # Package description; a more verbose description on what our package does define Package/helloopenwrt/description A simple "Hello, OpenWrt!" -application. endef # Package preparation instructions; create the build directory and copy the source code. # The last command is necessary to ensure our preparation instructions remain compatible with the patching system. define Build/Prepare mkdir -p $(PKG_BUILD_DIR) cp $(SOURCE_DIR)/* $(PKG_BUILD_DIR) -r $(Build/Patch) endef # Package build instructions; invoke the target-specific compiler to first compile the source file, and then to link the file into the final executable define Build/Compile $(MAKE) -C $(PKG_BUILD_DIR) \ CC="$(TARGET_CC)" \ CFLAGS="$(TARGET_CFLAGS)" \ LDFLAGS="$(TARGET_LDFLAGS)" endef # Package install instructions; create a directory inside the package to hold our executable, and then copy the executable we built previously into the folder define Package/helloopenwrt/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloopenwrt $(1)/usr/bin endef # This command is always the last, it uses the definitions and variables we give above in order to get the job done $(eval $(call BuildPackage,helloopenwrt)) Makefile文件写好之后,我们可以输入以下命令测试一下是否有效 ...
1. 创建一个简单的helloworld程序 软件开发中的一种良好做法是将各个部分分开,并且只提供足够的连接点,以便软件组合的不同部分可以协同运行。这种方法称为关注点分离。 为了保持这种方法,我们将应用程序的源代码放在一个独立的目录中,与 OpenWrt 构建系统分开。 引用至OpenWrt官方文档– https://openwrt.org/docs/guide-developer/helloworld/chapter2 根据上一章的内容,进入openwrt编译环境容器,执行以下命令 cd /home/buildbot mkdir helloopenwrt cd helloopenwrt 创建并进入helloopenwrt目录后创建一个helloopenwrt.c touch helloopenwrt.c 选择用vi或者其他编辑器将以下内容复制进helloopenwrt.c #include <stdio.h> int main(void) { printf("\nHello, OpenWrt!\n\n"); return 0; } 编译helloopenwrt gcc -o helloopenwrt helloopenwrt.c -Wall 可以执行helloopenwrt看控制台是否由打印Hello, OpenWrt! ./helloopenwrt 2. 创建软件包 OpenWrt 构建系统主要围绕软件包的概念。它们是系统的支柱。无论什么软件,几乎总有一个软件包。这适用于系统中的几乎所有东西,无论是独立于目标的工具、交叉编译工具链、目标固件的 Linux 内核、与内核捆绑的附加模块,还是将安装到目标固件的根文件系统上的各种应用程序。 由于这种面向包的性质,对"helloopenwrt"应用程序采用相同的方法也是合乎逻辑的。 对于不属于构建系统本身组成部分的软件包,主要的交付系统是软件包源。它只是一个软件包存储库,其中包含最终固件中可能包含的软件包。存储库可以位于本地目录中,也可以位于网络共享中,也可以位于 GitHub 等版本控制系统中。创建和维护软件包源使我们能够通过将与软件包相关的文件与示例应用程序的源代码分开来保持关注点分离。 出于本文的目的,我们在本地目录中创建一个新的包存储库。此存储库的名称为"mypackages",它包含一个名为"examples"的类别。在此类别中,只有一个条目,即我们的"helloopenwrt"应用程序。 引用至OpenWrt官方文档– https://openwrt.org/docs/guide-developer/helloworld/chapter3 2.1 创建本地包源 cd /home/buildbot mkdir -p mypackages/examples/helloopenwrt 2.2 创建包清单文件package manifest file OpenWrt 构建系统中的每个软件包都由软件包清单文件描述。包清单文件负责描述软件包及其功能,并且必须至少提供有关从何处获取源代码、如何构建源代码以及最终可安装软件包中应包含哪些文件的说明。软件包清单还可能包含可选配置脚本的选项,指定软件包之间的依赖关系等。 为了使我们的应用程序的源代码成为一个包,并成为我们之前创建的包存储库的一部分,我们需要为其创建一个包清单文件: cd mypackages/examples/helloopenwrt touch Makefile 选择vi或者其他文本编辑器将以下内容写入Makefile,请注意,文件中有较短和较长的空白缩进。较短的是简单空格字符,而较长的是硬制表符(Tab),本章相关的几个文件是由OpenWrt自己的GUN Make编译的,而GUN Make的缩进不接受空格。 include $(TOPDIR)/rules.mk # Name, version and release number # The name and version of your package are used to define the variable to point to the build directory of your package: $(PKG_BUILD_DIR) PKG_NAME:=helloopenwrt PKG_VERSION:=1.0 PKG_RELEASE:=1 # Source settings (i.e. where to find the source codes) # This is a custom variable, used below SOURCE_DIR:=/home/buildbot/helloopenwrt include $(INCLUDE_DIR)/package.mk # Package definition; instructs on how and where our package will appear in the overall configuration menu ('make menuconfig') define Package/helloopenwrt SECTION:=examples CATEGORY:=Examples TITLE:=Hello, OpenWrt! endef # Package description; a more verbose description on what our package does define Package/helloopenwrt/description A simple "Hello, OpenWrt!" -application. endef # Package preparation instructions; create the build directory and copy the source code. # The last command is necessary to ensure our preparation instructions remain compatible with the patching system. define Build/Prepare mkdir -p $(PKG_BUILD_DIR) cp $(SOURCE_DIR)/* $(PKG_BUILD_DIR) $(Build/Patch) endef # Package build instructions; invoke the target-specific compiler to first compile the source file, and then to link the file into the final executable define Build/Compile $(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/helloopenwrt.o -c $(PKG_BUILD_DIR)/helloopenwrt.c $(TARGET_CC) $(TARGET_LDFLAGS) -o $(PKG_BUILD_DIR)/$1 $(PKG_BUILD_DIR)/helloopenwrt.o endef # Package install instructions; create a directory inside the package to hold our executable, and then copy the executable we built previously into the folder define Package/helloopenwrt/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloopenwrt $(1)/usr/bin endef # This command is always the last, it uses the definitions and variables we give above in order to get the job done $(eval $(call BuildPackage,helloopenwrt)) 3. 将软件包加入OpenWrt构建系统 3.1 包源配置 OpenWrt 构建系统使用一个名为feeds.conf的特定文件,该文件将在固件配置阶段提供的包源。为了使包含应用程序的包可见,必须将新的包源包含到此文件中。 ...
1. 环境准备 一台带有Windows10(64位)及以上专业版的电脑(其他操作系统也行,只要能用Docker就好了 CPU为X86_64 Docker(用作OpenWrt的编译环境和测试环境) 2. 使用Docker搭建OpenWrt编译环境 本文使用docker-compse构建,构建脚本目录环境为 docker-linux-env/ | docker-compose.yml | ----ubuntu-compile-openwrt/ | | Dockerfile | | sources.list | - 以下为各文件的具体内容 docker-compose.yml version: '3' services: ubuntu-compile-openwrt: build: ./ubuntu-compile-openwrt environment: TZ: Asia/Shanghai volumes: - compile-openwrt:/root # compile-openwrt 是数据卷 - compile-openwrt-home:/home ports: - "2211:22" volumes: compile-openwrt: compile-openwrt-home: Dockerfile # 以最新的Ubuntu镜像为模板 FROM ubuntu:24.04 # 将本目录下的sources.list作为容器的一个文件 ADD sources.list /root/sources.list # 使用国内Ubuntu源,更新快 RUN mv /etc/apt/sources.list /etc/apt/sources.list_bak RUN cp /root/sources.list /etc/apt/sources.list RUN apt update # 安装常用工具 RUN apt install -y vim git nano # 安装编译OpenWrt官方实例相关工具 RUN apt install -y build-essential clang flex bison g++ gawk \ gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev \ python3-setuptools rsync swig unzip zlib1g-dev file wget # 安装当前镜像对当前OpenWrt编译所需要库 RUN apt install -y libelf-dev locales # 设置LOCALE RUN locale-gen en_US.UTF-8 # 修改root密码 RUN echo 'root:pw' | chpasswd # 添加自定义用户 RUN adduser buildbot \ && echo 'buildbot:pw' | chpasswd # 安装ssh RUN apt install -y openssh-server RUN mkdir -p /var/run/sshd # 开放22端口 EXPOSE 22 #设置自启动命令 CMD ["/usr/sbin/sshd", "-D"] sources.list ...
hello world!