github.com/jspc/eggos@v0.5.1-0.20221028160421-556c75c878a5/docs/internal.md (about) 1 # The process of starting the program 2 3 Take GOOS=linux GOARCH=386 as an example, the normal go program uses `_rt0_386_linux` in `runtime/rt0_linux_386.s` as the entrance of the whole program 4 5 Since go assumes that it is running on Linux, and we are running on bare metal, a simple hardware initialization is required before starting the runtime of go. We need to modify the entry address of the go program and redirect it to our own entry function `kernel.rt0`. 6 7 Basic initialization actions are performed in our own entry function, such as `gdt`, `thread`, `memory`, etc. At the end of initialization, the thread scheduler will be started, and the thread scheduler will then schedule `thread0`, the real go The runtime entry is called in thread0, and then the real go runtime initialization operation starts. 8 9 # Memory layout 10 11 ``` 12 .------------------------------------------. 13 | Virtual memory(managed by go runtime) | 14 :------------------------------------------: 1GB 15 | ........ | 16 :------------------------------------------: memtop(256MB or more) 17 | Physical memory(managed by eggos kernel) | 18 :------------------------------------------: 20MB 19 | Kernel image | 20 :------------------------------------------: 1MB 21 | Unused | 22 '------------------------------------------' 0 23 ``` 24 25 The first 1KB of memory is not page-mapped, and the subsequent memory until `memtop` is a direct mapping from virtual memory to physical memory. 26 27 The virtual address space available for go runtime starts from 1GB, and it manages the virtual address space itself, so what the kernel does is allocate physical pages according to the mmap system call of go runtime and map them to virtual memory. 28 29 30 # Trap 31 32 # Syscall