To successfully compile Zeke, you'll need the following packages/tools:
Zeke
- GNU
make>3.8 llvm3.3 or 3.4clang3.3 or 3.4binutils2.24arm-none-eabimipsel-sde-elf
bashmkdosfsandmtoolsfor creating a rootfs imageclocfor source code statsncurses-devel
Documentation
- Doxygen
manfor viewing man pages
The easiest way to build and run Zeke is by using the ready built Docker image and dmk.
The Docker image is built by using the this Dockerfile, see Zekedoc documentation for more information.
When in the root directory of the Zeke repository:
$ dmk
you@abc:/build$ KBUILD_DEFCONFIG=qemu_rpi_headless_testing.defconfig ./configure defconfig
you@abc:/build$ make all -j5
you@abc:/build$ make qemuAfter making the defconfig you can change the configuration knobs by running
./configure menuconfig. More information regarding configure script can be
found here.
The userland unit tests must be built by specifying a special target opttest
as all doesn't include tests. The tests can be found under opt/test when
running Zeke, which means the tests must be run inside Zeke as thebinaries are
compiled for Zeke using its libc.
The unit tests for the kernel (kunit) can be executed by writing the name of
each test to /proc/kunit and available tests can be listed by reading the
same file.
The Docker image comes with a GCC version specially built for debugging the Zeke kernel. Debugging with GDB has some documentation about how to debug Zeke.
configure- Set defaults for files in config dirmake all rootfs- Compile the kernel, user space and create a rootfs imagemake kernel.img- Compile the kernelmake world- Compile only the user space without creating a rootfs imagemake opttest- Compile on target testsmake clean- Clean all compilation targets
Run make help for full list of targets and compilation flags.
Configure script accepts following commands as an argument:
configUpdate current config utilising a line-oriented programnconfigUpdate current config utilising a ncurses menu based programmenuconfigUpdate current config utilising a menu based programxconfigUpdate current config utilising a QT based front-endgconfigUpdate current config utilising a GTK based front-endoldconfigUpdate current config utilising a provided .config as baselocalmodconfigUpdate current config disabling modules not loadedlocalyesconfigUpdate current config converting local mods to coresilentoldconfigSame as oldconfig, but quietly, additionally update depsdefconfigNew config with default from ARCH supplied defconfigsavedefconfigSave current config as ./defconfig (minimal config)allnoconfigNew config where all options are answered with noallyesconfigNew config where all options are accepted with yesallmodconfigNew config selecting modules when possiblealldefconfigNew config with all symbols set to defaultrandconfigNew config with random answer to all optionslistnewconfigList new optionsolddefconfigSame as silentoldconfig but sets new symbols to their default value
To use defconfig you must set KBUILD_DEFCONFIG environment variable to any of the
filenames seen under defconfigs directory.
For example:
$ KBUILD_DEFCONFIG=qemu_rpi_headless_testing.defconfig ./configure defconfig
kern/Makefile is responsible of compiling the kernel and parsing kmod
makefiles. Module makefiles are following the naming convention
<module>.mk and are located under kern/kmodmakefiles directory.
Module makefiles are parsed like normal makefiles but care should be
taken when changing global variables in these makefiles. Module
makefiles are mainly allowed to only append IDIR variable and all
other variables should be more or less specific to the module makefile
itself and should begin with the name of the module.
A valid module makefile could look something like the following listing:
# Module example
# Mandatory file
# If any source files are declared like this the whole module becomes
# mandatory and won't be dropped even if its configuration is set to zero.
module-SRC-1 += src/module/test.c
# Optional file
# If all files are declared like this then the module is optional and can be
# enabled or disabled in the `config.mk`.
module-SRC-$(configMODULE_CONFIGURABLE) += src/module/source.c
# Assembly file
module-ASRC$(configMODULE_CONFIGURABLE) += src/module/lowlevel.SThe kernel makefile will automatically discover test-SRC-1 list and
will compile a new static library based on the compilation units in the
list. Name of the library is derived from the makefile’s name and so
should be the first word of the source file list name.
TODO
Userland makefiles are constructed from user_head.mk, user_tail.mk
and the actual targets between includes. A good example of a user space
makefile is bin/Makefile that compiles tools under /bin. A manifest
file is automatically generated by the make system and it will be used
for creating a rootfs image with tools/mkrootfs.sh script.
Userland program sources are mostly located under directories close to
the final location in rootfs image. Currently we only have bin and
sbin directories in the build but our intention is to follow FHS as
far as possible. So for example sources for init is located in
/sbin/src/sinit directory and the final elf binary is created to
/sbin. However if the final executable is compiled from one file
it's ok to omit the final level of the directory structure in source tree.
The build system for user programs is "fully" automated, meaning that there shouldn't be need to write any new makefiles to build new binaries.
Adding a new program to the build
-
Assuming that you have your source code files in the correct directory go to the top directory of the build tree eg.
/binand openMakefilewith your favorite editor. -
Add the final binary name to the list of name in
BINvariable. -
Create a list of source file as a variable named
BINFILENAME-SRC-y, whereycan be replaced with$(configSOMETHING)if compilation of the binary should be controlled by a Kconfig option.
Libc is linked by default and any other needed libraries or linker arguments
can be passed by setting BINFILENAME-LDFLAGS in the makefile.
TODO
TODO