Skip to content

Commit

Permalink
MikanOS build scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
uchan-nos committed Feb 26, 2020
1 parent 7d5d591 commit dd31c82
Show file tree
Hide file tree
Showing 18 changed files with 564 additions and 0 deletions.
128 changes: 128 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# mikanos-build

このリポジトリは uchan が開発している教育用 OS [MikanOS](https://github.com/uchan-nos/mikanos) をビルドする手順およびツールを収録しています。
Ubuntu 18.04 で動作を確認しています。

MikanOS のビルド手順は大きく次の 4 段階です。

1. ビルド環境の構築
2. MikanOS のソースコードの入手
3. ブートローダーのビルド
4. MikanOS のビルド

## ビルド環境の構築

ブートローダーおよび MikanOS 本体のビルドに必要なツールやファイルを揃えます。

### リポジトリのダウンロード

まずは Git をインストールして,mikanos-build リポジトリをダウンロードします。

$ sudo apt update
$ sudo apt install git
$ mkdir $HOME
$ git clone https://github.com/uchan-nos/mikanos-build.git osbook

### 開発ツールの導入

次に Clang,Nasm といった開発ツールや,EDK IIのセットアップを行います。
`ansible_provision.yml` に必要なツールが記載されています。
Ansible を使ってセットアップを行うと楽です。

$ sudo apt install ansible
$ cd $HOME/osbook/devenv
$ ansible-playbook -K -i ansible_inventory ansible_provision.yml

セットアップが上手くいけば `iasl` というコマンドがインストールされ,`$HOME/edk2` というディレクトリが生成されているはずです。
これらがなければセットアップが失敗しています。

$ iasl -v
$ ls $HOME/edk2

EDK II に含まれる細かいツールをビルドしておきます。

$ make -C $HOME/edk2/BaseTools/Source/C

### 標準ライブラリの入手

ビルド済みの標準ライブラリをダウンロードし展開します。

$ cd $HOME/osbook/devenv
$ wget https://github.com/uchan-nos/mikanos-build/releases/download/v1.0/x86_64-elf.tar.gz
$ tar xf x86_64-elf.tar.gz

`x86_64-elf.tar.gz` に含まれるファイルは [Newlib](https://sourceware.org/newlib/)[libc++](https://libcxx.llvm.org/) をビルドしたものです。
それらのライセンスは Newlib や libc++ のライセンスに従います。
MikanOS や mikanos-build リポジトリのライセンスとは異なりますので注意してください。

次のファイル群は Newlib 由来です。ライセンスは `x86_64-elf/LICENSE.newlib` を参照してください。

x86_64-elf/lib/
libc.a
libg.a
libm.a
x86_64-elf/include/
c++/ を除くすべて

次のファイル群は libc++ 由来です。ライセンスは `x86_64-elf/LICENSE.libcxx` を参照してください。

x86_64-elf/lib/
libc++.a
libc++abi.a
libc++experimental.a
x86_64-elf/include/c++/v1/
すべて

## MikanOS のソースコードの入手

Git で入手できます。

$ git clone https://github.com/uchan-nos/mikanos.git

## ブートローダーのビルド

EDK II のディレクトリに MikanOS ブートローダーのディレクトリをリンクします。

$ cd $HOME/edk2
$ ln -s /path/to/mikanos/MikanLoaderPkg ./

ブートローダーのソースコードが正しく見えればリンク成功です。

$ ls MikanLoaderPkg/Main.c

次に,`edksetup.sh` を読み込むことで EDK II のビルドに必要な環境変数を設定します。

$ source edksetup.sh

`edksetup.sh` ファイルを読み込むと,環境変数が設定される他に `Conf/target.txt` が自動的に生成されます。
このファイルをエディタで開き,次の項目を修正します。

| 設定項目 | 設定値 |
|-----------------|-----------------------------------|
| ACTIVE_PLATFORM | MikanLoaderPkg/MikanLoaderPkg.dsc |
| TARGET | DEBUG |
| TARGET_ARCH | X64 |
| TOOL_CHAIN_TAG | CLANG38 |

設定が終わったらブートローダーをビルドします。

$ build

Loader.efi ファイルが出力されていればビルド成功です。

$ ls Build/MikanLoaderX64/DEBUG_CLANG38/X64/Loader.efi

## MikanOS のビルド

ビルドに必要な環境変数を読み込みます。

$ source $HOME/osbook/devenv/buildenv.sh

ビルドします。

$ cd /path/to/mikanos/kernel
$ ./build.sh

QEMU で起動するには `./build.sh``run` オプションを指定します。

$ ./build.sh run
3 changes: 3 additions & 0 deletions devenv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vagrant
*.retry
*.log
Binary file added devenv/OVMF_CODE.fd
Binary file not shown.
Binary file added devenv/OVMF_VARS.fd
Binary file not shown.
77 changes: 77 additions & 0 deletions devenv/Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.

# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "bento/ubuntu-18.04"

# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10"

# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"

# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
config.vm.synced_folder "..", "/home/vagrant/osbook_ro", :mount_options => ["ro"]

# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.

# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL

config.vm.provision "ansible_local" do |ansible|
ansible.playbook = "ansible_provision.yml"
ansible.inventory_path = "ansible_inventory"
end

config.ssh.forward_x11 = true
end
2 changes: 2 additions & 0 deletions devenv/ansible_inventory
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[default]
localhost ansible_connection=local
82 changes: 82 additions & 0 deletions devenv/ansible_provision.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
- hosts: all
tasks:
- name: ensure development tools are at the latest version
become: yes
apt: name={{ item }} state=latest install_recommends=no
with_items:
- make
- llvm-7-dev
- lld-7
- clang-7
- nasm
- acpica-tools
- uuid-dev
- qemu
- xauth
- unzip

- name: set llvm 7 as default
become: yes
alternatives:
name: "{{ item }}"
link: "/usr/bin/{{ item }}"
path: "/usr/bin/{{ item }}-7"
with_items:
- llvm-PerfectShuffle
- llvm-ar
- llvm-as
- llvm-bcanalyzer
- llvm-cat
- llvm-cfi-verify
- llvm-config
- llvm-cov
- llvm-c-test
- llvm-cvtres
- llvm-cxxdump
- llvm-cxxfilt
- llvm-diff
- llvm-dis
- llvm-dlltool
- llvm-dwarfdump
- llvm-dwp
- llvm-exegesis
- llvm-extract
- llvm-lib
- llvm-link
- llvm-lto
- llvm-lto2
- llvm-mc
- llvm-mca
- llvm-modextract
- llvm-mt
- llvm-nm
- llvm-objcopy
- llvm-objdump
- llvm-opt-report
- llvm-pdbutil
- llvm-profdata
- llvm-ranlib
- llvm-rc
- llvm-readelf
- llvm-readobj
- llvm-rtdyld
- llvm-size
- llvm-split
- llvm-stress
- llvm-strings
- llvm-strip
- llvm-symbolizer
- llvm-tblgen
- llvm-undname
- llvm-xray
- ld.lld
- lld-link
- clang
- clang++
- clang-cpp

- name: clone EDK II repository
git:
repo: "https://github.com/tianocore/edk2.git"
dest: "{{ ansible_env.HOME }}/edk2"
21 changes: 21 additions & 0 deletions devenv/build-edk2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash -ex

cd $HOME
if [ ! -d edk2 ]
then
git clone https://github.com/tianocore/edk2.git
fi

cd edk2

make -C /home/vagrant/edk2/BaseTools/Source/C

source ./edksetup.sh

sed -i '/ACTIVE_PLATFORM/ s:= .*$:= OvmfPkg/OvmfPkgX64.dsc:' Conf/target.txt
sed -i '/TARGET_ARCH/ s:= .*$:= X64:' Conf/target.txt
sed -i '/TOOL_CHAIN_TAG/ s:= .*$:= CLANG38:' Conf/target.txt

sed -i '/CLANG38/ s/-flto//' Conf/tools_def.txt

build
5 changes: 5 additions & 0 deletions devenv/buildenv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Usage: source buildenv.sh

BASEDIR="$HOME/osbook/devenv/x86_64-elf"
export CPPFLAGS="-I$BASEDIR/include/c++/v1 -I$BASEDIR/include -nostdlibinc -D__ELF__ -D_LDBL_EQ_DBL -D_GNU_SOURCE -D_POSIX_TIMERS"
export LDFLAGS="-L$BASEDIR/lib"
33 changes: 33 additions & 0 deletions devenv/make_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh -ex

if [ $# -lt 3 ]
then
echo "Usage: $0 <image name> <mount point> <.efi file> [another file]"
exit 1
fi

DEVENV_DIR=$(dirname "$0")
DISK_IMG=$1
MOUNT_POINT=$2
EFI_FILE=$3
ANOTHER_FILE=$4

if [ ! -f $EFI_FILE ]
then
echo "No such file: $EFI_FILE"
exit 1
fi

rm -f $DISK_IMG
qemu-img create -f raw $DISK_IMG 200M
mkfs.fat -n 'MIKAN OS' -s 2 -f 2 -R 32 -F 32 $DISK_IMG

$DEVENV_DIR/mount_image.sh $DISK_IMG $MOUNT_POINT
sudo mkdir -p $MOUNT_POINT/EFI/BOOT
sudo cp $EFI_FILE $MOUNT_POINT/EFI/BOOT/BOOTX64.EFI
if [ "$ANOTHER_FILE" != "" ]
then
sudo cp $ANOTHER_FILE $MOUNT_POINT/
fi
sleep 0.5
sudo umount $MOUNT_POINT
20 changes: 20 additions & 0 deletions devenv/mount_image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh -ex

if [ $# -lt 2 ]
then
echo "Usage: $0 <image name> <mount point>"
exit 1
fi

DEVENV_DIR=$(dirname "$0")
DISK_IMG=$1
MOUNT_POINT=$2

if [ ! -f $DISK_IMG ]
then
echo "No such file: $DISK_IMG"
exit 1
fi

mkdir -p $MOUNT_POINT
sudo mount -o loop $DISK_IMG $MOUNT_POINT
Loading

0 comments on commit dd31c82

Please sign in to comment.