본문 바로가기
개발 및 운영

UEFI development with Go-lang

by Joseph.Lee 2023. 11. 14.

tinygo 는 golang 으로 MCU 등 baremetal 펌웨어 개발을 가능하게 만들었습니다.
이런 가능성을 보고 UEFI Application 도 Go 로 만들 수 있지 않을까? 생각이 들어서 구현해봤습니다.

 

개발 브랜치 : https://github.com/jclab-joseph/tinygo/tree/feat/uefi

WIP 중인 PR : https://github.com/tinygo-org/tinygo/pull/3996

기존의 EFI 개발에는 edk2 라는 프레임워크가 있지만 사용하기가 복잡하고 다양한 라이브러리를 효과적으로 사용하기에는 어려움이 있습니다.
한 예로 얼마 전에 HttpDxe 대신 curl 을 구현하려고 했는데 LibC 종속성을 추가하면 OpenSsl 이 빌드가 안되는 등.. 문제가 있습니다.
무엇보다 C언어라는 점이 가장 큰 어려움인데..

golang 은 Java나 Node.js 등과는 달리 VM 이 필요없이 기계어로 컴파일되어 동작하는 큰 장점이 있으면서도, platform-specific 한 것들만 잘 구현해 주면 OS에 구애받지 않고 cross-platform 구현이 가능합니다.
그래서 UEFI도 가능합니다.

golang 과 C의 Call convention 은 달라서 native 함수 call 마다 별도의 래핑함수로 호출해 주는게 단점이긴 하지만 (이건 다른 OS에서도 마찬가지로 go의 syscall 을 사용해야 함) 뭐 uefi 프로토콜 관련해서 라이브러리만 잘 만들어 놓으면 쓸만할 듯 합니다.

리펙터링이나 테스트는 더 필요하지만.. 아래 동작하는 코드와 빌드 된 파일입니다:

package main

import (
        "time"
        "device/x86"
        "log"
)

func main() {
        println("HELLO")
        log.Println("InternalGetPerformanceCounterFrequency: ", x86.InternalGetPerformanceCounterFrequency())
        for {
                now := time.Now()
                log.Printf("WAIT 1 SEC: %s\r\n", now.String())
                time.Sleep(time.Second)
        }
}

 

 

main.efi
0.53MB

 

 

 

다음 프로젝트로는 UEFI 를 Exit 하지 않고 Linux 를 동작하는걸 구현해볼 생각입니다.
이게 된다면 Linux 를 UEFI BDS 처럼 동작이 가능하며 Windows도 chainload 할 수 있습니다.
저는 개인적으로 UEFI 드라이버가 부족한 환경에서 Linux 드라이버를 사용하기 위한 목적으로 개발할 예정입니다.
safeboot-loader 라는 기존의 프로젝트가 있는데 레지스터로 약간 해킹하는 방식이라 안정적이지 않은데 저는 AMP(nosmp) 를 이용해서 듀얼 코어 이상에서 UEFI와 Linux을 동시에 동작시킴으로써 구현할 예정입니다.

UEFI 에서 점유중인 디바이스를 어떻게 관리하느냐가 관건인데 safeboot-loader 처럼 UEFI Protocol 을 이용하여 사용할 것인지 아님 UEFI에서 Disconnect 해버릴 것인지 고민입니다.

Linux의 EFI함수 호출과 인터럽트 발생이 일어났을 때 동시성 처리도 문제일거 같구요.

반응형

'개발 및 운영' 카테고리의 다른 글

Intel AMT 개발 Summary  (0) 2024.02.03
pre-decompress linux kernel 디버깅  (0) 2023.11.30
메일서버 (SMAP/IMAP) 종류  (0) 2023.02.04
[임시] OpenWRT + Active Directory (AD) 구축  (0) 2022.07.12
MatterMost Webhook 설정  (0) 2022.03.04

댓글