Skip to content

Commit c6f332d

Browse files
committed
docs: a freestanding target does have main when a board package supplies crt0
docs/05 §2.7.2 told the reader there is no `main` on a bare-metal target and to point the target at a file carrying `_start`. That is only true for a board with no C library at all — with picolibc's semihosting crt0, which is what a board-support package ships, the entry point is an ordinary `int main()` whose return value reaches the host. Also leads the section with the short path (`mcpp new blinky --template riscv-virt-rt`), since the hand-written form below it is what to reach for when writing a package for a board that has none — not what to start with.
1 parent d93d228 commit c6f332d

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

‎docs/05-mcpp-toml.md‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,14 +909,30 @@ mcpp build --target riscv64-none-elf
909909
mcpp run --target riscv64-none-elf # via [target.<triple>].runner
910910
```
911911

912+
**Starting from a board package**
913+
914+
Almost nothing below has to be written by hand. A board-support package carries
915+
the C library, the startup code, the memory layout and the emulator, so the
916+
shortest path to a booting image is:
917+
918+
```bash
919+
mcpp new blinky --template riscv-virt-rt
920+
cd blinky && mcpp run
921+
```
922+
923+
The generated manifest names no linker script, load address, libc or emulator —
924+
it has no `[target.*]` section at all. The rest of this section describes what
925+
such a package supplies, which is what to reach for when writing one for a board
926+
that has none.
927+
912928
**What changes on a freestanding target**
913929

914930
| | |
915931
|---|---|
916932
| Link line | `-nostdlib -nostartfiles -static`, and nothing hosted — no crt files, no dynamic linker, no C++ runtime. The linker is addressed by **absolute path** (`-fuse-ld=<payload>/bin/ld.lld`), because `-fuse-ld=lld` resolves through `PATH` and finds GNU ld on any machine with binutils earlier on it. |
917933
| ISA flags | `-march` / `-mabi` / `-mcmodel` come from the target table, so `--target <triple>` alone is enough to produce a correct object file. |
918934
| `import std` | **Unavailable.** `std` is one module over the entire library — threads, filesystem and iostreams included — so there is no subset of it to build without an OS. The freestanding subset package replaces it, and mcpp's diagnostic names it. |
919-
| Entry point | There is no `main`. Declare the target explicitly and point `main` at the file carrying `_start`. |
935+
| Entry point | `int main()` works **as long as something supplies a `crt0`** — a board package normally does, and then a firmware's entry point is an ordinary `main` whose return value reaches the host through semihosting. Only a zero-libc board needs an explicit target whose `main` points at the file carrying `_start`. |
920936

921937
**A minimal firmware**
922938

‎docs/zh/05-mcpp-toml.md‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,14 +807,28 @@ mcpp build --target riscv64-none-elf
807807
mcpp run --target riscv64-none-elf # 经 [target.<triple>].runner
808808
```
809809

810+
**从板级支持包起步**
811+
812+
下面这些几乎都不需要手写。板级支持包(BSP)自带 C 库、启动代码、内存布局和模拟器,
813+
所以跑起一个镜像的最短路径是:
814+
815+
```bash
816+
mcpp new blinky --template riscv-virt-rt
817+
cd blinky && mcpp run
818+
```
819+
820+
生成的 manifest 里没有链接脚本、没有加载地址、没有 libc、没有模拟器 —— 连
821+
`[target.*]` 段都没有。本节余下的内容讲的是**这样一个包提供了什么**,也就是要给
822+
一块还没有 BSP 的板子写一个时该照着做什么。
823+
810824
**freestanding target 上有什么不同**
811825

812826
| | |
813827
|---|---|
814828
| 链接线 | `-nostdlib -nostartfiles -static`,且不带任何 hosted 的东西 —— 没有 crt 文件、没有动态链接器、没有 C++ 运行时。链接器用**绝对路径**寻址(`-fuse-ld=<载荷>/bin/ld.lld`),因为 `-fuse-ld=lld` 走 `PATH` 解析,在任何 binutils 排前面的机器上都会找到 GNU ld。 |
815829
| ISA flag | `-march` / `-mabi` / `-mcmodel` 来自 target 表,所以只写 `--target <triple>` 就足以产出正确的目标文件。 |
816830
| `import std` | **不可用。** `std` 是覆盖整个库的一个模块 —— 线程、文件系统、iostreams 全在内 —— 没有 OS 就没有它的子集可编。freestanding 子集包取代它,mcpp 的诊断会点名。 |
817-
| 入口点 | 没有 `main`。显式声明 target,并把 `main` 指向携带 `_start` 的那个文件。 |
831+
| 入口点 | **只要有人提供 `crt0`,`int main()` 就能用** —— 板级支持包通常就提供它,于是固件的入口就是普通的 `main`,它的返回值经 semihosting 传回宿主。**只有零 libc 的板子**才需要显式声明 target 并把 `main` 指向携带 `_start` 的那个文件。 |
818832

819833
**一个最小固件**
820834

0 commit comments

Comments
 (0)