w4linux is external WrmOS project that contains paravirtualized Linux kernel and busybox userspace environment. It allows to combine real-time part of project (for example Machine Control) and wealth of software that provides Linux (for example drivers, web services, communications). This article describe how to build and run w4linux project.
Contents 1. w4linux example
1. w4linux example [up]
Step 1.1. Get cross-platform toolchain
See the article How to get toolchain for detail.
Step 1.2. Get WrmOS sources
Clone repository from github:
git clone https://github.com/wrmlab/wrmos.git
or download zip archive.
Step 1.3. Get w4linux sources
Clone repository from github:
git clone https://github.com/wrmlab/w4linux.git
or download zip archive.
Step 1.4. Build w4linux project
Run building of w4linux project for architecture SPARC and platform LEON3 (it may take a few minutes):
cd w4linux make build P=cfg/prj/linux-qemu-leon3.prj W=../wrmos B=../build/linux-qemu-leon3 -j
As result we will get bootloader image with RAMFS containing linux.elf:
ls ../build/linux-qemu-leon3/ldr/bootloader.elf
Step 1.5. Run w4linux on QEMU virtual machine
qemu-system-sparc -M leon3_generic -display none -serial stdio \ -kernel ../build/linux-qemu-leon3/ldr/bootloader.elf
As result we will see output:
[ldr] _ _ ___ __ __ ___ ___ [ldr] | | | | _ \ \/ | / _ \/ __| [ldr] | |/\| | / |\/| || (_) \__ \ [ldr] |__/\__|_|_\_| |_(_)___/|___/ [ldr] From Russia with love! [ldr] [ldr] cpu #0/1 ready, sp=0x4069c4c8. [ldr] [ldr] hello: 13:57:16 Jun 5 2018. [ldr] gccver: 7.3.0. [ldr] hware: sparc, leon3, qemu, qemu_leon3. [ldr] ram: [0x40000000 - 0x48000000) 128 MB. [ldr] ramfs: [0x40292000 - 0x40690000) 4088 KB. [ldr] ## name data size content [ldr] 1 kernel.elf 0x40293000 373468 'ELF ...' [ldr] 2 sigma0.elf 0x402ee2dc 43180 'ELF ...' [ldr] 3 roottask.elf 0x402f8b88 153140 'ELF ...' [ldr] 4 config.alph 0x4031e1bc 1475 '# config ...' [ldr] 5 uart.elf 0x4031f000 83944 'ELF ...' [ldr] 6 console.elf 0x40334000 116444 'ELF ...' [ldr] 7 linux.elf 0x40351000 3396528 'ELF ...' [ldr] [ldr] elf: foreach: elf=0x40293000, sz=0x5b2dc. [ldr] app=kernel, va=0x40000000, pa=0x40000000, sz=0x00001000, load=1. [ldr] app=kernel, va=0xf0020000, pa=0x40020000, sz=0x00201000, load=1. [ldr] app=kernel, va=0x00000000, pa=0x00000000, sz=0x00000000, load=0. [ldr] elf: foreach: elf=0x402ee2dc, sz=0xa8ac. [ldr] app=sigma0, addr=0x00000000, sz=0x00000000, acc=0, progbits=0, name=. [ldr] app=sigma0, addr=0x40221000, sz=0x00006000, acc=5, progbits=1, name=.text. [ldr] app=sigma0, addr=0x40227000, sz=0x00001000, acc=4, progbits=1, name=.rodata. [ldr] app=sigma0, addr=0x40228000, sz=0x00001000, acc=6, progbits=1, name=.data. [ldr] app=sigma0, addr=0x40229000, sz=0x00004000, acc=6, progbits=1, name=.bss. [ldr] app=sigma0, addr=0x00000000, sz=0x00000010, acc=0, progbits=0, name=.gnu.attributes. [ldr] app=sigma0, addr=0x00000000, sz=0x00000b10, acc=0, progbits=0, name=.symtab. [ldr] app=sigma0, addr=0x00000000, sz=0x00000bdf, acc=0, progbits=0, name=.strtab. [ldr] app=sigma0, addr=0x00000000, sz=0x00000044, acc=0, progbits=0, name=.shstrtab. [ldr] app=sigma0, va=0x40221000, pa=0x40221000, sz=0x0000c000, load=1. [ldr] elf: foreach: elf=0x402f8b88, sz=0x25634. [ldr] app=roottask, addr=0x00000000, sz=0x00000000, acc=0, progbits=0, name=. [ldr] app=roottask, addr=0x4022d000, sz=0x0001b000, acc=5, progbits=1, name=.text. [ldr] app=roottask, addr=0x40248000, sz=0x00004000, acc=4, progbits=1, name=.rodata. [ldr] app=roottask, addr=0x4024c000, sz=0x00001000, acc=6, progbits=1, name=.data. [ldr] app=roottask, addr=0x4024d000, sz=0x00044000, acc=6, progbits=1, name=.bss. [ldr] app=roottask, addr=0x40291000, sz=0x00001000, acc=6, progbits=1, name=.stack. [ldr] app=roottask, addr=0x00000000, sz=0x00000010, acc=0, progbits=0, name=.gnu.attributes. [ldr] app=roottask, addr=0x00000000, sz=0x00001780, acc=0, progbits=0, name=.symtab. [ldr] app=roottask, addr=0x00000000, sz=0x00002cc9, acc=0, progbits=0, name=.strtab. [ldr] app=roottask, addr=0x00000000, sz=0x0000004b, acc=0, progbits=0, name=.shstrtab. [ldr] app=roottask, va=0x4022d000, pa=0x4022d000, sz=0x00065000, load=1. [ldr] memory regions: [ldr] [40000000 - 40001000) sz=0x00001000, kernel. [ldr] [40020000 - 40221000) sz=0x00201000, kernel. [ldr] [40221000 - 4022d000) sz=0x0000c000, sigma0. [ldr] [4022d000 - 40292000) sz=0x00065000, roottask. [ldr] [40690000 - 4069d000) sz=0x0000d000, bootloader. [ldr] [4069d000 - 48000000) sz=0x07963000, free. [ldr] elf: foreach: elf=0x40293000, sz=0x5b2dc. [ldr] load: loc=0x40294000, pa=0x40000000, sz=0x00001000, load=1. [ldr] load: loc=0x40295000, pa=0x40020000, sz=0x00201000, load=1. [ldr] load: loc=0x40293000, pa=0x00000000, sz=0x00000000, load=0. [ldr] elf: foreach: elf=0x402ee2dc, sz=0xa8ac. [ldr] load: loc=0x402ef2dc, pa=0x40221000, sz=0x0000c000, load=1. [ldr] elf: foreach: elf=0x402f8b88, sz=0x25634. [ldr] load: loc=0x402f9b88, pa=0x4022d000, sz=0x00065000, load=1. [ldr] KIP found at 0x40020000. [ldr] Go to kernel. [----:0.000000] kernel: cpu #0 hello, sp=0xf006cf00. [sgm0:0.006661] inf: hello. [sgm0:0.009527] inf: free memory = 0x7970000. [alph:0.055043] inf: hello. [alph:0.060676] inf: get memory from sigma0. [alph:0.269694] inf: got memory: 0x7970000 bytes. [alph:0.272740] inf: Project config: [alph:0.273016] inf: Board config: [alph:0.273273] inf: ## device paddr size irq [alph:0.273630] inf: 0 uart 0x80000100 0x00000100 3 [alph:0.274062] inf: Memory config: [alph:0.274340] inf: ## name size cached contig [alph:0.274775] inf: Apps config: [alph:0.275124] inf: [0] [alph:0.275363] inf: name: uart [alph:0.275659] inf: short_name: uart [alph:0.275955] inf: file: ramfs:/uart.elf [alph:0.276307] inf: stack_sz: 0x1000 [alph:0.276672] inf: heap_sz: 0x4000 [alph:0.276978] inf: max_aspaces: 1 [alph:0.277269] inf: max_threads: 3 [alph:0.277559] inf: max_prio: 120 [alph:0.277854] inf: fpu: 0 [alph:0.278157] inf: malloc_strategy: on_startup [alph:0.278477] inf: devices: 0 [alph:0.278765] inf: memory: [alph:0.279047] inf: args: uart [alph:0.279362] inf: [1] [alph:0.279594] inf: name: console [alph:0.279892] inf: short_name: cons [alph:0.280208] inf: file: ramfs:/console.elf [alph:0.280537] inf: stack_sz: 0x1000 [alph:0.280830] inf: heap_sz: 0x4000 [alph:0.281126] inf: max_aspaces: 1 [alph:0.281405] inf: max_threads: 3 [alph:0.281697] inf: max_prio: 110 [alph:0.281983] inf: fpu: 0 [alph:0.282282] inf: malloc_strategy: on_startup [alph:0.282587] inf: devices: [alph:0.282864] inf: memory: [alph:0.283139] inf: args: [alph:0.283414] inf: [2] [alph:0.283644] inf: name: linux [alph:0.283935] inf: short_name: lx [alph:0.284216] inf: file: ramfs:/linux.elf [alph:0.284537] inf: stack_sz: 0x1000 [alph:0.284866] inf: heap_sz: 0x40000 [alph:0.285231] inf: max_aspaces: 9 [alph:0.285570] inf: max_threads: 22 [alph:0.285918] inf: max_prio: 100 [alph:0.286284] inf: fpu: 0 [alph:0.286635] inf: malloc_strategy: on_startup [alph:0.287013] inf: devices: [alph:0.287350] inf: memory: [alph:0.287689] inf: args: [alph:0.288061] inf: get iospace from sigma0. [alph:0.289429] inf: got iospace from sigma0. [alph:0.290195] inf: prepare named memory regions for apps. [alph:0.290967] inf: prepared named memory regions for apps. [alph:0.291404] inf: create app=uart. [alph:0.300403] inf: create app=console. [alph:0.303546] inf: create app=linux. [uart:0.374879] inf: hello. [uart:0.377880] inf: argc=2, argv=0xff2000. [uart:0.378609] inf: arg[0] = uart. [uart:0.378880] inf: arg[1] = uart. [uart:0.379183] inf: myid=131. [uart:0.381028] inf: map_io: addr=0x70000100, sz=0x100. [uart:0.385900] inf: create_thread: rc=0, id=132. [uart:0.387753] inf: create_thread: rc=0, id=133. [u-tx:0.388715] inf: tx: hello: tx_thread. [u-tx:0.389091] inf: tx: myid=132. [u-rx:0.390172] inf: rx: hello: rx_thread. [u-rx:0.390560] inf: rx: myid=133. [u-hw:0.391376] inf: attach_int: dev=uart, irq=3. [u-tx:0.392104] inf: attach: thread 'uart-tx-stream' is registered, key: 5f1e5/5f1fe. [u-tx:0.392641] inf: attach: wait attach msg. [u-rx:0.393106] inf: attach: thread 'uart-rx-stream' is registered, key: 5f781/5f797. [u-rx:0.393625] inf: attach: wait attach msg. [cons:0.444318] inf: hello: myid=134. [cons:0.453151] inf: create_thread: rc=0, id=135. [cons:0.455107] inf: create_thread: rc=0, id=136. [c-dr:0.456121] inf: drv: myid=135. [c-dr:0.457696] inf: attach: got id=132, for thread 'uart-tx-stream', key: 5f1e5/5f1fe. [u-tx:0.458540] inf: attach: attached to 135. [u-tx:0.458948] inf: tx: attached to client=135 [c-cl:0.461121] inf: cli: myid=136. [c-dr:0.461918] inf: attach: got id=133, for thread 'uart-rx-stream', key: 5f781/5f797. [u-rx:0.462655] inf: attach: attached to 135. [u-rx:0.463056] inf: rx: attached to client=135 [c-cl:0.463636] inf: cli: thread 'console-server' is registered, key: 70b66/70b7d. [ lx:0.524237] inf: hello. [ lx:0.534241] inf: argc=0x1, argv=0x00fbe000. [ lx:0.535144] inf: arg[0] = linux. [ lx:0.538623] inf: App attached to system console. [ lx:0.539806] inf: create_threads: vcpu 0 ... [ lx:0.542869] inf: create_thread: kernel-mapper ... [ lx:0.547448] inf: stack_va=0xe0000000, stack_sz=0x1000. [ lx:0.550763] inf: rc=0, id=138. [ lx:0.551957] inf: create_thread: kernel-exc thread ... [ lx:0.553232] inf: stack_va=0xe0002000, stack_sz=0x1000. [ lx:0.555176] inf: rc=0, id=139. [ lx:0.556335] inf: create_thread: kernel thread ... [ lx:0.557545] inf: stack_va=0xe0004000, stack_sz=0x1000. [ lx:0.559484] inf: rc=0, id=140. [ lx:0.561105] inf: create_thread: pager thread ... [ lx:0.562352] inf: stack_va=0xe0006000, stack_sz=0x1000. [ lx:0.564336] inf: rc=0, id=141. [ lx:0.565583] inf: create_task: user task ... [ lx:0.566798] inf: stack_va=0xe0008000, stack_sz=0x1000. [ lx:0.569876] inf: rc=0, id=142. [ lx:0.571114] inf: create_thread: user-mapper thread ... [ lx:0.572350] inf: stack_va=0xe0009000, stack_sz=0x1000. [ lx:0.574353] inf: rc=0, id=143. [ lx:0.575512] inf: create_task: user task ... [ lx:0.576649] inf: stack_va=0xe000d000, stack_sz=0x1000. [ lx:0.579298] inf: rc=0, id=144. [ lx:0.580463] inf: create_thread: user-mapper thread ... [ lx:0.581691] inf: stack_va=0xe0010000, stack_sz=0x1000. [ lx:0.583557] inf: rc=0, id=145. [ lx:0.584687] inf: create_task: user task ... [ lx:0.585889] inf: stack_va=0xe0012000, stack_sz=0x1000. [ lx:0.588631] inf: rc=0, id=146. [ lx:0.589785] inf: create_thread: user-mapper thread ... [ lx:0.590999] inf: stack_va=0xe0013000, stack_sz=0x1000. [ lx:0.592871] inf: rc=0, id=147. [ lx:0.594009] inf: create_task: user task ... [ lx:0.595156] inf: stack_va=0xe0017000, stack_sz=0x1000. [ lx:0.597980] inf: rc=0, id=148. [ lx:0.599152] inf: create_thread: user-mapper thread ... [ lx:0.600383] inf: stack_va=0xe001a000, stack_sz=0x1000. [ lx:0.602273] inf: rc=0, id=149. [ lx:0.603405] inf: create_task: user task ... [ lx:0.604555] inf: stack_va=0xe001c000, stack_sz=0x1000. [ lx:0.607222] inf: rc=0, id=150. [ lx:0.608354] inf: create_thread: user-mapper thread ... [ lx:0.609570] inf: stack_va=0xe001d000, stack_sz=0x1000. [ lx:0.611468] inf: rc=0, id=151. [ lx:0.612597] inf: create_task: user task ... [ lx:0.613735] inf: stack_va=0xe0021000, stack_sz=0x1000. [ lx:0.616408] inf: rc=0, id=152. [ lx:0.617538] inf: create_thread: user-mapper thread ... [ lx:0.618724] inf: stack_va=0xe0024000, stack_sz=0x1000. [ lx:0.620610] inf: rc=0, id=153. [ lx:0.621751] inf: create_task: user task ... [ lx:0.622912] inf: stack_va=0xe0026000, stack_sz=0x1000. [ lx:0.625592] inf: rc=0, id=154. [ lx:0.626767] inf: create_thread: user-mapper thread ... [ lx:0.627969] inf: stack_va=0xe0027000, stack_sz=0x1000. [ lx:0.629844] inf: rc=0, id=155. [ lx:0.631022] inf: create_task: user task ... [ lx:0.632156] inf: stack_va=0xe002b000, stack_sz=0x1000. [ lx:0.634840] inf: rc=0, id=156. [ lx:0.636042] inf: create_thread: user-mapper thread ... [ lx:0.637396] inf: stack_va=0xe002e000, stack_sz=0x1000. [ lx:0.639280] inf: rc=0, id=157. [ lx:0.640471] inf: create_thread: console input thread ... [ lx:0.641737] inf: stack_va=0xe0030000, stack_sz=0x1000. [ lx:0.643608] inf: rc=0, id=158. [l-in:0.646020] inf: hello: console_input_thread, param=0x0. [l-in:0.647350] inf: my global_id=158. [l-m0:0.653399] inf: hello: mapper_thread, krn=1. [l-m0:0.658582] inf: my global_id=138. [l-U0:0.668453] inf: hello: mapper_thread, krn=0. [l-U0:0.668894] inf: hello: mapper_thread, krn=0. [l-U0:0.669339] inf: hello: mapper_thread, krn=0. [l-U0:0.669803] inf: hello: mapper_thread, krn=0. [l-U0:0.670285] inf: hello: mapper_thread, krn=0. [l-U0:0.670732] inf: hello: mapper_thread, krn=0. [l-U0:0.671177] inf: hello: mapper_thread, krn=0. [l-U0:0.671621] inf: hello: mapper_thread, krn=0. [l-U0:0.725776] inf: my global_id=143. [l-U0:0.726895] inf: my global_id=145. [l-U0:0.728018] inf: my global_id=147. [l-U0:0.729118] inf: my global_id=149. [l-U0:0.730263] inf: my global_id=151. [l-U0:0.731367] inf: my global_id=153. [l-U0:0.732456] inf: my global_id=155. [l-U0:0.733539] inf: my global_id=157. [l-e0:0.735421] inf: hello: kernel_thread, exch_level=2. [l-k0:0.736588] inf: hello: kernel_thread, exch_level=1. [l-p0:0.737743] inf: hello: upager_thread. [l-e0:0.740094] inf: my global_id=139. [l-k0:0.741194] inf: my global_id=140. [l-p0:0.742437] inf: my global_id=141. [l-u0:0.749607] inf: hello: user_thread, param=0x0. [l-u0:0.751499] inf: hello: user_thread, param=0x0. [l-u0:0.752700] inf: hello: user_thread, param=0x0. [l-u0:0.753858] inf: hello: user_thread, param=0x0. [l-u0:0.755048] inf: hello: user_thread, param=0x0. [l-u0:0.756211] inf: hello: user_thread, param=0x0. [l-u0:0.757397] inf: hello: user_thread, param=0x0. [l-u0:0.758658] inf: hello: user_thread, param=0x0. [l-u0:0.759842] inf: my global_id=142. [l-u0:0.760977] inf: my global_id=144. [l-u0:0.762039] inf: my global_id=146. [l-u0:0.763098] inf: my global_id=148. [l-u0:0.764223] inf: my global_id=150. [l-u0:0.765371] inf: my global_id=152. [l-u0:0.766504] inf: my global_id=154. [l-u0:0.767616] inf: my global_id=156. [l-u0:0.768793] inf: switch to kernel. [l-u0:0.769877] inf: switch to kernel. [l-u0:0.771005] inf: switch to kernel. [l-u0:0.772112] inf: switch to kernel. [l-u0:0.773359] inf: switch to kernel. [l-u0:0.774450] inf: switch to kernel. [l-u0:0.775549] inf: switch to kernel. [l-u0:0.776642] inf: switch to kernel. [l-k0:0.778432] inf: wait_msg_loop: suspend usr thread id=142. [l-k0:0.780842] inf: wait_msg_loop: suspend usr thread id=144. [l-k0:0.782122] inf: wait_msg_loop: suspend usr thread id=146. [l-k0:0.783385] inf: wait_msg_loop: suspend usr thread id=148. [l-k0:0.784659] inf: wait_msg_loop: suspend usr thread id=150. [l-k0:0.785892] inf: wait_msg_loop: suspend usr thread id=152. [l-k0:0.787125] inf: wait_msg_loop: suspend usr thread id=154. [l-k0:0.788403] inf: sp_bank[0].base_addr=0xd0000000, sp_bank[0].num_bytes=0x1392000. [ 0.000000] Linux version 4.12.1 (worm@comp) (gcc version 7.3.0 (Buildroot 2018.02.2) ) #3 Tue Jun 5 13:57:13 MSK 2018 [ 0.000000] bootconsole [earlyprom0] enabled [ 0.000000] ARCH: [ 0.000000] SUN4M IDPROM: Warning, unknown format type! IDPROM: Warning, bogus id_machtype value, 0x0 [ 0.000000] Ethernet address: 00:00:00:00:00:00 [ 0.000000] bootmem_init: hello. [ 0.000000] bootmem_init: done. [ 0.000000] Built 1 zonelists in Zone order, mobility grouping off. Total pages: 8110 [ 0.000000] Kernel command line: console=ttyWrm0 [ 0.000000] PID hash table entries: 64 (order: -4, 256 bytes) [ 0.000000] Dentry cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.000000] Sorting __ex_table... [ 0.000000] Memory: 13872K/16380K available (1867K kernel code, 94K rwdata, 0K rodata, 880K init, 467K bss, 2508K reserved, 0K cma-reserved, 0K highmem) [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [ 0.000000] NR_IRQS:64 [ 0.000000] init_IRQ: hello. [ 0.000000] leon_init_timers: HZ=100, irq=10. [ 0.000000] leon_unmask_irq: IMPLME. [ 0.000000] console [ttyWrm0] enabled [ 0.000000] console [ttyWrm0] enabled [ 0.000000] bootconsole [earlyprom0] disabled [ 0.000000] bootconsole [earlyprom0] disabled [ 0.000000] Console: colour dummy device 80x25 [ 0.000000] clocksource: timer_cs: mask: 0xffffffffffffffff max_cycles: 0x1358c14ce, max_idle_ns: 57775908723750000 ns [ 0.080000] Calibrating delay loop... 4272.12 BogoMIPS (lpj=21360640) [ 0.080000] pid_max: default: 32768 minimum: 301 [ 0.080000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.080000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes) [ 0.100000] devtmpfs: initialized [ 0.100000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns [ 0.100000] wrmos-uart 00000000: w4con_uart_probe: uart(0) driver initialized. [ 0.100000] clocksource: Switched to clocksource timer_cs [ 0.200000] workingset: timestamp_bits=30 max_order=12 bucket_order=0 [ 0.210000] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252) [ 0.210000] io scheduler noop registered [ 0.210000] io scheduler deadline registered [ 0.210000] io scheduler cfq registered (default) [ 0.210000] io scheduler mq-deadline registered [ 0.210000] io scheduler kyber registered [ 0.260000] leon: power management initialized [ 0.260000] hctosys: unable to open rtc device (rtc0) [ 0.260000] leon_unmask_irq: IMPLME. [ 0.260000] Freeing unused kernel memory: 880K [ 0.260000] This architecture does not have kernel memory protection. Starting logging: OK Initializing random number generator... [ 1.470000] random: dd: uninitialized urandom read (512 bytes read) done. Welcome to Buildroot buildroot login:
Step 1.6. Work with Linux shell
You will see buildroot prompt:
... Welcome to Buildroot buildroot login:
Input login "root" and will get busybox shell:
... Welcome to Buildroot buildroot login: root Jan 1 00:00:52 login[37]: root login on 'console' # # ls / bin init linuxrc opt run tmp dev lib media proc sbin usr etc lib32 mnt root sys var # # cat /proc/cpuinfo cpu : wrm.os virtual CPU vendor : WrmLab version : 0.01 (experimental) fpu : yes #