Наилучший способ изучить WrmOS — использовать его. Поэтому эта статья предоставляет пошаговое руководство как собрать и запустить свой собственный проект Hello World. Сперва мы соберём проект Hello из примеров WrmOS. Затем мы создадим новый внешний (external) проект.
Содержание 1. Ознакомительный проект Hello 2. Создание нового внешнего (external) проекта
1. Ознакомительный проект Hello [наверх]
Шаг 1.1. Получить кроссплатформенный тулчейн
Подробную информацию смотрите в статье Как получить тулчейн.
Шаг 1.2. Получить исходники WrmOS
Клонировать репозиторий из github:
git clone https://github.com/wrmlab/wrmos.git
или загрузить zip архив.
Шаг 1.3. Собрать ознакомительный проект Hello
Запустим сборку ознакомительного проекта Hello для архитектуры ARM и платформы Versatile Express Cortex-A9:
cd wrmos make build P=cfg/prj/hello-qemu-veca9.prj B=../build/hello-qemu-veca9 -j
В результате мы получим образ загрузчика с файловой системой, содержащей исполняемый файл приложения hello.elf:
ls ../build/hello-qemu-veca9/ldr/bootloader.elf
Шаг 1.4. Запустить WrmOS на виртуальной машине QEMU
qemu-system-arm -M vexpress-a9 -display none -serial stdio \ -kernel ../build/hello-qemu-veca9/ldr/bootloader.elf
В результате мы увидим следующий вывод:
[ldr] _ _ ___ __ __ ___ ___ [ldr] | | | | _ \ \/ | / _ \/ __| [ldr] | |/\| | / |\/| || (_) \__ \ [ldr] |__/\__|_|_\_| |_(_)___/|___/ [ldr] From Russia with love! [ldr] [ldr] cpu #0/1 ready, sp=0x60341a78. [ldr] [ldr] hello: 13:39:09 Jun 5 2018. [ldr] gccver: 7.3.0. [ldr] hware: arm, cortex_a9, vexpress_a9, qemu_vexpress_a9. [ldr] ram: [0x60000000 - 0x60800000) 8 MB. [ldr] ramfs: [0x6028d000 - 0x60338000) 684 KB. [ldr] ## name data size content [ldr] 1 kernel.elf 0x6028e000 443148 'ELF ...' [ldr] 2 sigma0.elf 0x602fa30c 41120 'ELF ...' [ldr] 3 roottask.elf 0x603043ac 144704 'ELF ...' [ldr] 4 config.alph 0x603278ec 516 '# config ...' [ldr] 5 hello.elf 0x60328000 64204 'ELF ...' [ldr] [ldr] elf: foreach: elf=0x6028e000, sz=0x6c30c. [ldr] app=kernel, va=0x60000000, pa=0x60000000, sz=0x00014000, load=1. [ldr] app=kernel, va=0xf0020000, pa=0x60020000, sz=0x001f9000, load=1. [ldr] app=kernel, va=0x00000000, pa=0x00000000, sz=0x00000000, load=0. [ldr] elf: foreach: elf=0x602fa30c, sz=0xa0a0. [ldr] app=sigma0, addr=0x00000000, sz=0x00000000, acc=0, progbits=0, name=. [ldr] app=sigma0, addr=0x60219000, sz=0x00005000, acc=5, progbits=1, name=.text. [ldr] app=sigma0, addr=0x6021e000, sz=0x00001000, acc=4, progbits=1, name=.rodata. [ldr] app=sigma0, addr=0x6021f000, sz=0x00001000, acc=6, progbits=1, name=.data. [ldr] app=sigma0, addr=0x60220000, sz=0x00004000, acc=6, progbits=1, name=.bss. [ldr] app=sigma0, addr=0x00000000, sz=0x00000039, acc=0, progbits=0, name=.ARM.attributes. [ldr] app=sigma0, addr=0x00000000, sz=0x00001240, acc=0, progbits=0, name=.symtab. [ldr] app=sigma0, addr=0x00000000, sz=0x00000c76, acc=0, progbits=0, name=.strtab. [ldr] app=sigma0, addr=0x00000000, sz=0x00000044, acc=0, progbits=0, name=.shstrtab. [ldr] app=sigma0, va=0x60219000, pa=0x60219000, sz=0x0000b000, load=1. [ldr] elf: foreach: elf=0x603043ac, sz=0x23540. [ldr] app=roottask, addr=0x00000000, sz=0x00000000, acc=0, progbits=0, name=. [ldr] app=roottask, addr=0x60224000, sz=0x00018000, acc=5, progbits=1, name=.text. [ldr] app=roottask, addr=0x6023c000, sz=0x00004000, acc=4, progbits=1, name=.rodata. [ldr] app=roottask, addr=0x60240000, sz=0x00001000, acc=6, progbits=1, name=.data. [ldr] app=roottask, addr=0x60241000, sz=0x0004c000, acc=6, progbits=1, name=.bss. [ldr] app=roottask, addr=0x00000000, sz=0x00000039, acc=0, progbits=0, name=.ARM.attributes. [ldr] app=roottask, addr=0x00000000, sz=0x00002600, acc=0, progbits=0, name=.symtab. [ldr] app=roottask, addr=0x00000000, sz=0x00002d58, acc=0, progbits=0, name=.strtab. [ldr] app=roottask, addr=0x00000000, sz=0x00000044, acc=0, progbits=0, name=.shstrtab. [ldr] app=roottask, va=0x60224000, pa=0x60224000, sz=0x00069000, load=1. [ldr] memory regions: [ldr] [60000000 - 60014000) sz=0x00014000, kernel. [ldr] [60020000 - 60219000) sz=0x001f9000, kernel. [ldr] [60219000 - 60224000) sz=0x0000b000, sigma0. [ldr] [60224000 - 6028d000) sz=0x00069000, roottask. [ldr] [60338000 - 60342000) sz=0x0000a000, bootloader. [ldr] [60342000 - 60800000) sz=0x004be000, free. [ldr] elf: foreach: elf=0x6028e000, sz=0x6c30c. [ldr] load: loc=0x60292000, pa=0x60000000, sz=0x00014000, load=1. [ldr] load: loc=0x602a6000, pa=0x60020000, sz=0x001f9000, load=1. [ldr] load: loc=0x6028e000, pa=0x00000000, sz=0x00000000, load=0. [ldr] elf: foreach: elf=0x602fa30c, sz=0xa0a0. [ldr] load: loc=0x602fb30c, pa=0x60219000, sz=0x0000b000, load=1. [ldr] elf: foreach: elf=0x603043ac, sz=0x23540. [ldr] load: loc=0x603053ac, pa=0x60224000, sz=0x00069000, load=1. [ldr] KIP found at 0x60020000. [ldr] Go to kernel. [----:0.000000] kernel: cpu #0 hello, sp=0xf0065f88. [sgm0:0.007522] inf: hello. [sgm0:0.009770] inf: free memory = 0x4c8000. [alph:0.064399] inf: hello. [alph:0.068992] inf: get memory from sigma0. [alph:0.089952] inf: got memory: 0x4c8000 bytes. [alph:0.093330] inf: Project config: [alph:0.093521] inf: Board config: [alph:0.093698] inf: ## device paddr size irq [alph:0.093953] inf: Memory config: [alph:0.094143] inf: ## name size cached contig [alph:0.094370] inf: Apps config: [alph:0.094616] inf: [0] [alph:0.094787] inf: name: hello [alph:0.094999] inf: short_name: hell [alph:0.095207] inf: file: ramfs:/hello.elf [alph:0.095448] inf: stack_sz: 0x1000 [alph:0.095670] inf: heap_sz: 0x0 [alph:0.095898] inf: max_aspaces: 1 [alph:0.096101] inf: max_threads: 3 [alph:0.096304] inf: max_prio: 100 [alph:0.096512] inf: fpu: 0 [alph:0.096725] inf: malloc_strategy: on_startup [alph:0.096942] inf: devices: [alph:0.097149] inf: memory: [alph:0.097351] inf: args: arg1=123, arg2=345 [alph:0.097614] inf: get iospace from sigma0. [alph:0.097827] inf: got iospace from sigma0. [alph:0.098519] inf: prepare named memory regions for apps. [alph:0.098777] inf: prepared named memory regions for apps. [alph:0.099028] inf: create app=hello. hello. argc=0x3, argv=0xff2000. arg[0] = hello. arg[1] = arg1=123. arg[2] = arg2=345. hello: I'm alive. hello: I'm alive. hello: I'm alive. hello: I'm alive. hello: I'm alive. hello: bye-bye.
2. Создание нового внешнего (external) проекта [наверх]
Типовым вариантом использоавния WrmOS является внешний (external) проект. Это позволяет не вносить изменений в оригинальные исходники WrmOS.
Шаг 2.1. Получить кроссплатформенный тулчейн
Подробную информацию смотрите в статье Как получить тулчейн.
Шаг 2.2. Получить исходники WrmOS
Клонировать репозиторий из github:
git clone https://github.com/wrmlab/wrmos.git
или загрузить zip архив.
Шаг 2.3. Создать директорию для внешнего (external) проекта
mkdir my_project
Шаг 2.4. Создать директорию для приложения
mkdir -p my_project/app/my_hello
Шаг 2.5. Создать исходный файл приложения my_project/app/my_hello/main.cpp
#include <stdio.h> #include <unistd.h> int main(int argc, const char* argv[]) { printf("hello.\n"); printf("argc=0x%x, argv=0x%p.\n", argc, argv); for (int i=0; i<argc; i++) { printf("arg[%d] = %s.\n", i, argv[i]); } const char* app_name = argv[0]; for (int i=0; i<5; ++i) { printf("%s: I'm alive.\n", app_name); sleep(1); } printf("%s: bye-bye.\n", app_name); return 0; }
Шаг 2.6. Создать мэйкфайл приложения my_project/app/my_hello/Makefile
objs := main.o incflags := -I$(cfgdir) baseflags := -O2 -Wall -Werror cxxflags := -std=c++11 -fno-rtti -fno-exceptions ldflags := libs := $(rtblddir)/lib/l4/libl4.a libs += $(rtblddir)/lib/wrmos/libwrmos.a libs += $(rtblddir)/lib/wlibc/libwlibc.a libs += $(rtblddir)/lib/wstdc++/libwstdc++.a ifeq ($(dbg),1) baseflags += -DDEBUG else baseflags += -DNDEBUG endif include $(wrmdir)/mk/base.mk
Шаг 2.7. Создать конфигурационную директорию проекта
mkdir -p my_project/cfg/prj
Шаг 2.8. Создать конфигурационный файл проекта my_project/cfg/prj/hello.prj
# platform parameters plt_file = $(wrmdir)/cfg/plt/arm-qemu-veca9.plt # toolchain gccprefix = arm-linux- # debug flags usr_lib_dbg = 1 usr_krn_dbg = 1 usr_krn_log = 1 usr_app_dbg = 1 usr_ldr_dbg = 0 # files to put in the ramfs usr_ramfs = config.alph:$(extdir)/cfg/alph/hello.alph usr_ramfs += hello.elf:$(blddir)/app/hello/hello.elf # base file to set all project params include $(wrmdir)/cfg/base.cfg
Шаг 2.9. Создать конфигурационную директорию корневого приложения Alpha
mkdir -p my_project/cfg/alph
Шаг 2.10. Создать конфигурационный файл времени выполения для корневого приложения Alpha my_project/cfg/alph/hello.alph
APPLICATIONS { name: myhello short_name: myhl file_path: ramfs:/hello.elf stack_size: 0x1000 heap_size: 0x0 aspaces_max: 1 threads_max: 3 prio_max: 100 fpu: off malloc_strategy: on_startup devices: memory: args: arg1=xxx, arg2=yyy }
Шаг 2.11. Собрать внешний (external) проект
cd my_project make -C ../wrmos build P=$(pwd)/cfg/prj/hello.prj E=$(pwd) B=$(pwd)/../build/my_hello -j
Шаг 2.12. Запустить собранный проект на виртуальной машине QEMU
qemu-system-arm -M vexpress-a9 -display none -serial stdio \ -kernel ../build/my_hello/ldr/bootloader.elf
В результате мы увидим следующий вывод:
[ldr] _ _ ___ __ __ ___ ___ [ldr] | | | | _ \ \/ | / _ \/ __| [ldr] | |/\| | / |\/| || (_) \__ \ [ldr] |__/\__|_|_\_| |_(_)___/|___/ [ldr] From Russia with love! [ldr] [ldr] cpu #0/1 ready, sp=0x60340518. [ldr] [ldr] hello: 13:46:59 Jun 5 2018. [ldr] gccver: 7.3.0. [ldr] hware: arm, cortex_a9, vexpress_a9, qemu_vexpress_a9. [ldr] ram: [0x60000000 - 0x60800000) 8 MB. [ldr] ramfs: [0x6028d000 - 0x60338000) 684 KB. [ldr] ## name data size content [ldr] 1 kernel.elf 0x6028e000 443140 'ELF ...' [ldr] 2 sigma0.elf 0x602fa304 41112 'ELF ...' [ldr] 3 roottask.elf 0x6030439c 144696 'ELF ...' [ldr] 4 config.alph 0x603278d4 343 'APPLICAT ...' [ldr] 5 hello.elf 0x60328000 64204 'ELF ...' [ldr] [ldr] KIP found at 0x60020000. [ldr] Go to kernel. [----:0.000000] kernel: cpu #0 hello, sp=0xf0065f88. [sgm0:0.007362] inf: hello. [sgm0:0.009624] inf: free memory = 0x4c8000. [alph:0.064424] inf: hello. [alph:0.069014] inf: get memory from sigma0. [alph:0.089183] inf: got memory: 0x4c8000 bytes. [alph:0.092560] inf: Project config: [alph:0.092771] inf: Board config: [alph:0.092962] inf: ## device paddr size irq [alph:0.093224] inf: Memory config: [alph:0.093421] inf: ## name size cached contig [alph:0.093684] inf: Apps config: [alph:0.093936] inf: [0] [alph:0.094115] inf: name: myhello [alph:0.094352] inf: short_name: myhl [alph:0.094570] inf: file: ramfs:/hello.elf [alph:0.094812] inf: stack_sz: 0x1000 [alph:0.095046] inf: heap_sz: 0x0 [alph:0.095255] inf: max_aspaces: 1 [alph:0.095450] inf: max_threads: 3 [alph:0.095647] inf: max_prio: 100 [alph:0.095846] inf: fpu: 0 [alph:0.096047] inf: malloc_strategy: on_startup [alph:0.096255] inf: devices: [alph:0.096452] inf: memory: [alph:0.096640] inf: args: arg1=xxx, arg2=yyy [alph:0.096895] inf: get iospace from sigma0. [alph:0.097101] inf: got iospace from sigma0. [alph:0.097748] inf: prepare named memory regions for apps. [alph:0.097992] inf: prepared named memory regions for apps. [alph:0.098221] inf: create app=myhello. hello. argc=0x3, argv=0xff2000. arg[0] = myhello. arg[1] = arg1=xxx. arg[2] = arg2=yyy. myhello: I'm alive. myhello: I'm alive. myhello: I'm alive. myhello: I'm alive. myhello: I'm alive. myhello: bye-bye.
- Войдите или зарегистрируйтесь, чтобы оставлять комментарии