refactor(boot): move x86 UEFI code under arch and add agent docs entrypoint

This commit is contained in:
Microindole 2026-05-08 19:34:51 +08:00
parent 9a71252f91
commit 80a2ec024d
No known key found for this signature in database
GPG Key ID: 22FB34CD2133ACA1
7 changed files with 105 additions and 35 deletions

26
AGENTS.md Normal file
View File

@ -0,0 +1,26 @@
# Tianole Agent Guide
这个文件是仓库内 agent 文档的入口。
## 文档位置
- 正式设计、路线图、架构说明放在 `docs/`
- 面向 agent 的任务、会话记录、检查单放在 `docs/agents/`
## 工作规则
- agent 修改代码前,先确认相关正式文档是否已经存在。
- agent 修改代码后,如果改动影响了架构边界、目录结构、构建方式、阶段计划或操作流程,必须同步更新 `docs/``docs/agents/`
- 纯粹的小修复如果不改变这些信息,可以不额外补文档。
## 推荐同步范围
- 结构变化:更新 `docs/roadmap.md`
- agent 协作约定变化:更新 `docs/agents/README.md`
- 阶段性实现记录:在 `docs/agents/` 下新增对应笔记
## 当前约定
- 当前代码以“先做最小,但不把架构完全写死”为原则推进。
- `arch/` 放架构相关实现。
- `include/tianole/` 放尽量与具体架构无关的共享接口。

View File

@ -2,18 +2,27 @@ SHELL := /bin/bash
CC := clang
LD := lld-link
ARCH ?= x86_64
ifeq ($(ARCH),x86_64)
ARCH_DIR := arch/x86
EFI_ARCH_TARGET := x86_64-unknown-windows
BOOT_EFI_NAME := BOOTX64.EFI
else
$(error Unsupported ARCH '$(ARCH)')
endif
BUILD_DIR := build
EFI_DIR := $(BUILD_DIR)/image/EFI/BOOT
BOOT_EFI := $(EFI_DIR)/BOOTX64.EFI
BOOT_OBJ := $(BUILD_DIR)/boot/main.obj
BOOT_EFI := $(EFI_DIR)/$(BOOT_EFI_NAME)
BOOT_OBJ := $(BUILD_DIR)/arch/boot/main.obj
DEBUG_LOG := $(BUILD_DIR)/debug.log
OVMF_CODE ?= /usr/share/OVMF/OVMF_CODE_4M.fd
OVMF_VARS_TEMPLATE ?= /usr/share/OVMF/OVMF_VARS_4M.fd
OVMF_VARS := $(BUILD_DIR)/OVMF_VARS.fd
CFLAGS := \
-target x86_64-unknown-windows \
-target $(EFI_ARCH_TARGET) \
-ffreestanding \
-fshort-wchar \
-mno-red-zone \
@ -22,7 +31,8 @@ CFLAGS := \
-Wall \
-Wextra \
-Werror \
-Iinclude
-Iinclude \
-I$(ARCH_DIR)/include
LDFLAGS := \
/subsystem:efi_application \
@ -37,9 +47,9 @@ LDFLAGS := \
all: $(BOOT_EFI)
dirs:
mkdir -p $(BUILD_DIR)/boot $(EFI_DIR)
mkdir -p $(BUILD_DIR)/arch/boot $(EFI_DIR)
$(BOOT_OBJ): boot/main.c include/efi.h | dirs
$(BOOT_OBJ): $(ARCH_DIR)/boot/main.c $(ARCH_DIR)/include/efi.h include/tianole/boot_info.h | dirs
$(CC) $(CFLAGS) -c $< -o $@
$(BOOT_EFI): $(BOOT_OBJ) | dirs

View File

@ -1,10 +1,16 @@
#include "efi.h"
#include "tianole/boot_info.h"
static efi_char16_t banner_text[] = {
'T', 'i', 'a', 'n', 'o', 'l', 'e', ' ',
'b', 'o', 'o', 't', ' ', 's', 't', 'u',
'b', ' ', 'l', 'o', 'a', 'd', 'e', 'd',
'.', '\r', '\n', 0
'x', '8', '6', ' ', 'b', 'o', 'o', 't',
' ', 's', 't', 'u', 'b', ' ', 'l', 'o',
'a', 'd', 'e', 'd', '.', '\r', '\n', 0
};
static const tianole_boot_info_t boot_info = {
.version = TIANOLE_BOOT_INFO_VERSION,
.boot_flags = 0,
};
static inline void debug_putc(char ch) {
@ -20,11 +26,17 @@ static void debug_puts(const char *text) {
}
}
static void debug_boot_info(const tianole_boot_info_t *info) {
(void)info;
debug_puts("boot_info.version=1\n");
}
efi_status EFIAPI efi_main(efi_handle image_handle, efi_system_table_t *system_table) {
(void)image_handle;
system_table->con_out->output_string(system_table->con_out, banner_text);
debug_puts("Tianole boot stub loaded.\n");
debug_puts("Tianole x86 boot stub loaded.\n");
debug_boot_info(&boot_info);
for (;;) {
system_table->boot_services->stall(1000 * 1000);

View File

@ -1,5 +1,5 @@
#ifndef TIANOLE_EFI_H
#define TIANOLE_EFI_H
#ifndef TIANOLE_ARCH_X86_EFI_H
#define TIANOLE_ARCH_X86_EFI_H
#include <stdint.h>
@ -9,7 +9,6 @@ typedef uint16_t efi_char16_t;
typedef uint64_t efi_uintn_t;
#define EFI_SUCCESS 0
#define EFI_RESET_SHUTDOWN 2
#if defined(__x86_64__)
#define EFIAPI __attribute__((ms_abi))
@ -26,7 +25,6 @@ typedef struct {
} efi_table_header_t;
typedef struct efi_simple_text_output_protocol efi_simple_text_output_protocol_t;
typedef struct efi_runtime_services efi_runtime_services_t;
typedef struct efi_boot_services efi_boot_services_t;
struct efi_simple_text_output_protocol {
@ -37,26 +35,6 @@ struct efi_simple_text_output_protocol {
);
};
struct efi_runtime_services {
efi_table_header_t hdr;
void *get_time;
void *set_time;
void *get_wakeup_time;
void *set_wakeup_time;
void *set_virtual_address_map;
void *convert_pointer;
void *get_variable;
void *get_next_variable_name;
void *set_variable;
void *get_next_high_mono_count;
void(EFIAPI *reset_system)(
uint32_t reset_type,
efi_status reset_status,
efi_uintn_t data_size,
void *reset_data
);
};
struct efi_boot_services {
efi_table_header_t hdr;
void *raise_tpl;
@ -101,7 +79,7 @@ typedef struct {
efi_simple_text_output_protocol_t *con_out;
efi_handle standard_error_handle;
efi_simple_text_output_protocol_t *std_err;
efi_runtime_services_t *runtime_services;
void *runtime_services;
efi_boot_services_t *boot_services;
uint64_t number_of_table_entries;
void *configuration_table;

View File

@ -2,6 +2,8 @@
这个目录专门放面向 AI / agent 的项目材料,不和内核设计文档混放。
根入口文档在仓库根目录的 `AGENTS.md`
建议内容:
- `session-notes/`:实现日志和阶段结论。
@ -10,3 +12,11 @@
- `checklists/`:启动、验证、回归检查单。
正式架构决策仍然放在 `docs/`,然后在 agent 任务文档里引用它们。
当 agent 修改代码且影响下列内容时,应该同步更新这里或 `docs/`
- 架构边界
- 目录结构
- 构建方式
- 阶段计划
- 协作约定

View File

@ -157,6 +157,22 @@
- `ExitBootServices`
- 真正的内核子系统
## 当前代码组织原则
当前先不直接复制 Linux 的完整目录树,但开始采用接近 Linux 的分层方向:
- `arch/`:架构相关实现,目前只放 `x86`
- `kernel/`:未来放架构无关的内核主体
- `include/tianole/`:内核与 bootloader 共享的项目自有接口
- `docs/`:正式设计与路线图
- `docs/agents/`agent 协作文档
当前这样拆分的目的不是过早抽象,而是先把边界立住:
- `UEFI` 相关定义留在 `arch/x86/`
- 通用交接结构放在 `include/tianole/`
- 以后新增架构时,优先新增新的 `arch/<name>/`,而不是改写通用代码
## 接下来最近三个里程碑
### 里程碑 1独立 kernel 接管

View File

@ -0,0 +1,18 @@
#ifndef TIANOLE_BOOT_INFO_H
#define TIANOLE_BOOT_INFO_H
#include <stdint.h>
/*
* Boot-time handoff data owned by Tianole rather than by a specific
* firmware or architecture API. Fields can grow over time while the
* kernel entry stays stable.
*/
typedef struct {
uint32_t version;
uint32_t boot_flags;
} tianole_boot_info_t;
#define TIANOLE_BOOT_INFO_VERSION 1u
#endif