Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Porting Golang Runtime To Baremetal

Porting Golang Runtime To Baremetal

Analyze biscuit and get to know how to porting golang runtime to baremetal

morimolymoly

March 10, 2019
Tweet

More Decks by morimolymoly

Other Decks in Programming

Transcript

  1. WHO AM I ❖ I am morimolymoly a.k.a GNM ❖

    Interests ❖ InfoSec ❖ Hypervisor ❖ Aikatsu! ❖ Details available at morimolymoly.com * GNM means “ήΩΧϫͶ͜ΈΈϝΠυ”. It sound better right?
  2. mit-pdos/biscuit ❖ POSIX compatible kernel written in Golang ❖ Secure,

    fast, USEFUL FEATURES(channels, interface, goroutine, etc…) ❖ 4-Components ❖ Bootloader(C, asm) + Kernel(Golang) + Go runtime(Golang, C, asm) + UserProgram(C) ❖ You can utilize goroutine, memory safety, etc … IN KERNEL LAND!
  3. Golang Runtime ❖ Runtime do initialization and goroutine stuff. ❖

    Kernel loads Go program into memory and call initialize function of Golang Runtime.(For Linux, ELF header’s entrypoint defines it) ❖ Initialization stage is huge. ❖ Init goroutine ❖ Get args passed by OS ❖ Init scheduler(stack, mm, GC, etc…) ❖ Runtime needs kernel!
  4. Without kernel ❖ Who loads Go Runtime? ❖ Write some

    bootloader to load runtime!(Runtime loads kernel main function) ❖ How initialize goroutine, memory, some low level stuff(Interrupt, I/O)? ❖ Replace system call with own system call ❖ Get memory map from BIOS and set it. ❖ WRITE LOW LEVEL CODE IN ASSEMBLY(ಀ͛ͪΌͩΊͩ)
  5. Boot Sequence BIOS Bootloader Runtime Biscuit ❖ Runtime and Biscuit

    build actual KERNEL ❖ BIOS gives primitive services(PS/2 Keyboard and Mouse, Serial, VGA, get memory map) to KERNEL Boot sector:0x00007c00
  6. Minimize Biscuit code and analyze it ❖ Biscuit forked golang:1.4(Above

    golang:1.5, most of runtime code is written in Go rather than C) ❖ You can see commits related to biscuit by command below ❖ git log --author="Cody Cutler" —reverse ❖ I forked and minimzed biscuit ❖ https://github.com/morimolymoly/biscuit ❖ I focused on commits before c14beb90191e74163c20c48596a5eed576fbc664(It is so primitive but there is goroutine, interface, collections…)
  7. Important Modified files under `src/runtime` ❖ src/runtime/asm_amd64.s - register ops(rdmsr,

    invlpg, change CRx), in/out, ❖ src/runtime/os_linux.c - system call implementation ❖ src/runtime/rt0_linux_amd64.s - entrypoint code ❖ src/runtime/sys_linux_amd64.s - runtime syscall wrapper
  8. Detail of runtime initialization ❖ Makefile makes main.gobin which is

    ELF binary from kernel code ❖ biscuit/kernel/chentry.c changes entrypoint of main.gobin to _rt0_hack ❖ _rt0_hack is like a _rt0_amd64_linux which is used when you launch Go program in Linux AMD64 arch ❖ _rt0_hack calls runtime·rt0_go_hack in src/runtime/asm_amd64.s ❖ runtime·rt0_go_hack init segment, interrupt, syscall table, first goroutine
  9. goroutine on Baremetal ❖ goroutine = Kernel Thread ❖ Kenel’s

    main function is also goroutine(created by runtime·newproc in rt0_go_hack) ❖ After setting up Virtual Memory(Paging, Segment), you can free to fire it! ❖ Set M(Machine), P(Processor) up.(M(Machine) and P is used in Golang runtime internal)
  10. Conclusion ❖ Sorry for ultra fast tour! ❖ HLL gives

    us new perspective of next generation Operating System ❖ e.g. Keyboard driver uses goroutine in biscuit ❖ Reading runtime is absolutely fun!(Try it ! Fork and read it for free!) ❖ Read code and hack it!
  11. References ❖ Cody Cutler, M. Frans Kaashoek, and Robert T.

    Morris. “The benefits and costs of writing a POSIX kernel in a high-level language”. In: 13th USENIX Symposium on Operating Systems Design and Implementation (OSDI 18). ❖ Yoshiki Shibukawa, “Biscuit Code Reading”. In: GoCon2018 Autumn ❖ Achilleas Anagnostopoulos, “Bare Metal Gophers: can you write an OS Kernel in Go?”. In: GolangUK2017