Операционная система на Go?

Теперь даже такое возможно! Попробуем?

Собираем Go

В языке Go появился недавно новый режим runtime. Называется он tiny. Фактически, это минимально возможный рантайм для работы с «голым» железом. Сейчас есть версии для i386 и для arm. Конечно, второй кажется более вкусным, но мы начнем с первого — его хотя бы будет на чем проверить.

На всякий случай напомню, что рантайм — это та часть языка Go, которая позволяет ему работать с системными вызовами (чтение/запись, работа с памятью) на самом низком уровне. Сейчас в язык входят различные рантаймы — для linux/freebsd/darwin/windows/plan9, для 386/amd64/arm. Есть еще для Native Client.

Все они в отличие от tiny используют функции низлежащей ОС, в то время как tiny работает непосредственно с аппаратной частью.

Начинаем подготовку со сборки обычного Go для linux/i386.  Для этого я развернул еще один репозиторий в отдельной папке, чтобы ниче не напортить в основном репозитории.

Собрали? А теперь модифицируем и пересобираем рантайм.

export GOOS=tiny
cd $GOROOT/src/pkg/runtime
make clean && make install

Теперь можно заглянуть в папку tiny. Там есть особый файлик — bootblock. Это загрузчик для наших «tiny» программ (512 загрузочных байт). Он нам еще пригодится, можете скопировать его в вашу рабочую папку.

Пишем простую программу

Писать особо нечего, т.к. из всех функций языка нам доступен только `print();`
Ну и конечно, все базовые конструкции — массивы, слайсы, go-routines, каналы и т.д.

package main

var quit = make(chan int)

// Делаем визуальную задержку
func delay() {
	for i := 0; i < 1000000; i++ {
		for j := 0; j < 100; j++ {
		}
	}
}

// Выводит числа Фиббоначчи
func printFibonacci() {
	var f1, f0 = 1, 0
	for {
		print(f0, " ")
		delay()
		tmp := f1
		f1 = f1 + f0
		f0 = tmp
	}
}

func main() {
	print("Booting....\n")
	go printFibonacci()
	<-quit } 

Собираем эту программу (обойдемся без makefile):

8g demo.go && 8l -a demo.8 > demo.asm && 8l demo.8

У меня линковщик ругнулся на неопределенный signame() — пришлось закомментировать эту строчку в исходниках рантайма и пересобрать его 🙂 (проблема была в файле `sigqueue.goc`). Надеюсь, скоро пофиксят.

Итак, получаем бинарник 8.out в 170 килобайт и гору ассемблерного листинга в demo.asm. Судя по всему, 8.out — это ELF binary. Я даже его запустить попробовал — не работает.

Запускаем

Подготовим образ диска:

dd if=/dev/zero of=disk count=10000
cat bootblock 8.out | dd of=disk conv=notrunc
# Если пользуемся виртуалбоксом - то
# VBoxManage convertfromraw disk go-tiny.vdi

Теперь мы получили пятиметровый виртуальный диск с нашей ОС. Смело создаем виртуальную машину и подключаем этот диск. На VirtualBox все мои труды потерпели крах — я так и не смог понять как быстро подменять диск, да и писал он на экран какую-то фигню в итоге.

Но зато qemu меня порадовал. У меня в итоге получилось вот такое:

Go tiny runtime example in qemu

Выводы

На мой взгляд, Go развивается в правильном направлении. Для embedded систем средней сложности такой язык более пригоден, чем тот же C++. К сожалению большие размеры бинарников отпугивают. Поглядим, что преподнесет нам gccgo с tiny runtime — там, я надеюсь, оптимизация посильнее будет.

То, что в язык изначально заложена хорошая поддержка arm, работа с потоками, каналами, динамической памятью делает ненужными применение каких-либо RTOS. Так что, может быть размер в 170 кб и оправдан. Программа работает при 4 Мб ОЗУ (правда, я надеялся, что и при двух мегабайтах будет — не вышло, культурно заявила о проблемах с malloc()).

Короче, в целом впечатления хорошие. Если кто попробует tiny runtime на arm — отпишитесь, пожалуйста!

P.S. А еще я пробовал собрать Chromium OS. Об этом тоже расскажу немного 😉

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s