Refinement on documentation (#38)
authorLunaixsky <lunaixsky@qq.com>
Wed, 14 Aug 2024 13:31:43 +0000 (14:31 +0100)
committerGitHub <noreply@github.com>
Wed, 14 Aug 2024 13:31:43 +0000 (14:31 +0100)
* start a docs series on lunaix-internal

* update readme, include a list for auto-loaded symbols

* tweak the gitignore file
* add a script to dump all .lga symbols

* fix the image link to mem map

* update readme, fix gitignore

README.md
docs/img/boot_sequence.jpeg [deleted file]
docs/img/boot_sequence.png [new file with mode: 0644]
docs/lunaix-boot.md [new file with mode: 0644]
docs/lunaix-internal.md [new file with mode: 0644]
docs/lunaix-mem-map.md [new file with mode: 0644]
docs/lunaix-syscall-table.md
lunaix-os/.gitignore
lunaix-os/kernel.mk
lunaix-os/scripts/gather_lga.sh [new file with mode: 0755]

index 86d04432f3e13e5fa2f96a881695d30a99a13f71..43695ee4ed744d5a388f952d0b0007e1a08ae17d 100644 (file)
--- a/README.md
+++ b/README.md
@@ -14,12 +14,8 @@ LunaixOS - 一个简单的,详细的,POSIX兼容的(但愿!),带有
 
 如果有意研读 Lunaix 内核代码和其中的设计,或欲开始属于自己的OS开发之道,以下资料可能会对此有用。
 
 
 如果有意研读 Lunaix 内核代码和其中的设计,或欲开始属于自己的OS开发之道,以下资料可能会对此有用。
 
++ [内核文档(Luna's Tour)](docs/lunaix-internal.md)
 + [LunaixOS源代码分析教程](docs/tutorial/0-教程介绍和环境搭建.md)
 + [LunaixOS源代码分析教程](docs/tutorial/0-教程介绍和环境搭建.md)
-+ 内核虚拟内存的详细布局
-  + [x86_32](docs/img/lunaix-mem-map/lunaix-mem-x86_32.png)
-  + [x86_64](docs/img/lunaix-mem-map/lunaix-mem-x86_64.png)
-+ [LunaixOS启动流程概览](docs/img/boot_sequence.jpeg)
-+ LunaixOS总体架构概览(WIP)
 + [作者修改的QEMU](https://github.com/Minep/qemu) (添加了一些额外用于调试的功能)
 
 ## 2. 当前进度以及支持的功能
 + [作者修改的QEMU](https://github.com/Minep/qemu) (添加了一些额外用于调试的功能)
 
 ## 2. 当前进度以及支持的功能
@@ -194,9 +190,9 @@ ARCH=x86_64 ./live_debug.sh
 
 ### 5.1 代码稳定性
 
 
 ### 5.1 代码稳定性
 
-主分支一般是稳定的。因为在大多数情况下,我都会尽量保证本机运行无误后,push到该分支中。至于其他的分支,则是作为标记或者是开发中的功能。前者标记用分支一般会很快删掉;后者开发分支不能保证稳定性,这些分支的代码有可能没有经过测试,但可以作为Lunaix当前开发进度的参考
+主分支一般是稳定的。因为在大多数情况下,我都会尽量保证本机运行无误后,push到该分支中。所有正在开发的功能请参考当前活跃的Pull Request
 
 
-该系ç»\9fæ\98¯ç»\8fè¿\87è\99\9aæ\8b\9fæ\9cºå\92\8cç\9c\9fæ\9cºæµ\8bè¯\95ã\80\82å¦\82æ\9e\9cå\8f\91ç\8e°å\9c¨ä½¿ç\94¨`make all`ä¹\8bå\90\8eï¼\8cè\99\9aæ\8b\9fæ\9cºä¸­è¿\90è¡\8cæ\8a¥é\94\99ï¼\8cå\88\99ä¸\80è\88¬æ\98¯ç¼\96è¯\91å\99¨ä¼\98å\8c\96é\97®é¢\98ã\80\82è¿\99个é\97®é¢\98ç¬\94è\80\85ä¸\80è\88¬å¾\88å¿«å°±ä¼\9aä¿®å¤\8dï¼\8cå¦\82æ\9e\9c你使ç\94¨å\88«ç\9a\84ç\89\88æ\9c¬ç\9a\84gccï¼\88ç¬\94è\80\85ç\89\88æ\9c¬11.2ï¼\89ï¼\8cå\87ºç\8e°äº\86æ­¤é\97®é¢\98ï¼\8c欢è¿\8eæ\8f\90issueã\80\82请å\8f\82è\80\83\99\84å½\953ï¼\9aIssueç\9a\84æ\8f\90交](#appendix3)
+å¦\82æ\9e\9c主å\88\86æ\94¯ç\9a\84è¿\90è¡\8cå\87ºç\8e°äº\86æ­¤é\97®é¢\98ï¼\8c欢è¿\8eæ\8f\90issueã\80\82请å\8f\82è\80\83\99\84å½\953ï¼\9aIssueç\9a\84æ\8f\90交](#appendix3)
 
 ## 6. 调试 Lunaix 内核
 
 
 ## 6. 调试 Lunaix 内核
 
@@ -263,7 +259,7 @@ ARCH=x86_64 ./live_debug.sh
 
 #### 网站
 
 
 #### 网站
 
-+ [OSDev](https://wiki.osdev.org/Main_Page) - 杂七杂八的参考,很多过来人的经验。作者主要用于上古资料查询以及收集;技术文献,手册,标准的粗略总结;以及开发环境/工具链的搭建。当然,上面的内容假设了x86_32架构的生态,对于其他的ISA支持,该网站便失去了其价值了
++ [OSDev](https://wiki.osdev.org/Main_Page) - 适合快速入门,和一些文档手册的总结
 + [FreeVGA](http://www.osdever.net/FreeVGA/home.htm) - 98年的资源!关于VGA编程技术的宝藏网站。
 + GNU CC 和 GNU LD 的官方文档。
 + [PCI Lookup](https://www.pcilookup.com/) - PCI设备编号查询
 + [FreeVGA](http://www.osdever.net/FreeVGA/home.htm) - 98年的资源!关于VGA编程技术的宝藏网站。
 + GNU CC 和 GNU LD 的官方文档。
 + [PCI Lookup](https://www.pcilookup.com/) - PCI设备编号查询
diff --git a/docs/img/boot_sequence.jpeg b/docs/img/boot_sequence.jpeg
deleted file mode 100644 (file)
index 0d57d31..0000000
Binary files a/docs/img/boot_sequence.jpeg and /dev/null differ
diff --git a/docs/img/boot_sequence.png b/docs/img/boot_sequence.png
new file mode 100644 (file)
index 0000000..3d580c4
Binary files /dev/null and b/docs/img/boot_sequence.png differ
diff --git a/docs/lunaix-boot.md b/docs/lunaix-boot.md
new file mode 100644 (file)
index 0000000..9477ab2
--- /dev/null
@@ -0,0 +1,117 @@
+# Lunaix内核初始化流程
+
+虽然不同的架构对启动与初始化有着不同的要求,但这些区分只是针对指令集架构或其微架构的特性。对于架构中性的内核而言,其初始化流程是保持不变的。
+
+下图展示了从内核被引导,及至第一个用户进程的创建,这之间的流程。
+
+![boot](img/boot_sequence.png)
+
+## 图例与解释
+
+### 1. 架构相关
++ **ISA Config** 
+  对CPU状态进行而外的配置,如进行模式切换,开启或关闭CPU特性。该部分代码为架构相关,如果某些架构没有这个需求,那么该步骤将只是一个单纯的占位符,以满足Lunaix的规范。
++ **collect boot info**
+  收集引导信息,以及平台信息。比如内存地图,内核启动参数的存放地址。
++ **high-mem**
+  配置内核的虚拟地址资源,包括:按照[虚拟内存地址映射图](./lunaix-mem-map.md)进行页表的构建,以及将内核重映射到高内存区。
++ **exception model** 
+  初始化CPU的异常模型(或者也叫中断模型),包括:安装异常处理函数,配置CPU使得其按照Lunaix预定的方式进行异常的接受和分派。
++ **hw_irq manager**
+  初始化硬件中断资源管理器。该组件用于管理外部中断号的分配,比如:当一个驱动程序想获得一个中断号以便配置与相应该设备的中断。
++ **install syscall**
+  安装系统调用接口
+
+### 2. 架构中性
+
++ **pmm_init**
+  初始化物理管理器,主要包括:内存页池创建,分配器初始化。
++ **vmm_init**
+  初始化虚拟内存管理器(该步骤目前没有任何行为)
++ **kmem_init**
+  初始化内核内存管理器,主要包括:蛋糕分配器初始化(Lunaix内核的动态内存分配器,是slab分配器的一个变体)
++ **cmdline parse**
+  解析内核启动参数,方便其他组件随时取阅。
++ **trace_init**
+  初始化内核跟踪器,用于在内核出现无法恢复的致命错误时,打印出详尽的调试信息,并跟踪堆栈。
++ **dev driver**
+  扫描并注册所有的编译进内核的设备驱动程序
++ **device: (stage)**
+  加载驱动程序。注意,该步骤是参数化的。驱动程序可能对加载的时序有要求,不同的驱动需要在内核启动过程中不同的时刻加载。该时刻由参数`stage`定义,每一次调用该步骤只会加载注册在指定时刻下的驱动程序。
+  这里需要明确指出一点:该步骤只是负责运行驱动程序的安装函数。如果一个驱动程序在该平台上找不到兼容的设备进行认领,则可以选择忽略本次运行。安装函数可以在内核进入正常的工作序列后,由用户通过`twifs`暴露的接口进行手动执行。
+  Lunaix目前规定了以下几个时刻
+  + **sysconf**
+    序章时刻。驱动程序所能使用的内核组件只有最基本的内存管理服务,以及中断资源管理服务。其他组件/服务处于未定义阶段。像ACPI,芯片组这类的驱动程序一般会在这个时候进行加载。
+  + **onboot**
+    正文时刻。在这个时刻,基本上所有的内核服务都可以使用,比如:时钟/计时器服务,虚拟文件系统,调度服务,块儿设备IO。大部分驱动程序将会在此时加载。
+  + **postboot**
+    终章时刻。在这个时刻与正文时刻几乎一样。但不同于正文时——其运行在同步模式,该时刻的驱动运行在抢占模式,也就是内核线程已经开始进入正常的调度序列。
++ **init_fn: (stage)**
+  加载内核组件初始化程序。注意,该步骤是参数化的。初始化程序可能对加载的时序有要求,不同的初始化程序需要在内核启动过程中不同的时刻加载。该时刻由参数`stage`定义,每一次调用该步骤只会加载注册在指定时刻下的初始化程序。Lunaix目前规定了以下几个时刻
+  + **earlyboot**
+    序章时刻。在驱动程序的序章时刻后进行。
+  + **onboot**
+    正文时刻。在驱动程序的正文时刻后进行。
+  + **postboot**
+    终章时刻。在驱动程序的终章时刻后进行。
++ **timer/clock init**
+  计数器与系统时钟的初始化。前者负责控制整个系统的时序,提供精确到毫秒或以下(取决于架构)的计时服务;后者构建与前者与RTC设备之上,提供基本的时间播报与统计服务(如当前的时间戳,系统运行时间,等等)
++ **vfs init**
+  虚拟文件系统初始化,同时加载文件系统驱动。
++ **pseudo fs load**
+  伪文件系统加载(如`twifs`,`devfs`)
++ **kernel daemon**
+  内核守护线程,用于重复执行一些具有维护性的例程(如LRU检查,僵尸线程自动回收)
++ **lock pmem**
+  冻结物理内存。用于“锁住”包含启动时所需信息的物理页,这类页面一般由固件提供,以便OS能够更好的进行适配。如ACPI的系统描述表们。该类页面将在 **unlock pmem** 时分释放。
++ **unlock pmem**
+  解冻物理内存。
+
+### 自加载符号
+
+上文提到的“安装函数”,如 init_fn,均属于Lunaix的自加载函数。这类函数通常由内核在初始化过程中自动调用。当然,可以被自加载的东西并不局限于函数,而是可以为任意符号,比如一个全局变量。Lunaix的自加载框架只负责统筹所有导出的符号,具体的释义和用法由具体使用此框架的子系统决定,而不同的释义与用法也就构成了不同的自加载类型。
+
+目前定义的自加载类型由如下几大类:
+
++ **devdefs** 设备驱动声明(`device`阶段)
++ **lunainit** 通用初始化函数(`init_fn`阶段)
++ **twiplugin** (twifs) 内核态映射构建函数
++ **fs** 文件系统驱动声明
+
+#### 所有自加载符号
+
+| 类型 | 符号 | 源文件 |
+| --- | --- | --- |
+| fs | `iso9660` | kernel/fs/iso9660/mount.c |
+| devdefs | `randdev` | arch/x86/hal/rngx86.c |
+| fs | `ext2fs` | kernel/fs/ext2/mount.c |
+| twiplugin | `sys_clock` | kernel/time/clock.c |
+| devdefs | `lxconsole` | hal/char/lxconsole.c |
+| devdefs | `zerodev` | hal/char/devzero.c |
+| lunainit | `lxconsole_init` | hal/char/lxconsole.c |
+| devdefs | `vga_pci` | hal/gfxa/vga/vga_pci.c |
+| twiplugin | `fstab` | kernel/fs/fsm.c |
+| devdefs | `ahci` | hal/ahci/ahci_pci.c |
+| twiplugin | `rtc_fsexport` | hal/rtc/rtc_device.c |
+| lunainit | `vga_rawtty_init` | hal/gfxa/vga/vga_rawtty.c |
+| twiplugin | `cake_alloc` | kernel/mm/cake_export.c |
+| twiplugin | `pci_devs` | hal/bus/pci.c |
+| lunainit | `init_serial_dev` | hal/char/serial.c |
+| twiplugin | `vfs_general` | kernel/fs/fs_export.c |
+| devdefs | `uart16550_pci` | hal/char/uart/16x50_pci.c |
+| twiplugin | `devdb` | kernel/device/devdb.c |
+| fs | `twifs` | kernel/fs/twifs/twifs.c |
+| lunainit | `setup_default_tty` | hal/term/console.c |
+| twiplugin | `__lru_twimap` | kernel/lrud.c |
+| devdefs | `uart16550_pmio` | hal/char/uart/16x50_isa.c |
+| fs | `ramfs` | kernel/fs/ramfs/ramfs.c |
+| lunainit | `__intc_init` | arch/x86/exceptions/isrm.c |
+| devdefs | `acpi` | hal/acpi/acpi.c |
+| fs | `devfs` | kernel/device/devfs.c |
+| devdefs | `mc146818` | arch/x86/hal/mc146818a.c |
+| lunainit | `__init_blkbuf` | kernel/block/blkbuf.c |
+| twiplugin | `kprintf` | kernel/kprint/kprintf.c |
+| devdefs | `nulldev` | hal/char/devnull.c |
+| devdefs | `pci3hba` | hal/bus/pci.c |
+| fs | `taskfs` | kernel/process/taskfs.c |
+| devdefs | `i8042_kbd` | arch/x86/hal/ps2kbd.c |
diff --git a/docs/lunaix-internal.md b/docs/lunaix-internal.md
new file mode 100644 (file)
index 0000000..21c7ef6
--- /dev/null
@@ -0,0 +1,11 @@
+# Luna's Tour
+
+这里是一个目录,收集了关于 Lunaix 内核设计的种种文档。
+
+需要注意的是,这里的文档并不是教程,而是为读者提供一个
+针对Lunaix内核架构的高层次描述和概览,帮助读者快速的,
+清晰的,掌握整个架构的设计;以便更容易进行源代码的阅读。
+
++ [虚拟内存资源划分](./lunaix-mem-map.md)
++ [启动流程概览](./lunaix-boot.md)
+
diff --git a/docs/lunaix-mem-map.md b/docs/lunaix-mem-map.md
new file mode 100644 (file)
index 0000000..3b47c67
--- /dev/null
@@ -0,0 +1,36 @@
+# Lunaix 虚拟内存地址映射图简要
+
+该说明将会展示 Lunaix 内核在不同架构下的虚拟内存地址资源的划分。
+请参看下表:
+
++ [x86_32](img/lunaix-mem-map/lunaix-mem-x86_32.png)
++ [x86_64](img/lunaix-mem-map/lunaix-mem-x86_64.png)
+
+## 图例
+
+| 名称              | 类型 | 默认权限 | 说明 |
+| ---              | --- | ---          | --- |
+| `reserved`       | `PcLc` | `R`       | 保留区域(存在映射,但暂无用途,或为过时硬件/功能预留) |
+| <阴影区域>        | `PcLc` | N/A       | 空洞区,没有任何用处,没有任何映射 |
+| `32 bits legacy` | `PcLc` | `RW`      | 存在于 64位系统上,为32位4GiB地址资源的对等映射|
+| `kstask_area`    | `PcLc` | `RW`      | 内核栈聚集地,所有内核线程的栈都来自于此 |
+| `ks@threadN`     | `PcLc` | `RW`      | 第N个内核线程的栈 |
+| `usr_space`      | `PcLc` | `URW`     | 用户空间 |
+| `usr_exec`       | `PcLv` | `URX` | 用户程序镜像映射加载区 |
+| `heap`           | `PvLv` | `URW`     | 用户堆(起始地址取决于`usr_exec`) |
+| `mmaps`          | `PcLc` | `URW`     | 通用内存映射区 |
+| `ustack_area`    | `PcLc` | `URW`     | 用户栈聚集地,所有用户线程的栈都来自于此 |
+| `vmap`           | `PcLc`* | `RW`      | 内核通用内存映射区,一个内存地址池,为内核所有组件/子系统,提供地址资源管理服务 |
+| `vms_mnt`        | `PcLc` | `RW`      | 虚拟内存空间挂载点,用于远程编辑其他虚拟内存空间的映射关系(PTE们) |
+| `vms_self`       | `PcLc` | `RW`      | 环回挂载点,用于编辑当前虚拟内存空间的映射关系。 |
+| `pg_mnts`        | `PcLc` | `RW`      | 页挂载点,用于临时挂载页面,以便对其内容进行读写,最多支持挂载4个标准页以及一个大小不超过512M的巨页/复合页 |
+| `pmap`           | `PvLc` | `RW`      | 用于存放物理页管理结构(一个巨型数组,长度取决于实装内存大小) |
+| `kernel_exec`    | `PcLc` | `RX`   | 内核镜像 |
+
+类型注释:
+
++ `Pv`: 动态起始地址(Positione varia)
++ `Pc`: 固定起始地址(Positione certa)
++ `Lv`: 动态长度(Longitudinis variae)
++ `Lc`: 固定长度(Longitudinem certam)
++ `*`: vmap的起始地址在x86_32中为动态的,取决于`pmap`的长度。
\ No newline at end of file
index 29b76c8c209cf31aa3c01eedbeaf865fd1be7674..43633d87dd405315d091de218189ca567d6d2bc0 100644 (file)
@@ -1,4 +1,4 @@
-| Name | Id |
+| Name | ID |
 | ----- | ---- |
 | __SYSCALL_fork |  1 |
 | __SYSCALL_yield |  2 |
 | ----- | ---- |
 | __SYSCALL_fork |  1 |
 | __SYSCALL_yield |  2 |
index a8dbb20884295474fd569d6443d39aa824bae0d4..f167317436a870dc49996adc67c27b00577b510c 100644 (file)
@@ -1,26 +1,29 @@
-build/
-playground/
-.vscode/settings.json
-.vscode/*.log
-.VSCodeCounter/
-.idea
-bx_enh_dbg.ini
-machine/
-draft/
-iso_inspect/
-unused/
-__pycache__/
+/*
 
 
-.builder/
-.config.json
-
-link/lunaix.ld
-
-.gdb_history
+!arch
+!hal
+!kernel
+!libs
+!makeinc
+!includes
+!scripts
+!usr
+!link
 
 
-**.o
-**.d
+!.gitignore
+!*.md
+!.pre-commit-config.yaml
+!LBuild
+!LConfig
+!makefile
+!live_debug.sh
+!kernel.mk
 
 
+*.[od]
+*.ld
 *.log
 
 *.log
 
-.lunaix_ksymtable.S
\ No newline at end of file
+__pycache__
+
+.config.json
+.builder
\ No newline at end of file
index be10da2f40ca622209dd1ba99115de2164031de4..eb5276d779f6ee2b6bd6b0d95666ed480c8c2b72 100644 (file)
@@ -45,9 +45,9 @@ $(tmp_kbin): $(klinking) $(ksrc_objs)
 
 $(ksymtable): $(tmp_kbin)
        $(call status_,KSYM,$@)
 
 $(ksymtable): $(tmp_kbin)
        $(call status_,KSYM,$@)
-       @ARCH=$(ARCH) scripts/gen_ksymtable.sh DdRrTtAGg $< > .lunaix_ksymtable.S
+       @ARCH=$(ARCH) scripts/gen_ksymtable.sh DdRrTtAGg $< > lunaix_ksymtable.S
 
 
-       @$(CC) $(CFLAGS) -c .lunaix_ksymtable.S -o $@
+       @$(CC) $(CFLAGS) -c lunaix_ksymtable.S -o $@
 
 
 .PHONY: __do_relink
 
 
 .PHONY: __do_relink
@@ -68,4 +68,4 @@ clean:
        @rm -f $(ksrc_objs)
        @rm -f $(ksrc_deps)
        @rm -f $(klinking)
        @rm -f $(ksrc_objs)
        @rm -f $(ksrc_deps)
        @rm -f $(klinking)
-       @rm -f .lunaix_ksymtable.S $(ksymtable)
\ No newline at end of file
+       @rm -f lunaix_ksymtable.S $(ksymtable)
\ No newline at end of file
diff --git a/lunaix-os/scripts/gather_lga.sh b/lunaix-os/scripts/gather_lga.sh
new file mode 100755 (executable)
index 0000000..12134e0
--- /dev/null
@@ -0,0 +1,70 @@
+#!/usr/bin/env bash
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+
+declare -A nm_lookup
+
+kbin="$1"
+
+nm_out=($(nm -l "${kbin}" | awk '$3 ~ /^__lga*/ {print $3 "," $4}'))
+
+for line in "${nm_out[@]}"
+do
+    parts=(${line//,/ })
+    if [ "${parts[1]}" != "" ]; then
+        path=(${parts[1]//:/ })
+        relative=$(realpath -s --relative-to="${SCRIPT_DIR}/.." "${path[0]}")
+        nm_lookup["${parts[0]}"]="${relative}"
+    fi
+done
+
+objdump_out=($(objdump -t -j .lga "${kbin}" | grep .lga | awk '!($NF ~ /_start$|_end$|_ldorder$/) {print $NF}'))
+
+list=()
+dev_list=()
+init_list=()
+sysmap_list=()
+init_prefix="lunainit_"
+sysmap_prefix="twiplugin_inits_"
+devdefs_prefix="devdefs_"
+fs_prefix="fs_"
+
+for line in "${objdump_out[@]}"
+do
+    loc=${nm_lookup["$line"]}
+    if [ "$loc" == "" ]; then
+        continue
+    fi
+    
+    type="unknown"
+    line=$(echo "$line" | awk '{ sub(/^__lga_/, ""); print }')
+
+    if [[ $line == $init_prefix* ]]; then
+        line=$(echo "$line" | awk "{ sub(/^${init_prefix}/, \"\"); print }")
+        init_list+=("$line $loc")
+        type="lunainit"
+    fi
+    
+    if [[ $line == $sysmap_prefix* ]]; then
+        line=$(echo "$line" | awk "{ sub(/^${sysmap_prefix}/, \"\"); print }")
+        sysmap_list+=("$line $loc")
+        type="twiplugin"
+    fi
+
+    if [[ $line == $fs_prefix* ]]; then
+        line=$(echo "$line" | awk "{ sub(/^${fs_prefix}/, \"\"); print }")
+        sysmap_list+=("$line $loc")
+        type="fs"
+    fi
+
+    if [[ $line == $devdefs_prefix* ]]; then
+        line=$(echo "$line" | awk "{ sub(/^${devdefs_prefix}/, \"\"); print }")
+        type="devdefs"
+    fi
+
+    line=$(echo "$line" | awk "{ sub(/_on_[a-z]+$/, \"\"); print }")
+    list+=("$line $loc")
+
+    echo "| $type | \`$line\` | $loc |"
+done
+