# Bulid FEMU
###### tags: `FEMU`
https://github.com/vtess/FEMU
## Step 1
```bash=
$ git clone https://github.com/vtess/femu.git
$ cd femu
$ mkdir build-femu
# Switch to the FEMU building directory
$ cd build-femu
# Copy femu script
$ cp ../femu-scripts/femu-copy-scripts.sh .
./femu-copy-scripts.sh .
# only Debian/Ubuntu based distributions supported
$ sudo ./pkgdep.sh
```
## Step 2
```bash=
# compile & install FEMU
$ ./femu-compile.sh
```
## Step 3
Using this method if you want to use your personal kernel
```bash=
# Download a Ubuntu server ISO file
# You can choose every where you want to build the images
$ mkdir -p ~/images/
$ cd ~/images
$ wget http://releases.ubuntu.com/22.04/ubuntu-22.04.2-live-server-amd64.iso
$ sudo apt-get install qemu-system-x86
# Create a QCOW2 disk image(suggest size 120G)
$ qemu-img create -f qcow2 femu.qcow2 80G
# install guest OS to femu.qcow2 (You need a GUI environment to prepare the VM image)
# select the 22.04 because the 20.04 to compile the 5.10.83 kernel version will get many error
# the .iso path is decided where you downloaded
$ qemu-system-x86_64 -cdrom ubuntu-22.04.2-live-server-amd64.iso -hda femu.qcow2 -boot d -net nic -net user -m 8192 -smp 8 -cpu host -enable-kvm
```
## Step 4
When you finish the previous step, you will see a *QEMU* interface and install *Ubuntu*.
After reboot the kernel and then close the *QEMU* interface.
```bash=
# the disk images is up to your create path
$ qemu-system-x86_64 -hda ../../images/femu.qcow2 -net nic -net user -m 8192 -smp 8 -cpu host -enable-kvm
```
Editing ```/etc/default/grub``` setting.
```bash=
GRUB_CMDLINE_LINUX="ip=dhcp console=ttyS0,115200 console=tty console=ttyS0"
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
```
Update the GRUB
```bash=
$ sudo update-grub
$ sudo shutdown -h now
```
## Step 5
Create a *.sh file*(or *run-blackbox.sh*) and copy the following *Shell Script* in the ```build-femu``` folder.

```bash=
# !/bin/bash
# Huaicheng Li <huaicheng@cs.uchicago.edu>
# Run FEMU as a black-box SSD (FTL managed by the device)
# image directory
IMGDIR=/img
# Virtual machine disk image
OSIMGF=/home/shen/Desktop/images/femu2.qcow2
if [[ ! -e "$OSIMGF" ]]; then
echo ""
echo "VM disk image couldn't be found ..."
echo "Please prepare a usable VM image and place it as $OSIMGF"
echo "Once VM disk image is ready, please rerun this script again"
echo ""
exit
fi
sudo x86_64-softmmu/qemu-system-x86_64 \
-name "FEMU-BBSSD-VM" \
-enable-kvm \
-cpu host \
-smp 4 \
-m 8G \
-device virtio-scsi-pci,id=scsi0 \
-device scsi-hd,drive=hd0 \
-drive file=$OSIMGF,if=none,aio=native,cache=none,format=qcow2,id=hd0 \
-device femu,devsz_mb=4096,femu_mode=1 \
-net user,hostfwd=tcp::8080-:22 \
-serial stdio \
-net nic,model=virtio \
-nographic \
-qmp unix:./qmp-sock,server,nowait 2>&1 | tee log
```
Be careful the ```OSIMGF``` path and the ```-drive format=```*disk images file category*.
```-smp 4``` *threads count*.
```-m 8G``` *memory size*.
```-device devsz_mb=4096``` *simulate SSD size*.
## Step 6
### Option 1 (compile in the VM)
Using [sftp](https://www.man7.org/linux/man-pages/man1/sftp.1.html) or [git](https://git-scm.com/docs/git) to get the personal kernel folder.
Install some package to help compile kernel.
```bash=
$ cp /boot/config-$(uname -r) .config
```
```bash=
$ make
```
```bash=
$ make modules_install
```
```bash=
$ make install
```
```bash=
$ update-grub
```
```bash=
$ reboot
# press the F4 to the GRUB select interface.
```
### Option 2 (compile in the Host)
<font color = "red">Check Host and VM ```gcc``` version are the same.</font>
This method will be faster than **Option 1**.
If you want to use ```sftp```, check your Host support ```ssh``` service or use your own method to get the file/directory.
The much imformation of ```sftp``` below the [Suggest Useful Tool](<#Suggest Useful Tool>).
```bash=
# copy the VM .config
$ cp /boot/config-$(uname -r) .config
# use sftp to get the VM .config.
$ sftp > put -r foldername
```
<font color = "green">Host :</font>
Make on the Host.
```bash=
$ make
```
<font color = "green">VM :</font>
Get the host compile kernel and install the kernel on the VM.
```bash=
# get the Host compiled kernel
$ sftp > get -r remoteDirectory
$ make modules_install
```
```bash=
$ make install
```
```bash=
$ update-grub
```
```bash=
$ reboot
# press the F4 to the GRUB select interface.
```
## Step 7
Checking the kernel version and the *FEMU* simulating NVMe device.

## Suggest Useful Tool
[ccache](http://linuxdeveloper.blogspot.com/2012/05/using-ccache-to-speed-up-kernel.html) - This tool can improve the kernel compile speed.
[sftp](https://www.man7.org/linux/man-pages/man1/sftp.1.html) - base on the ```ssh``` service, can get or put your file/directory.
```bash=
# connect to the Host
$ sftp user_name@remote_server_address
# get the full folder to the VM
$ sftp> get -r remoteDirectory
# put the full folder to the Host
$ sftp> put -r folderName
```

<font color = "red">Get the IP address command</font>
```bash=
$ ip ad
```