# 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)