# 2024q1 Homework5 (assessment) contributed by < [hugo0406](https://github.com/hugo0406) > ## 閱讀〈[因為自動飲料機而延畢的那一年](https://blog.opasschang.com/the-story-of-auto-beverage-machine-1/)〉的啟發 在閱讀完**因為自動飲料機而延畢的那一年**,我深受啟發。對於文章作者勇於嘗試、不願放棄的精神感到敬佩,從一開始的滿腔熱血,過程中的不斷自我懷疑之後做出延畢的決定,最後做出成果。若是換成一般人,可能會迫於現實的壓力而放棄。 人們往往會被迫妥協,我也深受其害。回想起大學求學階段時,一開始非常鄙視只會看考古題而不認真上課、不願啃原文書的人,認為學習沒有捷徑可言,直到過了幾次考試,學習心態發生改變,我花了大量時間在啃原文書,然而考試成績與那些考前一天只瘋狂刷考古題的人卻相差不大,感受到心態上的不平衡,漸漸地我也同流合污,依賴考古題,只注重考試會考的來應付考試,享受低成本高報酬的快感而沾沾自喜,隨著大學將近四年這樣的學習心態也讓我與他人的差距越來越大。 一開始非常猶豫要不要修 Linux 核心實作 這門課,因為這堂課是出了名的硬,要花費大量的心力及時間。在聽了老師第一堂課程介紹後,首先就是要誠實面對自己,想到過去大學的自己不求甚解,學的不夠扎實,那就趁這個機會,把基礎打好,改變自己的學習態度,就頭鐵決定修下去。 修了這堂課的這幾週,深刻的體會到為大學的不努力而買帳,不論是在理解教材或是寫作業上都非常吃力,指定進度嚴重落後,與大部分學員的進度也落差很大,常常看不懂教材,想了半天也想不出個所以然,隨著每次的卡關,常常有退選的念頭出現,看了這系列的文章及同儕的鼓勵,有了動力。 ## 研讀 第 1 到第 6 週「課程教材」和 CS:APP 3/e ## 簡述想投入的專案 前陣子在翻閱 The Linux Programming Interface 這本書的時候,對第七章 Memory Alloctian 的主題感到興趣,花了一些時間把第七章閱讀完,因此想做跟 Memory 相關的專案 - 〈每位程式開發者都該有的記憶體知識〉翻譯和校訂 - 實作高效記憶體配置器 ## Running linux on stm32f429 discovery ### Prerequisites - OpenOCD ```bash git clone git://git.code.sf.net/p/openocd/code openocd cd openocd ./bootstrap ./configure --prefix=/usr/local --enable-stlink echo -e "all:\ninstall:" > doc/Makefile make sudo make install ``` - ~~Set ARM/uClinux Toolchain:~~ - Download [arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2](https://sourcery.mentor.com/public/gnu_toolchain/arm-uclinuxeabi/arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2) from Mentor Graphics ```bash tar jxvf arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2 export PATH=`pwd`/arm-2010q1/bin:$PATH ``` - ARM Cross Compile Toolchain: ```bash sudo apt-get install arm-linux-gnueabi-gcc which arm-linux-gnueabi-gcc export PATH=/usr/bin:$PATH source ~/.bashrc ``` Verify it by checking the installed version : ``` $ arm-linux-gnueabi-gcc --version arm-linux-gnueabi-gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ``` - genromfs ```bash sudo apt-get install genromfs ``` - STLINK Tools: `stlink`is an open source toolset to program and debug STM32 devices and boards manufactured by STMicroelectronics. ```bash cd ~ git clone https://github.com/texane/stlink.git cd ./stlink sudo apt-get install libusb-1.0-0-dev sudo apt-get -y install cmake sudo apt-get install libstlink1 make cd build/Release sudo make install ``` To verify the successful installation ```bash st-flash ``` ### Build - ~~simple bootloader~~ ```bash git clone git@github.com:mcoquelin-stm32/afboot-stm32.git ``` - U-boot ```bash git clone git://git.denx.de/u-boot.git cd u-boot make ARCH=arm CROSS_COMPILE=arm-none-eabi- stm32f429-discovery_defconfig make ARCH=arm CROSS_COMPILE=arm-none-eabi- -j4 ``` - kernel ```bash git clone git://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git // 版本太舊 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ``` minimal Linux config ```bash make ARCH=arm O=/build/stm32f429 tinyconfig ``` ``` make[1]: Entering directory '/home/cychen/stm32/stm32/build/stm32f429' HOSTCC scripts/basic/fixdep GEN ./Makefile GEN ./Makefile HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf scripts/kconfig/conf --allnoconfig Kconfig # # configuration written to .config # GEN ./Makefile Using .config as base Merging /home/cychen/stm32/stm32/kernel/configs/tiny.config Value of CONFIG_CC_OPTIMIZE_FOR_SIZE is redefined by fragment /home/cychen/stm32/stm32/kernel/configs/tiny.config: Previous value: # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set New value: CONFIG_CC_OPTIMIZE_FOR_SIZE=y Value of CONFIG_KERNEL_XZ is redefined by fragment /home/cychen/stm32/stm32/kernel/configs/tiny.config: Previous value: # CONFIG_KERNEL_XZ is not set New value: CONFIG_KERNEL_XZ=y Value of CONFIG_SLOB is redefined by fragment /home/cychen/stm32/stm32/kernel/configs/tiny.config: Previous value: # CONFIG_SLOB is not set New value: CONFIG_SLOB=y # # merged configuration written to .config (needs make) # GEN ./Makefile scripts/kconfig/conf --oldconfig Kconfig .config:867:warning: override: CC_OPTIMIZE_FOR_SIZE changes choice state .config:868:warning: override: KERNEL_XZ changes choice state .config:870:warning: override: SLOB changes choice state # # configuration written to .config # make[1]: Leaving directory '/home/cychen/stm32/stm32/build/stm32f429' ``` Menu Config ```bash make ARCH=arm O=build/stm32f429 menuconfig ``` When I try to menu config, but got some error message ``` make[1]: Entering directory '/home/cychen/stm32/stm32/build/stm32f429' GEN ./Makefile HOSTCC scripts/kconfig/mconf.o <command-line>: fatal error: curses.h: No such file or directory compilation terminated. make[2]: *** [scripts/Makefile.host:108: scripts/kconfig/mconf.o] Error 1 make[1]: *** [/home/cychen/stm32/stm32/Makefile:544: menuconfig] Error 2 make[1]: Leaving directory '/home/cychen/stm32/stm32/build/stm32f429' make: *** [Makefile:150: sub-make] Error 2 ``` `libncurses5-dev need` to be installed before compiling the kernel ```bash sudo apt-get install libncurses5-dev ``` ![image](https://hackmd.io/_uploads/rkb2YWimA.png) ![image](https://hackmd.io/_uploads/HkvJNNsQ0.png) ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -C build/stm32f429 -j 4 ``` Error Message: ``` make: Entering directory '/home/cychen/stm32/stm32/build/stm32f429' CHK include/config/kernel.release GEN ./Makefile CHK include/generated/uapi/linux/version.h CC scripts/mod/empty.o CC scripts/mod/devicetable-offsets.s HOSTLD scripts/dtc/dtc /usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x10): multiple definition of `yylloc'; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0): first defined here Using /home/cychen/stm32/stm32 as source for kernel MKELF scripts/mod/elfconfig.h HOSTCC scripts/mod/modpost.o HOSTCC scripts/mod/sumversion.o collect2: error: ld returned 1 exit status make[4]: *** [scripts/Makefile.host:100: scripts/dtc/dtc] Error 1 make[3]: *** [/home/cychen/stm32/stm32/scripts/Makefile.build:440: scripts/dtc] Error 2 make[3]: *** Waiting for unfinished jobs.... GEN scripts/mod/devicetable-offsets.h CHK include/generated/utsrelease.h HOSTCC scripts/mod/file2alias.o CC kernel/bounds.s In file included from /home/cychen/stm32/stm32/include/linux/kernel.h:11, from /home/cychen/stm32/stm32/include/asm-generic/bug.h:13, from /home/cychen/stm32/stm32/arch/arm/include/asm/bug.h:59, from /home/cychen/stm32/stm32/include/linux/bug.h:4, from /home/cychen/stm32/stm32/include/linux/page-flags.h:9, from /home/cychen/stm32/stm32/kernel/bounds.c:9: /home/cychen/stm32/stm32/include/linux/log2.h:22:1: warning: ignoring attribute ‘noreturn’ because it conflicts with attribute ‘const’ [-Wattributes] 22 | int ____ilog2_NaN(void); | ^~~ CHK include/generated/timeconst.h CHK include/generated/bounds.h UPD include/generated/bounds.h CC arch/arm/kernel/asm-offsets.s In file included from /home/cychen/stm32/stm32/include/linux/kernel.h:11, from /home/cychen/stm32/stm32/include/linux/sched.h:17, from /home/cychen/stm32/stm32/arch/arm/kernel/asm-offsets.c:14: /home/cychen/stm32/stm32/include/linux/log2.h:22:1: warning: ignoring attribute ‘noreturn’ because it conflicts with attribute ‘const’ [-Wattributes] 22 | int ____ilog2_NaN(void); | ^~~ CHK include/generated/asm-offsets.h UPD include/generated/asm-offsets.h CALL /home/cychen/stm32/stm32/scripts/checksyscalls.sh HOSTLD scripts/mod/modpost make[2]: *** [/home/cychen/stm32/stm32/Makefile:558: scripts] Error 2 make[1]: *** [Makefile:150: sub-make] Error 2 make: *** [Makefile:24: __sub-make] Error 2 make: Leaving directory '/home/cychen/stm32/stm32/build/stm32f429' ``` [參考](https://github.com/BPI-SINOVOIP/BPI-M4-bsp/issues/4),似乎是 GCC 版本太新所造成的問題 解決方法: ```bash cd scripts/dtc/ sudo vim dtc-lexer.lex.c_shipped -------------------------------------------------- 635 #line 37 "dtc-lexer.l" 636 #include "dtc.h" 637 #include "srcpos.h" 638 #include "dtc-parser.tab.h" 639 640 YYLTYPE yylloc; //檔案640行,前面加上 extern -------------------------------------------------- ``` https://hackmd.io/@cychen/linux-final Boot loader 存在必要? XIP image => 1.8MB boot loader 責任是初始化 memory controller, flash controller, 和相關周邊,之後再載入 Linux 核心 TODO: 確保 u-boot 正確編譯、用 st-link 燒錄成功,且在 STM32F429-Discovery 執行 u-boot (可見命令提示) TODO: 確認 u-boot 支援的 Linux image 格式 (Image, uImage, zImage),偏好用 XIP TODO: 在 u-boot 載入 Linux image (from flash),輸入正確的 boot cmd (boot args) non-XIP: load everything from Flash to RAM and then execute programs on RAM (佔用較多的記憶體) XIP : load data from Flash to RAM and then execute program on Flash + RAM (data section) https://www.kernel.org/doc/Documentation/nommu-mmap.txt uClibc : libc used for mmu and no-mmu ## Reference 1. [build-linux-kernel](https://phoenixnap.com/kb/build-linux-kernel) 2. [uClinux](https://community.intel.com/t5/FPGA-Wiki/UClinux/ta-p/735614) 3. [stlink Tools Tutorial](https://github.com/stlink-org/stlink/blob/testing/doc/tutorial.md) 4. [STM32](https://elinux.org/STM32)