嵌入式Linux編譯系統的設計——Bootloader, 核心,驅動,檔案系統,升級映象等自動化編譯打包
專案簡介
嵌入式系統的開發過程較為複雜,編譯,裁剪,定製等如果沒有一套規範的流程將會難於管理和控制。本專案的目的是設計一個嵌入式Linux編譯系統,實現程式碼的編譯,定製和裁剪。Bootloader, 核心,驅動,檔案系統,升級映象等都可以自動化編譯,打包。
本專案github:https://github.com/huangbin0709/easyLinux.git
EasyLinux平臺編譯系統架構
Buildroot
Buildroot是一個非常優秀的開源嵌入式編譯系統,其本身已經非常完善。但其預設是線上編譯的,即從網上下載原始碼包進行編譯。對企業而言,本地編譯可方便進行版本控制。EasyLinux平臺除了工具軟體之外,其他的軟體包如核心,bootloader,app等都是採用本地編譯的方式。此外,嵌入式系統模組之間的耦合還是比較大,如標頭檔案,庫檔案的引用等,需要設計一個目錄結構編譯時方便地對這些檔案進行引用。
EasyLinux平臺目錄結構
頂級目錄結構
easyLinux
├── archive
│ └── gt2440
├── boot
│ └── u-boot-2015.01
├── buildroot
│ ├── arch
│ ├── board
│ ├── boot
│ ├── build
│ ├── CHANGES
│ ├── Config.in
│ ├── Config.in.legacy
│ ├── configs
│ ├── COPYING
│ ├── dl
│ ├── docs
│ ├── easylinux
│ ├── easylinux_patch_clean.sh
│ ├── easylinux_patch.sh
│ ├── ext
│ ├── fs
│ ├── linux
│ ├── Makefile
│ ├── Makefile.legacy
│ ├── package
│ ├── README
│ ├── support
│ ├── system
│ └── toolchain
├── kernel
│ └── linux-3.18.6
├── LICENSE
├── README.md
└── src
├──application
└── platform
EasyLinux平臺有archive、boot、buildroot、kernel、src五個頂級目錄,每個目錄的設計如下:
Archive:存放src目錄下編譯生成的庫檔案,以機型為子目錄存放,如archive/gt2440.
Boot:這個目錄下存放bootloader原始碼,如uboot。
Buildroot:這個目錄下添加了我們自己的目錄easylinux,用於編譯easylinux平臺特有的軟體包。
Kernel:存放核心。
Src:存放專案原始碼
編譯目錄
easylinux
├── Config.in
├── core
│ ├── Config.in
│ └── core.mk
├── easylinux.mk
├── procmgr
│ ├── Config.in
│ └── procmgr.mk
└── watcher
├── Config.in
└── watcher.mk
EasyLinux編譯目錄中定義src目錄下的原始碼包的編譯規則。
EasyLinux/src目錄結構
src
├── application
│ ├── adapter
│ ├── app
│ ├── drivers
│ ├── include
│ └── lib
└── platform
├── adapter
├── app
│ ├── core
│ │ ├── CMakeLists.txt
│ │ ├── include
│ │ └── src
│ ├── procmgr
│ └── watcher
├── drivers
├── include
└── lib
Src目錄下存放我們自己開發的軟體包原始碼,包括應用層App和核心驅動,所有軟體包都以cmake組織。
庫和標頭檔案的引用
Buildroot中的package編譯時會把原始碼拷貝到$(BUILD_DIR)目錄下進行編譯,為了便於管理,我們把easylinux的package拷貝到$(BUILD_DIR)/easylinux目錄下進行編譯。編譯產生的庫檔案存放到easylinux/archive中。通過在$(BUILD_DIR)/easylinux目錄下建立軟連線arvhive,plat分別指向easylinux/arvhive中的庫檔案目錄和src/application/include下的標頭檔案目錄。則編譯軟體包時可通過../arvhive和../plat目錄引用標頭檔案和庫檔案。
板級適配
為了使不同的開發板和晶片可以共用一套編譯系統,需要進行一定的適配。
配置適配
buildroot/board/samsung
├── common
│ ├── busybox.config
│ ├── linux.config
│ ├── uboot.config
│ ├── uboot.mk
│ └── uClibc-0.9.33.config
└── yoka
└── uboot.mk
在vendor/board目錄下存放各自的配置檔案。
Xxx_defconfig檔案中通過BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE等變數可以指定配置檔案的路徑,可以為不同的板指定不同的配置檔案。
編譯適配
1. mk檔案中引入板級定製mk,以uboot為例:
#include board common mk files if any -include $(BR2_BOARD_COMMON_DIR)/uboot.mk #include board specify mk files if any -include $(BR2_BOARD_CUSTOM_DIR)/uboot.mk #include the mk file to fix the pkgdir in package/pkg-utils.mk include $(TOPDIR)/boot/uboot/uboot-last.mk $(eval $(generic-package)) |
在$(eval $(generic-package))之前插入上面的規則,則可以在板級的uboot.mk中重新設定一些環境變數,達到不同的板可以有不同的編譯引數,編譯路徑的目的。
2. 使用全域性編譯引數
BR2_EASYLINUX_CFLAGS "-Werror -D_LITTLE_EDIAN=0x1234 -D_BIG_EDIAN=0x3412 -DBYTE_ORDER=0x1234 -D_MIPS_=2 -D_ARM_=1 -DCPU_ARCH=1" |
Easylinux/Config.in中新增全域性編譯引數配置項,在所有package的mk檔案中新增進他們的CFLAGS中。如在core.mk中
CORE_CFLAGS += $(BR2_EASYLINUX_CFLAGS) #CORE_CFLAGS += CORE_CONF_OPTS += -DCMAKE_C_FLAGS="$(CORE_CFLAGS)" |
在core_main.c中
#if CPU_ARCH == _ARM_ Do something #else Do something #endif |
3. 在模組的編譯中定義巨集
如在core.mk中
#如果是yoka Ifeq ($(BR2_EASYLINUX_PROJECT_NAME),yoka) CORE_CFLAGS += -DEASYLINUX_YOKA endif |
EasyLinux平臺編譯方法
編譯所有的操作都在easylinux/buildroot目錄下
2.4.1打入配置和編譯
make O=build_dir xxx_defconfig 其中build_dir為想要輸出到的目錄 Xxx_defconfig為configs目錄下的機型配置檔案 make O=build_dir {target} target是可選的,如果輸入了target則只編譯這個目標,否則編譯配置的所有軟體包。 make O=build_dir target-dirclean target是目標,清理特定的軟體包 make O=build_dir easylinux-clean 這個命令是easylinux平臺的,用於清理easylinux平臺的所有軟體包。Buildroot全部編譯需要較長的時間,這個命令可用於只編譯easylinux軟體包。 |
2.4.2定製
make O=build_dir menuconfig make O=build_dir savedefconfig 定製package,儲存到xxx_defconfig檔案中 make O=build_dir linux-menuconfig make O=build_dir linux-update-config 定製linux核心並儲存 make O=build_dir busybox-menuconfig make O=build_dir busybox-update-config 定製busybox並儲存 make O=build_dir uboot-menuconfig make O=build_dir uboot-update-config 定製uboot並儲存 |
新增一個Package
2.5.1新增app
以新增應用程式procmgr為例
1. 在src/app相應目錄下新增原始碼,在原始碼下新增CMakeLists.txt檔案 cmake_minimum_required(VERSION 3.0) #project name PROJECT(procmgr) #head file path #module目錄下的標頭檔案 #$(BUILD_DIR)/easylinux目錄下的platform連結到$(TOPDIR)/../src/platform/include目錄 #CMakeLists.txt編譯時會拷貝到$(BUILD_DIR)/easylinux/{module}目錄下,則../platform指向這個標頭檔案目錄 INCLUDE_DIRECTORIES( include ../platform ) #source directory AUX_SOURCE_DIRECTORY(src DIR_SRCS) #set environment variable SET(TEST_MATH ${DIR_SRCS} ) SET(CMAKE_INSTALL_PREFIX /easylinux) #add executable file ADD_EXECUTABLE(core ${TEST_MATH}) # install(TARGETS procmgr RUNTIME DESTINATION app/bin) 2.在buildroot/easylinux/procmgr目錄下新增Config.in config BR2_EASYLINUX_PROCMGR bool "easylinux app procmgr" default n 3.在buildroot/easylinux/procmgr目錄下新增procmgr.mk ################################################################################ # # procmgr # ################################################################################ PROCMGR_VERSION = 1.0 PROCMGR_SITE = $(TOPDIR)/../src/platform/app/procmgr PROCMGR_SITE_METHOD = local PROCMGR_INSTALL_STAGING = NO PROCMGR_INSTALL_TARGET = YES #PROCMGR_CONF_OPTS += #PROCMGR_DEPENDENCIES += PROCMGR_CFLAGS += $(BR2_EASYLINUX_CFLAGS) #PROCMGR_CFLAGS += PROCMGR_CONF_OPTS += -DCMAKE_C_FLAGS="$(PROCMGR_CFLAGS)" $(eval $(cmake-package)) |
2.5.2新增核心驅動
1.在src/app相應目錄下新增原始碼,在原始碼下新增Makefile檔案 obj-m = demodriver.o 2.在buildroot/easylinux/demodriver目錄下新增Config.in 3.在buildroot/easylinux/demodriver目錄下新增demodriver.mk ################################################################################ # # demodriver # ################################################################################ DEMODRIVER_VERSION = 1.0 DEMODRIVER_SITE = $(TOPDIR)/../src/application/drivers/demodriver DEMODRIVER_SITE_METHOD = local DEMODRIVER_INSTALL_STAGING = NO DEMODRIVER_INSTALL_TARGET = YES #DEMODRIVER_CONFIG_SCRIPTS = DEMODRIVER-config #DEMODRIVER_DEPENDENCIES = host-libaaa libbbb define DEMODRIVER_BUILD_CMDS $(TARGET_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) M=$(@D) modules Endef define DEMODRIVER_INSTALL_TARGET_CMDS cp $(@D)/*.ko $(TARGET_DIR)/easylinux/lib/modules endef $(eval $(generic-package)) |
2.5.3新增動態庫
1.在src/app相應目錄下新增原始碼,在原始碼下新增CMakeLists.txt檔案 cmake_minimum_required(VERSION 3.0) #project name PROJECT(platform) #head file path INCLUDE_DIRECTORIES( ../platform ) #source directory AUX_SOURCE_DIRECTORY(demo DEMO_FILES) #set environment variable #SET(CMAKE_INSTALL_PREFIX /easylinux) #add executable file ADD_LIBRARY(platform SHARED ${DEMO_FILES}) #add link library #TARGET_LINK_LIBRARIES(core m) install(TARGETS platform LIBRARY DESTINATION lib) 2.在buildroot/easylinux/platform目錄下新增Config.in 3.在buildroot/easylinux/platform目錄下新增platform.mk ################################################################################ # # PLATFORM # ################################################################################ PLATFORM_VERSION = 1.0 PLATFORM_SITE = $(TOPDIR)/../src/platform/lib PLATFORM_SITE_METHOD = local PLATFORM_INSTALL_STAGING = NO PLATFORM_INSTALL_TARGET = YES PLATFORM_INSTALL_TARGET_OPTS = DESTDIR=$(BR2_EASYLINUX_ARCHIVE_DIR) install #PLATFORM_CONF_OPTS += #PLATFORM_DEPENDENCIES += PLATFORM_CFLAGS += $(BR2_EASYLINUX_CFLAGS) #PLATFORM_CFLAGS += PLATFORM_CONF_OPTS += -DCMAKE_C_FLAGS="$(PLATFORM_CFLAGS)" $(eval $(cmake-package)) |
檔案系統編譯和定製
目前easylinux平臺設計為3個檔案系統,根檔案系統initramfs,使用者映象檔案系統usrimage.jffs2和使用者配置檔案系統usrconf.jffs2。initramfs是最小根檔案系統,和核心編譯到一起掛載到記憶體。Usrimage.jffs2用來存放我們自己的可執行檔案和庫以及一些相應的資料。Usrconf.jffs用來儲存配置,升級的時候可以保留這個分割槽,從而儲存使用者配置。
Initramfs基於cpio製作,我們在cpio.mk中對根檔案系統進行定製
define ROOTFS_CPIO_CMD #刪掉不需要的檔案 rm -rf $(TARGET_DIR)/usr/bin/top && \ rm -rf $(TARGET_DIR)/usr/bin/unzip && \ rm -rf $(TARGET_DIR)/usr/bin/wget && \ #先拷出easylinux資料夾,這些資料放入usrimage.jffs2中 cp -arf $(BR2_EASYLINUX_ARCHIVE_DIR)/usr/lib/* $(TARGET_DIR)/easylinux/lib && \ mkdir -p $(TARGET_DIR)/../tmptarget && \ cp -rf $(TARGET_DIR)/easylinux $(TARGET_DIR)/../tmptarget && \ rm -rf $(TARGET_DIR)/easylinux && \ #製作cpio映象 cd $(TARGET_DIR) && find . | cpio --quiet -o -H newc > [email protected] && \ cp -rf $(TARGET_DIR)/../tmptarget/easylinux $(TARGET_DIR) endef |
製作usrimage.jffs2和usrconf.jffs2
define ROOTFS_JFFS2_CMD mkdir -p $(TARGET_DIR)/../tmptarget/usrconf && \ mkdir -p $(TARGET_DIR)/../tmptarget/usrconf/conf && \ mkdir -p $(TARGET_DIR)/../tmptarget/usrconf/log && \ mkdir -p $(TARGET_DIR)/../tmptarget/usrconf/key && \ $(MKFS_JFFS2) $(JFFS2_OPTS) –d \ $(TARGET_DIR)/../tmptarget/usrconf \ $(BINARIES_DIR)/usrconf.jffs2 && \ $(MKFS_JFFS2) $(JFFS2_OPTS) –d\ $(TARGET_DIR)/../tmptarget/easylinux –o\ $(BINARIES_DIR)/usrimage.jffs2 endef |
編譯系統後即可得到3個檔案系統映象
啟動指令碼start_system.sh製作
#!/bin/sh echo "start system,please wait..." #更改printk列印級別 echo 4 > /proc/sys/kernel/printk mkdir -p /mnt/easylinux mkdir -p /mnt/usrconf #掛載usrimage.jffs2 mount -t jffs2 /dev/mtdblock3 /mnt/easylinux #掛載usrconf.jffs2 mount -t jffs2 /dev/mtdblock4 /mnt/usrconf mkdir -p /easylinux #將usrimage.jffs2也掛載到ramfs中 mount -t ramfs none /easylinux cp -rf /mnt/easylinux/* /easylinux chmod 0644 /easylinux/lib/*.so #設定環境變數 export PATH=$PATH:/easylinux/app/bin export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/easylinux/lib #啟動我們的第一個程序,其他程序都由他派生 /usr/bin/procmgr echo "something error,we should not go here" |
Start_system.sh放在src/platform/app/procmgr/etc中,編譯procmgr時,和etc下的其他定製檔案一起拷貝到根檔案系統中。定製inittab檔案
# now run any rc scripts ::sysinit:/etc/init.d/rcS > /dev/null # Put a getty on the serial port #console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL #這裡啟動我們的指令碼 console::sysinit:/etc/start_system.sh > /dev/null # Stuff to do for the 3-finger salute ::ctrlaltdel:/sbin/reboot |
升級映象製作
Flash分割槽和檔案系統設計見《EasyLinux平臺檔案系統設計》
有兩種映象型別,一種是up.bin,用於系統升級,僅包含有效資料和頭部資訊。一種是flash.bin,用於工廠生產時燒寫,包含資料和分割槽之間填充的空洞。
Easylinux-mkimage目標用於製作映象檔案
make O=build/gt2440 easylinux-mkimage |
生成的映象在buildroot/image/img目錄下,buildroot/image/source目錄下是用於製作的原始檔。其中,gt2440_all包含uboot,kernel,usrimage等所有分割槽資料,exclude_uboot去掉了uboot,
Exclude_uboot_kernel去掉了uboot和kernel。升級的時候可根據需要只升級部分割槽域。
相關推薦
嵌入式Linux編譯系統的設計——Bootloader, 核心,驅動,檔案系統,升級映象等自動化編譯打包
專案簡介 嵌入式系統的開發過程較為複雜,編譯,裁剪,定製等如果沒有一套規範的流程將會難於管理和控制。本專案的目的是設計一個嵌入式Linux編譯系統,實現程式碼的編譯,定製和裁剪。Bootloader, 核心,驅動,檔案系統,升級映象等都可以自動化編譯,打包。 本專案git
嵌入式linux燒寫(一)—BootLoader的裁剪和編譯
一、BootLoader的概念 BootLoader是系統加電啟執行的第一段軟體程式碼.回憶一下PC的體系結構我們可以知道,PC機中的引導載入程式由BIOS(其本質就是一段韌體程式)和位於硬碟MBR中的載入程式一起組成。BIOS在完成硬體檢測和資源分配後,將硬碟MBR
LINUX 新增的磁碟不建立分割槽,直接建立檔案系統並掛載怎麼辦?
LINUX下新增的磁碟不建立分割槽,直接建立檔案系統並掛載: 不是都要先使用FDISK進行分割槽的麼?怎麼直接跳過了這步,直接建立檔案系統,並掛載了呢? 解決方法: 假設新硬碟是 /dev/sdcfdisk操作的是/dev/sdc ,分割槽後才會有/dev/sdc1 /
Linux核心移植和根檔案系統製作(詳細步驟精講)
start_kernel是所有 Linux 平臺進入系統核心初始化後的入口函式,它主要完成剩餘的與硬體平臺相關的初始化工作,在進行一系列與核心相關的初始化後,呼叫第一個使用者程序-init 程序並等待使用者程序的執行,這樣整個 Linux 核心便啟動完畢。該函式所做的具體工作有:呼叫 setup_arch
嵌入式Linux--基於物聯網實驗環境的溫溼度實時顯示系統
實驗內容與要求: 在物聯網實驗箱上實現一個溫溼度顯示系統,系統上電啟動後自動啟動此程式。每隔2秒自動重新整理溫溼度資料。溫溼度資料從物聯網試驗箱自帶的溫溼度感測器獲取。溫溼度顯示介面採用QT
Linux核心模組程式設計-proc檔案系統
什麼是proc proc檔案系統是一個偽檔案系統,它只存在記憶體當中,而不佔用外存空間。它以檔案系統的方式為訪問系統核心資料的操作提供介面。使用者和應用程式可以通過proc得到系統的資訊,並可以改變核心的某些引數。由於系統的資訊,如程序,是動態改變的,所以使用
linux-2.6.21核心中建立jffs2檔案系統(mtd分割槽的使用)
本文主要介紹如何在AT91SAM9261EK板子上製作和使用jffs2檔案系統,使用的是linux-2.6.21核心。 首先配置MTD $ make menuconfig 進入 Memory Technology Devices (MTD)
關於uboot如何找核心,核心如何找根檔案系統的個人見解
關於uboot如何找核心,核心如何找根檔案系統的個人見解 這幾天真算是讓這個辰漢給搞趴下了,唉。也沒有資料可以參考。一點資訊也不說,弄不弄就把Freescale的東東拿出來。而你的東東又跟原廠的不一
Linux核心通訊之---proc檔案系統(詳解)
使用 /proc 檔案系統來訪問 Linux 核心的內容,這個虛擬檔案系統在核心空間和用戶空間之間打開了一個通訊視窗: /proc 檔案系統是一個虛擬檔案系統,通過它可以使用一種新的方法在 Linux核心空間和使用者間之間進行通訊。在 /proc 檔案系統中,我
tiny linux: 核心精簡的根檔案系統製作
tiny_linux要求實現以下兩點: 精簡linux核心映象,要求在支援TCP/IP資料傳輸的情況下,核心映象和正常執行所需記憶體能夠做到儘可能的小。 採用busybox製作根檔案系統,利用kernel mode linux補丁,使得busybox執行
Linux學習筆記(4)磁碟分割槽與檔案系統命令
df 檢查檔案系統的磁碟空間佔用情況,引數-a列出全部目錄,引數-h按KB,MB,GB顯示 du 檢車某個目錄或者檔案佔用的磁碟空間,引數-s顯示佔用總空間,引數-sh統計目錄大小 mo
Linux入門到放棄之六《磁碟和檔案系統管理三》
設定磁碟配額 對之前建立的邏輯卷設定磁碟配額,要求使用者student對該邏輯卷 容量的軟限制是:5G,硬限制是7G,檔案個數軟限制為:25個,硬限制為30個。 (1)首先對/etc/fstab檔案進行編輯 命令:vi /etc/fstab 編輯內容如下截圖中紅框部分 (2)因fstab檔案修
Linux的Apache應用筆記--從URL對映到檔案系統
DocumentRoot 在決定為請求給定什麼檔案的時候,httpd預設是根據請求的URL和DocumentRoot指定的路徑來決定的。 例如:如果DocumentRoot設定為/var/www/
核心必須懂(二): 檔案系統初探
目錄 前言 檔案系統結構 新建檔案和inode 檔案建立過程 inode解析 開啟檔案 參考 最後 前言 這次來說檔案系統. 檔案系統是非常重要的, 提高磁碟使用率, 減小磁碟磨損等
DragonFly BSD 5.4.1 釋出,改進 HAMMER2 檔案系統
在 5.4.0 釋出20天后,DragonFly BSD 迎來了該系列的首個維護版本。DragonFly BSD 5.4.1 對 HAMMER2 檔案系統進行了大量改進,包括快照和崩潰的 meta-consistency 保護,更好的 on-media 拓撲等。
核心、裝置、驅動、檔案系統、核心空間、使用者空間
學習驅動過程中有一些疑問,記錄下來,並希望能在2015-6-30之前能夠有一個明確的答案。 疑問: 一、當裝置插上的時候,核心怎麼發現裝置並更新/sys、/dev、/proc檔案系統、怎麼通知給使用者空間?更具體一點是probe的過程 二、device和driver怎麼配對
linux驅動開發-檔案系統與裝置檔案
目錄 1.Linux檔案系統操作 Linux檔案建立,開啟,關閉函式 #檔案許可權最終由mode&umask決定 int creat (const char *filename,mode_t mod
Nginx服務搭建負載均衡,反向代理,快取加速,訪問分散式檔案系統高可用
主配置檔案如下:[[email protected]~]#vim /usr/local/nginx/conf/nginx.conf server{ listen 8099 //埠號 location / { autoindex on; autoinde
使用seek()方法,將Hadoop檔案系統中的一個檔案在標準輸出上顯示兩次
wechat:812716131 ------------------------------------------------------ 技術交流群請聯絡上面wechat ----------------------------------------------
Hadoop 《一》,HDFS 分散式檔案系統
Hadoop-HDFS 儲存模型:位元組 -檔案線性切割成塊(Block):偏移量 offset -block分散儲存在叢集結點中 -單一檔案block大小一致,檔案與檔案可以不一致 -block可以設定副本數,副本無序分散在不同結點中 >副本數不要超過結點數量 -檔案上傳可以