学习路线
我们的首个解决方法
我们准备好《操作系统原理》《计算机组成原理》《TCP/IP 详解》,做好计划,开始学习。
很显然,这个方案是不可行的。之所以不可行,不是学习内容的问题,而是意志力和知识储备的问题。说到意志力,这几本书可不是随随便便坚持几个月就能看完的。说到知识储备,这基本书又会牵扯比如算法数据结构等等方面的知识。根本就不适合我们这种外行。(历史总是在重演嘛,我们不止一次拿起经典著作,看个几页后就放在一边)
简单可行的解决方案
我们从简单的开始,学习简单的操作系统知识,对操作系统有个初步的认识。正巧我们手里有本《30天自制操作系统》,我们可以先写个简单的操作系统,达到对操作系统有个初步的认识,掌握操作系统的基础简单知识。
但是在学习《30天自制操作系统》的过程中,我们发现,需要准备汇编语言的知识,不然看这本书的时候就之剩下抄代码了。所以我们开始看汇编语言的知识《汇编语言(第 3 版)》、《x86 汇编语言 从实模式到保护模式》、《32 位汇编语言程序设计(第 2 版)》,好在这些书中都提及硬件工作的基本原理(汇编语言本来就是用于操作硬件,如果没有书中没有介绍硬件,那八成不是什么好的汇编教学),因此我们不用再单独去看硬件方面的书籍。
如果相对硬件的原理有个基本的了解,可以阅读《穿越计算机的迷雾(第 2 版)》。
# 注意事项 # 该方案中介绍的书籍只是用于简单入门,之后依旧阅读《操作系统原理》、《计算机组成原理》、《TCP/IP 详解》、《Linux 内核设计与实现》等等书籍
所以,根据该解决方案,产生以下笔记内容:
1)Assembly Language / Intel 80×86
2)Writing a Simple Operating System
获取内核源码
make kernelversion
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git git pull wget https://mirrors.edge.kernel.org/pub/linux/kernel/v2.4/linux-2.4.0.tar.gz # 查看当前内核版本 make kernelversion
源码阅读工具
Is it possible to develop linux kernel module in CLion? | Newbedev
Solution:
Yes, It is. But you will need to write make file for building kernel module.
Update 1: I recommend QtCreator for writing linux kernel module. See my manual
Update 2: I also recommend eclipse cdt. See eclipse manual about how to prepare it for linux kernel.
我们选择 Eclipse 来阅读源码,我们认为:其存在时间久,解决方案较多,遇到问题会少;功能比较丰富,无需过多配置;开源免费,无需付费购买;
VS Code
visual studio code – HowTo use the VSC to navigate Linux kernel source – Stack Overflow
Install ms-vscode.cpptools extension.
Open kernel source folder in VSCode.
Follow the instructions, add “${workspaceFolder}/include” and “${workspaceFolder}/arch/{your arch}/include” to includePath, “your arch” is x86/arm etc.
Wait for IntelliSence indexing.
Eclipse
FAQ How do I increase the heap size available to Eclipse? – Eclipsepedia
HowTo use the CDT to navigate Linux kernel source – Eclipsepedia
Disclaimer: These steps were last updated for Eclipse 2019‑03, CDT 9.7.0, and Linux v5.1-rc4:
Download and install Eclipse plus the CDT.
Configure and build your kernel to define CONFIG_* and generate autoconf.h.
Start up Eclipse.
Click File -> New -> Project
In the pop-up window, choose C/C++-> C Project. Click Next
Fill in a project name like Linux v5.1
Uncheck the Use default location box and type in the root directory of your kernel into the Location box.
In the Project type: pane, click the Makefile project and select Empty Project
On the right side, select Linux GCC. Click Next
Click Advanced settings… and a Properties dialog will pop up.
Note: At this point, and starting from Eclipse Oxygen, Eclipse will aggressively start indexing your project, which can make Eclipse painfully slow for the rest of the configuration steps below. To mitigate that, temporarily disable indexing now by opening C/C++ General section, click on Indexer, click on Enable project-specific settings, then unmark the Enable indexer option.
Open the C/C++ General selection on the left.
Click on Preprocessor Include Paths
Select GNU C in the Languages list
Select CDT User Setting Entries in the Setting Entries list
Click on Add…. Choose Preprocessor Macros File from the top left dropdown, Project Path from the top right dropdown, and enter “include/linux/kconfig.h” into the File text box.
Also add any other macros files you are using.
Click on Indexer
Checkmark the Enable project specific settings box.
Uncheck Index source files not included in the build
Click on Paths and Symbols on the left.
Select the Includes tab and then select GNU C
Click Add…
Click Workspace… then select your kernel’s include, and include/uapi directories
Do another Add, Workspace and add both arch/architecture/include, and arch/architecture/include/uapi directories. e.g., arch/powerpc/include and arch/powerpc/include/uapi (The UAPI directories are due to the kernel’s user/kernel header split covered here in-detail)
Click the # Symbols tab
Click Add…
Set the name to KERNEL
Set the value to 1 and click OK
Click the Source Location tab
Click the plus sign (or arrow/triangle) next to your project name.
Select the Filter item and click Edit Filter…
Click Add Multiple… and then select all of the arch/* directories in your kernel source that will not be used (i.e. all the ones that are not for the architecture you are using)
Click OK and OK again to dismiss that dialog.
Under C/C++ General, select Preprocessor Include Paths, Macros etc.
Click the Providers tab and select CDT GCC Built-in Compiler Settings
Uncheck Use global provider shared between projects
Append -nostdinc to the curretly-existing Command to get compiler specs. The kernel is a free-standing environment by ISO C99 definition. That is, it does not want to be polluted, and obviously cannot work with, the “host” header files and libraries.
Open a terminal, and type “echo -isystem $(gcc -print-file-name=include/)”. Append the resulting output to the Command to get compiler specs mentioned above. If you’re using a cross-toolchain to compile the kernel, use the full path of that cross GCC compiler, instead of just typing gcc in the command mentioned. Rationale for this step: -nostdinc already asked gcc to not search the standard system directories for header files. But the Linux Kernel depends on GCC-provided “freestanding environment” headers like stdarg.h, stdbool.h and so on, which are typically hosted by GCC under /usr/lib/gcc/<arch>/<version>/include. Thus this step.
Click OK on the Properties dialog.
Note: If you temporarily disabled indexing as earlier recommended. This is the right time to re-enable it. Under C/C++ General, click on Indexer, and mark the Enable indexer option.
Click Finish on the C Project dialog.
The Project will index automatically.
On a platter drive indexing will take upwards of 20 minutes to complete, on a SSD indexing will take about 5 minutes to complete.
源码目录结构
# tree -L 1 --dirsfirst . ├── arch -------------------------- Architecture-specific source ├── block ------------------------- Block I/O layer ├── crypto ------------------------ Crypto API ├── Documentation ----------------- Kernel source documentation ├── drivers ----------------------- Device drivers ├── firmware ---------------------- Device firmware needed to use certain drivers ├── fs ---------------------------- The VFS and the individual filesystems ├── include ----------------------- Kernel headers ├── init -------------------------- Kernel boot and initialization ├── ipc --------------------------- Interprocess communication code ├── kernel ------------------------ Core subsystems, such as the scheduler ├── lib --------------------------- Helper routines ├── mm ---------------------------- Memory management subsystem and the VM ├── net --------------------------- Networking subsystem ├── samples ----------------------- Sample, demonstrative code ├── scripts ----------------------- Scripts used to build the kernel ├── security ---------------------- Linux Security Module ├── sound ------------------------- Sound subsystem ├── tools ------------------------- Early user-space code (called initramfs) ├── usr --------------------------- Tools helpful for developing Linux ├── virt -------------------------- Virtualization infrastructure ├── COPYING ├── CREDITS ├── Kbuild ├── MAINTAINERS ├── Makefile ├── README └── REPORTING-BUGS
编译安装内核
第一步、配置内核
方法一、生成默认配置:
make defconfig
方法二、根据需要,配置内核(以下命令是等价的,操作方式不同):
# make config # make gconfig make menuconfig
方法三、将旧的配置,应用于当前源码:
zcat /proc/config.gz > .config make oldconfig
当配置结束后,将生成 .config 文件。
第二步、编译内核
make
System.map:符号对照表;
第三步、安装内核
安装内核镜像文件的方式,取决于引导加载程序
安装内核模块,可以执行如下命令:
make modules_install