First Run!
In order to run the docker image, you will simply do:
~/Downloads/pcs3746-sistemas-operacionais/1$ ./run.sh
You will see a lot of messages corresponding to the code in init.c.
run.sh put the docker image to run as in:
docker run -ti --rm -v "$PWD/linux":/home/student/src/linux -v "$PWD/initramfs":/home/student/src/initramfs tiagoshibata/pcs3746
The -v "$PWD/linux":/home/student/src/linux means:
it attaches the $PWD/Linux that is in your machine to /home/student/src/linux inside the docker container where $PWD means the working directory. In our case: ~/Downloads/pcs3746-sistemas-operacionais/1
This attachment is really very important because it is how you communicate with the docker. It means that a docker image may write something in /home/student/src/linux and you get it on ~/Downloads/pcs3746-sistemas-operacionais/1/linux.
The same goes to the initramfs.
This docker image raises ubuntu 16.4, makes the linux kernel, makes the rootfs (contains init) and runs qemu above it.
In the Dockerfile (~/Downloads/pcs3746-sistemas-operacionais/1/docker/Dockerfile) you see that it builds everything upon ubuntu 16.4, gets the proper packages (ex: tool chain), and ends with:
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/default_cmd.sh"]
The Makefile that generates rootfs is:
CC=$(CROSS_COMPILE)gcc -Wall -Wextra -static -g
$(shell mkdir -p build/initramfs_root)
.PHONY: all clean
all: build/rootfs.gz
clean:
rm -rf build
find -name '*.o' -delete
build/rootfs.gz: build/initramfs_root/init build/initramfs_root/stack_pop build/initramfs_root/stack_push
cd build/initramfs_root ; \
find -type f -print0 | cpio -0 -ov -H newc | gzip -9 > ../rootfs.gz
build/initramfs_root/init: init.o
$(CC) -o $@ $^
build/initramfs_root/stack_push: stack_push.o
$(CC) -o $@ $^
build/initramfs_root/stack_pop: stack_pop.o
$(CC) -o $@ $^
Basically, it compiles the init.c and inserts it in the rootfs.gz file using the cpio command.
qemu may also run with gdb; more specifically with:
arm-none-eabi-gdb -ex '\''target remote:1234'\'' /home/student/src/linux/vmlinux
In this case, the gdb (gnu debugger) connects to the qemu and controls it.
You may give commands to the qemu from gdb; but let us first see how it may become possible.
~/Downloads/pcs3746-sistemas-operacionais/1/initramfs$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b18bb9eb0a2 tiagoshibata/pcs3746 "/entrypoint.sh /def…" 2 minutes ago Up 2 minutes cranky_lewin
jk@jk-desktop:~/Downloads/pcs3746-sistemas-operacionais/1/initramfs$ docker kill cranky_lewin
cranky_lewin
~/Downloads/pcs3746-sistemas-operacionais/1$ ./run.sh
You will see a lot of messages corresponding to the code in init.c.
run.sh put the docker image to run as in:
docker run -ti --rm -v "$PWD/linux":/home/student/src/linux -v "$PWD/initramfs":/home/student/src/initramfs tiagoshibata/pcs3746
The -v "$PWD/linux":/home/student/src/linux means:
it attaches the $PWD/Linux that is in your machine to /home/student/src/linux inside the docker container where $PWD means the working directory. In our case: ~/Downloads/pcs3746-sistemas-operacionais/1
This attachment is really very important because it is how you communicate with the docker. It means that a docker image may write something in /home/student/src/linux and you get it on ~/Downloads/pcs3746-sistemas-operacionais/1/linux.
The same goes to the initramfs.
This docker image raises ubuntu 16.4, makes the linux kernel, makes the rootfs (contains init) and runs qemu above it.
How the docker image is built?
In order to make any update, for instance changing the init process, you must carefully understand how it is made.In the Dockerfile (~/Downloads/pcs3746-sistemas-operacionais/1/docker/Dockerfile) you see that it builds everything upon ubuntu 16.4, gets the proper packages (ex: tool chain), and ends with:
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/default_cmd.sh"]
entrypoint.sh makes ubuntu logs to user "student".
default_cmd.sh makes all other stuff: makes the kernel and the rootfs.
Therefore, in order to make any change, you must understand what commands defaul_cmd runs.
Basically it compiles the linux kernel, when in dictory $SRC/linux, by:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all
and makes the rootfs (compiling init.c and inserting in rootfs), when in directory $SRC/initramfs, by:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
The Makefile that generates rootfs is:
CC=$(CROSS_COMPILE)gcc -Wall -Wextra -static -g
$(shell mkdir -p build/initramfs_root)
.PHONY: all clean
all: build/rootfs.gz
clean:
rm -rf build
find -name '*.o' -delete
build/rootfs.gz: build/initramfs_root/init build/initramfs_root/stack_pop build/initramfs_root/stack_push
cd build/initramfs_root ; \
find -type f -print0 | cpio -0 -ov -H newc | gzip -9 > ../rootfs.gz
build/initramfs_root/init: init.o
$(CC) -o $@ $^
build/initramfs_root/stack_push: stack_push.o
$(CC) -o $@ $^
build/initramfs_root/stack_pop: stack_pop.o
$(CC) -o $@ $^
Qemu with or without gdb connection
qemu may run alone, and in this case it will take the ARM linux image and fire the init as a user process, no stop.qemu may also run with gdb; more specifically with:
arm-none-eabi-gdb -ex '\''target remote:1234'\'' /home/student/src/linux/vmlinux
In this case, the gdb (gnu debugger) connects to the qemu and controls it.
You may give commands to the qemu from gdb; but let us first see how it may become possible.
Killing your docker container.
The docker container will finish when qemu finishes or when the container is killed. In your ubuntu you may kill the docker container. First you need to know its name by "docker ps" and then kill it.~/Downloads/pcs3746-sistemas-operacionais/1/initramfs$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b18bb9eb0a2 tiagoshibata/pcs3746 "/entrypoint.sh /def…" 2 minutes ago Up 2 minutes cranky_lewin
jk@jk-desktop:~/Downloads/pcs3746-sistemas-operacionais/1/initramfs$ docker kill cranky_lewin
cranky_lewin
Next Steps
We want:- to modify init.c - the first process to run.
- to have qemu communicating with gdb.
Comentários
Postar um comentário