gllvm/examples/linux-kernel/README.md

173 lines
4.7 KiB
Markdown
Raw Normal View History

2018-04-30 19:42:25 +02:00
# Building a recent Linux Kernel.
In this directory we include all the necessary files needed to
build the kernel in a Ubuntu 16.04 vagrant box. We will guide the reader through
2018-05-02 22:07:16 +02:00
the relatively simple task. We assume familiarity with [Vagrant.](https://www.vagrantup.com/)
2018-04-30 19:42:25 +02:00
## Vagrantfile
2018-04-30 22:47:38 +02:00
```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.provision :shell, path: "bootstrap.sh"
config.vm.provider "virtualbox" do |vb|
vb.memory = "4096"
vb.customize ["modifyvm", :id, "--ioapic", "on"]
vb.customize ["modifyvm", :id, "--memory", "4096"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
```
2018-04-30 19:42:25 +02:00
## Bootstrapping
2018-04-30 22:47:38 +02:00
```bash
#!/usr/bin/env bash
2018-05-07 18:41:38 +02:00
# vagrant bootstrapping file
sudo apt-get update
sudo apt-get install -y emacs24 dbus-x11
sudo apt-get install -y git
sudo apt-get install -y llvm-5.0 libclang-5.0-dev clang-5.0
sudo apt-get install -y python-pip golang-go
sudo apt-get install -y flex bison bc libncurses5-dev
sudo apt-get install -y libelf-dev libssl-dev
echo ". /vagrant/bash_profile" >> /home/vagrant/.bashrc
bash /vagrant/init_script.sh
```
2018-05-01 01:43:08 +02:00
## Shell Settings
```bash
2018-05-07 18:41:38 +02:00
#### /vagrant/bash_profile
2018-05-01 01:43:08 +02:00
#### llvm
export LLVM_HOME=/usr/lib/llvm-5.0
export GOPATH=/vagrant/go
######## gllvm/wllvm configuration #############
export LLVM_COMPILER=clang
export WLLVM_OUTPUT_LEVEL=WARNING
export WLLVM_OUTPUT_FILE=/vagrant/wrapper.log
export PATH=${GOPATH}/bin:${LLVM_HOME}/bin:${PATH}
2018-05-01 01:43:08 +02:00
```
2018-04-30 19:42:25 +02:00
## Configuration stuff.
2018-05-07 18:56:48 +02:00
The file [`tinyconfig64`](https://github.com/SRI-CSL/gllvm/blob/master/examples/linux-kernel/tinyconfig64) is generated
2018-05-07 18:58:38 +02:00
by `make tinyconfig` and then using `make menuconfig` to specialize the build to 64 bits.
2018-05-07 18:41:38 +02:00
## The Tarball Build with gllvm
2018-04-30 19:42:25 +02:00
The build process is carried out by running the `build_linux_gllvm_tarball.sh`
script.
2018-04-30 22:47:38 +02:00
```bash
#!/usr/bin/env bash
2018-05-07 18:41:38 +02:00
### building from a tarball with gllvm
go get github.com/SRI-CSL/gllvm/cmd/...
2018-05-07 18:41:38 +02:00
cd ${HOME}
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.14.39.tar.xz
tar xvf linux-4.14.39.tar.xz
cd linux-4.14.39
cp /vagrant/tinyconfig64 .config
make CC=gclang HOSTCC=gclang
get-bc -m -b built-in.o
get-bc -m vmlinux
```
2018-05-07 18:41:38 +02:00
## The Tarball Build with wllvm
The build process is carried out by running the `build_linux_wllvm.sh`
script.
```bash
#!/usr/bin/env bash
2018-05-07 18:41:38 +02:00
### building from a tarball with wllvm
sudo pip install wllvm
2018-05-07 18:41:38 +02:00
cd ${HOME}
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.14.39.tar.xz
tar xvf linux-4.14.39.tar.xz
cd linux-4.14.39
cp /vagrant/tinyconfig64 .config
make CC=wllvm HOSTCC=wllvm
extract-bc -m -b built-in.o
extract-bc -m vmlinux
```
2018-05-07 20:34:36 +02:00
## Comparing the two
`gclang` build:
```
real 2m55.689s
user 4m10.036s
sys 0m34.780s
```
`wllvm` build:
```
real 6m52.443s
user 4m32.124s
sys 0m44.072s
```
2018-05-07 18:41:38 +02:00
## Building from a git clone
You can also build from a [git clone using gllvm,](https://github.com/SRI-CSL/gllvm/blob/master/examples/linux-kernel/build_linux_gllvm_git.sh)
or build from a [git clone using wllvm.](https://github.com/SRI-CSL/gllvm/blob/master/examples/linux-kernel/build_linux_wllvm_git.sh)
Though using a tarball is faster, and seemingly more reliable.
# Building a bootable kernel from bitcode
The init_script.sh script will build a bootable kernel from mostly bitcode (drivers and ext4 file system are currently not translated).
## Building the kernel with gclang
The init script will build the required folder architecture for the build and call build_linux_gllvm, only this time with a default configuration instead of tinyconfig.
## Building the kernel from bitcode
The copy.sh script will then extract the bitcode from the archives in the linux build folder, and copy them along with necessary object files (the files compiled straight from assembly will not emit a bitcode file).
It will then call the link command on those files and generate a vmlinux executable containing the kernel.
## Booting on the generated kernel
The gclang build of the kernel adds llvm_bc headers to most files, and those mess with the generation of a compressed bootable kernel.
We need to have a separate folder built form clang or gcc on which to finish the kernel build and install.
That is the purpose of the bootable-kernel script.
Finally, calling the install-kernel script will copy the new kernel into the clang generated folder and finish the build and install. Rebooting will be on the bitcode kernel.
NB: The generated kernel boots properly but it may be buggy. Most notably, I have experienced issues when shutting down and booting the machine a second time.