-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from xuesongbj/feat/init
feat(init): add init notes
- Loading branch information
Showing
2 changed files
with
468 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# 引导 | ||
|
||
随意编译一个可执行程序。 | ||
|
||
```go | ||
$ gdb test | ||
|
||
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 | ||
Copyright (C) 2020 Free Software Foundation, Inc. | ||
|
||
Reading symbols from test... | ||
Loading Go Runtime support. | ||
|
||
(gdb) starti | ||
Starting program: test | ||
|
||
Program stopped. | ||
_rt0_amd64_linux () at /usr/local/go/src/runtime/rt0_linux_amd64.s:8 | ||
8 JMP _rt0_amd64(SB) | ||
``` | ||
|
||
| ||
|
||
也可用 `readelf` 获取起始地址。 | ||
|
||
```go | ||
$ readelf -h ./test | ||
|
||
ELF Header: | ||
Entry point address: 0x453860 | ||
|
||
|
||
$ addr2line -e ./test -a 0x453860 | ||
|
||
/usr/local/go/src/runtime/rt0_linux_amd64.s:8 | ||
``` | ||
|
||
| ||
|
||
查看 `go/src/runtime` 目录下以汇编实现的引导过程源码。 | ||
|
||
```go | ||
// rt0_linux_amd64.s | ||
|
||
TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8 | ||
JMP _rt0_amd64(SB) | ||
``` | ||
|
||
```go | ||
// asm_amd64.s | ||
|
||
// _rt0_amd64 is common startup code for most amd64 systems when using | ||
// internal linking. This is the entry point for the program from the | ||
// kernel for an ordinary -buildmode=exe program. The stack holds the | ||
// number of arguments and the C-style argv. | ||
|
||
TEXT _rt0_amd64(SB),NOSPLIT,$-8 | ||
MOVQ 0(SP), DI // argc | ||
LEAQ 8(SP), SI // argv | ||
JMP runtime·rt0_go(SB) | ||
``` | ||
|
||
| ||
|
||
核心流程是创建 `main goroutine(runtime.main)`,并执行 `mstart` 进入调度循环。 | ||
|
||
```go | ||
TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0 | ||
|
||
CALL runtime·check(SB) | ||
|
||
CALL runtime·args(SB) | ||
CALL runtime·osinit(SB) | ||
CALL runtime·schedinit(SB) | ||
|
||
// create a new goroutine to start program | ||
MOVQ $runtime·mainPC(SB), AX // entry | ||
PUSHQ AX | ||
CALL runtime·newproc(SB) | ||
POPQ AX | ||
|
||
// start this M | ||
CALL runtime·mstart(SB) | ||
|
||
CALL runtime·abort(SB) // mstart should never return | ||
RET | ||
``` | ||
|
||
```go | ||
// mainPC is a function value for runtime.main, to be passed to newproc. | ||
|
||
DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB) | ||
GLOBL runtime·mainPC(SB),RODATA,$8 | ||
``` |
Oops, something went wrong.