mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-22 04:52:56 +01:00
Compare commits
4491 Commits
17.08
...
sculpt-21.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abc9a2f232 | ||
|
|
0a35e02961 | ||
|
|
98ffa60577 | ||
|
|
9980718c92 | ||
|
|
2e0d9c8521 | ||
|
|
31567c8e46 | ||
|
|
006e807103 | ||
|
|
4dac2fd008 | ||
|
|
68e8d1fd21 | ||
|
|
6a89f8b19e | ||
|
|
ee463b21ae | ||
|
|
1088035f8e | ||
|
|
b2ff2a2950 | ||
|
|
c976a1d7e0 | ||
|
|
98400a68c9 | ||
|
|
8679f32d0b | ||
|
|
1d1379430a | ||
|
|
b7a379546e | ||
|
|
873eb687b0 | ||
|
|
1508fdc276 | ||
|
|
c79cdc7b39 | ||
|
|
440debfc39 | ||
|
|
28a71f4a73 | ||
|
|
4fd2c9c618 | ||
|
|
96997ead62 | ||
|
|
a12168e1bb | ||
|
|
d1461f6a72 | ||
|
|
c7abc9f983 | ||
|
|
d078f7db76 | ||
|
|
6f1d3862cd | ||
|
|
d5d7915b4d | ||
|
|
b337ee2f2b | ||
|
|
ef8a43c546 | ||
|
|
350353885e | ||
|
|
eb80d6ce66 | ||
|
|
bc5a7eb495 | ||
|
|
cb67d07e61 | ||
|
|
96ebed6c31 | ||
|
|
6093f8ad81 | ||
|
|
f6d845e630 | ||
|
|
27e55dab3e | ||
|
|
05b451c563 | ||
|
|
2604c3cca6 | ||
|
|
8ebc185caf | ||
|
|
6e32102cc6 | ||
|
|
42541fcc92 | ||
|
|
7cae324726 | ||
|
|
1072a91592 | ||
|
|
07bb3fc1ec | ||
|
|
93583cce3b | ||
|
|
e6bd9fd7da | ||
|
|
870c5c7a81 | ||
|
|
3e375e4315 | ||
|
|
8dfa586462 | ||
|
|
a661aa79de | ||
|
|
94701eec09 | ||
|
|
a28ca44101 | ||
|
|
641a738e3d | ||
|
|
f41dec67e1 | ||
|
|
75a55b62a3 | ||
|
|
989b7f39e1 | ||
|
|
a2d2b874ec | ||
|
|
42490208c2 | ||
|
|
95639a7492 | ||
|
|
df7de17435 | ||
|
|
1b4a80ffae | ||
|
|
88e6991083 | ||
|
|
9b953e79ba | ||
|
|
4c1eae97cf | ||
|
|
f051bfa90d | ||
|
|
4ed45dd303 | ||
|
|
2d0ac161cb | ||
|
|
34245376ba | ||
|
|
bd79f93657 | ||
|
|
731df4b037 | ||
|
|
d3cc5c9cd2 | ||
|
|
ff656401b3 | ||
|
|
46ee872b50 | ||
|
|
5aee693f70 | ||
|
|
f21cf3f8b1 | ||
|
|
32c283d26f | ||
|
|
f4cb5cc299 | ||
|
|
6ae55d490b | ||
|
|
2ac8620f44 | ||
|
|
d8c344f6b9 | ||
|
|
f8cf0442ed | ||
|
|
9bc7ecb605 | ||
|
|
4c4ce2f899 | ||
|
|
4803937dd2 | ||
|
|
6789b86871 | ||
|
|
9542bcf88c | ||
|
|
ad059362d2 | ||
|
|
49b09702b8 | ||
|
|
5d74509b2d | ||
|
|
b817e1977c | ||
|
|
910788313e | ||
|
|
02f00a999c | ||
|
|
441d137482 | ||
|
|
0c61b25bcf | ||
|
|
b6641eaa25 | ||
|
|
d6e347163d | ||
|
|
5dd8ee5840 | ||
|
|
c49db16762 | ||
|
|
b247def09a | ||
|
|
2b89cd66cb | ||
|
|
be3d5232c8 | ||
|
|
82cf31ac27 | ||
|
|
9de43a48b6 | ||
|
|
a9563bfd4c | ||
|
|
693a2b5421 | ||
|
|
277adcacb0 | ||
|
|
aa6a7db50a | ||
|
|
8b69bc96f9 | ||
|
|
6e4ef43bf0 | ||
|
|
b922dc5c10 | ||
|
|
cacb83b163 | ||
|
|
90e151e2c4 | ||
|
|
e37792ce94 | ||
|
|
cfb170c719 | ||
|
|
3b40790e02 | ||
|
|
9a80c3a618 | ||
|
|
ba430dfeac | ||
|
|
b157256a2b | ||
|
|
60980045ea | ||
|
|
880cd3a490 | ||
|
|
b7f66626c2 | ||
|
|
c0a7696c71 | ||
|
|
d85a448c52 | ||
|
|
d67899be95 | ||
|
|
6112c0df6d | ||
|
|
367385aed7 | ||
|
|
0f72356570 | ||
|
|
727fa86088 | ||
|
|
32394c0733 | ||
|
|
5aa3c56e5c | ||
|
|
0c2edce8ac | ||
|
|
2d2ef2a763 | ||
|
|
b6beff673a | ||
|
|
07881f90a9 | ||
|
|
3daa94ff2e | ||
|
|
59b23bc7e1 | ||
|
|
b7bb6869b4 | ||
|
|
e6cdaafb20 | ||
|
|
d072c408ab | ||
|
|
4dacac3dbb | ||
|
|
914a41a8bd | ||
|
|
e6c915ae06 | ||
|
|
6ef6f16cb3 | ||
|
|
f327a40bbb | ||
|
|
e34d1550a4 | ||
|
|
77a5cf7fd4 | ||
|
|
2ba5e4a5b1 | ||
|
|
5c82045170 | ||
|
|
4a87fcc4cf | ||
|
|
e5b828ae8f | ||
|
|
f1b72d0281 | ||
|
|
ebd140cacb | ||
|
|
64e2912a2f | ||
|
|
339dda8b43 | ||
|
|
397a3e45d1 | ||
|
|
f8898f3a56 | ||
|
|
83c5648d33 | ||
|
|
7fdebc6a09 | ||
|
|
4782f9376c | ||
|
|
a362505e8a | ||
|
|
ece837e8b8 | ||
|
|
eedbcf88ec | ||
|
|
2b0bb6dda0 | ||
|
|
31b049864c | ||
|
|
46be4f1145 | ||
|
|
e4ae817e82 | ||
|
|
38d731bd79 | ||
|
|
9041567f14 | ||
|
|
b6ec4bdf05 | ||
|
|
dd90424129 | ||
|
|
c26c50e59b | ||
|
|
ac9e0947fd | ||
|
|
fb4d357b59 | ||
|
|
7a4626861e | ||
|
|
bac7381be3 | ||
|
|
6b1f1794c4 | ||
|
|
eab92f8d6f | ||
|
|
ee283c0d12 | ||
|
|
c5d8a43418 | ||
|
|
cc2363d421 | ||
|
|
b287c4888a | ||
|
|
66ac2dc635 | ||
|
|
6c7bcdd32e | ||
|
|
b2440a72c3 | ||
|
|
8a285a7bee | ||
|
|
c9809fde67 | ||
|
|
de8327c11a | ||
|
|
0aa17661cc | ||
|
|
82a51d8eaa | ||
|
|
040628894c | ||
|
|
b5dd1dd01b | ||
|
|
ffbd26d63f | ||
|
|
1416b2258f | ||
|
|
436d946300 | ||
|
|
324ad33736 | ||
|
|
2cb4157211 | ||
|
|
c95af254f4 | ||
|
|
29032caf40 | ||
|
|
36af114d78 | ||
|
|
149bd999f3 | ||
|
|
a6fb61dbf2 | ||
|
|
50cc51f132 | ||
|
|
c54473abea | ||
|
|
611e93a5f2 | ||
|
|
d6bde82894 | ||
|
|
88b3880c77 | ||
|
|
7618c9410a | ||
|
|
5e284bfb35 | ||
|
|
81d939f947 | ||
|
|
9898341d4a | ||
|
|
812fdec27c | ||
|
|
fa64aae7f8 | ||
|
|
1111472af7 | ||
|
|
9e6f7988c2 | ||
|
|
80c1459e79 | ||
|
|
0840cfe834 | ||
|
|
e648e7255a | ||
|
|
06a4608f4a | ||
|
|
619474bc90 | ||
|
|
b0e558f486 | ||
|
|
d7a27c448d | ||
|
|
626b2f9cf2 | ||
|
|
2533d7b4b6 | ||
|
|
60c8369718 | ||
|
|
b59e2ba677 | ||
|
|
c3e8c22a6d | ||
|
|
2fe70f111b | ||
|
|
1727de30b7 | ||
|
|
6c003a13d2 | ||
|
|
11192b18e6 | ||
|
|
fe867765a8 | ||
|
|
ffc89f3edf | ||
|
|
067b7d7c67 | ||
|
|
4b653fbac1 | ||
|
|
7dc997c8e6 | ||
|
|
5d6ea5ef22 | ||
|
|
a721933771 | ||
|
|
c949e5c90d | ||
|
|
243a9ec3ca | ||
|
|
b3147050cc | ||
|
|
f8953de7ac | ||
|
|
fce525f122 | ||
|
|
2afae7e7c1 | ||
|
|
d06773b957 | ||
|
|
c8a8cbd7be | ||
|
|
00e8e363d8 | ||
|
|
8bc861ca71 | ||
|
|
9384e075cb | ||
|
|
52011ec034 | ||
|
|
908d581a8c | ||
|
|
b38ec9f238 | ||
|
|
9334ec09e2 | ||
|
|
1bfc828826 | ||
|
|
b51b9e1ef3 | ||
|
|
3d36291d7f | ||
|
|
2afb7c5567 | ||
|
|
ee045a68cc | ||
|
|
1a526e73a3 | ||
|
|
1aba330ae6 | ||
|
|
119d72ad94 | ||
|
|
b16bb82f8b | ||
|
|
f939b9ffb5 | ||
|
|
45f5ed173a | ||
|
|
6de19e4a9b | ||
|
|
5138aeba80 | ||
|
|
f3908b8283 | ||
|
|
fdc4bd2f90 | ||
|
|
4d4cc4fd02 | ||
|
|
4b10aa94ec | ||
|
|
688379d1ed | ||
|
|
0074a7c4ac | ||
|
|
388e2a0e6d | ||
|
|
a856bfb4ab | ||
|
|
3824c0ca5f | ||
|
|
40e2aa6617 | ||
|
|
2d017ad7b7 | ||
|
|
be644098d7 | ||
|
|
fd9bc43be1 | ||
|
|
a6fe6c90d4 | ||
|
|
ece33d37f8 | ||
|
|
e7067050be | ||
|
|
ed0cc5330e | ||
|
|
b83c8f35c6 | ||
|
|
a242bfce48 | ||
|
|
19a7997734 | ||
|
|
a58473dece | ||
|
|
cd25dc4e6a | ||
|
|
c585e008b1 | ||
|
|
5b85bd9602 | ||
|
|
0dc7084b0f | ||
|
|
16c4aacf34 | ||
|
|
6bfdddd0b5 | ||
|
|
026b117a63 | ||
|
|
e5600fea06 | ||
|
|
f541668604 | ||
|
|
bf7500ad7b | ||
|
|
29b7c5a202 | ||
|
|
7346defc26 | ||
|
|
dff1df0b49 | ||
|
|
2c87c68a5d | ||
|
|
52a4293bbc | ||
|
|
ff57bf617b | ||
|
|
818f1682ee | ||
|
|
eabda8907f | ||
|
|
4aa99fd1a9 | ||
|
|
ff452619e3 | ||
|
|
19a5fee70b | ||
|
|
c66a196f76 | ||
|
|
9165c7601d | ||
|
|
ff128df131 | ||
|
|
747d01e854 | ||
|
|
331844c979 | ||
|
|
434d007dc1 | ||
|
|
7db6f457d4 | ||
|
|
37f1873f2e | ||
|
|
002037ce15 | ||
|
|
2a1a47b598 | ||
|
|
ab31de0f6a | ||
|
|
a37ff1d985 | ||
|
|
4053e1628b | ||
|
|
27004e1fd5 | ||
|
|
b09e69a444 | ||
|
|
758c0a21cc | ||
|
|
60eec251e0 | ||
|
|
336350fe60 | ||
|
|
8408bf6ac0 | ||
|
|
73d87073af | ||
|
|
cf2527269f | ||
|
|
520b69ef0d | ||
|
|
c0150f97e5 | ||
|
|
5dc7d55cc0 | ||
|
|
fd2f137a9b | ||
|
|
1d52bd017d | ||
|
|
e06f3bba27 | ||
|
|
1d12755401 | ||
|
|
f2ac341003 | ||
|
|
f2ff1a6d52 | ||
|
|
4383579db6 | ||
|
|
f0b9549376 | ||
|
|
aab6f52325 | ||
|
|
6e85a73a28 | ||
|
|
4abc530974 | ||
|
|
583ba0e9db | ||
|
|
62f83b7198 | ||
|
|
464f0eaf8b | ||
|
|
0f72a342f3 | ||
|
|
3dff399fba | ||
|
|
0aa99648d7 | ||
|
|
6b9fcc9449 | ||
|
|
f9c7947c45 | ||
|
|
28189ba77a | ||
|
|
fc5903c917 | ||
|
|
7f6f710bd2 | ||
|
|
ed7d6c74f4 | ||
|
|
9f099bd61c | ||
|
|
6780cf0790 | ||
|
|
7b197d54ed | ||
|
|
933de21339 | ||
|
|
509e5aa776 | ||
|
|
e1abd2db4e | ||
|
|
faf491ce92 | ||
|
|
98f524bb41 | ||
|
|
7fcf9053b9 | ||
|
|
6910b880e7 | ||
|
|
708b7f4619 | ||
|
|
921a99bb9b | ||
|
|
a13dee8d19 | ||
|
|
0069660958 | ||
|
|
7b09675236 | ||
|
|
4bed825956 | ||
|
|
5135ff2dc2 | ||
|
|
4a56171a77 | ||
|
|
ae5b4c9624 | ||
|
|
46c846ef91 | ||
|
|
c8c589d91a | ||
|
|
5254930930 | ||
|
|
70797fe879 | ||
|
|
100583e262 | ||
|
|
57fbd2b658 | ||
|
|
9549eeeca4 | ||
|
|
9166a75f2c | ||
|
|
dd587c6712 | ||
|
|
3ed26e7bb2 | ||
|
|
6e900f147c | ||
|
|
0507d3f44b | ||
|
|
0b641ba581 | ||
|
|
b3a229eebb | ||
|
|
fd0a4e78c8 | ||
|
|
74d826d1ad | ||
|
|
b6b9801c20 | ||
|
|
b22d9385f1 | ||
|
|
516601b7ba | ||
|
|
67a8f29697 | ||
|
|
3e284558a1 | ||
|
|
04d8e03ecb | ||
|
|
cfe29b0e52 | ||
|
|
d4b9be8d44 | ||
|
|
db97af8dec | ||
|
|
4daf19ec7e | ||
|
|
18a43c1afd | ||
|
|
813f4d976b | ||
|
|
a24224ffc3 | ||
|
|
9543161827 | ||
|
|
a0517686ca | ||
|
|
9209dfc9d5 | ||
|
|
f8d0552d52 | ||
|
|
139a2cfae9 | ||
|
|
1c20ed12c1 | ||
|
|
d516544a1f | ||
|
|
f8b2fd522b | ||
|
|
471d34a367 | ||
|
|
d5e4ffd191 | ||
|
|
4a4b754bf2 | ||
|
|
a0f5d34e25 | ||
|
|
9a3d5dcf21 | ||
|
|
9c05cda6e7 | ||
|
|
6639261126 | ||
|
|
fc902d9e66 | ||
|
|
6a11b78cdf | ||
|
|
7fd598f0c1 | ||
|
|
777923f9bd | ||
|
|
d2bf565503 | ||
|
|
384a8da50b | ||
|
|
b6bdd91cfa | ||
|
|
a5385cebf4 | ||
|
|
c5c3d7ca98 | ||
|
|
d19b751632 | ||
|
|
ff160decec | ||
|
|
a4115cfea9 | ||
|
|
2f9d430c00 | ||
|
|
718f44ae5b | ||
|
|
66feb939e6 | ||
|
|
1baf844e20 | ||
|
|
5fa2efa745 | ||
|
|
ad847d0543 | ||
|
|
0b36d81c0c | ||
|
|
a4727c90a8 | ||
|
|
e65b7f3b82 | ||
|
|
0f0edc0134 | ||
|
|
d0f084d449 | ||
|
|
c7b2314d23 | ||
|
|
eb94f03416 | ||
|
|
516a9a6925 | ||
|
|
fdb1a4dd88 | ||
|
|
d477062c56 | ||
|
|
811009d18b | ||
|
|
00d13cf304 | ||
|
|
49184fb938 | ||
|
|
52e8c95321 | ||
|
|
9b854e1496 | ||
|
|
d5e7870532 | ||
|
|
bc8dbc6b1a | ||
|
|
8f23e377d9 | ||
|
|
aebece5110 | ||
|
|
82604f2c2b | ||
|
|
4563baae77 | ||
|
|
c4e3d3dbc4 | ||
|
|
eb53f8c113 | ||
|
|
07649b667b | ||
|
|
0f679bb35e | ||
|
|
d6e9d74038 | ||
|
|
405e6744fb | ||
|
|
fad85c3fd5 | ||
|
|
49392dfa44 | ||
|
|
e627f8320f | ||
|
|
8196e229b0 | ||
|
|
0a8394c891 | ||
|
|
66e8f8d764 | ||
|
|
84e4cbb54c | ||
|
|
23b21812dd | ||
|
|
d66e55ec37 | ||
|
|
5dbc9ef244 | ||
|
|
4e822436fc | ||
|
|
ce75b25fd4 | ||
|
|
118e8ee6e1 | ||
|
|
f236e99b5c | ||
|
|
86e09b60c4 | ||
|
|
373b45a0f0 | ||
|
|
a2491c30b3 | ||
|
|
d80b2a150a | ||
|
|
c802de2cf9 | ||
|
|
e86387d557 | ||
|
|
f6aabfe233 | ||
|
|
8617e5cee0 | ||
|
|
2db94b8438 | ||
|
|
7b9e7361ba | ||
|
|
910ea16405 | ||
|
|
58db8c647a | ||
|
|
4826bd82fe | ||
|
|
7b90f8f857 | ||
|
|
bf3ad3baff | ||
|
|
8a4b52d9e3 | ||
|
|
a47fd36b9f | ||
|
|
a2e62db6ec | ||
|
|
7503472ae6 | ||
|
|
1c49da8ce4 | ||
|
|
9cb8c37e3a | ||
|
|
bb6617ad03 | ||
|
|
f49ec5b171 | ||
|
|
507a7789fb | ||
|
|
421d2bed40 | ||
|
|
6caa74a18e | ||
|
|
5ac3c335dc | ||
|
|
e8b97ad684 | ||
|
|
3f450a77e1 | ||
|
|
462bff5aef | ||
|
|
ace7c9172b | ||
|
|
173264ed1e | ||
|
|
190eafeaa6 | ||
|
|
ddf6a0c276 | ||
|
|
8f30fc993d | ||
|
|
33a64f79dc | ||
|
|
7de62734e5 | ||
|
|
d73eaaa14c | ||
|
|
efbed6f7bf | ||
|
|
5ca024ff8b | ||
|
|
dc8c899c1d | ||
|
|
d1cf9c86b8 | ||
|
|
46ca576eac | ||
|
|
70281715c6 | ||
|
|
4546148ab7 | ||
|
|
80cf47d906 | ||
|
|
7c01053842 | ||
|
|
e28709d54d | ||
|
|
dc89ebf978 | ||
|
|
7ae1210531 | ||
|
|
c9d904df71 | ||
|
|
21e9e1840a | ||
|
|
4e714d3f3a | ||
|
|
2084404aba | ||
|
|
9c9302e51d | ||
|
|
af490bdd5b | ||
|
|
0339318572 | ||
|
|
53e44f8bfd | ||
|
|
a839b4f0bb | ||
|
|
468e7a825c | ||
|
|
3ed8df9089 | ||
|
|
97a9ad114c | ||
|
|
f5f5b8c1f1 | ||
|
|
b661459aca | ||
|
|
f925fef17b | ||
|
|
97d44c5a79 | ||
|
|
1867cf4967 | ||
|
|
f3f8d9a6de | ||
|
|
99f4b3cd07 | ||
|
|
ac07f9d08e | ||
|
|
ed9487b452 | ||
|
|
729b22f04f | ||
|
|
698f6eb86c | ||
|
|
73e8d64c34 | ||
|
|
cb9a26f1ed | ||
|
|
49481dd3fb | ||
|
|
dc8dd3396d | ||
|
|
9ac23a18d4 | ||
|
|
ae8050bb82 | ||
|
|
0a849a1681 | ||
|
|
f89414c637 | ||
|
|
4cdfeb13e2 | ||
|
|
1a57a5a959 | ||
|
|
96cc660f95 | ||
|
|
2c7c7767fc | ||
|
|
9f8c555e7d | ||
|
|
fb9f6812e1 | ||
|
|
839183d2b6 | ||
|
|
c67e78a7f0 | ||
|
|
0ac4d1d411 | ||
|
|
0f9cb72cfa | ||
|
|
27527bf165 | ||
|
|
f839b3ecba | ||
|
|
bfea27a258 | ||
|
|
4f91d71cf9 | ||
|
|
32169cd137 | ||
|
|
eb89b13327 | ||
|
|
b51c1a0fe3 | ||
|
|
f90cd542cb | ||
|
|
dce272ba8f | ||
|
|
141af733aa | ||
|
|
945b4760ef | ||
|
|
53041f4cd8 | ||
|
|
521f61b9e0 | ||
|
|
ca50a41d28 | ||
|
|
b29f1497bf | ||
|
|
ca5522d4d9 | ||
|
|
36ef41626a | ||
|
|
e9ac14ed49 | ||
|
|
8f1db47c26 | ||
|
|
d2fc834bfa | ||
|
|
3d432331b9 | ||
|
|
446df00d0d | ||
|
|
2f0898d2a9 | ||
|
|
9a0217f21a | ||
|
|
0cfafa1c8f | ||
|
|
2c85e48a0d | ||
|
|
15780a657c | ||
|
|
5c5b56d1e0 | ||
|
|
00900d82b5 | ||
|
|
18182b11da | ||
|
|
8eb514d6b5 | ||
|
|
8a8de970a5 | ||
|
|
cae3e447d6 | ||
|
|
f98d10a3f3 | ||
|
|
521663c6de | ||
|
|
9b5bedefc7 | ||
|
|
8ecc258d3f | ||
|
|
7bbd050f25 | ||
|
|
7e7c10e66c | ||
|
|
d5d3b3c3a4 | ||
|
|
2baa283d87 | ||
|
|
4a12b5c653 | ||
|
|
ba6c4a664f | ||
|
|
9093c293cb | ||
|
|
935bb36fe4 | ||
|
|
755aed7cb2 | ||
|
|
6223ae4413 | ||
|
|
bebba3876e | ||
|
|
aa0a98bd43 | ||
|
|
42f3d2eccd | ||
|
|
c03534e355 | ||
|
|
1e0d843464 | ||
|
|
8c7d34ff21 | ||
|
|
d6a312f438 | ||
|
|
6544cca320 | ||
|
|
3d0ed5992d | ||
|
|
366fda0e47 | ||
|
|
7ce1f8e92d | ||
|
|
6e9843bd05 | ||
|
|
2ff252360d | ||
|
|
9de61e7014 | ||
|
|
6712eac7e6 | ||
|
|
25a212aa24 | ||
|
|
89ffc48576 | ||
|
|
9a5bc9caf0 | ||
|
|
c0a7565c21 | ||
|
|
a02ec07e49 | ||
|
|
1f29055927 | ||
|
|
7af276ac81 | ||
|
|
de62582905 | ||
|
|
ba567f4ba8 | ||
|
|
ee0ed273e6 | ||
|
|
e1bb0e8e15 | ||
|
|
2e4ccc1459 | ||
|
|
80522fadf6 | ||
|
|
2ce4a3b400 | ||
|
|
c68443e2eb | ||
|
|
9685a8b60d | ||
|
|
23e3079f46 | ||
|
|
10b56afff0 | ||
|
|
d4b58b689c | ||
|
|
1826ff8a59 | ||
|
|
86ad4ed17f | ||
|
|
1d1b5b88c5 | ||
|
|
4f1a3a8000 | ||
|
|
0afd3db894 | ||
|
|
cbe81d35b9 | ||
|
|
1d551bd967 | ||
|
|
812c3599de | ||
|
|
20caac5f3b | ||
|
|
a47b374905 | ||
|
|
7a3dc68f34 | ||
|
|
dd92ab126b | ||
|
|
f68e655312 | ||
|
|
64165d829e | ||
|
|
c2feba065f | ||
|
|
219809ffed | ||
|
|
6e8728f2d3 | ||
|
|
90d9470dfd | ||
|
|
2879aa003b | ||
|
|
83c2309710 | ||
|
|
59459e60e7 | ||
|
|
8d13121e84 | ||
|
|
3ff0efd627 | ||
|
|
10605a6903 | ||
|
|
6937eb7d94 | ||
|
|
a462a8e741 | ||
|
|
3485282909 | ||
|
|
b6d20b4742 | ||
|
|
7318ca6084 | ||
|
|
ca777fe93f | ||
|
|
ccd9ba4161 | ||
|
|
954f03257d | ||
|
|
190b4784c5 | ||
|
|
f23e302475 | ||
|
|
f5cd12dcf9 | ||
|
|
ce31c90bc3 | ||
|
|
f9c258a372 | ||
|
|
048a4625c5 | ||
|
|
db3f86d603 | ||
|
|
fa68325a57 | ||
|
|
1b77cb3832 | ||
|
|
19d9409a34 | ||
|
|
9918a8f88d | ||
|
|
a6f0b05834 | ||
|
|
b51ae104c2 | ||
|
|
23620942bf | ||
|
|
a99f6a81b6 | ||
|
|
fd0e6685fc | ||
|
|
18e282ab8a | ||
|
|
1e84b46c3f | ||
|
|
19d0142e10 | ||
|
|
983a18d06e | ||
|
|
f654e6f02d | ||
|
|
cb2e27f8e4 | ||
|
|
c58acd0b2b | ||
|
|
26506673c4 | ||
|
|
df38140ed6 | ||
|
|
9633a0a524 | ||
|
|
7d568247e3 | ||
|
|
b5fb37ddee | ||
|
|
d29b843a0f | ||
|
|
8958c769ab | ||
|
|
210f5073e3 | ||
|
|
ef88d05f2b | ||
|
|
d6a5a66623 | ||
|
|
d186e4361e | ||
|
|
2acfacb639 | ||
|
|
696d8f030f | ||
|
|
e3233a4824 | ||
|
|
5c5d16f524 | ||
|
|
c16611dff2 | ||
|
|
33406940f3 | ||
|
|
e1698cf200 | ||
|
|
2670ae399b | ||
|
|
91a7fb1da7 | ||
|
|
a9c4ebc9e9 | ||
|
|
e3783b00bb | ||
|
|
493924a35e | ||
|
|
cbae9bc1c8 | ||
|
|
8cc2662aac | ||
|
|
af9ab9190b | ||
|
|
14db22c77c | ||
|
|
691be92046 | ||
|
|
9f3c5d92b3 | ||
|
|
36b55e065a | ||
|
|
6789ce8b83 | ||
|
|
a981fb864c | ||
|
|
c4cf9b6e6d | ||
|
|
4bc9b9a2ef | ||
|
|
ad4211ae2c | ||
|
|
ff28ed0f8c | ||
|
|
693a4d78dd | ||
|
|
8f6b934caa | ||
|
|
384cf14bee | ||
|
|
90b20b4daf | ||
|
|
80318b9ae0 | ||
|
|
fce5c249c2 | ||
|
|
71abfb3b4f | ||
|
|
395a9b5bf5 | ||
|
|
53081ac6b3 | ||
|
|
c6d5b98227 | ||
|
|
c402cc1045 | ||
|
|
1edac9730c | ||
|
|
d475015ada | ||
|
|
ffb931f8b1 | ||
|
|
b4d294f62e | ||
|
|
052f678225 | ||
|
|
3fdf323e6e | ||
|
|
05c36d67ce | ||
|
|
ffc2a2f306 | ||
|
|
fc089a1673 | ||
|
|
428de89f9a | ||
|
|
30429a5228 | ||
|
|
e6a9e06f62 | ||
|
|
8b172bf22e | ||
|
|
80e8cf99e2 | ||
|
|
9d239957bc | ||
|
|
5fa91c573b | ||
|
|
9bfd812a88 | ||
|
|
1ccf8a280c | ||
|
|
f034f560be | ||
|
|
f45aa85e9f | ||
|
|
84443d6548 | ||
|
|
a6a923c31b | ||
|
|
f687d4824b | ||
|
|
0a478dac7f | ||
|
|
5905e0a4a0 | ||
|
|
d0ac8a6036 | ||
|
|
bdd923406f | ||
|
|
5a123e37c9 | ||
|
|
6cfaac182a | ||
|
|
3e73d8d7b6 | ||
|
|
a4d5687510 | ||
|
|
2b0170fb6a | ||
|
|
2d21d04c76 | ||
|
|
f6d195a9de | ||
|
|
1d2649b49a | ||
|
|
cf72d1aac3 | ||
|
|
9222463565 | ||
|
|
8ff75346dd | ||
|
|
cae5d380c4 | ||
|
|
14d8627186 | ||
|
|
f358fcbda6 | ||
|
|
b185f3fac1 | ||
|
|
5f7fe7498f | ||
|
|
c89864c830 | ||
|
|
59fafac4d6 | ||
|
|
ebf7f8f599 | ||
|
|
f57519397b | ||
|
|
5ca3847c89 | ||
|
|
eee8f64fd4 | ||
|
|
0a5741f076 | ||
|
|
1147f35972 | ||
|
|
d698e0876d | ||
|
|
98798f18b5 | ||
|
|
8bed4c1d54 | ||
|
|
72801975cd | ||
|
|
7266f29491 | ||
|
|
2c82636a98 | ||
|
|
d47f87a768 | ||
|
|
887fcecf63 | ||
|
|
0428e5e8b9 | ||
|
|
0359ee6a76 | ||
|
|
1bef11accf | ||
|
|
c5de2acf57 | ||
|
|
9189342b77 | ||
|
|
abd688097a | ||
|
|
6930372d55 | ||
|
|
a124f5b88d | ||
|
|
0beda6bca4 | ||
|
|
a0fb944721 | ||
|
|
36eeab6df2 | ||
|
|
537472e9af | ||
|
|
496dc5508f | ||
|
|
2a659cb750 | ||
|
|
b097e598f1 | ||
|
|
2c639169fd | ||
|
|
bad8caee3f | ||
|
|
306466fc60 | ||
|
|
063e4bd072 | ||
|
|
e14b58a82c | ||
|
|
8d8edaea5d | ||
|
|
b0327d0544 | ||
|
|
a7b878cbb5 | ||
|
|
7ac6f93838 | ||
|
|
70ff3d9c90 | ||
|
|
0209a2465d | ||
|
|
b6408cec1c | ||
|
|
3fac8b106d | ||
|
|
5c27270b17 | ||
|
|
3f15d18392 | ||
|
|
f2e0c164c2 | ||
|
|
d672e95090 | ||
|
|
98211db63d | ||
|
|
722254f864 | ||
|
|
b907629341 | ||
|
|
22852f2e50 | ||
|
|
e22e2540ee | ||
|
|
78ab3c8db5 | ||
|
|
ffdd49f9ce | ||
|
|
0cbd1d1b7c | ||
|
|
f4ac642f64 | ||
|
|
955afd8837 | ||
|
|
9b544787bd | ||
|
|
774b1f4277 | ||
|
|
dbcb1ff480 | ||
|
|
551b17591c | ||
|
|
51a50ece60 | ||
|
|
0dcb526ae5 | ||
|
|
dc016cbd5c | ||
|
|
e5f442f2d3 | ||
|
|
5db2971903 | ||
|
|
aa7f5bc95f | ||
|
|
6872fdb0de | ||
|
|
48220dfd9b | ||
|
|
50ab86cd72 | ||
|
|
cc7de65c9e | ||
|
|
cc193a9155 | ||
|
|
c0309a634e | ||
|
|
30b8f4efc8 | ||
|
|
24181f2bf6 | ||
|
|
fae3c12366 | ||
|
|
4e90dc4512 | ||
|
|
a4c7837fb3 | ||
|
|
764ab3be20 | ||
|
|
c6a2e287d0 | ||
|
|
d16a1bd922 | ||
|
|
b7ba508110 | ||
|
|
d9cde328cb | ||
|
|
6b20a6bc7c | ||
|
|
95c2e5beb3 | ||
|
|
194305a8bb | ||
|
|
b6912a3d87 | ||
|
|
1b4444ce9e | ||
|
|
b9869b666a | ||
|
|
cd7c99afdc | ||
|
|
2ec398e550 | ||
|
|
bdb71d94c2 | ||
|
|
7193902cc0 | ||
|
|
3faf5c43a8 | ||
|
|
6c7f0cb7cc | ||
|
|
54d36a7d1b | ||
|
|
9b164d20fd | ||
|
|
cd8b436566 | ||
|
|
87e90d640f | ||
|
|
db71cb8c63 | ||
|
|
a892018926 | ||
|
|
1643d623e4 | ||
|
|
9b84a8a402 | ||
|
|
db17d51ff1 | ||
|
|
736b000c19 | ||
|
|
187b8ece27 | ||
|
|
93288bccb3 | ||
|
|
444bc18fcf | ||
|
|
18be6315cb | ||
|
|
9c3ce58e57 | ||
|
|
d4a3aa7eda | ||
|
|
8d6ca9556f | ||
|
|
81a49bffee | ||
|
|
53a990579b | ||
|
|
a8d3cd9b15 | ||
|
|
5dfca79bcc | ||
|
|
ff429a8056 | ||
|
|
eafbfb8edf | ||
|
|
b72503e581 | ||
|
|
429cd8d37a | ||
|
|
6be09a27ca | ||
|
|
7298b00013 | ||
|
|
1d826a2c48 | ||
|
|
40445d7011 | ||
|
|
11e261ada4 | ||
|
|
c93f3a1136 | ||
|
|
e339dd542c | ||
|
|
3d23c8c419 | ||
|
|
89d28c8222 | ||
|
|
dff3bac441 | ||
|
|
798beab30e | ||
|
|
50e0f3b977 | ||
|
|
f754e2a7d7 | ||
|
|
1dd1bfe692 | ||
|
|
a74b572e1f | ||
|
|
a24911296a | ||
|
|
563cc07cb0 | ||
|
|
59f562f627 | ||
|
|
4981eb425e | ||
|
|
de8411a5e1 | ||
|
|
5be1c793a5 | ||
|
|
b4076e762c | ||
|
|
6ea628195f | ||
|
|
64487ded7c | ||
|
|
405955eaef | ||
|
|
0aaed47652 | ||
|
|
20606bc6de | ||
|
|
9cd38a6846 | ||
|
|
bf4afefaa1 | ||
|
|
f09b0dc224 | ||
|
|
658030ef49 | ||
|
|
4e8bfed5b1 | ||
|
|
5c47fa0d41 | ||
|
|
058f2e687c | ||
|
|
7d21335ac9 | ||
|
|
3d2b0cab93 | ||
|
|
bcf1cc6397 | ||
|
|
bff624c75a | ||
|
|
512be0a52a | ||
|
|
91f8281618 | ||
|
|
0e01729d77 | ||
|
|
fe1ee05186 | ||
|
|
ec957739e9 | ||
|
|
8d5005e03a | ||
|
|
7fbb245710 | ||
|
|
9bd548c4bd | ||
|
|
fe0ad0addb | ||
|
|
aa2511e209 | ||
|
|
3cf3344fa3 | ||
|
|
c79687f5f4 | ||
|
|
b9bd179e54 | ||
|
|
6c6deb7e8b | ||
|
|
d387eba0ba | ||
|
|
96eb83f19a | ||
|
|
89972b11b7 | ||
|
|
664b861f9d | ||
|
|
27f705bc48 | ||
|
|
325e9cb9fa | ||
|
|
50b10ef4a5 | ||
|
|
c0f8022a78 | ||
|
|
5d808cdc01 | ||
|
|
abefca500b | ||
|
|
7feea78991 | ||
|
|
9e5d479d03 | ||
|
|
26011a7151 | ||
|
|
bbb017dc24 | ||
|
|
04d3c9e750 | ||
|
|
e5fe9c6fc7 | ||
|
|
04821b1abc | ||
|
|
afab15f1a4 | ||
|
|
e61f6cfd38 | ||
|
|
90bea1499e | ||
|
|
99fa203673 | ||
|
|
1b41d9db90 | ||
|
|
c1d0179194 | ||
|
|
04463806a8 | ||
|
|
af01370cc1 | ||
|
|
4eb4bd6f96 | ||
|
|
d2d74cc5fa | ||
|
|
f53df495db | ||
|
|
f3268cade6 | ||
|
|
1a54ee895e | ||
|
|
27d4cb871f | ||
|
|
2312ad35dd | ||
|
|
85a84f5042 | ||
|
|
0fd979b147 | ||
|
|
ad595d2701 | ||
|
|
f6337a6446 | ||
|
|
f1b3e826d5 | ||
|
|
2afba3c137 | ||
|
|
e0d9a04f67 | ||
|
|
274f306315 | ||
|
|
c59c266afc | ||
|
|
9aca1ac775 | ||
|
|
3e83b4b39e | ||
|
|
d7eb174c88 | ||
|
|
c48b3ca16f | ||
|
|
951409f14b | ||
|
|
2075b119ac | ||
|
|
0d61029d7e | ||
|
|
2eb8c5e21a | ||
|
|
c0f9f2c6d7 | ||
|
|
f0f8d0e0ca | ||
|
|
5dc8e330b6 | ||
|
|
c9f2847420 | ||
|
|
fcb0ca305c | ||
|
|
fd161cd814 | ||
|
|
5913cdae89 | ||
|
|
8dde14f93e | ||
|
|
f5dc71ed35 | ||
|
|
e0ca250232 | ||
|
|
75ba52a52b | ||
|
|
a0a112ffe7 | ||
|
|
a891b3832c | ||
|
|
d6f89b285d | ||
|
|
e9a3f0f095 | ||
|
|
52a6cf1412 | ||
|
|
aeeade53f9 | ||
|
|
c05f716478 | ||
|
|
4aca94b08b | ||
|
|
3031fd2a7d | ||
|
|
7de2b040f8 | ||
|
|
0af969543d | ||
|
|
9e97393e3a | ||
|
|
be14e68a83 | ||
|
|
c1d99630c2 | ||
|
|
328a4fa644 | ||
|
|
ff82dc1ad5 | ||
|
|
17a6318ad6 | ||
|
|
0605180a61 | ||
|
|
ab953a534c | ||
|
|
0977574372 | ||
|
|
99bdfbe36f | ||
|
|
f70b02ae3b | ||
|
|
574e41119a | ||
|
|
8d31590a66 | ||
|
|
8a5277d53f | ||
|
|
fb6549a092 | ||
|
|
c649307720 | ||
|
|
bf0f3b65b4 | ||
|
|
b9a21ee3ae | ||
|
|
8d790010bf | ||
|
|
e29485fa59 | ||
|
|
ace172ebf3 | ||
|
|
bbfda019df | ||
|
|
5cc2adb421 | ||
|
|
90b3b72a91 | ||
|
|
dd4a3b0263 | ||
|
|
7d0cb9620b | ||
|
|
2c29bf5a21 | ||
|
|
80bc1cff5f | ||
|
|
a5f6d0f081 | ||
|
|
e223be32ce | ||
|
|
73d3698e2f | ||
|
|
5f5ad41ad3 | ||
|
|
7ba31d4447 | ||
|
|
224f5907b2 | ||
|
|
70f98fcc44 | ||
|
|
06edc0d52b | ||
|
|
af6d2a8c54 | ||
|
|
157f4b1270 | ||
|
|
66ff18a53e | ||
|
|
2a4adc895c | ||
|
|
d21bc8268b | ||
|
|
8b556a9435 | ||
|
|
a68a6665ac | ||
|
|
1e7c94759d | ||
|
|
9ec2a19cc0 | ||
|
|
9bc6b8be5a | ||
|
|
f8f8b665c3 | ||
|
|
31397d67ae | ||
|
|
dd8777093d | ||
|
|
2f55ffdf20 | ||
|
|
7c1a4522d6 | ||
|
|
3e8824908d | ||
|
|
28714979bd | ||
|
|
658091bfad | ||
|
|
e8e14ad1bf | ||
|
|
e544464354 | ||
|
|
969e59c599 | ||
|
|
f2d7f7aa6e | ||
|
|
a59b69758b | ||
|
|
c7d9b2ca92 | ||
|
|
2437d759b6 | ||
|
|
0434cb6fd6 | ||
|
|
556a5c8086 | ||
|
|
852ab79359 | ||
|
|
66063e5137 | ||
|
|
f03917ab7c | ||
|
|
5ed528a2ad | ||
|
|
81ae4599ae | ||
|
|
82090d2ea1 | ||
|
|
2e3b11b354 | ||
|
|
f3eaeb08ef | ||
|
|
3f97269988 | ||
|
|
1aed881313 | ||
|
|
3c78265e66 | ||
|
|
fcb21732e0 | ||
|
|
db0e86fa41 | ||
|
|
2e22498e5a | ||
|
|
264f695373 | ||
|
|
a2381c7e4c | ||
|
|
974118acec | ||
|
|
08ef528577 | ||
|
|
50b367c076 | ||
|
|
36b6ebc030 | ||
|
|
a89d61acf2 | ||
|
|
9e42a9ac7e | ||
|
|
19690193a4 | ||
|
|
78047b5bd8 | ||
|
|
9662d89cfb | ||
|
|
bc5b161260 | ||
|
|
c502e1d095 | ||
|
|
6c4ce86a34 | ||
|
|
7bac1ec7e5 | ||
|
|
7932c76d85 | ||
|
|
66c520cdae | ||
|
|
9453287a6b | ||
|
|
40e936911f | ||
|
|
d9121e50c3 | ||
|
|
cb15f40028 | ||
|
|
ce1d0464b8 | ||
|
|
bed531b604 | ||
|
|
257b3b6775 | ||
|
|
420ed91480 | ||
|
|
c6b17be744 | ||
|
|
d266f44ef3 | ||
|
|
5a2ac73b69 | ||
|
|
7996fc45f3 | ||
|
|
a03a37b1d9 | ||
|
|
76ac94f4f2 | ||
|
|
f4d3231034 | ||
|
|
b7ffeb51aa | ||
|
|
ed15a46ca4 | ||
|
|
c55a499009 | ||
|
|
d1be1281bc | ||
|
|
377dadd461 | ||
|
|
353baa9251 | ||
|
|
60106ac2c8 | ||
|
|
de7d4a5523 | ||
|
|
9b6cc75f1c | ||
|
|
18b26ff595 | ||
|
|
e44ffa02c9 | ||
|
|
5122917d62 | ||
|
|
3639a1af80 | ||
|
|
851b842033 | ||
|
|
072a00ba18 | ||
|
|
7e0b66835b | ||
|
|
73e671893b | ||
|
|
fd682cd470 | ||
|
|
bfd94d64ba | ||
|
|
d8539af412 | ||
|
|
cd7a6fc9fe | ||
|
|
41380ff769 | ||
|
|
0ed7367c97 | ||
|
|
eab09a2f7c | ||
|
|
de795b1a6e | ||
|
|
73546a135a | ||
|
|
c888d856ee | ||
|
|
c81af531a3 | ||
|
|
6743669ab8 | ||
|
|
320387db89 | ||
|
|
4cad1a87df | ||
|
|
22cb6dded7 | ||
|
|
537b317273 | ||
|
|
795a817a33 | ||
|
|
067a7ad7e9 | ||
|
|
3863de9589 | ||
|
|
443d3c98dd | ||
|
|
602def9bdd | ||
|
|
3d1d1b439d | ||
|
|
49e907e5f6 | ||
|
|
c4a8c6798b | ||
|
|
21e48a8e12 | ||
|
|
a7d170adda | ||
|
|
91b71f7a9f | ||
|
|
641679f7e7 | ||
|
|
ed4594c76b | ||
|
|
997a77b3de | ||
|
|
6fa4307005 | ||
|
|
f3efbe50bb | ||
|
|
ce6f4dffe5 | ||
|
|
a0b0892df3 | ||
|
|
e163055f6a | ||
|
|
7acc34b48b | ||
|
|
a9827c662e | ||
|
|
9a8a42e819 | ||
|
|
5516dbcb1f | ||
|
|
b7cdb5840a | ||
|
|
61d798c629 | ||
|
|
973fbc98be | ||
|
|
3d634df34d | ||
|
|
ad284491e6 | ||
|
|
f946de4450 | ||
|
|
377c6ed0ce | ||
|
|
1609d8a92f | ||
|
|
169cad6059 | ||
|
|
bba4790002 | ||
|
|
c943e26913 | ||
|
|
7d1fd0b0a3 | ||
|
|
6d653b3c0f | ||
|
|
5936d00b5e | ||
|
|
5af4552511 | ||
|
|
0310c733d5 | ||
|
|
0e6c32f75e | ||
|
|
93ab972ddc | ||
|
|
35c3acdf05 | ||
|
|
103236fdca | ||
|
|
62848b1a68 | ||
|
|
64ef651d4d | ||
|
|
1a620acc17 | ||
|
|
6e71208db3 | ||
|
|
8e205e0324 | ||
|
|
9578fadae2 | ||
|
|
1ec823bf5e | ||
|
|
2471410fe5 | ||
|
|
3fb5ae4fdc | ||
|
|
4450b37ff5 | ||
|
|
309597bbda | ||
|
|
7dbf836217 | ||
|
|
5249f3358f | ||
|
|
1f91fd3f7d | ||
|
|
01676717e2 | ||
|
|
1cfb1af56e | ||
|
|
ef741ef80d | ||
|
|
6119e03081 | ||
|
|
6d945e6a61 | ||
|
|
6fc7ed55cf | ||
|
|
8b590e2330 | ||
|
|
ec711b008e | ||
|
|
e5b00d89fb | ||
|
|
be55f080e4 | ||
|
|
e1aab829ca | ||
|
|
e56dd15a4b | ||
|
|
103ae9df4a | ||
|
|
b5f0c07eb3 | ||
|
|
eb3a81a874 | ||
|
|
1e96510815 | ||
|
|
04d8c859d8 | ||
|
|
b11da67679 | ||
|
|
c8322ffd2a | ||
|
|
f63713694c | ||
|
|
7a97cd70aa | ||
|
|
48b4891f6e | ||
|
|
5d40c0c1ce | ||
|
|
e8f5706382 | ||
|
|
98f39c698f | ||
|
|
c6eda9bd80 | ||
|
|
87b08d6c7f | ||
|
|
5f7e670ebc | ||
|
|
e8fec3eed6 | ||
|
|
dc8b4eeb40 | ||
|
|
4f87fbd5ae | ||
|
|
df3f7dc1bc | ||
|
|
8e85d889f1 | ||
|
|
f687b0f3b9 | ||
|
|
5b87f68900 | ||
|
|
7221199f74 | ||
|
|
6006051fb9 | ||
|
|
63048fb89f | ||
|
|
a90aa78c6e | ||
|
|
70acd4b2d5 | ||
|
|
1a80f166c5 | ||
|
|
935dcf8b18 | ||
|
|
b915b0adc4 | ||
|
|
6e6b671a66 | ||
|
|
e1333c9421 | ||
|
|
ab8ef5750d | ||
|
|
7c20ba84e4 | ||
|
|
78497c03ca | ||
|
|
128ba65109 | ||
|
|
f80b4b9fd9 | ||
|
|
7f6b6d7e13 | ||
|
|
51104454aa | ||
|
|
2f47bbde30 | ||
|
|
b078224753 | ||
|
|
0f27d139bd | ||
|
|
77a875735a | ||
|
|
32753c3f69 | ||
|
|
7d2eb71094 | ||
|
|
0de54cddaa | ||
|
|
4002653334 | ||
|
|
adb48b5c9e | ||
|
|
7f928a6573 | ||
|
|
f1427fc02a | ||
|
|
8ce798abed | ||
|
|
dd0c1575f5 | ||
|
|
4b9c1d8f2b | ||
|
|
be65c4acd2 | ||
|
|
d22b95ded3 | ||
|
|
c11d9b7b5c | ||
|
|
42fddf8390 | ||
|
|
589b416ca8 | ||
|
|
4738d77c88 | ||
|
|
64bc008c3a | ||
|
|
236e02a2dd | ||
|
|
cb5b688eb9 | ||
|
|
c39a342fe5 | ||
|
|
07502ce6bb | ||
|
|
48b2456845 | ||
|
|
894c7411e7 | ||
|
|
ea78d85d35 | ||
|
|
04aeaa25e5 | ||
|
|
9d67f9fc8e | ||
|
|
1cc7277996 | ||
|
|
a9f0e47ea3 | ||
|
|
bbc21cf063 | ||
|
|
f722aa3325 | ||
|
|
eb0a33302a | ||
|
|
151828752c | ||
|
|
6a8fb48c13 | ||
|
|
07b87f6f1f | ||
|
|
905b0c4aef | ||
|
|
6505ce47ae | ||
|
|
31d7b3eb97 | ||
|
|
80d89c20fd | ||
|
|
1a94338389 | ||
|
|
dd899fde29 | ||
|
|
1bf796d69a | ||
|
|
c12d76686e | ||
|
|
199821a247 | ||
|
|
840f383e46 | ||
|
|
1459085a4d | ||
|
|
6f6340644b | ||
|
|
b134867f31 | ||
|
|
01bf32b998 | ||
|
|
f14cc2edab | ||
|
|
f0c4fc1e22 | ||
|
|
f891f4c963 | ||
|
|
9f28f4f803 | ||
|
|
0e49336b96 | ||
|
|
941e918b46 | ||
|
|
74e75d7fbc | ||
|
|
58db6542f8 | ||
|
|
fca2a05adf | ||
|
|
4639978b3a | ||
|
|
870d348d77 | ||
|
|
db8ec81e9f | ||
|
|
1d9a2dce94 | ||
|
|
12ea494477 | ||
|
|
b60b591d06 | ||
|
|
9fbc68bda1 | ||
|
|
132569d12b | ||
|
|
319d2be1af | ||
|
|
29911cf114 | ||
|
|
8be72b0be1 | ||
|
|
6359445a8e | ||
|
|
c783764d0b | ||
|
|
ff378a8c5b | ||
|
|
03c3040a1d | ||
|
|
cc4e21e7a7 | ||
|
|
bb34aafa45 | ||
|
|
6dfd268ef1 | ||
|
|
838c5ba7de | ||
|
|
4ab990ad5b | ||
|
|
13cd25e7b0 | ||
|
|
2b41323fe6 | ||
|
|
7bf47b1982 | ||
|
|
22d71d5a8b | ||
|
|
3956530634 | ||
|
|
e87d60ddf7 | ||
|
|
85a1f91f59 | ||
|
|
dc90740549 | ||
|
|
d111af922a | ||
|
|
40c21b6d0f | ||
|
|
4dd110ce5e | ||
|
|
d6bdeed38f | ||
|
|
e8fb7ad470 | ||
|
|
5b68286e07 | ||
|
|
bb12d79ae9 | ||
|
|
d657b61f1b | ||
|
|
42a77c531a | ||
|
|
5347278136 | ||
|
|
ca5c25ac04 | ||
|
|
bb35b997b8 | ||
|
|
9c95e4bb4f | ||
|
|
e63195a940 | ||
|
|
0836293d1a | ||
|
|
330672e030 | ||
|
|
150d143755 | ||
|
|
e63c5e6c69 | ||
|
|
69080014b0 | ||
|
|
f051065582 | ||
|
|
585c4b8c69 | ||
|
|
dad1de1865 | ||
|
|
6f1357c6f8 | ||
|
|
336228f357 | ||
|
|
df553e9360 | ||
|
|
ddc0caa605 | ||
|
|
0df358a550 | ||
|
|
9da428dccf | ||
|
|
46fa8197a2 | ||
|
|
52d798ff40 | ||
|
|
256b2fa3e1 | ||
|
|
d8bcaa4fa4 | ||
|
|
7a5841b637 | ||
|
|
358fdd54b9 | ||
|
|
45a74023a7 | ||
|
|
6f3f46c7ba | ||
|
|
2064ffd64b | ||
|
|
685bd763f9 | ||
|
|
0f3ac4cb9f | ||
|
|
208294b0d3 | ||
|
|
cf052996d3 | ||
|
|
4961c84f12 | ||
|
|
2f598e5680 | ||
|
|
951f484fad | ||
|
|
c086bba71a | ||
|
|
5a02b5fd23 | ||
|
|
50a1e540a0 | ||
|
|
b8738dee90 | ||
|
|
a7e7eeec38 | ||
|
|
1d480e3329 | ||
|
|
3b427824a7 | ||
|
|
3a1f5bc13a | ||
|
|
923c38f7cd | ||
|
|
ee6d38a770 | ||
|
|
dd524b56fa | ||
|
|
4fe4c9aa63 | ||
|
|
e3bc77c386 | ||
|
|
cacbad1bd8 | ||
|
|
cc8552f81e | ||
|
|
34a60b56f6 | ||
|
|
25f7fdcb40 | ||
|
|
b6d3063ada | ||
|
|
c2cf0ae8c6 | ||
|
|
7f5186d489 | ||
|
|
e67f389da1 | ||
|
|
4ebc164c11 | ||
|
|
886d0da57c | ||
|
|
2912096f6e | ||
|
|
ba55409c86 | ||
|
|
f3185de7f5 | ||
|
|
c1b6000248 | ||
|
|
0a468a07a7 | ||
|
|
6d48b5484d | ||
|
|
3a862334fc | ||
|
|
cd1c0aace3 | ||
|
|
6e54cad44c | ||
|
|
a71ef16423 | ||
|
|
2495a86aff | ||
|
|
5225d12381 | ||
|
|
e096202b1f | ||
|
|
44ace04b95 | ||
|
|
507a34b3d0 | ||
|
|
677d9abd07 | ||
|
|
e66726e931 | ||
|
|
cda778a94d | ||
|
|
a799a5f978 | ||
|
|
f5a6d85bc2 | ||
|
|
8535688605 | ||
|
|
8788f13e11 | ||
|
|
aee5b59c51 | ||
|
|
66a7e749e8 | ||
|
|
e2b9308b11 | ||
|
|
97bbad5aea | ||
|
|
d452094f43 | ||
|
|
139f390317 | ||
|
|
9ee1045aad | ||
|
|
25c85fab18 | ||
|
|
095a0a6439 | ||
|
|
bf36d9eb48 | ||
|
|
9d24e906a8 | ||
|
|
44e4d1bd6c | ||
|
|
ab5770c492 | ||
|
|
a90eab8b9a | ||
|
|
e54e4dd532 | ||
|
|
c856ba2a49 | ||
|
|
1087e3f59e | ||
|
|
cfb49c7316 | ||
|
|
a3fad2e171 | ||
|
|
dd5db8484a | ||
|
|
5affd51250 | ||
|
|
ce27b5ebce | ||
|
|
fce9cd8c22 | ||
|
|
8faa916d93 | ||
|
|
e52802162c | ||
|
|
f3ec246b67 | ||
|
|
434c9ceb5d | ||
|
|
c3fb81d1a1 | ||
|
|
c340f57207 | ||
|
|
bbe1bf9c3a | ||
|
|
accda1211b | ||
|
|
daee1f4cb8 | ||
|
|
87cb10c558 | ||
|
|
904651ada9 | ||
|
|
1d3ce93107 | ||
|
|
103dcdeea8 | ||
|
|
f77531138a | ||
|
|
c8b3b060aa | ||
|
|
7780ee6a34 | ||
|
|
2e2625e952 | ||
|
|
55c3eb7c14 | ||
|
|
a7a9855493 | ||
|
|
5eaaee0dbe | ||
|
|
b2bc718c1f | ||
|
|
7118ad494c | ||
|
|
582e0e718c | ||
|
|
1713583a19 | ||
|
|
38aef49428 | ||
|
|
a9caf3fbe4 | ||
|
|
80ff844dc2 | ||
|
|
c53be5a3fb | ||
|
|
6addd6cf1e | ||
|
|
3995d2f4a2 | ||
|
|
b95dc611d6 | ||
|
|
4cccf74664 | ||
|
|
8cc48d5688 | ||
|
|
b76bd57ed1 | ||
|
|
2afc218767 | ||
|
|
5bbaa30655 | ||
|
|
5440cd4b50 | ||
|
|
e686ff78e9 | ||
|
|
2bd77722c7 | ||
|
|
00f69bc70d | ||
|
|
d1609e771a | ||
|
|
89f813f113 | ||
|
|
9b0fbf000e | ||
|
|
725d16e18e | ||
|
|
e42a205a51 | ||
|
|
0d5f185267 | ||
|
|
c146a215fb | ||
|
|
eef7b5e168 | ||
|
|
a753b6ce46 | ||
|
|
793e12f8f3 | ||
|
|
751e6430fa | ||
|
|
9eb20c2be7 | ||
|
|
5e460394d2 | ||
|
|
88043e144a | ||
|
|
3cc7774fe4 | ||
|
|
a04243aaf4 | ||
|
|
5a95183c3e | ||
|
|
6a5aa18a7b | ||
|
|
4b3c40f35b | ||
|
|
79fba6c2ac | ||
|
|
4f217b19a9 | ||
|
|
202333c881 | ||
|
|
2ce0395fd8 | ||
|
|
bbdf181828 | ||
|
|
0181c6025a | ||
|
|
6eff83c1eb | ||
|
|
5aae0f2379 | ||
|
|
49ae4a834f | ||
|
|
5b650434b0 | ||
|
|
e612f7cd7d | ||
|
|
7cc4aa2a28 | ||
|
|
60f5d0e34a | ||
|
|
46c5a90ba1 | ||
|
|
1273c573b6 | ||
|
|
3a2895af19 | ||
|
|
0bffac6c98 | ||
|
|
c25de5dba3 | ||
|
|
60edfa4d77 | ||
|
|
52e582132f | ||
|
|
a888041ba4 | ||
|
|
844af06782 | ||
|
|
7da3404bd0 | ||
|
|
7676f47540 | ||
|
|
9d7a58f6a7 | ||
|
|
9bd3d2aa5c | ||
|
|
28e782dda5 | ||
|
|
597098845c | ||
|
|
8a7deae238 | ||
|
|
73f2c7043c | ||
|
|
de24035066 | ||
|
|
57ea1dbdd3 | ||
|
|
9f73f09cec | ||
|
|
d56b21d329 | ||
|
|
8d60bc11b5 | ||
|
|
604f4c666b | ||
|
|
ff5175ec76 | ||
|
|
6aebd5dd95 | ||
|
|
3d4bed3374 | ||
|
|
ee7a77643e | ||
|
|
646d6c368c | ||
|
|
d96e14fe16 | ||
|
|
3a9d450106 | ||
|
|
a73ef9fc06 | ||
|
|
3016b64fac | ||
|
|
22498e0b09 | ||
|
|
79dff674fd | ||
|
|
56ef7ca9e7 | ||
|
|
9db50753f1 | ||
|
|
e84e1bbf36 | ||
|
|
fda337a1c0 | ||
|
|
f49f91da08 | ||
|
|
90535a1401 | ||
|
|
43719b5fd1 | ||
|
|
2a94f8cdb4 | ||
|
|
1e578f1a50 | ||
|
|
a036d2373a | ||
|
|
a2b303e95a | ||
|
|
7b964fa700 | ||
|
|
72f5f9d133 | ||
|
|
186a6bc080 | ||
|
|
567d9f7910 | ||
|
|
d70cf314d8 | ||
|
|
c6445da654 | ||
|
|
96cde52838 | ||
|
|
c67a0d3dd8 | ||
|
|
78c0e5f6b6 | ||
|
|
f82e7df0ba | ||
|
|
640a001ab6 | ||
|
|
c5c5f8754c | ||
|
|
5be3bf4f26 | ||
|
|
d132fc0a73 | ||
|
|
285a33c97d | ||
|
|
f09ac23144 | ||
|
|
734752d6b5 | ||
|
|
4fc6c4ff5c | ||
|
|
746d373362 | ||
|
|
2256f5fb4b | ||
|
|
d8e2c95597 | ||
|
|
6506240642 | ||
|
|
bd284347da | ||
|
|
3813f9772a | ||
|
|
1902d1a06b | ||
|
|
7ecabb25eb | ||
|
|
5b633a83df | ||
|
|
beb8bf498c | ||
|
|
de764d8490 | ||
|
|
5635c1318c | ||
|
|
01713c74f9 | ||
|
|
9ec66f0594 | ||
|
|
6947bddd3f | ||
|
|
37ec636018 | ||
|
|
9bba6613e7 | ||
|
|
d4f246517c | ||
|
|
5bfebe7a3f | ||
|
|
3df67362b4 | ||
|
|
f1042e7fb1 | ||
|
|
b29112efdf | ||
|
|
fe899eecc7 | ||
|
|
c2a2ec121f | ||
|
|
e1e1fa23b7 | ||
|
|
aee8d35dc4 | ||
|
|
4bbbf5d2e3 | ||
|
|
ba7e832c5d | ||
|
|
bbfc092a31 | ||
|
|
de52cf1cdd | ||
|
|
783c05fd6c | ||
|
|
6ae98e2e6d | ||
|
|
ffc099eb54 | ||
|
|
9321067b68 | ||
|
|
0eaa1f7a08 | ||
|
|
18f90ca1e3 | ||
|
|
9a35743df6 | ||
|
|
8d63a3c1f3 | ||
|
|
1ac33caa90 | ||
|
|
1c361bf545 | ||
|
|
a41dd48986 | ||
|
|
b931b67cba | ||
|
|
24435e9ca1 | ||
|
|
e54ff599ca | ||
|
|
04969b6be0 | ||
|
|
1ddf1dbc25 | ||
|
|
8699f5592f | ||
|
|
73d089da36 | ||
|
|
c8cd09e72c | ||
|
|
be1ef01f10 | ||
|
|
0a1bc1f4b7 | ||
|
|
bcb7f45201 | ||
|
|
33db0e0d4d | ||
|
|
504539ad1e | ||
|
|
a62fce8dc5 | ||
|
|
81a78cf1d0 | ||
|
|
283135c9cd | ||
|
|
22d4d5c1c1 | ||
|
|
9c372c36c1 | ||
|
|
9767c4db0e | ||
|
|
9812799b24 | ||
|
|
d385749ead | ||
|
|
23ed5d3936 | ||
|
|
cebc963396 | ||
|
|
0c8ec41c21 | ||
|
|
9f7b8c1a17 | ||
|
|
cd92b32622 | ||
|
|
5853a68904 | ||
|
|
ae64830bd5 | ||
|
|
e8878eee8a | ||
|
|
3897ddea03 | ||
|
|
6858270517 | ||
|
|
4e57b6eceb | ||
|
|
298f317f44 | ||
|
|
5820ad8309 | ||
|
|
b7fbe65ff2 | ||
|
|
d1cf216384 | ||
|
|
3011dc5876 | ||
|
|
6e99f00f5c | ||
|
|
beb1e084a6 | ||
|
|
e34b443c29 | ||
|
|
6b17bb647e | ||
|
|
4299b85cdb | ||
|
|
6dae147785 | ||
|
|
e4255e4c8b | ||
|
|
161274f785 | ||
|
|
6145cdcf37 | ||
|
|
b57a4c98cf | ||
|
|
a3e43aca87 | ||
|
|
6b6915e304 | ||
|
|
3f83ac5580 | ||
|
|
7f57de1b74 | ||
|
|
648382db74 | ||
|
|
2c510bb7f9 | ||
|
|
23710dff5e | ||
|
|
ff0436357b | ||
|
|
091e5157aa | ||
|
|
c1e181a407 | ||
|
|
8f71c90ca8 | ||
|
|
f85ec313de | ||
|
|
2aa6471608 | ||
|
|
9814fc5447 | ||
|
|
3655ea77a3 | ||
|
|
89d35bc41e | ||
|
|
93639532f0 | ||
|
|
8cf7aaad65 | ||
|
|
25a8ef3b7c | ||
|
|
b18a56c2c4 | ||
|
|
9d42e3f69b | ||
|
|
11ef8e1ff2 | ||
|
|
1deab4a67f | ||
|
|
f23c70e068 | ||
|
|
f7c818d303 | ||
|
|
7996cf06ab | ||
|
|
4800bcf5a0 | ||
|
|
4c74f4792c | ||
|
|
57d080d4f8 | ||
|
|
2778debc29 | ||
|
|
7182c10c90 | ||
|
|
7309bcf4b5 | ||
|
|
309bc2083e | ||
|
|
6e098a9d17 | ||
|
|
573b6d3345 | ||
|
|
077fa355ce | ||
|
|
e76ce05844 | ||
|
|
4622ddb46f | ||
|
|
972e1893c9 | ||
|
|
af29dcf557 | ||
|
|
f82714f341 | ||
|
|
02d68fdb97 | ||
|
|
065b9fdb46 | ||
|
|
18dbd75860 | ||
|
|
3ac970ac1d | ||
|
|
3aaed7188f | ||
|
|
ee64e29e77 | ||
|
|
cfba429c15 | ||
|
|
25aa25c6a0 | ||
|
|
2afc02051c | ||
|
|
ce1b813105 | ||
|
|
7ed1d7f11d | ||
|
|
6ccd65bd8e | ||
|
|
18b621c2fe | ||
|
|
cb61a28362 | ||
|
|
4d7d208940 | ||
|
|
f7509a5b78 | ||
|
|
a54c04d247 | ||
|
|
e70c04ef86 | ||
|
|
6410e88698 | ||
|
|
a3cb9d9897 | ||
|
|
b2a7ac2996 | ||
|
|
5f350adb57 | ||
|
|
1485cd9d24 | ||
|
|
65d72fb07a | ||
|
|
4871c7bba0 | ||
|
|
97e2968986 | ||
|
|
eb9a9bf23d | ||
|
|
c51b4b5742 | ||
|
|
9b7915facb | ||
|
|
f0de187bbb | ||
|
|
539110c0b1 | ||
|
|
d7b1a89087 | ||
|
|
c50252fb35 | ||
|
|
54002e6e6b | ||
|
|
16994d637b | ||
|
|
b541a0d448 | ||
|
|
d4e0d2f578 | ||
|
|
fab2fc874f | ||
|
|
54643d6878 | ||
|
|
2653fad0c4 | ||
|
|
b752d22a77 | ||
|
|
ad12b42d1c | ||
|
|
c845a2d943 | ||
|
|
b7e06a0b5b | ||
|
|
417dd59b22 | ||
|
|
3024720656 | ||
|
|
f23eab735b | ||
|
|
112c32eb54 | ||
|
|
3103ce1fa8 | ||
|
|
db18fc42fe | ||
|
|
d28fe9e938 | ||
|
|
31a035a907 | ||
|
|
91412c6c52 | ||
|
|
068324536c | ||
|
|
bb6eb0f6ea | ||
|
|
c1012e6a45 | ||
|
|
23d21d77e9 | ||
|
|
8c44b17e86 | ||
|
|
636e0f6444 | ||
|
|
fafa409cf9 | ||
|
|
dbecceec09 | ||
|
|
60f390ddf8 | ||
|
|
c79ebc93a2 | ||
|
|
55ab694d79 | ||
|
|
f5c5479faa | ||
|
|
ba9b612c4f | ||
|
|
7b0771659e | ||
|
|
e9762ee25f | ||
|
|
7549189f88 | ||
|
|
a5bc031cca | ||
|
|
5cd684997a | ||
|
|
93d3a0848a | ||
|
|
f1b1dd26cf | ||
|
|
cd5e906bd0 | ||
|
|
c589660182 | ||
|
|
8a8aa85726 | ||
|
|
105b2c9b7a | ||
|
|
f6435d91fc | ||
|
|
3e3fb63863 | ||
|
|
4007cee852 | ||
|
|
b622a5a788 | ||
|
|
ec9e40695d | ||
|
|
0ad0153626 | ||
|
|
cd37bff514 | ||
|
|
27c2a66bbd | ||
|
|
58247737fd | ||
|
|
ebcca179ed | ||
|
|
60d37f690c | ||
|
|
0ed5655086 | ||
|
|
87a6368ba1 | ||
|
|
1cbd77c806 | ||
|
|
e3f82b09d7 | ||
|
|
d4a3db22bd | ||
|
|
43f28e0451 | ||
|
|
d516515c7a | ||
|
|
7ac32ea60c | ||
|
|
07a40d028a | ||
|
|
a47adecdcd | ||
|
|
355d94f5df | ||
|
|
c0789a6c0e | ||
|
|
530144b040 | ||
|
|
c85bc38802 | ||
|
|
a8dd7dd2fa | ||
|
|
6e86d6d699 | ||
|
|
2954abb58a | ||
|
|
5bb366513b | ||
|
|
4bcc75365c | ||
|
|
288f79270d | ||
|
|
3c62a33a25 | ||
|
|
80a84bef26 | ||
|
|
022fac0d37 | ||
|
|
5ab1505d43 | ||
|
|
1297a8fb57 | ||
|
|
732215a83f | ||
|
|
e11addec7d | ||
|
|
2166a4b17f | ||
|
|
291587f545 | ||
|
|
97df705e53 | ||
|
|
e281174dae | ||
|
|
ed73feddc5 | ||
|
|
c5706e8f4a | ||
|
|
1782c6be79 | ||
|
|
cccfd0719d | ||
|
|
edc9545229 | ||
|
|
cc611834c9 | ||
|
|
bbd27a54d3 | ||
|
|
5a06751242 | ||
|
|
6df8b44616 | ||
|
|
e0af9c2d8b | ||
|
|
11a7ac0536 | ||
|
|
5c25e0bdb0 | ||
|
|
222f214341 | ||
|
|
eefe91ee41 | ||
|
|
979d823d85 | ||
|
|
76438a3f85 | ||
|
|
b0271ae5e1 | ||
|
|
6a063364da | ||
|
|
99b632f86c | ||
|
|
180f9e6384 | ||
|
|
94b63924ed | ||
|
|
d0bf6d2b52 | ||
|
|
9a82bbb54d | ||
|
|
400039e1b6 | ||
|
|
2e5166efd7 | ||
|
|
2ec3aaf639 | ||
|
|
ab5187d673 | ||
|
|
697d496093 | ||
|
|
a17c5e30b7 | ||
|
|
8d6285927b | ||
|
|
90a91f3536 | ||
|
|
c8b7710e5d | ||
|
|
59c60b8031 | ||
|
|
9500e8b6e1 | ||
|
|
e0ee56275e | ||
|
|
418ac4c560 | ||
|
|
5f5d709c07 | ||
|
|
89a38723bd | ||
|
|
648bcd1505 | ||
|
|
bf92232698 | ||
|
|
aec1178ab1 | ||
|
|
efe7f5172d | ||
|
|
0aedabd245 | ||
|
|
4a7b0e99a6 | ||
|
|
614f7fa56a | ||
|
|
6d230134cb | ||
|
|
d953030c0e | ||
|
|
6fe80c3cc7 | ||
|
|
afa0e26a6a | ||
|
|
1d3bbde70a | ||
|
|
6f0c6501f2 | ||
|
|
e448022f23 | ||
|
|
664d858e63 | ||
|
|
ede009edf9 | ||
|
|
08aa7d310a | ||
|
|
19bf0fdeb8 | ||
|
|
36111a2edf | ||
|
|
ab017607a2 | ||
|
|
2c47cd5c94 | ||
|
|
44ce1b37c1 | ||
|
|
9a52a93c24 | ||
|
|
b2c59576ae | ||
|
|
7f8fe00cdc | ||
|
|
c0e8336e98 | ||
|
|
155e214a69 | ||
|
|
4911acedf5 | ||
|
|
01bd87e90b | ||
|
|
65f402807f | ||
|
|
d00cfd7cff | ||
|
|
701b1d41e8 | ||
|
|
8ae5c906d0 | ||
|
|
43a8118d2e | ||
|
|
ca850c787f | ||
|
|
4491c070be | ||
|
|
a97b8043b5 | ||
|
|
4967166811 | ||
|
|
cc2828cf3a | ||
|
|
1dd68ce04b | ||
|
|
23f3112e3e | ||
|
|
6894ced63b | ||
|
|
2a3cebdd6e | ||
|
|
66d5359d75 | ||
|
|
fa48054959 | ||
|
|
808ff3714e | ||
|
|
a98f78afd9 | ||
|
|
4c14af4d8a | ||
|
|
817ff6ca68 | ||
|
|
3c6fe6e741 | ||
|
|
bb5827b4e3 | ||
|
|
581785a48f | ||
|
|
65f75589e9 | ||
|
|
6e38b53001 | ||
|
|
354e310c87 | ||
|
|
2cff12e1fb | ||
|
|
55e99e16ef | ||
|
|
e499a04de7 | ||
|
|
abdf422681 | ||
|
|
fd8a209da2 | ||
|
|
15b27a1e9d | ||
|
|
b113f869bb | ||
|
|
6fb7022508 | ||
|
|
cc437a5eca | ||
|
|
312f801f8a | ||
|
|
8509687c8d | ||
|
|
ce633c0bba | ||
|
|
2fc6cedcc0 | ||
|
|
468270f6e9 | ||
|
|
32323abe8e | ||
|
|
1113c4f6a2 | ||
|
|
e855638266 | ||
|
|
f3a7d3750f | ||
|
|
1bdd18a196 | ||
|
|
0c20bb6ab9 | ||
|
|
d01cc3bf41 | ||
|
|
9cf5da85ef | ||
|
|
316f9e4df3 | ||
|
|
18e586daed | ||
|
|
1fdd5b636b | ||
|
|
b8ed80b7dd | ||
|
|
cb6377355e | ||
|
|
322bacd380 | ||
|
|
99cb585b6e | ||
|
|
0037edfeee | ||
|
|
a7fe4a502d | ||
|
|
ea2b330158 | ||
|
|
86cacd23bb | ||
|
|
85b1563e57 | ||
|
|
35c724512d | ||
|
|
ff07654560 | ||
|
|
695a212877 | ||
|
|
686dd8affd | ||
|
|
3acb509b9e | ||
|
|
874172ca76 | ||
|
|
114de7721f | ||
|
|
ceae637416 | ||
|
|
23c2606ce0 | ||
|
|
67a3c2ea4b | ||
|
|
2d03e622f1 | ||
|
|
b9f0318ab8 | ||
|
|
08ac64bba9 | ||
|
|
f018dac506 | ||
|
|
607fe83c63 | ||
|
|
f73c63900f | ||
|
|
2fad5eff95 | ||
|
|
1f56ffa51a | ||
|
|
ce149397ec | ||
|
|
a7835650e8 | ||
|
|
83ead086a1 | ||
|
|
91c8e70bef | ||
|
|
38dcdeeb04 | ||
|
|
1c77ea2b03 | ||
|
|
82d50912f6 | ||
|
|
4c113182b0 | ||
|
|
7ced122ddc | ||
|
|
6b09ac59f0 | ||
|
|
ee38504d81 | ||
|
|
dd505edd19 | ||
|
|
fa1aa33f83 | ||
|
|
907de9d37f | ||
|
|
5c7436bf10 | ||
|
|
0b77e8ea62 | ||
|
|
875858b2cc | ||
|
|
fe426e6f8f | ||
|
|
1e379cb3a9 | ||
|
|
ead385dd17 | ||
|
|
b87e21a392 | ||
|
|
04e8ba716c | ||
|
|
193a401097 | ||
|
|
53a83fb76e | ||
|
|
47e6d72bf2 | ||
|
|
91ce57848c | ||
|
|
22d7871e1d | ||
|
|
4189157d10 | ||
|
|
eaefcc2c6f | ||
|
|
92bdcbf1fe | ||
|
|
c011d54158 | ||
|
|
d782499541 | ||
|
|
59f9af23b9 | ||
|
|
70a236cccd | ||
|
|
d33bef2e49 | ||
|
|
fbae7767b4 | ||
|
|
17d32b3e15 | ||
|
|
6380ad1c80 | ||
|
|
0c3d3e7c8f | ||
|
|
3b0d694f42 | ||
|
|
c7e79030dd | ||
|
|
58a0f5c30b | ||
|
|
c92a9ce591 | ||
|
|
605f9abf96 | ||
|
|
e4412a3e56 | ||
|
|
1fe9b07c99 | ||
|
|
2da604a6e2 | ||
|
|
fc7b983a40 | ||
|
|
6399fc12ac | ||
|
|
db6e013577 | ||
|
|
71ce1442c8 | ||
|
|
5dd1abcc2d | ||
|
|
4dafdbd5b7 | ||
|
|
949130d80e | ||
|
|
4c8369ab1b | ||
|
|
fcdad00044 | ||
|
|
417191bdbd | ||
|
|
c00666b7e8 | ||
|
|
854a154fb4 | ||
|
|
7e7eff0eb7 | ||
|
|
48a361107f | ||
|
|
716453aaa1 | ||
|
|
63e69d35e0 | ||
|
|
a0c71cffd4 | ||
|
|
d1da5b9e16 | ||
|
|
52ec4526e1 | ||
|
|
e199acca05 | ||
|
|
cea842b256 | ||
|
|
984bddcedd | ||
|
|
d32e8390c2 | ||
|
|
57e650ef2c | ||
|
|
c34176580c | ||
|
|
807f5d9af1 | ||
|
|
d18f8eea2b | ||
|
|
8d62f21b40 | ||
|
|
7b1e3a9d63 | ||
|
|
070a24956d | ||
|
|
dec2d897c3 | ||
|
|
8625146011 | ||
|
|
24eea0b653 | ||
|
|
18b3253cac | ||
|
|
25484f870e | ||
|
|
ac0ecdf855 | ||
|
|
399487c85d | ||
|
|
bc14a32998 | ||
|
|
cf2c9f8d88 | ||
|
|
186c35bb09 | ||
|
|
3a2de0d9a3 | ||
|
|
1b489820a9 | ||
|
|
ef8140cce5 | ||
|
|
790a57041c | ||
|
|
e43b848ac8 | ||
|
|
59347d2560 | ||
|
|
2b14284e2b | ||
|
|
c107aba913 | ||
|
|
e337b844e5 | ||
|
|
90d07741aa | ||
|
|
87015df66c | ||
|
|
d9a0f76e7a | ||
|
|
0ecc48e6de | ||
|
|
efe0887247 | ||
|
|
3c4c460f82 | ||
|
|
ab3efc0a33 | ||
|
|
e1e67d8330 | ||
|
|
de4c31e557 | ||
|
|
5a59d295a4 | ||
|
|
fe5ada85cb | ||
|
|
b55358c535 | ||
|
|
1b059649ff | ||
|
|
45f3ccc42a | ||
|
|
4d34f9f9f4 | ||
|
|
62232f9a35 | ||
|
|
a25c656b1a | ||
|
|
ed0d76552b | ||
|
|
43315444a8 | ||
|
|
c055986e38 | ||
|
|
7ec37b2d8d | ||
|
|
64fac6cee7 | ||
|
|
12127a7bd2 | ||
|
|
eaed28f68d | ||
|
|
4a102fb58c | ||
|
|
ae7fbd6b1a | ||
|
|
72478a9e31 | ||
|
|
811410fdbb | ||
|
|
5738e53be2 | ||
|
|
be4d8b24e2 | ||
|
|
1f77f37310 | ||
|
|
7e174e73be | ||
|
|
ff23d665c6 | ||
|
|
00daecf838 | ||
|
|
f8f9f710e5 | ||
|
|
e77362e7b9 | ||
|
|
c58acbd444 | ||
|
|
e2c1ce2add | ||
|
|
fc1b7a626c | ||
|
|
a7825ef292 | ||
|
|
8dd391371c | ||
|
|
737e9580b8 | ||
|
|
a2abc13425 | ||
|
|
1daf179db9 | ||
|
|
6b48a08697 | ||
|
|
dc8a2ec523 | ||
|
|
46f89d143b | ||
|
|
8a4adceaf0 | ||
|
|
bbf7a6230e | ||
|
|
24a3eea89e | ||
|
|
65b9a46d6c | ||
|
|
4dbb18bf5e | ||
|
|
44181fedf7 | ||
|
|
2b183f9497 | ||
|
|
a09150e6b4 | ||
|
|
da3c52668d | ||
|
|
5ba19dd49b | ||
|
|
4b72bbaa57 | ||
|
|
9f02151d0b | ||
|
|
f75f477c2b | ||
|
|
cec050983a | ||
|
|
ca39a9ea61 | ||
|
|
ca95621db5 | ||
|
|
27e9d1fcf0 | ||
|
|
f99a1d78bb | ||
|
|
d417d26ce8 | ||
|
|
5611020f33 | ||
|
|
fc68e97e4a | ||
|
|
b3a9ad2215 | ||
|
|
ab6315d6b4 | ||
|
|
5673c163fb | ||
|
|
07ee9654e4 | ||
|
|
9f70084524 | ||
|
|
da17f2cbd3 | ||
|
|
34a711b439 | ||
|
|
b359ec14a8 | ||
|
|
68d5293f01 | ||
|
|
91146a3a70 | ||
|
|
405a9d2144 | ||
|
|
6c42bd4dd3 | ||
|
|
9288fe63ad | ||
|
|
bd045c65a2 | ||
|
|
35b1440c97 | ||
|
|
ba9ffc6243 | ||
|
|
95ece89cf8 | ||
|
|
6d8d6b5552 | ||
|
|
f18285205c | ||
|
|
e60b597af5 | ||
|
|
96b29c6f8a | ||
|
|
a5d6cbf44d | ||
|
|
79d1c4f83a | ||
|
|
4dd9d5eb6c | ||
|
|
753e78d122 | ||
|
|
b50e54b0a8 | ||
|
|
7fadfbbd9f | ||
|
|
b4649d84ee | ||
|
|
eb4d431e76 | ||
|
|
8e2e4374f5 | ||
|
|
720919bc14 | ||
|
|
61140380ee | ||
|
|
a8d856fb65 | ||
|
|
7dc875e8c7 | ||
|
|
f0d28eeca7 | ||
|
|
71a48c0a26 | ||
|
|
c98597a2c0 | ||
|
|
6af3899bcb | ||
|
|
74260c96bf | ||
|
|
fc922d263c | ||
|
|
36f90e57f3 | ||
|
|
f369da741d | ||
|
|
1720d2d86d | ||
|
|
96ed3c8db0 | ||
|
|
fe878e65de | ||
|
|
d223539165 | ||
|
|
a71253fa58 | ||
|
|
6db43d2c19 | ||
|
|
4fc3eca4aa | ||
|
|
5c77ebb1fb | ||
|
|
054df95ea4 | ||
|
|
8eecb39792 | ||
|
|
8af81668ea | ||
|
|
c9b5dcafbd | ||
|
|
f596595c98 | ||
|
|
3fa994a7a4 | ||
|
|
c7d9df6350 | ||
|
|
c2c33d6808 | ||
|
|
9923a1bf50 | ||
|
|
863654d188 | ||
|
|
777d92f6de | ||
|
|
382371d9e4 | ||
|
|
3556a40f81 | ||
|
|
4caffd79db | ||
|
|
3460444d84 | ||
|
|
faee97dd1e | ||
|
|
c6ec2c1dd7 | ||
|
|
92c314d3c8 | ||
|
|
934ada72fa | ||
|
|
05a382b1a8 | ||
|
|
0777d16e78 | ||
|
|
d131e537e9 | ||
|
|
37ff9e1e23 | ||
|
|
c8c354d1e6 | ||
|
|
4e6216bced | ||
|
|
5b232df503 | ||
|
|
a1e70b9ba4 | ||
|
|
c43267dbaa | ||
|
|
02afb04b7d | ||
|
|
e9fcbace61 | ||
|
|
2b21f41495 | ||
|
|
dd6bd0f880 | ||
|
|
1583782446 | ||
|
|
22af4436f7 | ||
|
|
8fb0d668e0 | ||
|
|
467b96abf4 | ||
|
|
4f0b17a4dc | ||
|
|
a633b5e36e | ||
|
|
ea954e7e15 | ||
|
|
3033496fa4 | ||
|
|
13fb51eecf | ||
|
|
9c17c83bf1 | ||
|
|
2191ff656e | ||
|
|
2aeb1a70ea | ||
|
|
aa63628536 | ||
|
|
5a2e7a8d66 | ||
|
|
a41d46e193 | ||
|
|
940ba9ba95 | ||
|
|
96627df4d4 | ||
|
|
47a2ad604c | ||
|
|
70e0514a02 | ||
|
|
9135be8d5f | ||
|
|
c5fee20286 | ||
|
|
817eb4f23c | ||
|
|
4fa34190de | ||
|
|
be053ed257 | ||
|
|
ae3a6fe270 | ||
|
|
da498af74e | ||
|
|
1e986fade8 | ||
|
|
d9143f805e | ||
|
|
2e68fae2ec | ||
|
|
d18d2d0d9b | ||
|
|
4e6b571a36 | ||
|
|
e6f83d4df2 | ||
|
|
a623a66019 | ||
|
|
35e73b1a2d | ||
|
|
8d1cfce15e | ||
|
|
4550056de7 | ||
|
|
0451d3bbed | ||
|
|
9097c80269 | ||
|
|
739317a83f | ||
|
|
92510af9d4 | ||
|
|
b3f288c035 | ||
|
|
761e312219 | ||
|
|
c0f03a28e9 | ||
|
|
d2ab699cd5 | ||
|
|
5d4064fed4 | ||
|
|
5182224c2b | ||
|
|
8dd618d67f | ||
|
|
82693ba5b5 | ||
|
|
ff031d792c | ||
|
|
5b5e8a9bd4 | ||
|
|
4fdbb1b1ad | ||
|
|
bf5a631a14 | ||
|
|
d5104aca05 | ||
|
|
d00bcac941 | ||
|
|
5bc498c812 | ||
|
|
312499a1ef | ||
|
|
dcc28b65cb | ||
|
|
b6d14d9960 | ||
|
|
7c1e3c84ba | ||
|
|
911f4ada0a | ||
|
|
c55663b923 | ||
|
|
cac0f44194 | ||
|
|
5bc9082fb7 | ||
|
|
62a4d1de0e | ||
|
|
5f0aa16184 | ||
|
|
ba51800b31 | ||
|
|
b495799d31 | ||
|
|
c0a00019c0 | ||
|
|
85d98195d5 | ||
|
|
3e848dff10 | ||
|
|
b85071174a | ||
|
|
918b9a9fa4 | ||
|
|
089cb0f536 | ||
|
|
f42c21f16b | ||
|
|
c38c80fd43 | ||
|
|
3f8dfa346c | ||
|
|
05fa063068 | ||
|
|
dca144f2ee | ||
|
|
4672fdb9f0 | ||
|
|
d6332f1767 | ||
|
|
c767f6ccf1 | ||
|
|
0b9916cae2 | ||
|
|
181c78d482 | ||
|
|
e072ee480b | ||
|
|
eb933af40a | ||
|
|
6d0a271308 | ||
|
|
4bcd9169c0 | ||
|
|
95b9e0a0e2 | ||
|
|
cc64c43758 | ||
|
|
8950de5a89 | ||
|
|
8840ca96a9 | ||
|
|
35d46dca72 | ||
|
|
393643515c | ||
|
|
17fda73ca1 | ||
|
|
784206c85c | ||
|
|
976f67eee6 | ||
|
|
e5f27b44b5 | ||
|
|
6c0dd9fe3b | ||
|
|
7a45867841 | ||
|
|
0e94d7410d | ||
|
|
f074954d3d | ||
|
|
c433f87000 | ||
|
|
ea6b1c255e | ||
|
|
35cf804471 | ||
|
|
526554741f | ||
|
|
d2229ab381 | ||
|
|
d459432c45 | ||
|
|
450c8dc149 | ||
|
|
169c51d50d | ||
|
|
d1f37e66eb | ||
|
|
812149ed29 | ||
|
|
593e971121 | ||
|
|
e058adc4fe | ||
|
|
a39474a245 | ||
|
|
ed246d152b | ||
|
|
7f965dad29 | ||
|
|
0a470e66f2 | ||
|
|
94881e757a | ||
|
|
26796c8f7a | ||
|
|
51f51c18af | ||
|
|
34fd5f626a | ||
|
|
bbe3ee8dc5 | ||
|
|
2208220c12 | ||
|
|
10c567daee | ||
|
|
6ea1179145 | ||
|
|
71a8dcca08 | ||
|
|
a147bdf406 | ||
|
|
0ca199f89a | ||
|
|
9e238d624e | ||
|
|
6d11591d83 | ||
|
|
5937492e93 | ||
|
|
ec70081258 | ||
|
|
9948a77558 | ||
|
|
724761565d | ||
|
|
9d236e8e03 | ||
|
|
a9851aca55 | ||
|
|
a2743dcaeb | ||
|
|
8b4e2a21e4 | ||
|
|
642c2ab4bc | ||
|
|
93ba870b2d | ||
|
|
36fac8e22b | ||
|
|
ae16edf1d6 | ||
|
|
66f49e6c42 | ||
|
|
a635873568 | ||
|
|
e2ff776b35 | ||
|
|
356526d610 | ||
|
|
38a10c92d3 | ||
|
|
3c8714ed5a | ||
|
|
3362216b66 | ||
|
|
5ceba11982 | ||
|
|
b9e12d7c23 | ||
|
|
5af0162b3f | ||
|
|
a3411c8e96 | ||
|
|
d027f12764 | ||
|
|
4b0b4928f5 | ||
|
|
ca32c11f4f | ||
|
|
38de57be76 | ||
|
|
2b8ea7845f | ||
|
|
483de40c96 | ||
|
|
a224d828f6 | ||
|
|
ef130a3bf9 | ||
|
|
b75307b070 | ||
|
|
3a1bbfad28 | ||
|
|
ae31b761f4 | ||
|
|
f927684eb8 | ||
|
|
5fa91a1bcc | ||
|
|
aeb7e7cd7c | ||
|
|
935abb55b7 | ||
|
|
00953e39f4 | ||
|
|
3b36673e03 | ||
|
|
3b36542212 | ||
|
|
af97a581e3 | ||
|
|
baf815d099 | ||
|
|
8f28f884ee | ||
|
|
4c492a3be7 | ||
|
|
3d727a403f | ||
|
|
c19c5ed0a4 | ||
|
|
1caa2ff3cb | ||
|
|
ed33cf08c7 | ||
|
|
a67b23eb2d | ||
|
|
01cff3ce84 | ||
|
|
d6376f8188 | ||
|
|
f0a3377247 | ||
|
|
9debc0fa4b | ||
|
|
37a93f53c4 | ||
|
|
c3fd572a52 | ||
|
|
bcc049ceeb | ||
|
|
3a59f11708 | ||
|
|
bafe3c3fc3 | ||
|
|
ce1f245952 | ||
|
|
800b4e44b1 | ||
|
|
260fc30be3 | ||
|
|
3725e91603 | ||
|
|
b04a70177b | ||
|
|
e9b3569f44 | ||
|
|
9bbc91bb52 | ||
|
|
5efa6d5273 | ||
|
|
6819c43a05 | ||
|
|
35c17ced72 | ||
|
|
1705aab290 | ||
|
|
9f50b8897a | ||
|
|
1c746df82c | ||
|
|
8456ffa231 | ||
|
|
ebe71a12ed | ||
|
|
0872406e3c | ||
|
|
cffe847778 | ||
|
|
4353c9e0f1 | ||
|
|
6763ac29d9 | ||
|
|
4f99224255 | ||
|
|
c76f7c0c2a | ||
|
|
806dc5de36 | ||
|
|
104def8e51 | ||
|
|
dc4513f965 | ||
|
|
822a6e7c5f | ||
|
|
91197804ac | ||
|
|
ff2516deb2 | ||
|
|
a74ae75680 | ||
|
|
9438caa6a3 | ||
|
|
d75c5f6722 | ||
|
|
baf46db287 | ||
|
|
67fd77d10a | ||
|
|
98e2f91036 | ||
|
|
326deb14fe | ||
|
|
591e9457e6 | ||
|
|
1f3f7282f3 | ||
|
|
1ead0ea3a7 | ||
|
|
f3d4ee4d4c | ||
|
|
8ccfe4361c | ||
|
|
cb2ebd0bf7 | ||
|
|
1c2dabc6d7 | ||
|
|
cac3f3b24e | ||
|
|
73f79ed5b1 | ||
|
|
4264de05f9 | ||
|
|
6528f50bfc | ||
|
|
94e2a64f60 | ||
|
|
330692350e | ||
|
|
3e70b53165 | ||
|
|
00eb100114 | ||
|
|
41575ad60d | ||
|
|
122c404883 | ||
|
|
ba5de21db4 | ||
|
|
b3219fc3a4 | ||
|
|
905da4b0cc | ||
|
|
116bfab449 | ||
|
|
ebd9f36b0d | ||
|
|
b00e1f4e4b | ||
|
|
f4542b378c | ||
|
|
0c6548fda0 | ||
|
|
669aed0ac0 | ||
|
|
014e800e8a | ||
|
|
a61c5b6be3 | ||
|
|
ac3509d308 | ||
|
|
30505c7977 | ||
|
|
2a71c8fa82 | ||
|
|
4796f761b8 | ||
|
|
18546ea16d | ||
|
|
0ef784b8fd | ||
|
|
80fa23da5e | ||
|
|
2ecf1d887b | ||
|
|
a58fcc3b1e | ||
|
|
4c8d787918 | ||
|
|
127e5a2726 | ||
|
|
7bd506b913 | ||
|
|
bd09783438 | ||
|
|
ef0a3f5be1 | ||
|
|
653f653c67 | ||
|
|
ac37991b34 | ||
|
|
6ee7049736 | ||
|
|
57fd4e9148 | ||
|
|
93fb79f357 | ||
|
|
c41fbe9ea5 | ||
|
|
1cc3472e1d | ||
|
|
00ac29e53d | ||
|
|
434783da4d | ||
|
|
71019eccbd | ||
|
|
06d68e87ba | ||
|
|
8c2235c9a7 | ||
|
|
cd244c2077 | ||
|
|
30ddae0f91 | ||
|
|
38d3577c10 | ||
|
|
bffcffe072 | ||
|
|
18ce901746 | ||
|
|
4afab58739 | ||
|
|
ca7bc5913f | ||
|
|
36adbef3f9 | ||
|
|
d6030a16b3 | ||
|
|
3840ea9537 | ||
|
|
2c253edda9 | ||
|
|
47730f9a6e | ||
|
|
a5d0f6a2af | ||
|
|
fb155b95c7 | ||
|
|
28c25f120e | ||
|
|
b06ec370d1 | ||
|
|
2f7fa3b905 | ||
|
|
23220a98b9 | ||
|
|
e679d55f67 | ||
|
|
7921834b1d | ||
|
|
c0b93190d0 | ||
|
|
b7f5aae64a | ||
|
|
2163ce25f6 | ||
|
|
21968d35bb | ||
|
|
d0e1ddb8c2 | ||
|
|
010caa6236 | ||
|
|
e9f40e9d68 | ||
|
|
1afec11dfc | ||
|
|
852c319399 | ||
|
|
6110e6561c | ||
|
|
ac68073ffc | ||
|
|
1b518965cc | ||
|
|
0d5b8cb0fe | ||
|
|
de26d3c099 | ||
|
|
db8b054fa4 | ||
|
|
edef2df21b | ||
|
|
c25fbc010d | ||
|
|
90709fc4d3 | ||
|
|
74c31c60c6 | ||
|
|
cb163bfbe1 | ||
|
|
40b986bcc4 | ||
|
|
ca51692164 | ||
|
|
c51508a47c | ||
|
|
fa5de776a6 | ||
|
|
fd6047f5d8 | ||
|
|
f30a82d599 | ||
|
|
46a29532a9 | ||
|
|
11d8f97845 | ||
|
|
c1caeb7e70 | ||
|
|
1d0a1e7937 | ||
|
|
d9043057a2 | ||
|
|
65a662f5b3 | ||
|
|
d273129d9d | ||
|
|
a85c47134b | ||
|
|
2cf4e5a6de | ||
|
|
1ff36965f4 | ||
|
|
55b0dff795 | ||
|
|
7ffc480db8 | ||
|
|
20f7f5b64f | ||
|
|
6c7356072d | ||
|
|
3de673a8ca | ||
|
|
bce4fa9531 | ||
|
|
5335563a4b | ||
|
|
dcdd3bff94 | ||
|
|
2211d20c1d | ||
|
|
d3d6b643f1 | ||
|
|
5fa0de95f6 | ||
|
|
30b47eab37 | ||
|
|
bebbc87c3a | ||
|
|
024630d6ad | ||
|
|
2fa7964a39 | ||
|
|
8ca887a25c | ||
|
|
2a41f50661 | ||
|
|
c749f577e6 | ||
|
|
a9d58e47cb | ||
|
|
5ed5fddb7c | ||
|
|
ffeb8e2af0 | ||
|
|
ee423e5bf1 | ||
|
|
0e0b6bdde7 | ||
|
|
dabddd4c89 | ||
|
|
5bab5f4cca | ||
|
|
2f33d44713 | ||
|
|
4921388732 | ||
|
|
fb18e7e95d | ||
|
|
aa662f939a | ||
|
|
b5bd6e0114 | ||
|
|
b24edc1633 | ||
|
|
c4c19f885f | ||
|
|
1c1cbb9b95 | ||
|
|
3d6f4979c3 | ||
|
|
630cb96a54 | ||
|
|
cf70f65bec | ||
|
|
8f2212ea1e | ||
|
|
d9feaa1875 | ||
|
|
b3727a9b46 | ||
|
|
1f47e2823a | ||
|
|
89f0717df6 | ||
|
|
5136d9ddc7 | ||
|
|
10b6b88b01 | ||
|
|
801aa46c46 | ||
|
|
c232d703ca | ||
|
|
924e5c54eb | ||
|
|
5e9102f031 | ||
|
|
3208c4f2cb | ||
|
|
abdd1d7715 | ||
|
|
00fa48a886 | ||
|
|
f9523c32d5 | ||
|
|
3858e1df51 | ||
|
|
69d6145f5a | ||
|
|
aa66b5d62f | ||
|
|
c629a92aa2 | ||
|
|
22327b43ae | ||
|
|
0c24e1efdc | ||
|
|
c5786b212b | ||
|
|
38ab456c78 | ||
|
|
328c1ad96e | ||
|
|
161f39f7af | ||
|
|
da502dd036 | ||
|
|
6bb145bdd8 | ||
|
|
87d526968c | ||
|
|
5ccae43552 | ||
|
|
3b41e02ea5 | ||
|
|
80a607ee0c | ||
|
|
253d6b0b92 | ||
|
|
271e2398f9 | ||
|
|
106cd86375 | ||
|
|
5d66bfbd19 | ||
|
|
193c1aa533 | ||
|
|
2b1732bdec | ||
|
|
dbac453a39 | ||
|
|
3ada4f4733 | ||
|
|
afc95e36e1 | ||
|
|
9e9614af13 | ||
|
|
ddacb1400c | ||
|
|
2e1e7b8270 | ||
|
|
03da438fa4 | ||
|
|
ac59b68257 | ||
|
|
8f47609024 | ||
|
|
1c0541e7cb | ||
|
|
369d60bc21 | ||
|
|
e9e048c4ea | ||
|
|
845253af3a | ||
|
|
bcef3aeb1e | ||
|
|
47c6377ac0 | ||
|
|
db9ff821a2 | ||
|
|
968e220fd2 | ||
|
|
13268ec401 | ||
|
|
2c969f1167 | ||
|
|
bcb24e316c | ||
|
|
6b289a1423 | ||
|
|
f9373b4430 | ||
|
|
437e6c5653 | ||
|
|
3a169d3a78 | ||
|
|
237d2bff3a | ||
|
|
158650ff01 | ||
|
|
9859df8c6c | ||
|
|
210fbcc4c2 | ||
|
|
4f88b664e2 | ||
|
|
37b2aaa051 | ||
|
|
87c9186efd | ||
|
|
f7f1509a27 | ||
|
|
27bb44d39c | ||
|
|
431c80bbca | ||
|
|
f3dfe88477 | ||
|
|
342ddcf71a | ||
|
|
4b805ccde9 | ||
|
|
d3759811b6 | ||
|
|
f529871162 | ||
|
|
6154d9067e | ||
|
|
ba2b0b8360 | ||
|
|
f23579532e | ||
|
|
954aff7002 | ||
|
|
6b94e65a95 | ||
|
|
cb36d96569 | ||
|
|
486e534df0 | ||
|
|
5f1f67153b | ||
|
|
8cc11d6cc6 | ||
|
|
fdbf30fc4c | ||
|
|
98a75b1a78 | ||
|
|
d7e552a169 | ||
|
|
3da6aab353 | ||
|
|
e889c58bbc | ||
|
|
ffd4e231d7 | ||
|
|
af146e7dcd | ||
|
|
7b37546a4d | ||
|
|
a155d0e531 | ||
|
|
e0af049124 | ||
|
|
f69d3020fd | ||
|
|
9a2bdf8798 | ||
|
|
9f8198d946 | ||
|
|
5b8e1cdbbb | ||
|
|
b765cef359 | ||
|
|
c65860ee53 | ||
|
|
2f9da1c7c8 | ||
|
|
3bd4197951 | ||
|
|
21ed41da9a | ||
|
|
ece5cbbbb5 | ||
|
|
6b4d76739e | ||
|
|
e8ea28d897 | ||
|
|
12c10dbcd1 | ||
|
|
ed65267bc5 | ||
|
|
9dfad6d9da | ||
|
|
97e3d05f37 | ||
|
|
3f60dcfae8 | ||
|
|
8aaffe829a | ||
|
|
81fb10daaa | ||
|
|
bf62d6b896 | ||
|
|
14cd115c82 | ||
|
|
119a12cba5 | ||
|
|
745ee04583 | ||
|
|
21a61cd583 | ||
|
|
60dc783399 | ||
|
|
f113460348 | ||
|
|
39085f08fc | ||
|
|
a15b825418 | ||
|
|
48aed0ea46 | ||
|
|
76e96e92cb | ||
|
|
97bfc13237 | ||
|
|
a636f90240 | ||
|
|
7c79bfc903 | ||
|
|
49e0036471 | ||
|
|
9efb957059 | ||
|
|
2d95c4dc1c | ||
|
|
a3bbef5f21 | ||
|
|
296a409a29 | ||
|
|
b188a4dbc9 | ||
|
|
2565928495 | ||
|
|
56cb1885bb | ||
|
|
f7d33010e5 | ||
|
|
cd29ca3c40 | ||
|
|
554a100407 | ||
|
|
dc9cd38189 | ||
|
|
b3fa7b0650 | ||
|
|
7f1692b3ca | ||
|
|
e31ded2198 | ||
|
|
56650e7f79 | ||
|
|
af710cdd7f | ||
|
|
f0842a27c5 | ||
|
|
b7cb5839eb | ||
|
|
ca6ee2d91a | ||
|
|
9818237918 | ||
|
|
4f316cffbc | ||
|
|
68f6b9443e | ||
|
|
c20c643b66 | ||
|
|
ed7dfddc5d | ||
|
|
8f1f4f2652 | ||
|
|
46b68b0e66 | ||
|
|
035439c710 | ||
|
|
89883a6988 | ||
|
|
89935e7308 | ||
|
|
c43723abdd | ||
|
|
0139fa20ff | ||
|
|
c58ad11f2f | ||
|
|
5147c71fdf | ||
|
|
9ca42448c7 | ||
|
|
a5547e5b1d | ||
|
|
3347d08b79 | ||
|
|
7c4986bd83 | ||
|
|
108034b050 | ||
|
|
6b35b9de00 | ||
|
|
9c8e76b190 | ||
|
|
5569d2ddc2 | ||
|
|
c2884a6e63 | ||
|
|
03cbd4257f | ||
|
|
d46b63a18c | ||
|
|
0dc4335fbc | ||
|
|
f213a07c83 | ||
|
|
59a8856773 | ||
|
|
88b704db19 | ||
|
|
19e928271b | ||
|
|
54d1a676b7 | ||
|
|
f3a520e75d | ||
|
|
7ad00d1152 | ||
|
|
600a5ecdaf | ||
|
|
bd53e5b496 | ||
|
|
a79bfad08e | ||
|
|
f8a27e6acf | ||
|
|
73e3ed0bd0 | ||
|
|
97d8bea5ec | ||
|
|
abe80a4bfe | ||
|
|
6a8a5d2167 | ||
|
|
da3e5fd3d6 | ||
|
|
0a0a6ef591 | ||
|
|
85b998a4af | ||
|
|
67fd3333e2 | ||
|
|
518d157f76 | ||
|
|
1ec0619b3e | ||
|
|
dbeb1b82a9 | ||
|
|
aa03c4ce9f | ||
|
|
5572430ba5 | ||
|
|
9bb0e10eec | ||
|
|
c2d54aaede | ||
|
|
7536b665f1 | ||
|
|
8db02b0a39 | ||
|
|
8e13b376b0 | ||
|
|
8236a18260 | ||
|
|
e1b27885f9 | ||
|
|
1d0e063f49 | ||
|
|
76966ed61a | ||
|
|
6315e4503e | ||
|
|
eead1af140 | ||
|
|
6fb9c802d3 | ||
|
|
42c5f2e91e | ||
|
|
216dc49741 | ||
|
|
271fd0ba06 | ||
|
|
858a7823fb | ||
|
|
79ca4e1718 | ||
|
|
7f959a06f6 | ||
|
|
ac8d030855 | ||
|
|
f2df40f58b | ||
|
|
5c2599e24e | ||
|
|
82ded858aa | ||
|
|
8cb8082206 | ||
|
|
aeb7ab4774 | ||
|
|
8a3b0ebea9 | ||
|
|
9c7d5b2a66 | ||
|
|
8f43a1303b | ||
|
|
d69cb1ba7b | ||
|
|
456dda9ac0 | ||
|
|
11eecdc7bd | ||
|
|
34480c9269 | ||
|
|
fa67ec52ae | ||
|
|
41dfc51beb | ||
|
|
9857a0c956 | ||
|
|
db162477a4 | ||
|
|
3b1653dad7 | ||
|
|
d7fa4cfb8b | ||
|
|
4b4247f412 | ||
|
|
08bb689ae7 | ||
|
|
4145417f67 | ||
|
|
af5869cd07 | ||
|
|
876f60169c | ||
|
|
4ea98dfee4 | ||
|
|
376f086ec1 | ||
|
|
005d6d6b35 | ||
|
|
89020bc3c0 | ||
|
|
538c3a6692 | ||
|
|
8015dbe8b7 | ||
|
|
d3dbdae395 | ||
|
|
48e07d7dff | ||
|
|
2d17af9f28 | ||
|
|
98518e39cd | ||
|
|
af49ec7583 | ||
|
|
a20d37c50a | ||
|
|
a2bdcc68c2 | ||
|
|
e5d1d26535 | ||
|
|
91225fbcca | ||
|
|
13be339d81 | ||
|
|
b89cfa95e7 | ||
|
|
6c70a51d28 | ||
|
|
7f1974e9e8 | ||
|
|
9f4801363c | ||
|
|
8199b3e685 | ||
|
|
918281b01f | ||
|
|
447329eaee | ||
|
|
74f2954013 | ||
|
|
4e375ec6df | ||
|
|
dc0bfd7008 | ||
|
|
8ad56a6c0e | ||
|
|
7a11384177 | ||
|
|
fe322b8e82 | ||
|
|
5639f31295 | ||
|
|
651d9f587f | ||
|
|
1f985dec38 | ||
|
|
e74771e047 | ||
|
|
18e855e4d5 | ||
|
|
15039f3ae8 | ||
|
|
63b6e04dae | ||
|
|
fd7ab79fe0 | ||
|
|
cde542c37c | ||
|
|
789d908cee | ||
|
|
c405ec19ce | ||
|
|
c65a13b3a4 | ||
|
|
eb7c367e25 | ||
|
|
dee4d43eb9 | ||
|
|
1039ef7a65 | ||
|
|
c6fd0055b1 | ||
|
|
eab7f54139 | ||
|
|
abd3855161 | ||
|
|
712df01341 | ||
|
|
e63a870bce | ||
|
|
e0b7fb1929 | ||
|
|
a062ba6dd2 | ||
|
|
36fe50ebad | ||
|
|
19d7a488de | ||
|
|
d56a7beadc | ||
|
|
8c460b3ea5 | ||
|
|
4cffefe1dd | ||
|
|
70e7499e48 | ||
|
|
2d041ac0fc | ||
|
|
146f45f3d4 | ||
|
|
6a540652fa | ||
|
|
0c60b312be | ||
|
|
21efcf9e45 | ||
|
|
6c8f1c8796 | ||
|
|
bc539ce892 | ||
|
|
5a4dab88d6 | ||
|
|
1a75c5227e | ||
|
|
61863e2ffb | ||
|
|
c60604062c | ||
|
|
a973d9902b | ||
|
|
5bb5a62d37 | ||
|
|
a1ff3cc317 | ||
|
|
655fbbd984 | ||
|
|
f93294975b | ||
|
|
ee91d7339c | ||
|
|
941f785b7f | ||
|
|
f64ec500bf | ||
|
|
36932ee129 | ||
|
|
0c70a69618 | ||
|
|
0b3351991a | ||
|
|
99d9830968 | ||
|
|
719848d59a | ||
|
|
fff80bfe6c | ||
|
|
4e29c1ca40 | ||
|
|
ed1cec2efa | ||
|
|
510d7644fa | ||
|
|
51cae1f0a3 | ||
|
|
0b8ea50589 | ||
|
|
ebfd49661e | ||
|
|
0eef5b506c | ||
|
|
590dc1ac59 | ||
|
|
f439cf0de1 | ||
|
|
ebdb3c4c32 | ||
|
|
5e8c53f61c | ||
|
|
fe3f67f712 | ||
|
|
24e6a5ee73 | ||
|
|
f53a56982c | ||
|
|
886619f63e | ||
|
|
5120e5138c | ||
|
|
f7364d8463 | ||
|
|
fc0dbc3f70 | ||
|
|
17f7147ac1 | ||
|
|
4b62f091a9 | ||
|
|
9ee3843f35 | ||
|
|
7c9e850235 | ||
|
|
0867da28a2 | ||
|
|
3e5ac64ee2 | ||
|
|
6178e378c1 | ||
|
|
3e31e2ba53 | ||
|
|
3958ea50a0 | ||
|
|
9ca214eee8 | ||
|
|
9557e64822 | ||
|
|
82fb76c142 | ||
|
|
9ab288d8e3 | ||
|
|
5446c52c43 | ||
|
|
b112b7b4ce | ||
|
|
f21493272d | ||
|
|
c2d85ff554 | ||
|
|
b8cc468f02 | ||
|
|
e6ddffb93c | ||
|
|
ca727ea3d9 | ||
|
|
7d641d5f1f | ||
|
|
fe303f0e46 | ||
|
|
5473a36f81 | ||
|
|
cf7e23f0d6 | ||
|
|
ae55954919 | ||
|
|
7b47c8f0c6 | ||
|
|
304cb290d9 | ||
|
|
bd77bb41df | ||
|
|
3db7181104 | ||
|
|
b48c917984 | ||
|
|
d6c6549354 | ||
|
|
4442c79526 | ||
|
|
364f69edad | ||
|
|
85d589a49c | ||
|
|
e88081a454 | ||
|
|
31ca9d9ad7 | ||
|
|
9c6120ccad | ||
|
|
0cc87d3c85 | ||
|
|
a8ed11e75b | ||
|
|
24a2b15eec | ||
|
|
0a74f35062 | ||
|
|
a3fdefa6f9 | ||
|
|
d56454f153 | ||
|
|
c697fb6345 | ||
|
|
f65a7650c5 | ||
|
|
018aebc0c8 | ||
|
|
f888c70982 | ||
|
|
9eabe316bf | ||
|
|
0f9059dea8 | ||
|
|
05d9d753d3 | ||
|
|
e9e4b04bf4 | ||
|
|
d4de105a57 | ||
|
|
4c948ba4fb | ||
|
|
3824ad4756 | ||
|
|
5d15c8d534 | ||
|
|
cc92636de0 | ||
|
|
142d503cb4 | ||
|
|
337184fbc6 | ||
|
|
293e86eda9 | ||
|
|
ecccbb46cb | ||
|
|
8193e7b3b4 | ||
|
|
e382f68e48 | ||
|
|
9343618a9c | ||
|
|
f4c55aa4db | ||
|
|
b51ee34b11 | ||
|
|
1f5a083129 | ||
|
|
5dcf06d208 | ||
|
|
590ad78bfd | ||
|
|
d0aa699299 | ||
|
|
040eae4806 | ||
|
|
cc61227f93 | ||
|
|
090ba0e235 | ||
|
|
1d1942f48a | ||
|
|
2300feaf9d | ||
|
|
86ee1b7448 | ||
|
|
7e7cb15bd1 | ||
|
|
6a496087ba | ||
|
|
76e9645787 | ||
|
|
abe1b98486 | ||
|
|
98380cebda | ||
|
|
770fc77584 | ||
|
|
cc4a72243d | ||
|
|
9a2af89c4e | ||
|
|
5adb6f0c5f | ||
|
|
35f61475f5 | ||
|
|
473fde900b | ||
|
|
874ba409ca | ||
|
|
9f6838ae42 | ||
|
|
64a63885d1 | ||
|
|
d1e7ca23e2 | ||
|
|
4d228e22cb | ||
|
|
4ca8e31e00 | ||
|
|
3697f50bd3 | ||
|
|
8a9b18e40e | ||
|
|
9221f7916a | ||
|
|
1ec2f43713 | ||
|
|
bc9f0fdc34 | ||
|
|
f01464ef9e | ||
|
|
dbb37607c5 | ||
|
|
2049498af0 | ||
|
|
a6d7d5da07 | ||
|
|
a6acdac1cf | ||
|
|
cc311355cd | ||
|
|
20668ccfa3 | ||
|
|
826db3d73e | ||
|
|
b93f15046c | ||
|
|
9c377906cf | ||
|
|
50dcf40f24 | ||
|
|
fcbe060096 | ||
|
|
1370fa7631 | ||
|
|
0603481aaa | ||
|
|
358759f609 | ||
|
|
bbff6ae529 | ||
|
|
82c356015f | ||
|
|
de1c221bab | ||
|
|
e869254eb7 | ||
|
|
c2e0d0ae20 | ||
|
|
aa1488c768 | ||
|
|
601521c47a | ||
|
|
9bead32552 | ||
|
|
cd0e8fd637 | ||
|
|
6f8e8a6ea4 | ||
|
|
0bcab1df84 | ||
|
|
2bdeaec3d2 | ||
|
|
8c9ea49ff5 | ||
|
|
ecc4ac795a | ||
|
|
2882bd48e6 | ||
|
|
b32a3cd4d9 | ||
|
|
b02f483841 | ||
|
|
9d712b2ce9 | ||
|
|
0ee0844c59 | ||
|
|
babb633922 | ||
|
|
26611db95b | ||
|
|
e2215768a2 | ||
|
|
5e1e37df66 | ||
|
|
cbe6ef210f | ||
|
|
cdef4c2548 | ||
|
|
40a84e0c81 | ||
|
|
25ee872703 | ||
|
|
240e70d989 | ||
|
|
e0a97d5642 | ||
|
|
c270e4fb30 | ||
|
|
ccf6b237bb | ||
|
|
b4f596b197 | ||
|
|
1aba1fe8b1 | ||
|
|
3976a43c84 | ||
|
|
89d0d648ed | ||
|
|
3c1ea3667d | ||
|
|
124a216a94 | ||
|
|
99b8e062d7 | ||
|
|
d2a36c5958 | ||
|
|
efad33c3c5 | ||
|
|
023de11dc6 | ||
|
|
44a8bec56a | ||
|
|
ce414a5c5a | ||
|
|
db376bfddb | ||
|
|
d909715f1b | ||
|
|
87908242c5 | ||
|
|
cf3ff17c50 | ||
|
|
f0f473392d | ||
|
|
bf340eee91 | ||
|
|
538d91ecf2 | ||
|
|
e6046e0bc1 | ||
|
|
a149131dc2 | ||
|
|
237f6a6a62 | ||
|
|
8cdc266417 | ||
|
|
a35f585286 | ||
|
|
ffd688642a | ||
|
|
67d88526b9 | ||
|
|
14a338af40 | ||
|
|
3dc822f767 | ||
|
|
a8b6fbcc31 | ||
|
|
3b3e155c79 | ||
|
|
21ca7be235 | ||
|
|
39294b8e78 | ||
|
|
1cbb299c38 | ||
|
|
688a5677f4 | ||
|
|
db23b276f2 | ||
|
|
8a5e762c24 | ||
|
|
aa909702c6 | ||
|
|
6238d61f7e | ||
|
|
6f62f5d428 | ||
|
|
c75d9e2ee0 | ||
|
|
22ef3ed474 | ||
|
|
4bb5046e1f | ||
|
|
ae50bf84c6 | ||
|
|
ec9e8ecfaa | ||
|
|
4a47b7cb41 | ||
|
|
870505bcd9 | ||
|
|
eb62d9cc04 | ||
|
|
80104f5192 | ||
|
|
05179409be | ||
|
|
ced585fd5e | ||
|
|
2efc64ace7 | ||
|
|
bb8e532361 | ||
|
|
4678f27802 | ||
|
|
80974b8f62 | ||
|
|
0d7dec0436 | ||
|
|
007a977cb0 | ||
|
|
2041f957da | ||
|
|
f4ea50c6ff | ||
|
|
e521e100f1 | ||
|
|
06a72facc5 | ||
|
|
0ca197374e | ||
|
|
ddee65722f | ||
|
|
069a9ad56f | ||
|
|
ad3f020605 | ||
|
|
ea8b7d8128 | ||
|
|
e208fbb1b3 | ||
|
|
3a1c1d1fd5 | ||
|
|
2ec48c32cb | ||
|
|
a7eb347ce2 | ||
|
|
a7e5d4ef03 | ||
|
|
08b774e318 | ||
|
|
7fabc45313 | ||
|
|
bf8b52ec3a | ||
|
|
9b31aac1de | ||
|
|
d9a4773194 | ||
|
|
ac30e49df7 | ||
|
|
017685b1b2 | ||
|
|
e6c5ea21b4 | ||
|
|
bd91e70fae | ||
|
|
7002c9680a | ||
|
|
ed01c57677 | ||
|
|
82075a340d | ||
|
|
0ed2ef230b | ||
|
|
037a0d6822 | ||
|
|
b6bc44fd10 | ||
|
|
d00baf8db4 | ||
|
|
b7e95c1525 | ||
|
|
dd363da5b0 | ||
|
|
0502836975 | ||
|
|
7e08bba25c | ||
|
|
ac0562ec18 | ||
|
|
17e6db431e | ||
|
|
deb839ba6f | ||
|
|
526680e977 | ||
|
|
b2f7a6a934 | ||
|
|
e3005266b6 | ||
|
|
b4dd9bc802 | ||
|
|
5f9ac94bef | ||
|
|
9061217d80 | ||
|
|
59ac5b10c7 | ||
|
|
f6c47a46c6 | ||
|
|
ac335ef58a | ||
|
|
069f87a19f | ||
|
|
5a182651db | ||
|
|
436b10729e | ||
|
|
32a6d10de8 | ||
|
|
4c96d697d5 | ||
|
|
a2dc07056e | ||
|
|
726327d95c | ||
|
|
2b20fc1be2 | ||
|
|
ca042e4e6e | ||
|
|
953c62c04c | ||
|
|
6045277cca | ||
|
|
d38227f840 | ||
|
|
4b46abf813 | ||
|
|
c43ed44b17 | ||
|
|
b1b83f4d6d | ||
|
|
f3abee631a | ||
|
|
d2923253f3 | ||
|
|
ae028d89cf | ||
|
|
fbe9d26c47 | ||
|
|
09bf68e8ad | ||
|
|
495490743c | ||
|
|
45347749fe | ||
|
|
32d41388e2 | ||
|
|
0ac9d1ee31 | ||
|
|
6bb5b7190c | ||
|
|
bac7ba6639 | ||
|
|
117b932176 | ||
|
|
170507a85c | ||
|
|
b485caf33c | ||
|
|
e20fe9d402 | ||
|
|
4ca69b6d6d | ||
|
|
052ed10a17 | ||
|
|
39e6dd3d25 | ||
|
|
c18bee3d5b | ||
|
|
d068eaa9f7 | ||
|
|
5fe0e3d5fb | ||
|
|
77be0b23e5 | ||
|
|
5a194d82c8 | ||
|
|
e8dc6c84a4 | ||
|
|
1d3ec6f0ae | ||
|
|
2f7e421eed | ||
|
|
25b47758b7 | ||
|
|
46241da795 | ||
|
|
6c6b19b198 | ||
|
|
9039bd58bd | ||
|
|
a3858bff3c | ||
|
|
ddff89d43e | ||
|
|
1b993714c5 | ||
|
|
41fdb1d369 | ||
|
|
8d1d57fbdf | ||
|
|
182d1d339b | ||
|
|
0db81f66ae | ||
|
|
54a7301225 | ||
|
|
10485b0d39 | ||
|
|
365d0bccd5 | ||
|
|
3bbeacad20 | ||
|
|
2af9cb7952 | ||
|
|
2733d3fea5 | ||
|
|
e139c52262 | ||
|
|
0b8520a208 | ||
|
|
a9183da87b | ||
|
|
3148b67288 | ||
|
|
055862c0eb | ||
|
|
9b619e95b2 | ||
|
|
fec223016f | ||
|
|
745926d588 | ||
|
|
a9adc67421 | ||
|
|
042ff27366 | ||
|
|
38ae718509 | ||
|
|
96112ec66d | ||
|
|
4ae47c3f38 | ||
|
|
3161daacd7 | ||
|
|
6616b0efe7 | ||
|
|
b630bd8d6a | ||
|
|
cefd2e22fa | ||
|
|
74dcc7a3d5 | ||
|
|
a7a160eebc | ||
|
|
fb0a50c71c | ||
|
|
9d8bf1373e | ||
|
|
98f1d83194 | ||
|
|
366913c146 | ||
|
|
7e126f7fb6 | ||
|
|
4067cc7962 | ||
|
|
90fcba79c6 | ||
|
|
49a3a0e0d0 | ||
|
|
d4f08b5a71 | ||
|
|
ff7bc0ac6c | ||
|
|
27155a507f | ||
|
|
fc90c5f8f0 | ||
|
|
14357b0b44 | ||
|
|
e3fd554026 | ||
|
|
ebb7df8cbf | ||
|
|
dae9f9e164 | ||
|
|
30114e214b | ||
|
|
ba326a7ec8 | ||
|
|
246bacd9da | ||
|
|
b178777c3e | ||
|
|
33f55d84eb | ||
|
|
78d83ebda8 | ||
|
|
8f1eecdc29 | ||
|
|
6491ba0589 | ||
|
|
648539a513 | ||
|
|
ef482513c4 | ||
|
|
7243fe74e4 | ||
|
|
d4c22654e1 | ||
|
|
d1524ba0b8 | ||
|
|
347d82bdc6 | ||
|
|
0d9efd04a8 | ||
|
|
37be984d34 | ||
|
|
bf055e2cb4 | ||
|
|
97ea513122 | ||
|
|
fca3e59e26 | ||
|
|
3372c1a7b2 | ||
|
|
c1d2388c76 | ||
|
|
b96f0fa2df | ||
|
|
6ab259d642 | ||
|
|
81613afa03 | ||
|
|
578bec11ac | ||
|
|
7088e4faaa | ||
|
|
91b2e023b8 | ||
|
|
05f2ecc045 | ||
|
|
7d4174bceb | ||
|
|
4630c4b9ff | ||
|
|
410652d42a | ||
|
|
8004d8757f | ||
|
|
193e14a489 | ||
|
|
a3999c93f4 | ||
|
|
bf1428be18 | ||
|
|
1330c27ac6 | ||
|
|
ff1d3425b1 | ||
|
|
9334f6c05d | ||
|
|
ae55187a68 | ||
|
|
950b270e74 | ||
|
|
639c838707 | ||
|
|
3ec96ab080 | ||
|
|
5727da0c75 | ||
|
|
268b8205a1 | ||
|
|
7367ec2f1a | ||
|
|
d2bd8f70f6 | ||
|
|
f7ed614362 | ||
|
|
5ca30b0318 | ||
|
|
b8411ae1b8 | ||
|
|
d4408beeaf | ||
|
|
fc800ef9e5 | ||
|
|
8400b90a64 | ||
|
|
5eb41084a0 | ||
|
|
7791937e84 | ||
|
|
4bfc32789e | ||
|
|
f12ddb4ee7 | ||
|
|
fd7357d9d5 | ||
|
|
70028f8445 | ||
|
|
38d5a5bf0e | ||
|
|
1093adca7e | ||
|
|
2755772478 | ||
|
|
e087d6ad19 | ||
|
|
de328c412a | ||
|
|
a7dadd9dae | ||
|
|
e8acc5eabc | ||
|
|
a08ff1d1ce | ||
|
|
e533fe44b0 | ||
|
|
bd86efe5fe | ||
|
|
43039e19f7 | ||
|
|
3dd81b0d32 | ||
|
|
5d5756d0cb | ||
|
|
9760210c77 | ||
|
|
4979221152 | ||
|
|
a6aa4863f3 | ||
|
|
e285ecb76c | ||
|
|
30d004ab64 | ||
|
|
136b23cb5e | ||
|
|
a3905fcf87 | ||
|
|
1306892fbf | ||
|
|
e2559a822b | ||
|
|
30c69e73b3 | ||
|
|
5b8a2af979 | ||
|
|
6f0a727aee | ||
|
|
a4b94dad41 | ||
|
|
c21e5863b9 | ||
|
|
a529a35ce6 | ||
|
|
64810bb138 | ||
|
|
d65a2c7cab | ||
|
|
5958fe0a69 | ||
|
|
1af6bd1454 | ||
|
|
87be50c542 | ||
|
|
fc6e3c6b09 | ||
|
|
b541379037 | ||
|
|
22a69efafa | ||
|
|
3cac7e878d | ||
|
|
0592ac56c9 | ||
|
|
49dc2b264f | ||
|
|
44d97986a2 | ||
|
|
c32c584f65 | ||
|
|
4802d22527 | ||
|
|
fe21ab48e0 | ||
|
|
3108b71a89 | ||
|
|
19816bcd31 | ||
|
|
734d174f33 | ||
|
|
cea22866a8 | ||
|
|
14482146c5 | ||
|
|
6a384df412 | ||
|
|
f278a3bafb | ||
|
|
ba348b73e2 | ||
|
|
ed69c11b01 | ||
|
|
1cfcab536c | ||
|
|
6de79ad703 | ||
|
|
0996954abb | ||
|
|
75ff599a91 | ||
|
|
0d5ed994e2 | ||
|
|
bbc73e96ac | ||
|
|
cee0c86c3c | ||
|
|
342bdaf4a2 | ||
|
|
43faf63fde | ||
|
|
230ed1de37 | ||
|
|
0ef7e58ef9 | ||
|
|
39e1314d07 | ||
|
|
7b6b3a4535 | ||
|
|
6d5393dd31 | ||
|
|
b1b70e6c35 | ||
|
|
f390543550 | ||
|
|
ad40e71fdf | ||
|
|
0c26f33819 | ||
|
|
967abd4e91 | ||
|
|
329f8b30e9 | ||
|
|
675d31587c | ||
|
|
e6d20aba93 | ||
|
|
487e8ea934 | ||
|
|
aa8b725457 | ||
|
|
75ea9c35db | ||
|
|
bba5a61ef9 | ||
|
|
6be1d377db | ||
|
|
df9eb55c5a | ||
|
|
44a6e51114 | ||
|
|
78c09c27ca | ||
|
|
d3626bd84f | ||
|
|
096c1e1f7f | ||
|
|
66d44289e1 | ||
|
|
82897d672e | ||
|
|
72cb71c827 | ||
|
|
e36ddaf659 | ||
|
|
b1389416d2 | ||
|
|
0efa67893e | ||
|
|
874815ebf6 | ||
|
|
c5f1ac615c | ||
|
|
c6e4f5914e | ||
|
|
68ec33b0d3 | ||
|
|
5ac56be748 | ||
|
|
cecd461f38 | ||
|
|
106a5f1d4d | ||
|
|
3d480ec947 | ||
|
|
23f4acfabc | ||
|
|
501d82b99f | ||
|
|
24e6b677bd | ||
|
|
bf52f73d03 | ||
|
|
2a9b0a163e | ||
|
|
94db45036c | ||
|
|
9fd2ab1aaf | ||
|
|
e314edb736 | ||
|
|
8f102264d3 | ||
|
|
ab77f94348 | ||
|
|
3065cceb73 | ||
|
|
05b0010281 | ||
|
|
7d55adf01c | ||
|
|
5d23ef9447 | ||
|
|
f4cfa0ca43 | ||
|
|
cb3556877d | ||
|
|
0f7de9268d | ||
|
|
d450573681 | ||
|
|
bbfa65a88a | ||
|
|
29c08d4751 | ||
|
|
87e41ef47e | ||
|
|
1097a5c7c2 | ||
|
|
2b75445ac1 | ||
|
|
505d30cc42 | ||
|
|
2d229a2b72 | ||
|
|
d93fda594a | ||
|
|
ce57319e4b | ||
|
|
7085640f05 | ||
|
|
e83f095fd2 | ||
|
|
41dbad13e4 | ||
|
|
980f3e9c5c | ||
|
|
2bd163533b | ||
|
|
48bc69b14b | ||
|
|
7f285bb074 | ||
|
|
45743ce884 | ||
|
|
90360674ed | ||
|
|
40a0fe9349 | ||
|
|
9f8369c01e | ||
|
|
cfe6e0f15b | ||
|
|
bf0ef1b8eb | ||
|
|
de9d1afa99 | ||
|
|
25f2c44874 | ||
|
|
6080f4fb56 | ||
|
|
8bffc33d8f | ||
|
|
e8e2fc48f8 | ||
|
|
0de62717f9 | ||
|
|
58fb5ed722 | ||
|
|
a6e0fdd505 | ||
|
|
ea6b4a0caf | ||
|
|
9cdc24bd32 | ||
|
|
abe76e0d93 | ||
|
|
eccfa5e1e7 | ||
|
|
df3e4edd76 | ||
|
|
b4209cb3bb | ||
|
|
2ff11dc063 | ||
|
|
dfc2e2bd68 | ||
|
|
8605e15b4f | ||
|
|
bfd9c48039 | ||
|
|
419dc40c4d | ||
|
|
51722c1fe6 | ||
|
|
f78d856b37 | ||
|
|
e005d966b4 | ||
|
|
a9082eb162 | ||
|
|
f347cb90f1 | ||
|
|
e2661c58dc | ||
|
|
cbfec0deed | ||
|
|
058b92ca99 | ||
|
|
381a015b85 | ||
|
|
1b92943cf0 | ||
|
|
3b7d6394d7 | ||
|
|
5657375c9f | ||
|
|
68015a6e9d | ||
|
|
ad1b958b81 | ||
|
|
483d005350 | ||
|
|
0b370671af | ||
|
|
b748c4186d | ||
|
|
1f0f85f979 | ||
|
|
dd562f84fa | ||
|
|
134b07f41f | ||
|
|
9b9eb01097 | ||
|
|
8e0cc44e24 | ||
|
|
674b0ba947 | ||
|
|
3faf7aab8f | ||
|
|
60eeddf639 | ||
|
|
96579a72e0 | ||
|
|
e4328de251 | ||
|
|
401ba6e7fd | ||
|
|
0b980073c1 | ||
|
|
09ad962418 | ||
|
|
80749798c3 | ||
|
|
11a297b557 | ||
|
|
841d583678 | ||
|
|
6b55790e73 | ||
|
|
836df90f6b | ||
|
|
bb17e7cf01 | ||
|
|
375a7c701a | ||
|
|
6ec8824d75 | ||
|
|
7adc7bc01a | ||
|
|
48aa50b97c | ||
|
|
b47bf81b73 | ||
|
|
9fc3344ee8 | ||
|
|
373134c4e7 | ||
|
|
58fcf577ea | ||
|
|
cbdeb41094 | ||
|
|
be8addc608 | ||
|
|
0bded4478e | ||
|
|
f53ff49276 | ||
|
|
a496360c5b | ||
|
|
afcad2a968 | ||
|
|
df3ceda052 | ||
|
|
609074519d | ||
|
|
1d6d6966a1 | ||
|
|
a6760efc14 | ||
|
|
53821a6285 | ||
|
|
e8d17af1d0 | ||
|
|
341de74d83 | ||
|
|
52a69b8a6f | ||
|
|
c02ef3ec94 | ||
|
|
0c6504da5c | ||
|
|
5ef56395f0 | ||
|
|
c421f59314 | ||
|
|
2278104a8d | ||
|
|
178efe9c97 | ||
|
|
b2935b504d | ||
|
|
f58717205a | ||
|
|
b8def5a3c2 | ||
|
|
1d6301c689 | ||
|
|
4aefa395af | ||
|
|
80b3994500 | ||
|
|
b8ad9ad880 | ||
|
|
1afbc7f952 | ||
|
|
6389434222 | ||
|
|
afadbbbb04 | ||
|
|
4b4760ce8e | ||
|
|
26a2591896 | ||
|
|
403b5413fc | ||
|
|
f0ac01395f | ||
|
|
a75413a21b | ||
|
|
13419755f9 | ||
|
|
1f1302e185 | ||
|
|
0011dd1623 | ||
|
|
8bcf540915 | ||
|
|
e896d13eec | ||
|
|
6a12a6b4ba | ||
|
|
0a72b37363 | ||
|
|
20f7d0aed0 | ||
|
|
e834624bfa | ||
|
|
47569458d4 | ||
|
|
a25ec92a30 | ||
|
|
169d5bc376 | ||
|
|
761d75423d | ||
|
|
c6ca89fb0a | ||
|
|
f9ca0ae119 | ||
|
|
505ff0bb11 | ||
|
|
1261c18ce9 | ||
|
|
cb78516bf1 | ||
|
|
c1ff581fb4 | ||
|
|
3c07860aad | ||
|
|
97f50e8e15 | ||
|
|
fde056506e | ||
|
|
82a683eccc | ||
|
|
810f59b555 | ||
|
|
5c3461a851 | ||
|
|
ad99688853 | ||
|
|
2af5dbc201 | ||
|
|
a3171befe9 | ||
|
|
7949c194e9 | ||
|
|
f653be1ebc | ||
|
|
ca108222c6 | ||
|
|
77a2e02a0d | ||
|
|
970f8cf3ed | ||
|
|
7091f5febe | ||
|
|
04516a0d39 | ||
|
|
372e426ec7 | ||
|
|
ce93e47e89 | ||
|
|
d54f95d497 | ||
|
|
10c9b8a221 | ||
|
|
ecd7ff80b8 | ||
|
|
f9af0e6f0c | ||
|
|
fa59dc0a5b | ||
|
|
ca1751528d | ||
|
|
77e968a5e3 | ||
|
|
d6e1c462cc | ||
|
|
ed13a0a262 | ||
|
|
fed42e1742 | ||
|
|
a98a32757a | ||
|
|
14180d60be | ||
|
|
e77aa70ba2 | ||
|
|
fcae056c84 | ||
|
|
0f3a507691 | ||
|
|
9d233b73a3 | ||
|
|
23696760c3 | ||
|
|
0bd73e440d | ||
|
|
49f64a0cac | ||
|
|
db3250f6ee | ||
|
|
d67484bb87 | ||
|
|
4aa7057e68 | ||
|
|
f68a719f4c | ||
|
|
0fc3202160 | ||
|
|
cf32243822 | ||
|
|
b70fa7b0c1 | ||
|
|
38e50a5b4f | ||
|
|
ce9a0cbc19 | ||
|
|
72ddbf84ee | ||
|
|
d35d946adf | ||
|
|
6edf9ccf5a | ||
|
|
29685f48ef | ||
|
|
84a3fbd239 | ||
|
|
97317b0c95 | ||
|
|
92edcb17e5 | ||
|
|
b3791fabc2 | ||
|
|
f681f9e844 | ||
|
|
93a0c66589 | ||
|
|
f152e3e9d0 | ||
|
|
bfb96536da | ||
|
|
38dbd59d8a | ||
|
|
8c7bbdecdf | ||
|
|
87eb23f562 | ||
|
|
54b10b1b38 | ||
|
|
6a988749a1 | ||
|
|
168407a40a | ||
|
|
7b3343c2dc | ||
|
|
d2adce7ba6 | ||
|
|
8981d3baf5 | ||
|
|
9b936dd120 | ||
|
|
98617432c3 | ||
|
|
4dc8f6dca4 | ||
|
|
9c73326bbb | ||
|
|
009330ab4c | ||
|
|
365bd347a6 | ||
|
|
8ba26c612a | ||
|
|
c0ed3ca2bd | ||
|
|
9c6b720ec1 | ||
|
|
344d46ce78 | ||
|
|
f7ba777fff | ||
|
|
8310a94843 | ||
|
|
e1a079954b | ||
|
|
1ca2b6fab3 | ||
|
|
9204a8c260 | ||
|
|
68c1b8675c | ||
|
|
1784d9ab27 | ||
|
|
738b64909e | ||
|
|
81e55e8901 | ||
|
|
c5066a7317 | ||
|
|
23f07331c8 | ||
|
|
f837df34b1 | ||
|
|
3778558608 | ||
|
|
4c0f70fbcb | ||
|
|
c9d90c7f9f | ||
|
|
07cd0d5809 | ||
|
|
48c5707a0c | ||
|
|
b0b92e4ee2 | ||
|
|
f61c0c6309 | ||
|
|
eab4c887ec | ||
|
|
864e8ab0c8 | ||
|
|
a347be2222 | ||
|
|
de82980e89 | ||
|
|
fce15b4f13 | ||
|
|
0b7e2a1642 | ||
|
|
c8fcaf007e | ||
|
|
e213b9046d | ||
|
|
4bee38ea62 | ||
|
|
fec53690d7 | ||
|
|
04c3ae56ed | ||
|
|
7d50219902 | ||
|
|
b344f2bc39 | ||
|
|
1044c2fcab | ||
|
|
a3b04c55f3 | ||
|
|
92a30e0953 | ||
|
|
4e8453b7bf | ||
|
|
930c29a50c | ||
|
|
ec240a64d9 | ||
|
|
709afcd945 | ||
|
|
119b9f9c2c | ||
|
|
03062b83b6 | ||
|
|
e0081cfc29 | ||
|
|
5926261e08 | ||
|
|
44dd55a268 | ||
|
|
d5f645ee69 | ||
|
|
8fff7df438 | ||
|
|
2c2037952d | ||
|
|
63de13b50e | ||
|
|
2a77976164 | ||
|
|
bd16f89617 | ||
|
|
b69134f1fe | ||
|
|
95005a0ae3 | ||
|
|
ff7c378ff9 | ||
|
|
72036d3f88 | ||
|
|
8c65219c96 | ||
|
|
eb11e077fc | ||
|
|
b07d6eced8 | ||
|
|
26918b82b3 | ||
|
|
a6a196f042 | ||
|
|
bc2a998261 | ||
|
|
6151e1bbb2 | ||
|
|
5d1f08d512 | ||
|
|
e51e3dcdbd | ||
|
|
4b826d10ef | ||
|
|
9242b4278c | ||
|
|
ac42670a0e | ||
|
|
47724c68c2 | ||
|
|
661be648d5 | ||
|
|
77bbe87dc8 | ||
|
|
675aa2cd2f | ||
|
|
cb188f5f93 | ||
|
|
219c2fa2e1 | ||
|
|
c3b483d12a | ||
|
|
b60fd14679 | ||
|
|
d59d07b5e3 | ||
|
|
57fcd5e0c4 | ||
|
|
bb768c2cab | ||
|
|
3bcb45b4e7 | ||
|
|
6e2bd945b1 | ||
|
|
ed320f6f03 | ||
|
|
8e8878f187 | ||
|
|
2403c32d4f | ||
|
|
05765cd25b | ||
|
|
e5068fb469 | ||
|
|
eaa412022f | ||
|
|
579ca1063c | ||
|
|
f7cacd16a0 | ||
|
|
f2b9a6238c | ||
|
|
4b165190ee | ||
|
|
964aac599c | ||
|
|
f27953c48d | ||
|
|
f294ec608e | ||
|
|
80e1dce1b0 | ||
|
|
0fbd892b5c | ||
|
|
1f7b5e75bf | ||
|
|
3887ba8a21 | ||
|
|
8e9390e964 | ||
|
|
d332ee3fcd | ||
|
|
2eb13c9047 | ||
|
|
84ac5891b2 | ||
|
|
ed1c87c8d6 | ||
|
|
d15b396202 | ||
|
|
033e333691 | ||
|
|
6986b6ca95 | ||
|
|
bad002acb1 | ||
|
|
37b08797c0 | ||
|
|
07b371a095 | ||
|
|
d5a361c180 | ||
|
|
20e2a58c5e | ||
|
|
db23227ac3 | ||
|
|
d67e369433 | ||
|
|
9cb71d0260 | ||
|
|
9a46c670c1 | ||
|
|
f63e4312ec | ||
|
|
1eefc8d42d | ||
|
|
1cb9eeee05 | ||
|
|
a9cee58264 | ||
|
|
ddf2315dff | ||
|
|
7b8164d75e | ||
|
|
a8f186c7d4 | ||
|
|
e552f570eb | ||
|
|
adc3aa452a | ||
|
|
cd7cb5fbf4 | ||
|
|
ddd5e8abb4 | ||
|
|
e3d1b8b044 | ||
|
|
d72517e673 | ||
|
|
064e738d53 | ||
|
|
a322fbf822 | ||
|
|
ad56976131 | ||
|
|
77c5e55f4f | ||
|
|
3d14a94eac | ||
|
|
d9a34d9460 | ||
|
|
32b93e1f63 | ||
|
|
76b82020d4 | ||
|
|
7ac9a16090 | ||
|
|
ecff980761 | ||
|
|
88757a674a | ||
|
|
8dda68a1bd | ||
|
|
65f1100453 | ||
|
|
9e4ff8c196 | ||
|
|
97c2699392 | ||
|
|
9f945a782f | ||
|
|
d5dc234a00 | ||
|
|
590f51dbe1 | ||
|
|
03574e4a79 | ||
|
|
e1f7dd0553 | ||
|
|
5261462d7a | ||
|
|
f177107a4f | ||
|
|
01800ad1a3 | ||
|
|
eabe83d4f2 | ||
|
|
2e9a19d5b0 | ||
|
|
7bee21a4fd | ||
|
|
ff7eeb852b | ||
|
|
e79ce5a036 | ||
|
|
d4576833d6 | ||
|
|
f8376e1f49 | ||
|
|
dd73cf9baf | ||
|
|
126c72c9c8 | ||
|
|
5286456e48 | ||
|
|
cb9a448fc9 | ||
|
|
cc8b03ae4f | ||
|
|
7260a16f67 | ||
|
|
ead12669d5 | ||
|
|
fc902b797e | ||
|
|
0253cdd50c | ||
|
|
1053d78201 | ||
|
|
5d9eb55274 | ||
|
|
69ac68ca98 | ||
|
|
013eb506a8 | ||
|
|
2bbb183a18 | ||
|
|
2b006dbaac | ||
|
|
e05a708024 | ||
|
|
70112d29da | ||
|
|
accc7e7521 | ||
|
|
f4e9c94bf2 | ||
|
|
bfd24de4ad | ||
|
|
f05c4df36a | ||
|
|
4a3fc21ada | ||
|
|
21b2b7e1ea | ||
|
|
ff7e8086d7 | ||
|
|
fce01f8b84 | ||
|
|
f2d1ba483e | ||
|
|
e0f9e26c21 | ||
|
|
78ad18ca45 | ||
|
|
86e0c45514 | ||
|
|
047275f16b | ||
|
|
e57863c0e5 | ||
|
|
d82ddeeaff | ||
|
|
90753f3e50 | ||
|
|
db20aad591 | ||
|
|
980a2da677 | ||
|
|
c7d0accac0 | ||
|
|
c34a4bfdb4 | ||
|
|
e156511157 | ||
|
|
529be993c7 | ||
|
|
d76826ae83 | ||
|
|
bd81eac98b | ||
|
|
8287abf63f | ||
|
|
50966583f6 | ||
|
|
2ee15cc2e0 | ||
|
|
711cce3f4d | ||
|
|
9269d09e18 | ||
|
|
2bd873e2b4 | ||
|
|
7670f048c1 | ||
|
|
cd7e3425ee | ||
|
|
cd45a3b8d6 | ||
|
|
065c2163dd | ||
|
|
d7522defde | ||
|
|
3149506963 | ||
|
|
a57dd46aff | ||
|
|
a22b0c3ac6 | ||
|
|
8aa1e349fc | ||
|
|
96a068f90a | ||
|
|
12c8e51071 | ||
|
|
fefeb29d5f | ||
|
|
66a93d9199 | ||
|
|
8d09d02b85 | ||
|
|
9d16169a65 | ||
|
|
4853d61c3b | ||
|
|
abf9557bb5 | ||
|
|
4e9ff5ad7b | ||
|
|
38aab18392 | ||
|
|
79a433ae77 | ||
|
|
bb9d15b8b9 | ||
|
|
28f7568e82 | ||
|
|
e9a8d83eb5 | ||
|
|
7ba6297988 | ||
|
|
c79ffc5c79 | ||
|
|
30b0bd641f | ||
|
|
3c3c86bdba | ||
|
|
166e487559 | ||
|
|
584aaec2a5 | ||
|
|
c7d1a9e270 | ||
|
|
4447a54059 | ||
|
|
c2590995c0 | ||
|
|
ddc50431e6 | ||
|
|
ccc67d6f68 | ||
|
|
3e6d1b96e7 | ||
|
|
c10554851d | ||
|
|
c68d551c41 | ||
|
|
f0cfaaa147 | ||
|
|
ef1dee8bc6 | ||
|
|
bfe0031304 | ||
|
|
abd536d5d3 | ||
|
|
4a444651c5 | ||
|
|
666f6c9ac4 | ||
|
|
fcadbc9023 | ||
|
|
336140c5f1 | ||
|
|
1f1d1af041 | ||
|
|
10f1616c28 | ||
|
|
cde8163770 | ||
|
|
a740b066a6 | ||
|
|
faea43906f | ||
|
|
9175d801e0 | ||
|
|
d0eacdd0d6 | ||
|
|
fe6f616cf1 | ||
|
|
6575df84c5 | ||
|
|
0423eb4499 | ||
|
|
33ba587813 | ||
|
|
c7fa3b69d9 | ||
|
|
e9b9f684ef | ||
|
|
a9a8c65f53 | ||
|
|
e6b87e9d20 | ||
|
|
4619e2e84c | ||
|
|
eff67d3131 | ||
|
|
5641ebcd1b | ||
|
|
506bc023b7 | ||
|
|
f07cfbe02d | ||
|
|
6d6aff0093 | ||
|
|
18d963419d | ||
|
|
dcce0a1032 | ||
|
|
562325a28b | ||
|
|
c8c910a41b | ||
|
|
f1ce555cd9 | ||
|
|
5b6bd8459f | ||
|
|
8fca8a9a04 | ||
|
|
e0e9b3b32e | ||
|
|
47b11bf9b7 | ||
|
|
fe46d50ab3 | ||
|
|
02d33e7b28 | ||
|
|
df26dc07e9 | ||
|
|
7c0894159f | ||
|
|
2a0f940bd7 | ||
|
|
9fc4ee5f6c | ||
|
|
26f65f4996 | ||
|
|
84e476facb | ||
|
|
1936667a53 | ||
|
|
963f5de117 | ||
|
|
6013889028 | ||
|
|
6133977d8b | ||
|
|
ce44dcf9c1 | ||
|
|
a1e22789af | ||
|
|
d26554f38d | ||
|
|
4009239328 | ||
|
|
fb1c504568 | ||
|
|
55b070d204 | ||
|
|
8844c57254 | ||
|
|
80ef5fa73c | ||
|
|
b7fffb1b24 | ||
|
|
95785a9c46 | ||
|
|
fbd545ae70 | ||
|
|
4f1d43ce21 | ||
|
|
f4a2d932e3 | ||
|
|
89a9e88a7e | ||
|
|
67869a697b | ||
|
|
114af00913 | ||
|
|
a867c29633 | ||
|
|
2b711f59ed | ||
|
|
81ada6b4f2 | ||
|
|
bdc8e1f8fb | ||
|
|
219218dd38 | ||
|
|
dc246544de | ||
|
|
b34f70d312 | ||
|
|
a36def9a10 | ||
|
|
9e0dafbd93 | ||
|
|
9a671cf8bc | ||
|
|
b0abfc2dcd | ||
|
|
6552313098 | ||
|
|
f5fb9684db | ||
|
|
75e22fef4a | ||
|
|
5d6f97cc1d | ||
|
|
95a2fc7167 | ||
|
|
c513a63a04 | ||
|
|
cb24b1064d | ||
|
|
366bba0227 | ||
|
|
c30299feca | ||
|
|
eba9c15746 | ||
|
|
2a33d9aa76 | ||
|
|
8af45fd5fb | ||
|
|
bac3d620c6 | ||
|
|
6611c38184 | ||
|
|
226c4a475b | ||
|
|
36104098ad | ||
|
|
61e1bed2c2 | ||
|
|
1be4a0aeaf | ||
|
|
d873c13e16 | ||
|
|
fd89f510ca | ||
|
|
e40b3bbb30 | ||
|
|
57bfd09328 | ||
|
|
b6991f9c03 | ||
|
|
4c76a87fec | ||
|
|
3f74862666 | ||
|
|
f44edd407b | ||
|
|
553cf556af | ||
|
|
7499379862 | ||
|
|
b0e155d316 | ||
|
|
d6d0bcd960 | ||
|
|
1cae5ec8f6 | ||
|
|
75df14f190 | ||
|
|
f01bdb9949 | ||
|
|
edf1f9d849 | ||
|
|
4d6fcbb8b6 | ||
|
|
869297a672 | ||
|
|
859a5fd208 | ||
|
|
3ced146733 | ||
|
|
9e1d776da5 | ||
|
|
4927a6f679 | ||
|
|
f524fb8e61 | ||
|
|
b63d83e6a3 | ||
|
|
2d153c40e4 | ||
|
|
cfbd1f0749 | ||
|
|
0a77987778 | ||
|
|
bfddad17a3 | ||
|
|
54532b99f9 | ||
|
|
bd36933636 | ||
|
|
ed89f2f7f0 | ||
|
|
d4a75ed9bb | ||
|
|
684052df5e | ||
|
|
b4e437000a | ||
|
|
2f7217b29f | ||
|
|
7e3334ca02 | ||
|
|
f148388227 | ||
|
|
6b89eaaf79 | ||
|
|
9f2bec52d5 | ||
|
|
93e42bf5b9 | ||
|
|
9899fed654 | ||
|
|
e23fc5a1fc | ||
|
|
30f96657f1 | ||
|
|
552662d594 | ||
|
|
48132c9ca3 | ||
|
|
e4bb85b4de | ||
|
|
892f51ab1c | ||
|
|
a36465426b | ||
|
|
15cc6d688f | ||
|
|
2cb635c3e3 | ||
|
|
30fd10933a | ||
|
|
9f140ab843 | ||
|
|
17bf2564fa | ||
|
|
4d9037d112 | ||
|
|
16b395dce3 | ||
|
|
a52541de18 | ||
|
|
2d041f0e9c | ||
|
|
52301b3bb2 | ||
|
|
4dd69b1d5a | ||
|
|
9e93ea3e1c | ||
|
|
079f00e083 | ||
|
|
c9a5f0ce45 | ||
|
|
a3c217757c | ||
|
|
531a4bbb7e | ||
|
|
6d4e0c456b | ||
|
|
de38b2ece3 | ||
|
|
5574dd3465 | ||
|
|
ec6b23897f | ||
|
|
bdf70c0ecc | ||
|
|
88be272113 | ||
|
|
dd463d3014 | ||
|
|
c5f59ddfb1 | ||
|
|
9e34ba1458 | ||
|
|
bf74c1694d | ||
|
|
a38ec2854a | ||
|
|
419a48aa06 | ||
|
|
3f91f7402d | ||
|
|
58cbd11f6a | ||
|
|
9c0bd03363 | ||
|
|
70c5c31ec9 | ||
|
|
b32f2d126a | ||
|
|
703a013b60 | ||
|
|
8808b99cc5 | ||
|
|
c3853494c8 | ||
|
|
fc7999a62a | ||
|
|
b8d8bc3142 | ||
|
|
fb2398dbf2 | ||
|
|
568865bde0 | ||
|
|
dcce3d5a40 | ||
|
|
26f3a43df0 | ||
|
|
f591c12e77 | ||
|
|
64f7a04cec | ||
|
|
7fad78ba03 | ||
|
|
841b99ba3b | ||
|
|
d8b1159cbd | ||
|
|
b812179e82 | ||
|
|
bf60e1486d | ||
|
|
8fe0a7514f | ||
|
|
219615b0eb | ||
|
|
323de9b229 | ||
|
|
3cdcb528ff | ||
|
|
564e6a6885 | ||
|
|
53c87d18ed | ||
|
|
14a6be97cf | ||
|
|
799b07f21d | ||
|
|
25ca29002e | ||
|
|
1ae527ea67 | ||
|
|
a0a54df74c | ||
|
|
b0b436acef | ||
|
|
425d18e866 | ||
|
|
72dec21d8f | ||
|
|
dd98bd67a0 | ||
|
|
18993b5ede | ||
|
|
78b38cd65b | ||
|
|
5099d00eb3 | ||
|
|
f710e10206 | ||
|
|
0923ea5bea | ||
|
|
1556300ea6 | ||
|
|
d1e0e460a1 | ||
|
|
f68be31fa3 | ||
|
|
154c16753c | ||
|
|
3d12e7b242 | ||
|
|
99ddaaa9d7 | ||
|
|
dbf7588a76 | ||
|
|
38abfc79f5 | ||
|
|
15a5db61c8 | ||
|
|
e6a638e78c | ||
|
|
057749a3a9 | ||
|
|
d5518aa938 | ||
|
|
96fa3ef28c | ||
|
|
adfb1a77e2 | ||
|
|
c9bcce57e8 | ||
|
|
c63fe241f4 | ||
|
|
4761826843 | ||
|
|
64c8b06377 | ||
|
|
2b649cb633 | ||
|
|
73a3ef4dbe | ||
|
|
ea76b08f9f | ||
|
|
ad3ec34690 | ||
|
|
d57ebae6a0 | ||
|
|
af1c965831 | ||
|
|
6ca8f4c174 | ||
|
|
86c1f65dfe | ||
|
|
f36bc80bd7 | ||
|
|
3ea960932e | ||
|
|
e204b9532b | ||
|
|
1514667b42 | ||
|
|
f94f96c3ee | ||
|
|
b05ad847b9 | ||
|
|
544274feb9 | ||
|
|
7ca56a62fd | ||
|
|
82e2900aa7 | ||
|
|
40c9226bb9 | ||
|
|
0a5dcc86ed | ||
|
|
0b09cc8cf6 | ||
|
|
9d0518661b | ||
|
|
b8eae11356 | ||
|
|
c41a9e6a21 | ||
|
|
4e115a7de2 | ||
|
|
72f2ea349d | ||
|
|
44977e3519 | ||
|
|
9b09f0e2cb | ||
|
|
b7eb5d94f2 | ||
|
|
cda71e198f | ||
|
|
d2c7cfa5fa | ||
|
|
c05ab9c310 | ||
|
|
fe4f304815 | ||
|
|
12461291b8 | ||
|
|
4112037c0c | ||
|
|
19fe5da9be | ||
|
|
8bc4389411 | ||
|
|
d37f32fb21 | ||
|
|
c6718677b2 | ||
|
|
5e4b523357 | ||
|
|
9c852c750a | ||
|
|
66d5954fc5 | ||
|
|
0de751a1c9 | ||
|
|
18fcbbe1a1 | ||
|
|
858f5732ba | ||
|
|
e1ac124a4d | ||
|
|
2b6ae514b5 | ||
|
|
e87f63944f | ||
|
|
26bcd439f7 | ||
|
|
5d39acd3c3 | ||
|
|
f3dafbf5a6 | ||
|
|
59f97802a9 | ||
|
|
80778b267d | ||
|
|
2ba5f8f4f3 | ||
|
|
e8db9bda9a | ||
|
|
f4aff87e25 | ||
|
|
a255ffaee9 | ||
|
|
f2a5648deb | ||
|
|
b3b10c1439 | ||
|
|
5a5af878f7 | ||
|
|
c364c4de2a | ||
|
|
a6b4812b78 | ||
|
|
f32344138f | ||
|
|
987ec9d371 | ||
|
|
3988d6cde2 | ||
|
|
7d54d1da0c | ||
|
|
caba2d3021 | ||
|
|
990b7945a7 | ||
|
|
9c6de44f98 | ||
|
|
365bec38a0 | ||
|
|
41b3d3abc1 | ||
|
|
a110fef4d9 | ||
|
|
84e0ffe7cb | ||
|
|
f2d063be07 | ||
|
|
616352b840 | ||
|
|
adb00d329f | ||
|
|
f9c2e0e21c | ||
|
|
9646c17f2e | ||
|
|
de5c0603f1 | ||
|
|
0b60b8954b | ||
|
|
44a43aa060 | ||
|
|
c76faff7d4 | ||
|
|
054b8de67b | ||
|
|
f831800ae0 | ||
|
|
9e888df3c9 | ||
|
|
657fa16f8c | ||
|
|
f6dd1f9b9c | ||
|
|
55a014acbc | ||
|
|
8e80c05be7 | ||
|
|
07b36573ea | ||
|
|
a0c0f3d7c9 | ||
|
|
c9f4b455c5 | ||
|
|
ca0c86e7af | ||
|
|
83a88d46b7 | ||
|
|
44adc3c404 | ||
|
|
7ff6e96623 | ||
|
|
e54ad5c73a | ||
|
|
86f269feba | ||
|
|
1e04836a6d | ||
|
|
9672329772 | ||
|
|
bf3c57511b | ||
|
|
411601ebd1 | ||
|
|
b1c9db8a0d | ||
|
|
491be000ca | ||
|
|
d164cbac8c | ||
|
|
c365918b82 | ||
|
|
01698233fd | ||
|
|
a63afe53ae | ||
|
|
3b0899aae1 | ||
|
|
26d4753a3c | ||
|
|
55dc3abf00 | ||
|
|
0126523b83 | ||
|
|
bd18152d32 | ||
|
|
593fe2a571 | ||
|
|
ece48d7df5 | ||
|
|
a6b29530e8 | ||
|
|
7b4ef66d91 | ||
|
|
27c9e5c6e8 | ||
|
|
0b4b2b2fb2 | ||
|
|
aec97b7da0 | ||
|
|
13690ec898 | ||
|
|
2b632760b6 | ||
|
|
bc6f523c8d | ||
|
|
96351801c9 | ||
|
|
804fb4e10d | ||
|
|
8b05deba13 | ||
|
|
6cbf54aefb | ||
|
|
b0187ddc28 | ||
|
|
520eedb829 | ||
|
|
66f3742112 | ||
|
|
77010d6434 | ||
|
|
f15e8fec8f | ||
|
|
50ec5c03c1 | ||
|
|
6d69f946a8 | ||
|
|
aa0f13fba5 | ||
|
|
97c5e21ed6 | ||
|
|
c1493b2ed2 | ||
|
|
03ae78173b | ||
|
|
4eebd140b0 | ||
|
|
547cc06976 | ||
|
|
30948a4b0d | ||
|
|
e6b7e1f6e1 | ||
|
|
65b2e63bb9 | ||
|
|
0f6afa3d89 | ||
|
|
eae0445cd8 | ||
|
|
3b5a34c163 | ||
|
|
2f32308c0b | ||
|
|
bb95121ee5 | ||
|
|
94f4e2a276 | ||
|
|
b2ea164c76 | ||
|
|
db6a2419f2 | ||
|
|
1b4128d3d9 | ||
|
|
b0683a5acf | ||
|
|
d67db5cd74 | ||
|
|
b6b775cd60 | ||
|
|
61739de2f4 | ||
|
|
2116bcf733 | ||
|
|
be4e34b6b5 | ||
|
|
7f5bec5c0d | ||
|
|
42b1eefe73 | ||
|
|
9d84d8b3bd | ||
|
|
127ceaccb5 | ||
|
|
5e227f9ff1 | ||
|
|
db9d4d3a3c | ||
|
|
3560555acc | ||
|
|
0ca248551a | ||
|
|
50aba6f21b | ||
|
|
615878bb05 | ||
|
|
3409eeeb34 | ||
|
|
f18e8a4553 | ||
|
|
189c5fa628 | ||
|
|
a0a7d5d165 | ||
|
|
d6a05245f2 | ||
|
|
0635d5fffb | ||
|
|
84331ac0f7 | ||
|
|
e532fc83b6 | ||
|
|
73f1fa9a1f | ||
|
|
ca172aa4fb | ||
|
|
0ac6f6159e | ||
|
|
5e5c705fbc | ||
|
|
2eef27fca4 | ||
|
|
d4920eade4 | ||
|
|
3a350b65a3 | ||
|
|
1ccd9a2fdb | ||
|
|
f3988a27d4 | ||
|
|
dd5b03671d | ||
|
|
676d05b751 | ||
|
|
6aba4871a7 | ||
|
|
88a3fda36a | ||
|
|
26eb0ce794 | ||
|
|
9655ebbefe | ||
|
|
4dd5e6b266 | ||
|
|
aa1d5a7dd1 | ||
|
|
8ea584b1d2 | ||
|
|
f2c3225ab6 | ||
|
|
db329b02b5 | ||
|
|
03b8e70d3f | ||
|
|
e3d9f41496 | ||
|
|
d18262da1f | ||
|
|
e87b322616 | ||
|
|
dfa8b787be | ||
|
|
e6dcdcf277 | ||
|
|
c4c9e1fe7f | ||
|
|
db0589727a | ||
|
|
1bbe34540f | ||
|
|
ee4ee6a8ac | ||
|
|
ddb2805f3a | ||
|
|
4e97a6511b | ||
|
|
ca60e24ad9 | ||
|
|
7e47fa58b3 | ||
|
|
42db1e112b | ||
|
|
362337a9e8 | ||
|
|
0da420c104 | ||
|
|
487162a53d | ||
|
|
e4fa8e8fcf | ||
|
|
5f65791962 | ||
|
|
30a96706cb | ||
|
|
03144093b3 | ||
|
|
215937ff0f | ||
|
|
ee88d4d2d5 | ||
|
|
e5b9a6cc8b | ||
|
|
71bd9a1f10 | ||
|
|
d63c40af3e | ||
|
|
791fd9806f | ||
|
|
d0f5838c61 | ||
|
|
7b55d4d5d9 | ||
|
|
3f269b773d | ||
|
|
97b1a22a8a | ||
|
|
6b4b662357 | ||
|
|
642254134e | ||
|
|
b811ef4331 | ||
|
|
cd21074201 | ||
|
|
f9b3c6d2cf | ||
|
|
df71e02ef6 | ||
|
|
9705c90d87 | ||
|
|
7a359f95a3 | ||
|
|
28004bc9e6 | ||
|
|
23f65803fa | ||
|
|
226fcbc02f | ||
|
|
8ca63d4a6e | ||
|
|
170b532892 | ||
|
|
a67d24e509 | ||
|
|
82d20f94cd | ||
|
|
754d1bd4a3 | ||
|
|
7c269cb933 | ||
|
|
b3f620436c | ||
|
|
7b9edcf90c | ||
|
|
9ff82d76c0 | ||
|
|
be753ee863 | ||
|
|
f04ef8ed40 | ||
|
|
6d361b337b | ||
|
|
86656517e3 | ||
|
|
ad49fba42a | ||
|
|
ab0b0ac3a0 | ||
|
|
e1ada57bfa | ||
|
|
3f37a12e2d | ||
|
|
dae563725b | ||
|
|
ef9435b9ed | ||
|
|
4835da0f4d | ||
|
|
15606dfc49 | ||
|
|
40b12bb83c | ||
|
|
ace5400953 | ||
|
|
2ad57d3850 | ||
|
|
26d4d227ea | ||
|
|
bea305aec5 | ||
|
|
1cc09ac786 | ||
|
|
c66c23b7f1 | ||
|
|
ddfd3c0d7e | ||
|
|
ff800af820 | ||
|
|
6bfd4f4276 | ||
|
|
37b5c9a2c1 | ||
|
|
d80fadc635 | ||
|
|
c63f7725be | ||
|
|
02d7b401fe | ||
|
|
6fcf95d536 | ||
|
|
c6690ea447 | ||
|
|
ea21576eac | ||
|
|
796810ea06 | ||
|
|
47b7ce5149 | ||
|
|
d8861262b2 | ||
|
|
f10af1cc57 | ||
|
|
070aa62f92 | ||
|
|
1953a31031 | ||
|
|
9d3d7c4cb4 | ||
|
|
14b5e81f1e | ||
|
|
23e15cb2ab | ||
|
|
d9d32847b1 | ||
|
|
0574cdf705 | ||
|
|
1d56c3d3aa | ||
|
|
040e331f77 | ||
|
|
d62c3117de | ||
|
|
8fd914c6ab | ||
|
|
2633ff8661 | ||
|
|
a932fc2e5a | ||
|
|
b586b00845 | ||
|
|
b20b14de27 | ||
|
|
9b8228d76f | ||
|
|
5336ba4b8c | ||
|
|
d3f5a369a7 | ||
|
|
d43a5a6ef1 | ||
|
|
013efb58ac | ||
|
|
675e2f062a | ||
|
|
4fa0cb5c29 | ||
|
|
488396e78b | ||
|
|
8207fb8d98 | ||
|
|
a79378ff19 | ||
|
|
e99f2d0595 | ||
|
|
b446e17bcd | ||
|
|
fe33193ae1 | ||
|
|
555ebe1ffe | ||
|
|
5c4f0e1340 | ||
|
|
82c763fe75 | ||
|
|
a1e32a3ad9 | ||
|
|
8a6ad5f94b | ||
|
|
9bfc29e456 | ||
|
|
68cd5e8004 | ||
|
|
fd59c5f92a |
6
LICENSE
6
LICENSE
@@ -41,7 +41,7 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -683,7 +683,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -698,4 +698,4 @@ specific requirements.
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
26
README
26
README
@@ -65,34 +65,24 @@ The source tree is composed of the following subdirectories:
|
||||
|
||||
:'doc':
|
||||
|
||||
This directory contains general documentation. Please consider the following
|
||||
document for a quick guide to get started with the framework:
|
||||
|
||||
! doc/getting_started.txt
|
||||
|
||||
If you are curious about the ready-to-use components that come with the
|
||||
framework, please review the components overview:
|
||||
|
||||
! doc/components.txt
|
||||
This directory contains general documentation along with a comprehensive
|
||||
collection of release notes.
|
||||
|
||||
:'repos':
|
||||
|
||||
This directory contains the so-called source-code repositories of Genode.
|
||||
Please refer to the README file in the 'repos' directory to learn more
|
||||
about the roles of the individual repositories.
|
||||
This directory contains the source code, organized in so-called source-code
|
||||
repositories. Please refer to the README file in the 'repos' directory to
|
||||
learn more about the roles of the individual repositories.
|
||||
|
||||
:'tool':
|
||||
|
||||
Source-code management tools and scripts. Please refer to the README file
|
||||
contained in the directory.
|
||||
|
||||
:'depot' and 'public':
|
||||
:'depot':
|
||||
|
||||
Local depot and public archive of Genode packages. Please refer to
|
||||
|
||||
! doc/depot.txt
|
||||
|
||||
for more details.
|
||||
Directory used by Genode's package-management tools. It contains the public
|
||||
keys and download locations of software providers.
|
||||
|
||||
|
||||
Additional community-maintained components
|
||||
|
||||
1
depot/alex-ab/download
Normal file
1
depot/alex-ab/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
52
depot/alex-ab/pubkey
Normal file
52
depot/alex-ab/pubkey
Normal file
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBFqqaR8BEAC0vonMP5zZtWUYgQ76HIhvjkI3FWZ721fzg1245+B6vmUTBnon
|
||||
WvGa+Z2WcKiMJKKfBThm1SExAUsUT2DX4uxyvJWpActoAbcljvhRadVlAgZpPMUR
|
||||
Rc18FkH+Kc5hBxIJnrxD5eLReTqqKp2KQ1OznUHCCCZGV+rzbEWSCNnJmKEILgkq
|
||||
UeGZGDJ2aoQQBwVHNNd5PUM8PX1UqBpbB9GEbqEpCy6kNUrz3VTMKOm9WcveYV9c
|
||||
m27e+loebuimz7qin61d7MOr0WSnqY/MKI9pwAR9/rGeEf0GCZlBgLCmfZZmHnYV
|
||||
NpA0uY3viV4H2ooFX2cQ3FA1CVjBD5tHdMfNygDoPLjL8yaxcA5Ftdlt+D0mYFCt
|
||||
n5t1awZuLnJBgWoGKziOPpv38hHE1HPfKw9E14Y/DzBeNrmkfON21xbDgdgurWbM
|
||||
FSnOUxEKO/7PVMfLHLVz7Ml2bmZFic4XFKZGQAVft6eUV9t9NaaSuh5a9DO0wAVI
|
||||
9OkPm4MfWIu8dRhnHrxbmxlvhduGYZfUCNl8JGwgz7zstCeCuodzwfiYkjQVZCLD
|
||||
7MrT3pw2raAtbn5Tz3Crkxkmgj4rBTLui+IchTA0hIwFJIvvJxFT521pnnJfjuPX
|
||||
tsm3twlgEq1g3KR6GkFOvtBCln+pGslXve4+x5094HoZIlJwJ602KP1RiQARAQAB
|
||||
tDlBbGV4YW5kZXIgQm9ldHRjaGVyIDxhbGV4YW5kZXIuYm9ldHRjaGVyQGdlbm9k
|
||||
ZS1sYWJzLmNvbT6JAk4EEwEIADgWIQS94id8InEq6+roQea7Tef/n/btXgUCWqpp
|
||||
HwIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRC7Tef/n/btXrPaEACZEMqU
|
||||
D/nIcTQF1NdK19/GZ8vwtfEhsfFel975xjSOgEP+mslgoqXXeMYr9qB74564OPKd
|
||||
KBSoAi8FZkRGPYqVyp0jfbxC4b6TfuLPFONjcLT05kDnadL2MWPhvv9gRJ/J7Joq
|
||||
5z+vs6Anw9B//Vbpy9NaV+Vp6Zhf+ISR2EvThvmtGnDlt1Etv7py7v3uc12hLqjN
|
||||
FkVfyU+NZLY1XHDlNHEScmFri0w/nxsbc0Dp3nUr0Xr3mAdKlg/1Z0xS68QnkJg/
|
||||
B62Oy91spDPQtt6QEhO/PDFIff+404qJiMvUc8pFieIpZseVqwW5plhL21RBhIYu
|
||||
qvjcstXqFFHuzW0XvrjxMFizyRFgcO7QozsrLmrrFvseR1yXbDuXB2NMGUvL1ZpU
|
||||
cPTrdbBIMFsaxqMyG1ELfaNj1t8PsW85+6sN81Nc1bhr+rwW75qtIYhAbB+jcuY0
|
||||
fv0FVXw/BJOe9RnLdFhXmkOX+bQ+wcF0oAvLxd+wQtTPThfbYfUim+LTzw0DHpbK
|
||||
qdTcYzmk4AVinXuTwWqBAD3URbakWWqNrElQ5ad4iEZpcIP87FMvrS/dDB1/o1jQ
|
||||
dnJfSIjmKnVVLDT5SkWgeihfOFAUO6RDRG1/DOxLaARrfG3oYE5+6INYnZvU7a2d
|
||||
UOglDt2xRfGp6TWPawJEXsWfnok/gDq+J+6TEbkCDQRaqmkfARAAyCJNL3hJVS00
|
||||
v8KqJDa6BHBwhv86ybDRJKFbnDEtX9uFeRS2HlKHQfD3mCgtPv6tQYuyDC/AvMRF
|
||||
1N7v2B+P+UQVBrN/+3kyz3m12lP7ZT/imFR4cHehTUQeaJhXQrs1YC6J2gO81HET
|
||||
KsWa1B4DZdeFqRkgfm33Na521yaGtC6HG6yU8l4OG91Pm4iEZ5eGdzvDNa888+Kf
|
||||
ppXkaOlgaa1gd48g0rKvPrXlYUgg4MbmryKfOh8+Mrg4lkTkZGRIR2T+lGhVCTvZ
|
||||
VJkA/xD24Kbxv7U4CKhirbAW1L8fS6Z5wOoXAmFi8jKftvCoFEEDrclfoZaIS6pC
|
||||
OO7ZL2DlLBZ8Zg/Z8ncdisnQiURjobAK+H4ObzbuXAG7uLPMSSR6gmTULAIURfmF
|
||||
YaWGrqC2bPViVKBtS6yFoT0bwnQ2n5BbdbIKf03ljbM1kVa+WoyMw9/DUsjSqcmJ
|
||||
AXqVYR0FR3zBzcAwOnW/4yIcXqafY21WGByqF7WWN3DhWofm+WlshljOfjSvWEAR
|
||||
l/tIUSzYYEca0mKyAEtcwxSyKzzhYjEXRfA0Me73rVxa2Zjlunq0hwUQvOJ43l2R
|
||||
7R1FYlQhmbQWDByAg3W0eoE2qFrTvctLz172A/rK88VV6ULwpJ8IaTPg96n0PVPv
|
||||
kptb273cjKBFhJWDDcLU65ONygwC03kAEQEAAYkCNgQYAQgAIBYhBL3iJ3wicSrr
|
||||
6uhB5rtN5/+f9u1eBQJaqmkfAhsMAAoJELtN5/+f9u1ea2IP/3nfcsAzJtUhU+XV
|
||||
P6pO5kyQIvUgCj0gA/BNRom2FnTtfyThwumcdeKBrbddF7uFXGi/vLJ03qy2CusZ
|
||||
PEgiT6tcR4MpptlsMnKvRZsHHlnpxo54qdwfKpHv7NbLjelmhInkSe3/nz/JW9+m
|
||||
Wpzyhe0EHOkoZKO9U/RDkDw42pYVrSJoZE+mMNxZ1YJCqDMeClHumxpjWHdhuuR0
|
||||
2jY7sB8DBpuMWgHwle/FANG6sh2OprdGJlSqQzeqev8z2tY21cSqpPx4pYW/HvxD
|
||||
YcbMtwsTIHqU7YtKyH4t/C7r9yB/gcd60FwnY0YuqykdOTG8nesBQ+4rIDUqyqgV
|
||||
zT7agmaUhji4EMyjjRPiu81xole0TmO4HpklqQL5US2fW/4VRdan7lxxWvRm9U1h
|
||||
aM79kQSWIKUnGFQ5ekobTF3GSB46zfB0kgJivoP2+sOFPEu0p/mA28fCZmM3J6fx
|
||||
wBNW/8HTLOQ4gvLuRrxZ75PG6XeveNDTdnP/owNXd43NjRwpY4EJzBdI96ehCrNH
|
||||
VBUvvNwBCyf8hOPmPb7bw7lIvPjh2LNmwG9nep1i79I7SI3b9Xfs+6P7nSYXHkBp
|
||||
jFXPSZm7nP5+zgxO82Rp6sEqmNdWpVFjlLdOQRMhN+hDgtNJCUM7S5pjYMzGtwtV
|
||||
qXQ/nZ2NHZy9C3RfSKz3NJ/v69xS
|
||||
=alCT
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/cnuke/download
Normal file
1
depot/cnuke/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
52
depot/cnuke/pubkey
Normal file
52
depot/cnuke/pubkey
Normal file
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBFqQDrIBEAC7hA8ceYe/eMqWMUG74miep7D5q2ebbvSBJW69NuhjWefDQiey
|
||||
sJGIk52ZlHvVsXe/DR1GZ3uWyQVUufWU4hlcphmzzd3RJJ+MF4yhd0YbaefVL7vb
|
||||
g1soEgBGVsnLBW/sUDEcF1sIe/gh/HcZVWebFr3mCE9AVv/juroDVRL5Eah3YJbV
|
||||
wOQeMKhYzKUszEuYQGbNw2E7u/M+JUqSfAw49gtlT/HH2jJGF00YJo7SCRRzd6MP
|
||||
n3e/Fd6nVLcjpDJ+M0pEqqK/Uuiz/2VA6uU+IubqN8JoSWwbxvc09bafet3/CIAH
|
||||
78M5IrpHsPnH12odI81VRkAT6yjnjC3SjeGjsTeeayKmAt0gn5PAqqpK0Wt9R3GS
|
||||
xReEYBxqYWoKB1v85eSWlJ0jwjX6LFST5nR/R8ew2k7uLjY9tb0tIGbiG/ECpeHC
|
||||
kIeO1bXiCtca30rlXaT6U551m2Zhi8mwAGUxiuyLJQ+m0pXe82BB3hSDRUhQJ1Ra
|
||||
sCaRvwPZdRCDDdhObkgkMlYROVNdC7ju8jZmB4n5O/5N7Ll7/RVhUWD7KeJu1UTM
|
||||
oNEmhxEMrEcYcHFt8N8YVtJleRMVnsrZBNxOkFnpsPZr02XIQKfYi5tqSaBQZ47h
|
||||
TTtXP3+FEaU+EoJprWqH55Sh97Fg6vuBJEmcGJeMGudFrypTzwqnM22DHwARAQAB
|
||||
tCdKb3NlZiBTw7ZudGdlbiA8Y251a2VAZGVwb3QuZ2Vub2RlLm9yZz6JAlQEEwEI
|
||||
AD4CGwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AWIQSFq6G0496kOfRE2qnpSz5B
|
||||
lOa1+AUCXk6dFAUJB4D1YgAKCRDpSz5BlOa1+JHXEACyB6vfzfuyo8fu1IaGrloC
|
||||
qUUuSfhdleF1tPhZQn9W92bEEoXPfqFUuiNaxeFIXonyiD7wJYdcowdIb6CiNWrx
|
||||
B8yjDQ7yb08sDLlL821I93kByy24Er5hY3QEMuEL3qv8YD/6Bh36Q0aoTXqQXMuQ
|
||||
3AcHp0JI932Oez3q+gEdW7CUe40N9LaTx0A7ZTHe0i8IELkUPFtDg8xibOjZhBMR
|
||||
vlxNUtzQVvC5kT5Wt0w6ZFKPGJguFylaE+TcsTNtiLNS4Z8PmRPgygrWotmprELo
|
||||
2/py/VMxgQb7p4LFj+sNmU9x3ulFO3Efb9cVZVjBMYx5xh83ZiLZ3PvK43Eo+7nm
|
||||
kYQhPinAjNmqng4/ZdQFrayFMkZc4oKCqV6BaYnybbsSn2ZEwVQqpDMeswWXTf9k
|
||||
qC6DONz3ETtyzBEF8cHDpy+BwHRXx+pysGLhIvHS9C3M91j8oXvogZRbw/dEKGX2
|
||||
eWes7nsdHeTbyRJunCCnsXDm0Js8cZcqj3Eu3Kpeu2CbgJGD+ajOel2RSMo2mFtg
|
||||
OoRWjCibWHDSeUS+LGtspDpry+4VYwm4KBdcyEgiXnE8WDb/xk/hZgJCr2814AJC
|
||||
RPpXoIZdFiwSP46vgoAnHynPbGTmE/Wt+F9Y2cn/dz6rmg5ynS8AKuTOUSoAKEUV
|
||||
J20mBJpkSx7Cc95AGE8K/LkCDQRakA6yARAAws48PKN3BQPEM0M4kTO57/OqwGrA
|
||||
AMlxnB3n+AP7rtZEC2L548+3pfg7Ub45Oq1X0ySxgPhV15CDUEK69pgs0JhphMbM
|
||||
DyaUp04DyQWFhdueAqQVFnKvg6nZm/WIJF1VYEc0/q6Ramsdv2cWdxFBkFHYsH3P
|
||||
G2bXCZZAEO6eJI8cdmBH6+bVptky/AybzBLztp1ruWlj+rm79qULmW7zJfxYwL1U
|
||||
4MkSN6+nQ2diU2tsOOcENKzuQbB7N1Pdp4VItjIq+65z0U81iPGKMwVjcilx9pVV
|
||||
C1qf1YvsqsNhWcUCTDiPUrXW65ppq9VcQmHpNKtnrFEpQ3SjjEezWbiEmN5Ua8RJ
|
||||
NKT6RAy07wO8Fx2kUmnXiHgOu7CYAgXo9jwR/mWdnh3qNAtfvF/BS/EC/F97vWQi
|
||||
kAVN0Y0H9EGSEoVyKwS1DErzcBgajPKWedKlmjU1uIzupRWn5oqetVbNfZ3Z/EJ/
|
||||
HdMCX0PN1kxg4WoI9mkP/moly1yopVOTTLJwvC2C85NQUmxyZeb4h9O7toFczBxn
|
||||
7pV9Eprm/xRcO3ZEEpmdM7gR3+R3PpxkjgPIZAn9il32VYzdT3eQmDZ8sKC0qASG
|
||||
ik2if34YnAggGmsrVB0nzT9fZR7CQq2IR7eohczLJRl+n7USQMgRweF+sl9PcbDT
|
||||
aC0b0i+VveSEBOEAEQEAAYkCPAQYAQgAJgIbDBYhBIWrobTj3qQ59ETaqelLPkGU
|
||||
5rX4BQJeTp05BQkHgPWHAAoJEOlLPkGU5rX4RRAQAKSsr//mEXy6iQyoqaxJ796s
|
||||
ljaoqsmT4ly/+0k9diX1+/wkulSkj4/fL2fDvRQK2cU1i6mYJVugN5swqXvp8WF8
|
||||
scnDS/H75v/3Z+clTlsMjZ4qI0PmXYDpcvp5+zU85USEjOxpHmIKvQGflZ0NMvkI
|
||||
uo2ZC6F4xnB5iizx9Ebm0gGAiKKEJ8ID/LLhJmOtidnGc3322SUVXIl4+ue9KgpO
|
||||
hTBjx5UdIQ+21uSRf+zv3ZQH/KA/08iNyD20fIiUZKfEoeovlW8SipoO/pf/+1DE
|
||||
WSiJqL3K7T3ixkC4oWSp7tbo2MWU247PItxTnnGF+KjwbkzpPwyPYPHT5Ed3XEZV
|
||||
e39r9xUzdvYKKDCNDToDFsh4bm4hq7xXgnTwAbF6hw0iyBK02ZB6FKJsF/ZJi8gC
|
||||
Ni4d3Lb54CV/Z7nAqMFbTa6KT8o9fc0Bw6tgX2ch7SRWU70yVGYmQzrdRsOtDkIV
|
||||
iYA05JozwwsIcJQS7hBVnsqgD/huYLd+y7iCUgw35NdQ5764jzVlUpYtFO0NFrM6
|
||||
QSKnnFFRiwr3+ZqIja2SGW455uP1hsl2ccA4Rdp/JRuEI6ojIo0R+JBpcMeqdv9d
|
||||
HcNsAoZkrm/cQfIwlyKsU4/dEFL09kEtv7x/aO2ImqjAZ5xT3ml+4kFGEn7M7rsc
|
||||
M6R6fgkYrVo1GhjXTlCL
|
||||
=4bj4
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/cproc/download
Normal file
1
depot/cproc/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
57
depot/cproc/pubkey
Normal file
57
depot/cproc/pubkey
Normal file
@@ -0,0 +1,57 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v2
|
||||
|
||||
mQENBE5x1ZYBCACnYHUIJG9JDe5s2zEc7oQNEfRoqWHtj1hkT7jXzM8RgxT6I6M2
|
||||
StaPFvSQ0EWpLuZBlUrUKFcEQ5OAICx1asljSdW17hBel3nkSsA7ORfOi1St7FPo
|
||||
7GTgzoOuB3Db4xG/0IVEt7PZ+vO3T4we/+D49ShiNBEwp+iV/LX8HncQHCJqBYyn
|
||||
VZ11d67Hb4L/hKbcasL/3d7TFanBxyGj0lFnHtoOMP1SmXF2sx6W3Uz5tqN5LAyS
|
||||
+Bo2BBKQg/97fF35f+w0c8o9uVRQNW5srxmYn6sL7vMP7+2rD1frq8+2q7DlyJCW
|
||||
iKUb2kLN2l2lm+uIHhwqH8zu4lLiVCMc/by1ABEBAAG0OUNocmlzdGlhbiBQcm9j
|
||||
aGFza2EgPGNocmlzdGlhbi5wcm9jaGFza2FAZ2Vub2RlLWxhYnMuY29tPokBOAQT
|
||||
AQIAIgIbIwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AFAlqUONoACgkQAx0TUceu
|
||||
pp99XQf+Nd4waDIgDVwWxAYcs/fZig6a6j8Sq+9aMTGi+gfI/Kqq2PrMy917pbGr
|
||||
SjQ73g1Fwn6KRKHMG7Q5Auwo2iw0m7XQBxzFFKKDmGVMd5AJxhsRkIlGV/aZnG3u
|
||||
Mo8iSi/wq00SyAJZgOqEdGyEmqbyy6hCmsaW0oQczZYS5SfGTQkf6kwKKnRz0Vz/
|
||||
pg55bl3sjc6C+DnL6IKLW1pOFWfQXcKNam+bj32OeRL5k49IV+tx6l5eeWlVSob3
|
||||
E4j5iYW3f3+Ueu6YK7lKf4/cNTp1BXjvWApseWgUU6OlUpxQ7mFzvWuUf6Nci53F
|
||||
wecwf6OYscetMgNnTx2twOpzr+VPWIhGBBARAgAGBQJSoE05AAoJEGypJkWmdbFY
|
||||
OAUAoOWVPRLWHV3zHk57Gj+1DP0mFAgGAJ9Q6aaueOIhOj3YA6lssIY3OuRVbIkC
|
||||
HAQQAQoABgUCVo9xVQAKCRCnJGA0F+zWt7aoD/98PxUAKaPAopMf+FGgu/LoYCIZ
|
||||
uvkZav6OgYObck8s50mKVs+cXnYbCIthlVFjY1vss8Ztwrz4nnzqngHObQqD7Z7X
|
||||
OLjQC/1NU1+DSfIke1jTX5tSBbDzPTGU4PXkkdnSHpc1R/dGupcGU8JrTCy30iQT
|
||||
GNM7XBAwQ0B+ls1t5aOFtP1228GWuEGmFNlne3vwYH/+oxMG+uVZ9b6UWNeXRFcN
|
||||
Ke7mQ5LBjvJarFq/Hnrj8fPC223tixgEb+hFI0PK6rslRia6mqrjQOSdZaDL6zb9
|
||||
BHD+gSDktDYHHA6a0duP9+v0EaWaDC0PemIb1uinDxuUbDTHRXxIT/OP2bYQdiVI
|
||||
+sMPTz2HFEvbWYMG3sEeJ/YTct7tsK6ml5Wl8vB3aiX+k1a3e/bNosLMJ/Ht6DEQ
|
||||
uy4eTZn8itl6nwsdxoE+t7LXQSONi9GGYOCBzBb27ymh/bOcgUFIcUH5uxvTTSes
|
||||
VkiKdX6Nq3mkxY63dTm/CDMof64IJYBqnVVSTytlNVAB3PNGiEhK7GDZ5ykuuvxD
|
||||
jONloLCZbNG4arRcfFwb2E3Y7DCink4qKMPbSZlPUl6ho/gsU0WlGE26XqqgeTzL
|
||||
MThOfgcDAMAK7Zmev2dpzXBOFY8ZR4hpitYCBQsVnpexC5khGbnawgnWhudzg0ap
|
||||
SO0DxeOyyhJ8Qh2yMYkBPgQTAQIAKAUCTnHVlgIbIwUJCWYBgAYLCQgHAwIGFQgC
|
||||
CQoLBBYCAwECHgECF4AACgkQAx0TUceupp/qoQf/UJelQAsDLkEeAhZ8DRAXROJA
|
||||
25JXF3fCUF2oimih6k1aH+yAr610i1tct/ch1g7TKZEB9RJKbssAtGv9722oxla5
|
||||
zHc1ChYC7gaDNX1UDZ/ggsg7HLxGKS01t+9D9syT84PQFgod+ReoXvvpiuVlPjsw
|
||||
TAAUQN0QM7P8H7q3g4L7rByT+W0JwQ7KFSahWKoalgKXKR4XxgRoi1gga3scVqQj
|
||||
+nzXlKWAa6WbDwcFJnZP+vITYoAeWgPQ9ez7Uwi11IYk1q3LS34hlCxyZs1HWRrw
|
||||
eAT2V8aHGgf4GMkptOMRcQVFftk70+zaEMV4iSBwRwMKWnKMEtRv2nLFdKixQ4kB
|
||||
PgQTAQIAKAIbIwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AFAlf34TMFCQtnPx0A
|
||||
CgkQAx0TUceupp/quggAnCihEvOT3Qs/2LMZ2IrPiCEETNE10lD4EfNl/DpWqJaG
|
||||
730Olf4FLgCfsA/JQRyl6B//8UvSgPuU2+Lh+Swzita78AvGW3GsnVel54FHzAyx
|
||||
GLPyIIFk99J3CtKGCZEZA73q4En2k/Vo9d4g1md6dcXZaLNleXXpIXLKanX1BSPG
|
||||
jdHv5Ac76dM3JU46/Zxq5ZpYD2Oh2FQxqPtbUftWvi+gWQndcnU+ocEbWBvJ3ZiP
|
||||
f/YNdq0YQGUuaHlIV7abgD3Mq+LYxF91XWLE2aOYLrqupm1B9ZNkm8xqWJSU4nWK
|
||||
jbXVDgY2obLNz593OjLoOJ7PNRpK+7Q7uUwxSUBg2rkBDQROcdWWAQgAvvfPd2y9
|
||||
K7Pca9ABWr7JpJIX+Wc/b1YowaaUddvubLfHbyUXoWXX/mxcQow99kJaQ5xdMDsD
|
||||
qwdq44ni8uWWOIZHA+JSvARNrUz3zvb1vyUt0LvlzuhZjNMD3I3y8cmhF9W1OKNl
|
||||
yw/K1onwywkxvnUwrqxBj+hNYzl4xiALLV1g+OkkKhaO64zFcwovGomSWBU+kAAO
|
||||
RW7/7BPGgsOdB+V6RysUOenPyd88a21zV2JE0oiuxylTdUEd59VaPezANaxlgCDY
|
||||
PEyLO7ccNdaBkMZEHaIlG5JMNYLcCeWDsRPxngwJvapIb5gU6BGjXiYq2wLZco3O
|
||||
glzLcTTaIiReVwARAQABiQEfBBgBAgAJAhsMBQJalDjjAAoJEAMdE1HHrqaffocI
|
||||
AKPsOb12U5A5zPbhv1HuCp5eQOhGqARCTY5dbDHRlkUXiaoY+X+fpbu1ZUd/ZipK
|
||||
7ZqXlHLFBMBelEae5tC8xa/WYxJpk+AtqKVd8FiR3QR8ki0I+PVWcRdKsLt7pZGO
|
||||
pmtNGF5vQ9g/rzU5BOyjlN4d2bhjdhCOwRzfK8iGTA0qvoLCPKULVaRaJNadbh6V
|
||||
Xehep+BiVgOaoDRXAt+34hptB1S0WC5UcyLBXyd53pjCdMixal2um61qOhJNEAsx
|
||||
OSrHWaCQcJguSFgB5ALrxuQVqo9+pJAxxQvwy2YsthF/zZsdQtGy6AyMsDDQ+BA+
|
||||
fqZ/7ClCj4t1KdI4+LC9Qok=
|
||||
=mumy
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -1 +0,0 @@
|
||||
https://depot.fuzzlabs.org
|
||||
@@ -1,37 +0,0 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v2.0.22 (GNU/Linux)
|
||||
|
||||
mQENBFk3Up4BCAC/F6PIRSw/ZG35QLERg34TIqiQyG0jRazkwEjr4pjCAOTEQ56m
|
||||
MVlaCjv3MFZMvgJAVuvDBlRMdFKVGbjgL69iwjRYrf5xWlNNXsEXkHAGdm9j4DUa
|
||||
5IXqvgVYCwjyqf/JOj1KWIWG2wafPSkllImaskZjUEz1ZTatavjfxgdpNusvZKj3
|
||||
EzqAV5CboVzqxWIqMyEtExoB+mIBl6nXK2LL4bKnpgxBBX4Xh37uJpO3P5KZRIyw
|
||||
I/mTKFr3PU/F3fALx42HYUukTjYd8ghnXr3CeCUjCixblQIFpx3SERxjxg0g3OAs
|
||||
K7gej4PWn4p3P2FN60sAXabKV0RnjRKebdx9ABEBAAG0I0VtZXJ5IEhlbWluZ3dh
|
||||
eSA8ZW1lcnlAdmZlbWFpbC5uZXQ+iQE5BBMBAgAjBQJZN1KeAhsDBwsJCAcDAgEG
|
||||
FQgCCQoLBBYCAwECHgECF4AACgkQi8ZjSoC8n7QlpAf/UzHl+JV4s5oM//Owkbqq
|
||||
K/SMA6M0s6inRKv5zwxuWH+eo1MKzqx+vIBcdVzSNIm07KPBLKKccGv3AGx0kiRs
|
||||
ax8H8hcAR9sH+FEqqZh3dJZ86pxutco15aOBLZHVQJAevN/m0iS0Hd3nl/liO3a3
|
||||
aG2YSQ1cg1zl4o9ZGU6WztrYKTNa4MooY8oYZyE/Vpol/YKHTiGqslMXrIN/k8QL
|
||||
kdxGPDNce8FoR+gmFixiKgY/w74RDUnHRHbloIzunmGTZWerKWPw2rRi13fiD8OQ
|
||||
R2GrNbiY+yvOLFbIewt7uj130hBJDqzbXCc63Yz0p8FFxKNOf6yp4OcbcTE2xGj7
|
||||
E4kBMwQQAQgAHRYhBFHBhxKBMRgPHxIJ+oZq4LBroLaEBQJZN1hfAAoJEIZq4LBr
|
||||
oLaE+acH/ArxeYf3oqDa3dmmDEo7b6PTEuTFsnxaAl9hSKRVnnk2mTOjl1PaYTpm
|
||||
86F3Asusut5oQrIA6QIq/LxFDNKPfQSMb2Bj57t9FzUcvZ1NevovAs4TZMbR7c+j
|
||||
ycS2BNYFYT22NH+RvzLXK+ww9QFzfLb/FGM3byE06/730vzNpVZECyN27BsnGrJ3
|
||||
rk4Gw+NZ/bAxLr099CSJcc5AFBaYEvelIS9BCEksiL0LHRg6IRMQfbFmQWXDSvuj
|
||||
5ZRT8i4m419wvz70JbCz61FIwBQ58P3MovoIRHl55jmYTrUebgOKVv24PIDJ0Sps
|
||||
zur71txmofebT0SneeAuUf4qWdFZYqC5AQ0EWTdSngEIAMLlZdP9ARThorUEQWMK
|
||||
3gxlnxEp1+8Tp8rTFI0U1Ivh4r5TE76nMD8/TgDDVbZKNzuzpxx+33RZ7tGOp4We
|
||||
7aimIueh7hgesuHUDvOFWr5B5kpwrr4kD/k5hfhV2nzD+te5fMKcko8HkGC62Tw7
|
||||
sFWOk4zQWLkhkLt9wTXJnXM84CCltOMClrZ9ngkOngh10UUslq6mYMqvqwoMIlUo
|
||||
BvVwcCH6+whxjEI6+1wz8+6s5XTu1Iv9v6khl2j4q2xAvaP/bQDgZAomd9+Tw/IA
|
||||
sW2INCYV9eNACCJ7FHGSiOMxLmRxFUIpmN6USk9uH83fzSBTpNsVfJRIhOVq0WMz
|
||||
eH0AEQEAAYkBHwQYAQIACQUCWTdSngIbDAAKCRCLxmNKgLyftGIeB/9vajLjG+JD
|
||||
tvGrnO8LVJFGT4jA16eHYpkT6p2Af8lxFZik9RZEUwxfmaca15AvLWNlUU1OVaGE
|
||||
LtrD/9qiDta8yrfb2NshRteBtsNsTDnZsKotAMTES1YmYDHHK+FA4yf01FtjtW35
|
||||
DNqb+xb4mbDhWefNAtHTeQ5ZRbpxvEczyX8XLLnibqpRzqjjy4aixykrkjmnNnJM
|
||||
Z5evo32fICirhqLFGl75nJ02POM9eULfoBStCmw9a2AFhzuRWQ2k097j9v3Djgcz
|
||||
BQG82jZKVxVsuoZZC38ytz0IxpYe4Tgi6AJHi6bpg66m1OlFn6eid/NX0TkpeMfA
|
||||
Ep+9QNxdLX+S
|
||||
=iah3
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/jschlatow/download
Normal file
1
depot/jschlatow/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
59
depot/jschlatow/pubkey
Normal file
59
depot/jschlatow/pubkey
Normal file
@@ -0,0 +1,59 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBGBlsG4BEADBMY44lF/LYiZByj1clJa+aNCEMGtoulxhFgCLIt2DR9r5KRmi
|
||||
iAiweobH6ofbSXYKTOZqhAcmmkw3ihIVCsd1mHbdAAhlsnJetHLgOPL90aXVwce/
|
||||
CM5QDubFmSu1VuaCgp/GaPqtQ/yaIq4LPMK+w2BfNG2M5XBeM8qLzjIHF7KNN4nZ
|
||||
CX48Gx7q2DtIYCMUdIP0oK4dNfPDy6tvXiYvcz3lA2SNa6kszW3/mgIsurUEUFF6
|
||||
vtCjBS5f6vJikWsglvTXqS0Sw5aIPzvosL/U0fjM0BVdi2NK6dWfM4HUduzr5MTD
|
||||
Xc26CETmZ/8Sl4+mj0oUAuHU0SKDm22LNc+qRzXZxtkryDbFuikwtioYf3nIDTiA
|
||||
63YPsx1jHp3mitTQgvRlJdlncmKIxXIUyGXqWpc+QHGUsvbDFdsXRxtt3J+8QWso
|
||||
yLlaeP54E0OTQqdm+EnWGHahEKIwsn8/Gfs87phQsaF8Dlw+A132RukxB6zD35xF
|
||||
/rqu25/8B0tL603Z3TLIyLDNbh4xO/iNohTB1ps+ALRwu48MsXcTMGUeWuRt2YVJ
|
||||
RPG3KfIfnd+KcvJa2XFuzZCk57Jc8qGPmINPY5fJ7F9qIT0/9O7dlxzdoksfKXMf
|
||||
RdiSCiFgmgJTqpXyfEcV7GUHCj9e0WdCSmDIH13bbuUpaTQXxO5d+XkzGwARAQAB
|
||||
tDVKb2hhbm5lcyBTY2hsYXRvdyA8am9oYW5uZXMuc2NobGF0b3dAZ2Vub2RlLWxh
|
||||
YnMuY29tPokCVAQTAQgAPhYhBBHurPU5I/pstoojMcciWBOKaz+1BQJgZbBuAhsD
|
||||
BQkJZgGABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEMciWBOKaz+1L28P/R+T
|
||||
usXX/AdgaTRSY3hFDVnhV+adcyFdmTKWey0lMUMWRGsALd1EIJbqk4HAA81jW68j
|
||||
9XG/kZgkhGKz+vOwOD40Y6G6f1GfKIEknzWok5RgH4p0BT5+ZhbqfX3/Z6z0CsOD
|
||||
mXAo1At9JvGmP6OnpHbCwutEa/KAB2fgrjjgGMZcBlDzIsBugbT+shEAE5et0b0J
|
||||
TrsClqoO71wknMkNp0ijfvCT4VtiCq/UBD5XqYRtzDQC6dMic/dNXKp3JmcsYf17
|
||||
DUNM7RVdVx+v9onWiUre9poVn9YgA/MYwVb4hMyjJEc9R8yQhENSJtdhX2pkXVF6
|
||||
l4ONbkdaw3xJqVO1ouPBI68Ddirwfwk6kgvpkvJ+iCVQ2lWSvPbtrhmTGpeerfQD
|
||||
vbFwtUX1OZhZma5Gq8n5r6VM7N29hQalYaKPBS9AoL3YBO51NsUwde/EmZydlYl6
|
||||
C7Ny+2iuPgKCoXS2zAxM2t9Ar9K0ZhhaiEbSZHoT596M/cWnn483edt15CQZO5w0
|
||||
QNBv5nNKh0J/GmM45TtbhUya9Cpc9Ad2SVYSlNB3KQgC/n+1UQm+8UHOBq/5nuC/
|
||||
Ww2It8g1G9pkGijG/f7flh1qE7KqqYec3cMLWj8hHRYSak3omSYlt4aOJEQPinjo
|
||||
XUw+WBi/Mjrnd6UxB6mNs0VADOHDrCmFBBHcfWIAiQEzBBABCAAdFiEEwNwMDXup
|
||||
zMtoYvj6v6ZIQUWP8uIFAmBlu6wACgkQv6ZIQUWP8uKNqwf+IjqK19dU8zATB50s
|
||||
x4aEqTF6U5J2xO4xiBJlWv55zewjmmOsjJZYKBJd4UzTHqG/0CRUiDzUmsn3q1o+
|
||||
GEwC+bB/LQMi+MaSG4w901Hz2cZ/qXonHfOtISKxmW2wDcOlG8Xsds0X5gfLgIZv
|
||||
4EYK+Nh1HqcEj2/RHRzfT8/WkDSC7AzSd8nuwQL03ZkAW5woh8vX5A/Fgj77mJb+
|
||||
APi6flqnTXxsVnRLHP8ErWQ8Akg07xV5fsOt1bFpY0aKgw2HJCoFyPDzVR09QILo
|
||||
Th3jiHBdNTlbd+Hb1kQJfIyhIpwkNRKBxdbM0wZoKdVMl7xiDMMDHkYpvNyBQTkJ
|
||||
nug/1LkCDQRgZbBuARAAzwJSYFegsVTJxm/6N9gN3vcfbZkvxttQYhNefw2eog7a
|
||||
UZq8Eog4LUuhDmuVt0CWZh5YOz7u4XwjxOzNk6fw630AKiWiNkYtiLYwPyT1tPcz
|
||||
I0XI6EcIYShyOfVZ+egPUELkjdC+SVwIQttQCPpEYnzWjbg22n+XeNRUfAI4EGKj
|
||||
H5bqhKx6sR2cmbB4FPUO1kpYoqhEVdk1wdZI7n93SDPSLsoJSO+xBMPj6HqfXeab
|
||||
gvr3dpqNg05G5g5JQBznILEJBHZBuCfy01j7WNRftdwWCGfWAh53uq6ug1vilodd
|
||||
T1jvWmIbFE66rljH+sbtkZwBuEbEDnwZxNK/g72aQkog3AeDljG1a8GjazN6/upe
|
||||
JD8LfoE8gjlj9Ncg9eYvqnrGR3nv566i7cq7UO10Dl5d6bedpEIo2htm90AI3M8p
|
||||
nmtAZ18cbQodwerFvdQcegdejlpYJmI/3xaPZQqPH0puhDpT3oA53ObmjPb12ztH
|
||||
Za06+klrr1MYb+x4IQYAOO8wwVRY/+YS+YU+6mxePyPMUDJYnIgOcTkg04/O55MF
|
||||
KghOumAY3KTFoE7VlWXrBbhE/MW+Owp8zbtyFovJbmo8H718JHBQwlxzd1cS2Fvd
|
||||
7g7r5eqWZNl+bMJQmgA0ZTAI0gD5PJU+GJEhiky3e29H2tBKqozX539HCxdOJycA
|
||||
EQEAAYkCPAQYAQgAJhYhBBHurPU5I/pstoojMcciWBOKaz+1BQJgZbBuAhsMBQkJ
|
||||
ZgGAAAoJEMciWBOKaz+1y94QAMD//6IqvIQEvsmDsv0hDy/ryPgYA7+2gKQCrvsq
|
||||
rdhXYrBYGwgUPAeuYKgIFQIE+UqFZDwMbZ38DozyXvg4QYTEYQtPOio5WZGMHsNa
|
||||
VYXel8qOKAbSECuP6GFiyX+NsSKYzs+iQLCzzLJS2/N8U1TMbgOwpqcVovpKOHvE
|
||||
XPTUTwnUP25ubY32ElslRACZ/REJIm1Ftmloef50qnFggfCQdSsjevl74Q2+QOHk
|
||||
Nb5w+a+vM6CmTGM1kqEATSJfBkxS7jCnGH4H9t44cEYqECpOYm4eUjxpM/9rxMw8
|
||||
itrVs8preL28zzgKydVLO1JAX4WAw+X1k1Q9EGcRcXRnlxptZ71Lgnv4qCshPAXk
|
||||
Sm5acLgdoOOSDDCSGFtjenyDjoHWfDk22CBwmEtMDtQ02m0+IzkfpNizqKGHBpKm
|
||||
/hsu36teJilJWdAQOmDyrb0VsRweWM+rqClq3GS1+r791836WxQlKvx0/eO0gZOP
|
||||
QjQxOjeCzZ/H8h7HBZ4bwRjQzHGgIbl7k6WPIwmvM4vLQfB44YEi/zDW5ivBcDEo
|
||||
2VnHwAC2EPiVRwhRB/9+I8U09Ngrg2SnO8MkgmZpob1amblnhItM1US8bq/KDKld
|
||||
4sWgWcZO21jEqnEaep4n/9vaxvLHfFa7AYY2EbB+Dfrns80oAqHG78qFyzflnLxx
|
||||
kLJD
|
||||
=7iZV
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/mstein/download
Normal file
1
depot/mstein/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
51
depot/mstein/pubkey
Normal file
51
depot/mstein/pubkey
Normal file
@@ -0,0 +1,51 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBFuhfGYBEADOj0EW/U2O3koeGIuNGDuBDSzkYjncoBrrPN1z69hgK349xiP7
|
||||
ZwrPBA0kJ3ctLcRQcOEDF5XJzjByuNk3JV6MuKFqwy2i9dDTHkv5pv7Na/R3L2CM
|
||||
k79weVahjPllt9nnbSMMtYH0eL187EhLW9owd0CY9wDj1lhLISHpyKvb9vwiUAwQ
|
||||
i+xypGgU+Qvf8BmfTDdjfP0n+Iw31z+R3xiHhWmhrs9gID2XVtGZIy9NQQrijJYS
|
||||
1Hp8hjgH9Fzmj0GkxUI+2mEqLeEp6wBmmo+7PRzc+iRYJNocyRxDbmdE0eyh3P93
|
||||
QABzZiWTU+Feq0MYa1FK55uFCFHe6MSFLq33CGYMzQ9oFQHjuEX1KqJT/OoumPgN
|
||||
iEb8Bt3XmqiI8GejafLKIW8gO8tYLABdrEpFelnyXy12IIOpOwb8GrxFUEu8+bDb
|
||||
Fc0YkV7cZ4NH2Kq/6/Or30gCA2XUpqhDNSxA6jer35a3ZzvgXvcRkNR/oOt+qt/3
|
||||
u9ew+e6Xjque0PRWzdavVlKdYWzSV8umVw5DGgQj/rSn+8spog/5w1lElyUa/5Yx
|
||||
Z+1bvOIyXPg+tTLimWtGRZQorak1sMsLMDqQck9SwOQWpSmVGsJ14uWXSMaZjdj9
|
||||
4rHSSymYlcQWP8t9lfPf6/ZSH8574PbbJSe71UXcWWznSGprSt2QQAQ7NwARAQAB
|
||||
tCtNYXJ0aW4gU3RlaW4gPG1hcnRpbi5zdGVpbkBnZW5vZGUtbGFicy5jb20+iQI+
|
||||
BBMBAgAoBQJboXxmAhsDBQkDwmcABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
|
||||
CRDJZVRAR8NPkiTSD/9xiUVNgKTkmH9WRdCcaHuyhKoQI6CsWnMOW5OZ+gVXPc9U
|
||||
LapQ5Wymb+yGE8Uyn4EJnwdEa8TdWztMs3TNtK5vh1Pk1lKmtKcblBiDrUPEURhR
|
||||
mUBoUkMe2VDXyN27e0lkbxcFJ0HrYnhvb72Yfnw6B3XMa/NIhbOU3ttB/tVR6Kjl
|
||||
YVDtTokfILQc07Ai+TqkqNARtPGntHAn9qFvPLNKI31c+Xw/QGZbVPNFW1QAYBiO
|
||||
5dqsSwKaouapHAb0GBmU0fAfJZNcvwt9Ph7WDXU9Ce3LZmIshGW7Gzm7EGdf4VS6
|
||||
k4OtEWZhZHRnl9/sBJ2UlQU0tFs3ow53aDZQIa4FKd4JKabBeRgDUKCGEyfoNKCq
|
||||
NKkLZaR/kFA9EqTPZSIXPLYIzIlSFoL3LVDOc5O7hDT9vXaubdZeAfE9VcHDdm3u
|
||||
usW034F0zbsuu4G83qZ6QhDOp0UhujfSU+BDkH0I+OfFyVkQAmy69J3byi7Iluno
|
||||
OcZM13rbe30jzyyyWAnjHicAt8tNwCLMmnIRvYT9ELqywID0Zzxkct61eJQ6L6aq
|
||||
/DnUD9Kq0OwdxC1wMGtimX5eUnN7S7y5+TMRepJnWcTtgrLBVqwRrvSLnsKVd4Gb
|
||||
Bu3dSs+BxMV1UcyU0KWwDPY2D7k8SGgeH7IEPo/JiGO8RrWYJRac9qel9egMYbkC
|
||||
DQRboXxmARAAoaRH/xgKvp0QrNFJZBW12SdXT4h1nXglbpZd+bUl738LqM2JSIC5
|
||||
Qq7t2DUtOiL9UxqvRgAIjkVLR+hHJBZyuPOP5Ebaf3Mr7eAdmCx2TMsHZPKBLnTy
|
||||
EqeUcnPwThNKcUaGsQYlkxIQAJtPzy3YBuDCYnzzSi6KzP3VC8szHsXcPo2DeKWI
|
||||
m9BbMMSQkB3m0fz8W3ar/64RDoubRWRJ07b7q4WUb4jPvql+Tz+Gv5x3qm8g6m1j
|
||||
uD+U5OhGCe3m5/MsI2JYdWXEwif8YD59gylsj3LJIu3i4SkR8aS+x6n3LIvdSCOt
|
||||
P3To87wfoSqBWWObVe/vOHRXqpzEF6T/ih/rkhUFzrHNMziTPsujBazm82AUZ6xi
|
||||
2TddbdSAK+ZpSPQjyyRflNyNgv0iu6P3BnBgv0Xcuf2RsDMBDjdvHtX0lXkPMB+r
|
||||
6jgxl0faV6UktH5R2d4Zt9i0/vWlZZd0MDylPNQDiKs+qSIX3ntfUUaPdEJqYAwM
|
||||
gloXr3cZtsVh+Yoqt8pa4x0x6kqez+oyBUFf6y1FCKYq2H/QfPRkF/DrfZS+7jXW
|
||||
iAX8PcrDceCN6Dr10/g5LPWXQOHUWxCu7FEYoYJsVXst4N0FnCOCe/OGYIhMteSV
|
||||
IJJvNS4qwXZKKZ+cmuT9skEQ6zsLV9+VDYMwVqXB4wTp4EwT2pCp6LEAEQEAAYkC
|
||||
JQQYAQIADwUCW6F8ZgIbDAUJA8JnAAAKCRDJZVRAR8NPktRiD/9qjH6uuT1y5uNA
|
||||
4E8u6/vxZGsyBG57dtnQ0KQbcsZSrUxMiDTtMMrklsl2vtut/XDroajm+d2eaQ4K
|
||||
j0h285VRkT5xJ79JaIQ8oyzRWBtpENy0iLUm7CmqCMuH8VFifZyEBYZgR/K+9ago
|
||||
WwF3sk0QP0WJTFqIZajKK0Lo5Juk8DCXjvtkvGNytHkZ2vEkiZ9m7Eq0AjQnts5T
|
||||
PdHkob7Z8fu0KfUMoCUtb+TzNyMYOVGE6uTfo8wKvbhwzUWSymZkrecx73XUUmew
|
||||
MdZ2WzwGdUMXwcBZ4LvgrZVg+LKxR1lyJ+qbIUpDKXCZGGH2VZVaQspgnx2Yt0EI
|
||||
Zl2ELMrTq5IcOkxtblEZpQkwaXszqUDNO43ezp/PmbTRWChoM/k3RAbp9rvoYx93
|
||||
UChyRXpJRaqDxK502k3BSnOfmolpQvxTMKtLZO50URa0F0F4qD2csns4QrqOWsGr
|
||||
qPqVKcLn8Q/yMW9fm5+xX+ZHICKk64GAB0YyHcw9lOWekLhGzZV1KnD5ID6+5E0B
|
||||
nsWZB6PDqLM+/ykXh0rcN8DWwZvhimI5/dOEIWIkADKT8WGwh+2JnRyimhxYdaiH
|
||||
ul1BvZAYqF1FVXAHd0u48MssLywGGbW4fH8D9SM+LFpP4+8oYFLNgH1OreMENuag
|
||||
i47EaxpnQUgIt8PZ/gL3LeiGs8SNpw==
|
||||
=flyM
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/rite/download
Normal file
1
depot/rite/download
Normal file
@@ -0,0 +1 @@
|
||||
https://s3.eu-central-1.amazonaws.com/dev.depot.gapfruit.com
|
||||
29
depot/rite/pubkey
Normal file
29
depot/rite/pubkey
Normal file
@@ -0,0 +1,29 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBFp01OkBEADmU6vR+hQsfLSZW1aQacmd6PBt9vlPev2hqRfMhntgpWEYyGW8
|
||||
fz1+XPWJCBbMJC7Tq8feIJa1KAKkvLJMbnf+UTl7dbxeqwVOhFYi2hS7XbbHdUNH
|
||||
00PDT+tQSLQkRbfD7qQYvOiGcpu0x15KA53BJO8lJK+oxUVfThNsJK9STmOh0+lV
|
||||
ITtBkPBGEcQgQ9usLZRr2GSThYbfWfLd61BFWw4dJ0GVFk/jnq454laXKyoP7WvE
|
||||
T/WDCyHnnbz6vdWRrrHwLPBd+yi4uYSPorPcWeCm4eTEQABifx+jUOQSuFFozRUK
|
||||
8iQD4saquseWYyDHpH4LzIlIJtfZe1ukKMNnEhXTdQI2Fu4iyq63RiCP7WAiXMna
|
||||
JbqZ4QFMXUdhLrldDpYM9CdKMiI3eT9RT7C0DBv1uqfr7yZD7KG7uNVbHVZjn3Pb
|
||||
xjBmxccSFgZWwAJj9z4Rh6+KU/zpjP3FVQOznZptl1pg+l8CieUYF/RVTKzzYamN
|
||||
mrCqBeSVWyGqJlMOjPUv5/5RIAKsKn5zgoxPgGkiYn/2uO/YtiAajjrzVv4SsUly
|
||||
k6+IZhe58BM8KQFNBwlaSkRtbvL6+Q95G8Aqy5J/GEaiDPMJ4+bEa5bz4m86pRNM
|
||||
L0j6JAxWGNyPWM6bKRNRykFE5C2ruX60YlbjnL3EMCkM2q7sAAPW9K3iRwARAQAB
|
||||
tDRSb21hbiBJdGVuIChkZXBvdCBzaWduaW5nKSA8cm9tYW4uaXRlbkBnYXBmcnVp
|
||||
dC5jb20+iQJUBBMBCAA+FiEEWyrhpcjTKVapBRt/ldYTDrk++fsFAlp01OkCGwMF
|
||||
CQHhM4AFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQldYTDrk++fvkWg//VT9U
|
||||
pCPqYt5y/41jG0L4NkOXY144oMn0hZ3hWQMQOmiuvxp9nROxcI1tIZ3bjHBPWOv8
|
||||
hPXQ13haO0ZiPv7f9AfejspCNvoJYIRi1On3+RIZ2qjtS8s9sSwNX1aU1ZFUX6sE
|
||||
SYGDqDItYtJExvh3pTxFKbQ4l3ypYX3NKN2YcMYV8uIFqghTwX1ACHRl30CEgLSw
|
||||
g9JhKbu8sEMoPwv09v5rq9Ut1lY6mZ3Xv9Yjb4qKKPoSDuvaB2AsrgJJkFRWJs/h
|
||||
K7PprxdoxrwQ0LiH4YahIItXgxgizWI+opP4ARS8WiiwRMgZAgC+nHvyo7dirGrS
|
||||
tfzdC9QkqHOytSsgxLzvn4xqRXQwFU/7CABCaf28WCiz4ROsksaSpPvskmkbarqT
|
||||
rjevqi8fte7HIOxyhnkW6prGNwpLFHWmLVa4cULXiCuaY0viOEhF03d753aYCqos
|
||||
2oEEYOs25XyztLGkStea7KtCGTUnMTqSj5Hr9mZs354Joy+kU/pFlf2LgMucRE80
|
||||
WyWQOPNkQ+RwodjRjt20qvMNks1LAmw5Kh30VK3ld/mA35GcwGWEXJDgvPcUvlEq
|
||||
g1bEuio/YbNfMAy2FQY6aixtMpE6Ke8+jDW4rzEKHXln5FzB4FQTKpm6OxwTFXSc
|
||||
+RL16LtxpvCXEpgz2e+D5+5pKg/yD4AdjUw/IWM=
|
||||
=mScq
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/skalk/download
Normal file
1
depot/skalk/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
31
depot/skalk/pubkey
Normal file
31
depot/skalk/pubkey
Normal file
@@ -0,0 +1,31 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQENBFpT5C4BCADHk4DtY2IQI6KlE+2td4wXKw0dILOobGExRffOgdB5d0WWKQgW
|
||||
gFw+UaywFxgJT0p2b7XoVsXE0bOz4tQRMdMxtYhL0qAhyj9+DsqqCBp0EcBD3XEz
|
||||
spm0DdNCEVfUbIQUstbSNt1kDGIlqPvZmoRj5YwDECW6ULG8jTWhaAz9SybJCE86
|
||||
jLPzZHjKtVhCVO1X0ogSxvvYGemUpqVCLfKcIb1TucieKKCrnjiHwp0XZ41DWqSb
|
||||
kBwWW2YQMEsw8JNGNTfCCUFf6+1l4mMixtv2sEqFiH1wQJ0c4gSa4iSYZ+eNmzJ0
|
||||
B13K8kONOctSg3NYZz/dC1aUzLOTkgJHqEPHABEBAAG0KVN0ZWZhbiBLYWxrb3dz
|
||||
a2kgPHNrYWxrQGRlcG90Lmdlbm9kZS5vcmc+iQFUBBMBCAA+AhsDBQsJCAcCBhUI
|
||||
CQoLAgQWAgMBAh4BAheAFiEEI2X1/oP+p+Ls2L28qrC4CLnp/P8FAl4XHPUFCQ0p
|
||||
OkcACgkQqrC4CLnp/P8bAgf/ToUKzXMGdRXpB+xIBbOxuu8xVdLRj+5cm7cjZRiy
|
||||
N0ulrzAlaZqrfqb5rTujPDjakmVSBVRIi8zWlzU7y67fevTFdi/Q9xeLgbqP3cWU
|
||||
UgUJs03cdacFIamSIO//I9gaImZ2kpUcA6Nj+N+jPepRgUBzljsJG8678ndicA0e
|
||||
Yio4uAvZY9JmsWGn48rmkqshPf9lag4GUnXn+R/AFKCts55kOiPekux3pJBhmrLJ
|
||||
TdLgdAzlzGQfHxQbz3oVK4yE19ReAd6rnpW06oK4KfiWrgCmaEk1quirDNfIMDfr
|
||||
nwe6571TY5is0f9zJjJgP8ogLUMI3n54OvwMezUMz+bLbbkBDQRaU+QuAQgAuame
|
||||
2VDCgNmiwu+QmWyNN4jzbE7+VNmDr37HO9lZRIROC4eACPOGfUL03jLGvUn7rrxQ
|
||||
JK+Pit6gXXCoIWDhCMNRSZKho416KJZWxF2jxKBKGQ7DtWaTR3YOzSf0ka9DZSrp
|
||||
wG22xS0Uf1U/0ZBIf24LbyUDFLc8zt4eey2D9AHm+9vCf7wnf8TV6SNIXRz3wj7d
|
||||
VqoZLXRTT7twBSaNahLhNtg7fhS8Nu6/THuwXpNKPAvAsgJRTGk7kmrKj5P7rOZA
|
||||
rNHC1pvK1EWJJi2onHOmCzBccKRp9SeQlj+ddqG6seZhEnRYG6l7uhkyNZoyvKxO
|
||||
Fguc5g8Xf37VyuRMfwARAQABiQE8BBgBCAAmAhsMFiEEI2X1/oP+p+Ls2L28qrC4
|
||||
CLnp/P8FAl4XHW4FCQ0pOsAACgkQqrC4CLnp/P/xGggAhMz6NH1dYiFtc9+3vkAW
|
||||
bZ10MDvxdgyU+G1a0BVYVo2ZXkhJlb2yg5MEeL1MZ6cUtM7MR1OL0U1jayfdcTfr
|
||||
kkUi2a35BdvKRpxc3hcc4i2CdDxdx+IGrBa75P+vIKFj8WIvwABgRJNVzY1Oq6Lq
|
||||
zKPUpVPug80Hch++Kv6l1DEpcoXlGaI8Z1dWfAjYQ7HJF/YJNHloKwxa1mXo/l/S
|
||||
qQSFHB23IN682ANm8iEUphuvJVbOw4mubpCEpmJvIhEBeesgXfB503nniOsshq+9
|
||||
1bNZ3CFv/ylnj5sy5VzU0lfW/TrHiW4OOOSbX8mCSvcqN2mhjcu6r4olV0fWPrrV
|
||||
Lg==
|
||||
=H+8g
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/ssumpf/download
Normal file
1
depot/ssumpf/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
52
depot/ssumpf/pubkey
Normal file
52
depot/ssumpf/pubkey
Normal file
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBFxvvIkBEACdb88mQFNBM7IG6i52BgpBqfkn4HNrlb5xOBgV90btReZWUfgs
|
||||
2Fas7kg69yyYuuPkdsWHG5d06tj21WVuuB9r2I0aFvNOIFOc0uSDUCl+YZGiwYjB
|
||||
UvRg+oKFmWO2f62ttpsrAKjCKAIuQBJBnPsDXtvcRzquV8C/bJTMOTLQ1NfgS9Ay
|
||||
wSOdvooG8/gfuC0+ZgbdPgpDcDMQcS2o6Q0aAa3dbTksWKtrnqzE/m7wA4CgZWTd
|
||||
6LzD8hGayVjLcTUzsqBRqixPSACi4CbOnohWIuXPU6FZWD2YgOKfRf3w3OvX+o/k
|
||||
9SuOv8fR72kQoRrDhz6D3Fq5koST1977oEYc6Ns/yCdzV5xzCYBQ6D30LrkyGj6y
|
||||
4anEkaljeCqGXf1S/Dg+1lQ7lzbII/BHJIAn18303XBeg29mLSXPLpNtrpb7UFMX
|
||||
cjNlN4nG2N7Oa2N73lD+FK56mVwQfb5Xoj5kZCPMLvxicfRHmf1UAVE47Y0p0eE3
|
||||
B2SqqGflcSCZbpGK/o21jn16Vme2vJqIXbs+mGdYTBHn/9O312XWs8apNqWW92u3
|
||||
5pVcxc3JK1fLpLUZo/ohUneM2V8rXPdVCg7h5c84dHUrPXfOQH8e9s24Inq5l9vx
|
||||
zYcf1QUzeFQspO3ECKvuNmKyQTAWmrcD5vSx7Epa3wynsXOx6bttR2/OyQARAQAB
|
||||
tDREZXBvdCBTdW1wZiAoZGVwb3QgcGFja2FnZXMpIDxkZXBvdEBnZW5vZGUtbGFi
|
||||
cy5jb20+iQJOBBMBCAA4FiEE0Tow76OCSsNBYjoWmSWROw/a3bUFAlxvvIkCGwMF
|
||||
CwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQmSWROw/a3bWmcxAAiKJRk+Sp4wmP
|
||||
PVCztw0h4bwu6/AHWM34qgWLFIf7pX+uUp7NZ8vnMEft5+XXLJdCnIdCeMCgSfo/
|
||||
5FeD2uNHrLLI33PMCixAidg0sZ0ENpopY48SHdlADCMUH0c7/kFWdX63UznyhAIe
|
||||
KsUyglY9j6oCNSEEna3lUsFGQ2Z7Cl4b3OWSkBAMyBe7NUs3pnyy2XdCP5uUREuB
|
||||
PakqS2HuQ6zvdFLU0h2PBq4KT7nzBHPUMnkrw0ulM+4JX29GFk1WzNpJYCZW50vx
|
||||
kD8bEfzwqyZPpo12M4Ica9su7mMFpVSMeTVhI5vdQ6AxaCRRNojgfVNn1TjCRWUD
|
||||
91PxKg+CbHiAcEdFRNOH+nVZpqQ/sspSKigS5QrGmRvr2dwP8KFOyjN1hNLp3x1R
|
||||
SkGqPtThlpqAJo1YEsuy0gfetdSaLPXtkEFuAIynt861C/bBYfB9vaD8dSEbolQj
|
||||
CI2k6sWv8p9Ym+/2vNvYOgKe6PlVtoXOydRR1i4uWuVsJIFlIc2NGyiUXIZ0AvFp
|
||||
X2KAMjxGAvcfLN6MTzCwSSN5Zk0oOV3NRqbdqOWRDVhCZIpGpjov/E9LKjh4X4xf
|
||||
ybdrU4vRgiTRk4WriY0tiWOqgJrOo+wc+1VgJl6YaP4fY7eocGS7NvZVnWhq2JNY
|
||||
s8oiNYbdd72NVQYdTAJzDhpnjJ4USSC5Ag0EXG+8iQEQAMVEBe9AOUrsbqn6dvhS
|
||||
vgs/TsTx1R7hWA/RgP95nDZDnzQg+QVCs2rqp+pVgqNgaz9eJhlT7NCCLE95LCKY
|
||||
F0lWkSwRRWxMTQzdou0/o132UBSUKD2IAkY1wsH86foUZY7UDENm7Ht23Uvy2dCY
|
||||
fwNVaNOvqs7FGDWIPmb6IehJqrJgFUEfgJYUAqTr4R/q3MIYceC5Llnm6NqptlSy
|
||||
BN7Ixyvvij56MsWM9dasm/lHTYJuVWmRjo0gvlvL3eTD/NMSkRqzGw1O6RRbmQxX
|
||||
yfo19ERZ/ALY6q6/cmOSQh2Fi8vd+NgJ308PthwPAnAsnMz82sKnJAoZ6PNmk5GT
|
||||
dbQe+lQCwBreozGfLhP8hYlR27N6oydc0t2nf8h/GGQONcX6ySAiRaGt3Ryc59d0
|
||||
H+S1JTJoUxaFBBsLFJWe1Ci93ueg0370nHtZbjtP/TG/4pS+A/hDiRMCBIMOP1eh
|
||||
tQRjO6bMgPgxX0i1Lv6aHDf3cJcg0dqjAxfLaTVXYWtnDcqtwARnbcJYqaj6Umgm
|
||||
l1kOFN4HsqTSKViXeTrP0DGZ+NQn9fo0E0qyyY6/YwKw0/FAa3xQu1oYH+w2inzJ
|
||||
RbCHfSf4z49O8M3T7e6dskBj/YoKlRhYmazQrhZa3ixt2zwQuMH1L0DAnPY02U1y
|
||||
BeSEAlLpFI8vCSk5S0LEVOntABEBAAGJAjYEGAEIACAWIQTROjDvo4JKw0FiOhaZ
|
||||
JZE7D9rdtQUCXG+8iQIbDAAKCRCZJZE7D9rdtcY+D/9xykYgmOd09n6E2BjrV7H+
|
||||
CtTq4iF/Y+HhbMtmlon1F2nNmWP0i2l0HonTaQRfCXcpXJYjQQX9SDD3Bb8Qkdxr
|
||||
Bl3pMiixsbWyupQ8UxgEdK3mAfgnOxEilwlHB0vAhB2OX6zZVVH6g37+gJMiwOZf
|
||||
zISDQH1FI6feheYAqU8AVM3RE33K16fhslQEg5Gi87f8jXyVT01qwPNysOfRBB2u
|
||||
j8uJoeSKXwbHaTzzzlK1XzpPz3jCvy3QNZPMVi53KvEIzCKtBmrlgYbKKRLH2rMr
|
||||
C9DxbXihvnNyIyQT6VQCbC9m7qNwrcriE/TahCPy1GP9ZUT4RiF3oy7lDDlk+9Jo
|
||||
qh+LxbOw/UlEwgu7gtfcjfLK4yyLN1EjkCtGZIk5RHrA0fHYaRmjP82/h9QHIp8J
|
||||
bBO08eDanPC64PwLMLymW7GoU+afetjn/LzP02TjxuO55ZHn8UaG2Cxx0nlipm0n
|
||||
FXSect9nr/MiLRb+C3o0M4dZ/51IPl3BuhhBirKPe3li3ieaVQkZYnY4KhML2aj0
|
||||
A9H479fStEg1AlsISFH2wol7Gw3WP8zk58NqRF7l1h5XtMQ8sOsVVzqyOHwIr482
|
||||
UaY2AgdLgCCiVrHk4KzXxi9jA4vY5xWyU5SU2kEYJha5qAi8AzBWBvLrD/3YEdy/
|
||||
4oe2jMt7+puZ672u9RNjYg==
|
||||
=tNAP
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
1
depot/trimpim/download
Normal file
1
depot/trimpim/download
Normal file
@@ -0,0 +1 @@
|
||||
https://s3.eu-central-1.amazonaws.com/dev.depot.gapfruit.com
|
||||
18
depot/trimpim/pubkey
Normal file
18
depot/trimpim/pubkey
Normal file
@@ -0,0 +1,18 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQENBFrq0AsBCACyr5B8jH93vUYAspNeiiNd+e71gwA0ftJQJPMp+Fyr+02gI68W
|
||||
OZmxndHTDIuZkGsgRBkaeeHVbkXi0Br90oZClZKRkhseXgx5gcsvt6FsuakFwf21
|
||||
MNLYWNiKZhvntdJl7HYTxQ3rx3wMnYOyFhQRORQdSQS3i53CXoT7l+biJGH2ylnu
|
||||
AfOL5kOP60wrkP+S8tXZRmvXdhHMEy1sqKZoCuo7mEUmZnA4AL/A8n98jDSXw/bP
|
||||
xAMRSedqN4VAgTRBtgZTCDOU19Q0aRV/eEUsuZTHEU3qhdbHcrmXB2reiRjL+Ol8
|
||||
EY1Alb+p0c1SM1CmEKpSlpsjDJvzOSgPJuxtABEBAAG0MXRyaW1waW0tZ2l0bGFi
|
||||
LXN0YWdpbmcgPHBpcm1pbi5kdXNzQGdhcGZydWl0LmNvbT6JAU4EEwEIADgWIQRm
|
||||
OLnH3fFNXDibg3lDqO6DjZnR1QUCWurQCwIbAwULCQgHAgYVCgkICwIEFgIDAQIe
|
||||
AQIXgAAKCRBDqO6DjZnR1YNiB/45yYuznT9vi4o/NX1excQKA253CRXhPZii+gCn
|
||||
FIQk8dAO80fymdH51+h4WR2i1Vwgqrpfoss8dnZ/2BCseOlYbTco0NFISOKcwrTM
|
||||
ia/R8M4hOk3pAr/+5g5jKijQtYW1P156nJkINsHfxS15lfJwZkiP+FsSz4eV3Qrd
|
||||
RmBNrlZnUgV87O0my1gDoYwtP95D8qTErB28wQeBXSqoLxu1AJl5KqrFi4nAEgmj
|
||||
ZYk3abmyYV4KNQGzp3ju0BHdcW8dC/arvAfFJQPc24dH7STHC5ZvF6lQS9gDjDpS
|
||||
dgtpVymFUkxm9E7z34atXfZgtv3eSy5t8sJv8F0+j+qxiNWd
|
||||
=Wf/A
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -362,6 +362,20 @@ in its 'LIBS' declaration and refers to the tools relative to
|
||||
'$(BUILD_BASE_DIR)'.
|
||||
|
||||
|
||||
Building additional custom targets accompanying library or program
|
||||
==================================================================
|
||||
|
||||
There are cases when it is important to build additional targets
|
||||
besides standard files built for library or program. Of course there
|
||||
is no problem with writing specific make rules for commands that
|
||||
generate those target files but for them to be built a proper
|
||||
dependency must be specified. To achieve it those additional targets
|
||||
should be added to 'CUSTOM_TARGET_DEPS' variable like e.g. in
|
||||
iwl_firmware library from dde_linux repository:
|
||||
|
||||
! CUSTOM_TARGET_DEPS += $(addprefix $(BIN_DIR)/,$(IMAGES))
|
||||
|
||||
|
||||
Automated integration and testing
|
||||
#################################
|
||||
|
||||
|
||||
@@ -16,17 +16,6 @@ research projects on Genode.
|
||||
Applications and library infrastructure
|
||||
#######################################
|
||||
|
||||
:GNU Privacy Guard:
|
||||
|
||||
The [https://gnupg.org/ - GNU Privacy Guard] (GNUPG) is the most widely
|
||||
used Free-Software implementation of the OpenGPG standard. It comprises a
|
||||
rich set of tools for encryption and key management. For many forthcoming
|
||||
application scenarios of Genode such as package management and email
|
||||
communication, GNUPG is crucial. Hence, it should be ported to Genode. Such
|
||||
a port may leverage Genode's fine-grained component architecture to strongly
|
||||
separate network-exposed functionality, the storage of key material, and the
|
||||
cryptographic functions.
|
||||
|
||||
:VNC server implementing Genode's framebuffer session interface:
|
||||
|
||||
With 'Input' and 'Framebuffer', Genode provides two low-level interfaces
|
||||
@@ -50,24 +39,6 @@ Applications and library infrastructure
|
||||
integrated in the operating system, i.e., in the form of Genode components
|
||||
or a set of Genode VFS plugins.
|
||||
|
||||
:Tiled window manager:
|
||||
|
||||
At Genode Labs, we pursue the goal to shape Genode into an general-purpose
|
||||
operating system suitable for productive work. The feature set needed to
|
||||
achieve this goal largely depends on the tools and applications daily used by
|
||||
the Genode engineers. As one particularly important tool for being highly
|
||||
productive, we identified a tiled user interface. Currently, all developers
|
||||
at Genode Labs embrace either the Ion3 window manager or the tiled Terminator
|
||||
terminal emulator. Hence, we desire to have a similar mode of user
|
||||
interaction on Genode as well. The goal of this challenge is to identify the
|
||||
most important usage patters and the implementation of a tiled GUI that
|
||||
multiplexes the framebuffer into a set of tiled and tabbed virtual
|
||||
framebuffers.
|
||||
|
||||
Related to this work, the low-level 'Framebuffer' and 'Input' interfaces
|
||||
should be subject to a revision, for example for enabling the flexible change
|
||||
of framebuffer sizes as needed by a tiled user interface.
|
||||
|
||||
:Interactive sound switchbox based on Genode's Audio_out session interface:
|
||||
|
||||
Since version 10.05, Genode features a highly flexible configuration concept
|
||||
@@ -116,16 +87,33 @@ Applications and library infrastructure
|
||||
of communicating threads as captured on the running system. The tool should
|
||||
work on a selected kernel that provides a facility for tracing IPC messages.
|
||||
|
||||
The underlying light-weight tracing infrastructure is
|
||||
[https://genode.org/documentation/release-notes/19.08#Tracinghttps://genode.org/documentation/release-notes/19.08#Tracing - already in place].
|
||||
The Qt-based tracing tools would complement this infrastructure with
|
||||
an interactive front end.
|
||||
|
||||
:Ports of popular software:
|
||||
|
||||
Genode features a ports mechanism to cleanly integrate 3rd-party software.
|
||||
Thanks to the C runtime, the flexible per-component VFS, the standard
|
||||
C++ library, and the Noux runtime (for UNIX software), porting software
|
||||
to Genode is relatively straight forward. The
|
||||
[http://genode.org/documentation/developer-resources/porting - porting guide]
|
||||
[https://genode.org/documentation/developer-resources/porting - porting guide]
|
||||
explains the typical steps. A wish list of software that we'd like to
|
||||
have available on Genode is available at
|
||||
[http://usr.sysret.de/jws/genode/porting_wishlist.html].
|
||||
[https://usr.sysret.de/jws/genode/porting_wishlist.html].
|
||||
|
||||
:Native Open-Street-Maps (OSM) client:
|
||||
|
||||
When using Sculpt OS, we regularly need to spawn a fully fledged web
|
||||
browser in a virtual machine for using OSM or Google maps. The goal
|
||||
of this project would be a native component that makes maps functionality
|
||||
directly available on Genode, alleviating the urge to reach for a SaaS
|
||||
product. The work would include a review of existing OSM clients regarding
|
||||
their feature sets and the feasibility of porting them to Genode.
|
||||
Depending on the outcome of this review, an existing application could
|
||||
be ported or a new component could be developed, e.g., leveraging Genode's
|
||||
Qt support.
|
||||
|
||||
|
||||
Application frameworks and runtime environments
|
||||
@@ -133,20 +121,20 @@ Application frameworks and runtime environments
|
||||
|
||||
:OpenJDK:
|
||||
|
||||
[http://openjdk.java.net/ - OpenJDK] is the reference implementation of the
|
||||
[https://openjdk.java.net/ - OpenJDK] is the reference implementation of the
|
||||
Java programming language and hosts an enormous ecosystem of application
|
||||
software. The goal of this line of work is the ability to run this
|
||||
software directly on Genode. The centerpiece of OpenJDK is Hotspot - the
|
||||
Java virtual machine implementation, which must be ported to Genode.
|
||||
The initial port should suffice to execute simple example programs that
|
||||
operate on textual input. Since Genode has the FreeBSD libc readily
|
||||
available, OpenJDK's existing POSIX backends can be reused. The next step
|
||||
is the creation of Genode-specific native classes that bridge the gap
|
||||
between the Java world and Genode, in particular the glue code to
|
||||
run graphical applications as clients of Genode's GUI server. Since
|
||||
OpenJDK has been ported to numerous platforms (such as Haiku), there
|
||||
exists a comforting number of implementations that can be taken as
|
||||
reference.
|
||||
software.
|
||||
|
||||
Since
|
||||
[https://genode.org/documentation/release-notes/19.02#Showcase_of_a_Java-based_network_appliance - version 19.02],
|
||||
Genode features a port of OpenJDK that allows the use of Java for networking
|
||||
applications.
|
||||
|
||||
The next step would be the creation of Genode-specific native classes that
|
||||
bridge the gap between the Java world and Genode, in particular the glue
|
||||
code to run graphical applications as clients of Genode's GUI server. Since
|
||||
OpenJDK has been ported to numerous platforms (such as Haiku), there exists
|
||||
a comforting number of implementations that can be taken as reference.
|
||||
|
||||
:Android's ART VM natively on Genode:
|
||||
|
||||
@@ -155,22 +143,6 @@ Application frameworks and runtime environments
|
||||
removed from the trusted computing base of Android, facilitating the use of
|
||||
this mobile OS in high-assurance settings.
|
||||
|
||||
:Rust bindings for the Genode API:
|
||||
|
||||
Rust is a low-level systems programming language that ensures memory
|
||||
safety without employing a garbage collector. It thereby challenges C++
|
||||
as the go-to programming language for high-performance and low-level code.
|
||||
Since
|
||||
[http://genode.org/documentation/release-notes/16.05#New_support_for_the_Rust_programming_language - version 16.05],
|
||||
Genode supports the use of the Rust programming language within
|
||||
components. However, to unleash the potential of this combination,
|
||||
Genode's API must become available to native Rust code. The intermediate goal
|
||||
of this project is the implementation of an example server, e.g., a
|
||||
component that provides a terminal-session interface. Thereby, we
|
||||
will encounter the problems of bootstrapping and configuration of the
|
||||
component, the provisioning of signal handlers and session objects, and
|
||||
memory management.
|
||||
|
||||
:Go language runtime:
|
||||
|
||||
Go is a popular language in particular for web applications. In the past,
|
||||
@@ -218,10 +190,37 @@ Application frameworks and runtime environments
|
||||
analyzing such components with formal methods.
|
||||
|
||||
The use of Haskell for systems development was pioneered by the
|
||||
[http://programatica.cs.pdx.edu/House/ - House Project]. A more recent
|
||||
development is [http://halvm.org - HalVM] - a light-weight OS runtime for
|
||||
[https://programatica.cs.pdx.edu/House/ - House Project]. A more recent
|
||||
development is [https://halvm.org - HalVM] - a light-weight OS runtime for
|
||||
Xen that is based on Haskell.
|
||||
|
||||
:Xlib compatibility:
|
||||
|
||||
Developments like Wayland notwithstanding, most application software on
|
||||
GNU/Linux systems is built on top of the Xlib programming interface.
|
||||
However, only a few parts of this wide interface are actually used today.
|
||||
I.e., modern applications generally deal with pixel buffers instead of
|
||||
relying on graphical drawing primitives of the X protocol. Hence, it seems
|
||||
feasible to reimplement the most important parts of the Xlib interface to
|
||||
target Genode's native GUI interfaces (nitpicker) directly. This would
|
||||
allow us to port popular application software to Sculpt OS without
|
||||
changing the application code.
|
||||
|
||||
:Bump-in-the-wire components for visualizing session interfaces:
|
||||
|
||||
Genode's session interfaces bear the potential for monitoring and
|
||||
visualizing their use by plugging a graphical application
|
||||
in-between any two components. For example, by intercepting block
|
||||
requests issued by a block-session client to a block-device driver,
|
||||
such a bump-in-the-wire component could visualize
|
||||
the access patterns of a block device. Similar ideas could be pursued for
|
||||
other session interfaces, like the audio-out (sound visualization) or NIC
|
||||
session (live visualization of network communication).
|
||||
|
||||
The visualization of system behavior would offer valuable insights,
|
||||
e.g., new opportunities for optimization. But more importantly, they
|
||||
would be extremely fun to play with.
|
||||
|
||||
|
||||
Virtualization
|
||||
##############
|
||||
@@ -237,21 +236,6 @@ Virtualization
|
||||
is normally not possible. Also, complex Genode scenarios (like Turmvilla)
|
||||
could be prototyped on GNU/Linux.
|
||||
|
||||
:VirtualBox on top of seL4:
|
||||
|
||||
The [https://sel4.systems - seL4 microkernel] is a modern microkernel that
|
||||
undergoes formal verification to prove the absence of bugs. Since version
|
||||
4.0, the kernel supports virtualization support on x86-based hardware.
|
||||
Genode has experimental support for seL4 that allows almost all Genode
|
||||
components to be used on top of this kernel. VirtualBox is an exception
|
||||
because it closely interacts with the underlying kernel (like NOVA) to
|
||||
attain good performance. We have shown that VirtualBox can be executed
|
||||
within a protection domain of the NOVA microhypervisor. The goal of this
|
||||
project is the application of this approach to the virtualization
|
||||
interface of seL4. The result will be a VM hosting environment that
|
||||
ensures the separation of virtual machines via the formally verified
|
||||
seL4 kernel.
|
||||
|
||||
:Xen as kernel for Genode:
|
||||
|
||||
Using Xen as kernel for Genode would clear the way to remove the
|
||||
@@ -294,22 +278,25 @@ Virtualization
|
||||
the project bears the opportunity to explore the provisioning of the
|
||||
KVM interface based on Genode's VFS plugin concept.
|
||||
|
||||
:Hardware-accelerated graphics for virtual machines:
|
||||
|
||||
In
|
||||
[https://genode.org/documentation/release-notes/17.08#Hardware-accelerated_graphics_for_Intel_Gen-8_GPUs - Genode 17.08],
|
||||
we introduced a GPU multiplexer for Intel Broadwell along with support
|
||||
for Mesa-based 3D-accelerated applications.
|
||||
While designing Genode's GPU-session interface, we also aimed at supporting
|
||||
the hardware-accelerated graphics for Genode's virtual machine monitors like
|
||||
VirtualBox or Seoul, but until now, we did not took the practical steps of
|
||||
implementing a virtual GPU device model.
|
||||
|
||||
The goal of this project is the offering of a virtual GPU to a Linux guest
|
||||
OS running on top of Genode's existing virtualization and driver
|
||||
infrastructure.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
:Isochronous USB devices:
|
||||
|
||||
Genode's USB driver supports bulk and interrupt endpoints. Thereby, most
|
||||
USB devices like USB storage, user input, printers, and networking devices
|
||||
can be used. However, multi-media devices such as cameras or audio
|
||||
equipment use isochronous endpoints, which are not supported. The goal
|
||||
of this line of work is the support of these devices in Genode. The topic
|
||||
touches the USB driver, the USB session interface, an example implementation
|
||||
of a USB client driver (using the session interface) for a device of choice,
|
||||
and - potentially - the enhancement of Genode's USB-pass-through mechanism
|
||||
for VirtualBox.
|
||||
|
||||
:Sound on the Raspberry Pi:
|
||||
|
||||
The goal of this project is a component that uses the Raspberry Pi's
|
||||
@@ -318,24 +305,12 @@ Device drivers
|
||||
backend, the new driver will make the sound of all SDL-based games
|
||||
available on the Raspberry Pi.
|
||||
|
||||
:Framebuffer for UEFI and Coreboot:
|
||||
|
||||
By moving away from the legacy BIOS boot mechanism, it is time to
|
||||
reconsider closely related traditional approaches such as the use of
|
||||
the VESA BIOS extensions for accessing the frame buffer. On UEFI or
|
||||
Coreboot systems, there exist alternative ways to initialize and
|
||||
access the framebuffer in a hardware-independent way. On the course of
|
||||
this project, we will explore the available options and create dedicated
|
||||
Genode driver components that use the modern mechanisms.
|
||||
For reference, the current state of Genode's UEFI support is documented
|
||||
in [https://github.com/genodelabs/genode/issues/2242 - Issue 2242].
|
||||
|
||||
:Data Plane Development Kit (DPDK):
|
||||
|
||||
Genode utilizes the network device drivers of the iPXE project, which
|
||||
perform reasonably well for everyday use cases but are obviously not
|
||||
designated for high-performance networking.
|
||||
The [http://dpdk.org/ - DPDK] is a vendor-supported suite of network device
|
||||
The [https://dpdk.org/ - DPDK] is a vendor-supported suite of network device
|
||||
drivers that is specifically developed for high-performance applications.
|
||||
It presents an attractive alternative to iPXE-based drivers. This project
|
||||
has the goal to make DPDK drivers available as a Genode component.
|
||||
@@ -357,8 +332,22 @@ Platforms
|
||||
Genode functionality such as its native GUI, lwIP, and Noux, many protocol
|
||||
stacks can effectively be removed from the Linux kernel.
|
||||
|
||||
The goal of this project is to evaluate how small the Linux kernel can get
|
||||
when used as a microkernel.
|
||||
In 2018, Johannes Kliemann pursued this topic to a state where Genode
|
||||
could be used as init process atop a customized Linux kernel.
|
||||
[https://lists.genode.org/pipermail/users/2018-May/006066.html - His work]
|
||||
included the execution of Genode's regular device drivers for VESA and
|
||||
PS/2 as regular Genode components so that Genode's interactive demo
|
||||
scenario ran happily on a laptop. At this time, however, only parts of
|
||||
his results were merged into Genode's mainline.
|
||||
|
||||
The goal of this project is to follow up on Johannes' work, bring the
|
||||
[https://github.com/genodelabs/genode/pull/2829 - remaining parts] into
|
||||
shape for the inclusion into Genode, and address outstanding topics, in
|
||||
particular the handling of DMA by user-level device drivers. Further down
|
||||
the road, it would be tempting to explore the use of
|
||||
[https://en.wikipedia.org/wiki/Seccomp - seccomp] as sandboxing mechanism
|
||||
for Genode on Linux and the improvement of the Linux-specific implementation
|
||||
of Genode's object-capability model.
|
||||
|
||||
:Support for the HelenOS/SPARTAN kernel:
|
||||
|
||||
@@ -381,34 +370,46 @@ Platforms
|
||||
kernel is used for Mac OS X, it could represent an industry-strength
|
||||
base platform for Genode supporting all CPU features as used by Mac OS X.
|
||||
|
||||
:Linux process containers for supporting Genode`s resource trading:
|
||||
:Genode on the Librem5 phone hardware:
|
||||
|
||||
Even though the Linux version of Genode is primarily meant as a development
|
||||
platform, there exist interesting opportunities to explore when combining
|
||||
Genode with Linux, in particular Linux' process containers.
|
||||
Linux process containers provide a mechanism to partition physical resources,
|
||||
foremost CPU time, between Linux processes. This raises the interesting
|
||||
question of whether this mechanism could be used for a proper implementation
|
||||
of Genode's resource trading on Linux.
|
||||
[http://lwn.net/Articles/236038/ - Process containers introduction...]
|
||||
Even though there exists a great variety of ARM-based SoCs, Genode
|
||||
primarily focuses on the NXP i.MX family because it is - in contrast
|
||||
to most SoCs in the consumer space - very liberal in terms of
|
||||
good-quality public documentation and reference code, and it scales
|
||||
from industrial to end-user-facing use cases (multi-media).
|
||||
|
||||
The [https://puri.sm/products/librem-5/ - Librem5] project - with its
|
||||
mission to build a trustworthy mobile phone - has chosen the i.MX family as
|
||||
the basis for their product for likely the same reasons that attract us.
|
||||
|
||||
To goal of this work is bringing Genode to the Librem5 hardware.
|
||||
For the Librem5 project, Genode could pave the ground towards new use cases
|
||||
like high-security markets where a regular Linux-based OS would not be
|
||||
accepted. For the Genode community, the Librem5 hardware could become an
|
||||
attractive mobile platform for everyday use, similar to how we developers
|
||||
use our Genode-based [https://genode.org/download/sculpt - Sculpt OS] on our
|
||||
laptops.
|
||||
|
||||
|
||||
System management
|
||||
#################
|
||||
|
||||
:Remote management of Sculpt OS via Puppet:
|
||||
|
||||
[https://en.wikipedia.org/wiki/Puppet_(company)#Puppet - Puppet] is a
|
||||
software-configuration management tool for administering a large amount
|
||||
of machines from one central place. Genode's
|
||||
[https://genode.org/download/sculpt - Sculpt OS] lends itself to such
|
||||
an approach of remote configuration management by the means of the
|
||||
"config" file system (for configuring components and deployments) and
|
||||
the "report" file system (for obtaining the runtime state of components).
|
||||
The project would explore the application of the Puppet approach and tools
|
||||
to Sculpt OS.
|
||||
|
||||
|
||||
Optimizations
|
||||
#############
|
||||
|
||||
:Low-latency audio streaming:
|
||||
|
||||
Genode comes with an audio streaming interface called 'Audio_out' session.
|
||||
It is based on a shared-memory packet stream accompanied with asynchronous
|
||||
data-flow signals. For real-time audio processing involving chains of Genode
|
||||
components, streams of audio data must be carried at low latency, imposing
|
||||
constraints to buffer sizes and the modes of operation of the audio mixer and
|
||||
audio drivers. The goal of this project is to create a holistic design of the
|
||||
whole chain of audio processing, taking thread-scheduling into account. A
|
||||
particular challenge is the mixed output of real-time (small buffer, low
|
||||
latency) and non-real-time (larger buffer to compensate jitter, higher
|
||||
latency) audio sources.
|
||||
|
||||
:De-privileging the VESA graphics driver:
|
||||
|
||||
The VESA graphics driver executes the graphics initialization code provided
|
||||
|
||||
@@ -93,6 +93,24 @@ and the source code always looks good.
|
||||
_Hint:_ In VIM, use the 'set list' and 'set listchars' commands to make tabs
|
||||
and spaces visible.
|
||||
|
||||
* If class initializers span multiple lines, put the colon on a separate
|
||||
line and indent the initializers using one tab. For example:
|
||||
! Complicated_machinery(Material &material, Deadline deadline)
|
||||
! :
|
||||
! <tab>_material(material),
|
||||
! <tab>_deadline(deadline),
|
||||
! <tab>...
|
||||
! {
|
||||
! ...
|
||||
! }
|
||||
|
||||
* Preferably place statements that alter the control flow - such as
|
||||
'break', 'continue', or 'return' - at the beginning of a separate line,
|
||||
followed by vertical space (a blank line or the closing brace of the
|
||||
surrounding scope).
|
||||
! if (early_return_possible)
|
||||
! return;
|
||||
|
||||
|
||||
Switch statements
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -14,6 +14,11 @@ Genode comes with a growing number of components apparently scattered across
|
||||
various repositories. This document provides an overview of these components
|
||||
and outlines the systematics behind them.
|
||||
|
||||
The scope of this document is limited to the Genode main repository maintained
|
||||
by Genode Labs. Many additional components and device drivers can be found in
|
||||
the community-maintained
|
||||
[https://github.com/genodelabs/genode-world/ - Genode-World] repository.
|
||||
|
||||
|
||||
Categorization of components
|
||||
############################
|
||||
@@ -26,11 +31,11 @@ of them is briefly characterized as follows:
|
||||
session interfaces. Naturally, a device driver is specific to a
|
||||
particular hardware platform. The hardware resources are accessed
|
||||
via core's IO_MEM, IO_PORT, and IRQ services. The functionality of
|
||||
the driver is made available to other system components by announcing
|
||||
the driver is made available to other system components via
|
||||
one of Genode's device-independent session interfaces, which are
|
||||
'platform_session', 'framebuffer_session', 'input_session', 'block_session',
|
||||
'platform_session', 'capture_session', 'event_session', 'block_session',
|
||||
'audio_out_session', 'log_session', 'nic_session', and 'timer_session'
|
||||
(see 'os/include/' for the interface definitions). Those interfaces are
|
||||
(see _os/include/_ for the interface definitions). Those interfaces are
|
||||
uniform across hardware platforms and kernel base platforms. Usually,
|
||||
each device driver can accommodate only one client at a time.
|
||||
|
||||
@@ -59,7 +64,7 @@ of them is briefly characterized as follows:
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Device drivers usually reside in the 'src/drivers' subdirectory of source-code
|
||||
Device drivers usually reside in the _src/drivers/_ subdirectory of source-code
|
||||
repositories. The most predominant repositories hosting device drivers are
|
||||
'os', 'dde_ipxe', 'dde_linux'.
|
||||
|
||||
@@ -67,19 +72,23 @@ repositories. The most predominant repositories hosting device drivers are
|
||||
Platform devices
|
||||
================
|
||||
|
||||
:'os/src/drivers/platform/': Platform drivers for various platforms.
|
||||
:_os/src/drivers/platform/_: Platform drivers for various platforms.
|
||||
On x86, the platform driver uses the PCI controller as found on x86 PC
|
||||
hardware. A client can probe for a particular device and request information
|
||||
about physical device resources (using the 'platform_device' interface). I/O
|
||||
resources for MMIO regions, I/O ports, and interrupts can be requested by the
|
||||
provided device abstraction.
|
||||
|
||||
:'os/src/drivers/acpi':
|
||||
:_os/src/drivers/acpi/_:
|
||||
On x86 platforms that use the APIC (namely Fiasco.OC, NOVA, and hw_x86_64)
|
||||
this simple ACPI parser traverses the ACPI tables and reports device-resource
|
||||
information (e.g., interrupt lines of PCI devices).
|
||||
|
||||
:'libports/src/app/acpica':
|
||||
:_os/src/app/smbios_decoder/_:
|
||||
A component that parses SMBIOS information on x86 platforms and makes the
|
||||
result available as a report.
|
||||
|
||||
:_libports/src/app/acpica/_:
|
||||
In addition to our ACPI base driver, the acpica component uses the
|
||||
ACPICA library to provide access to dynamic functions like battery
|
||||
states, events (e.g., notebook lid close and power buttons), as well
|
||||
@@ -93,91 +102,71 @@ UART devices
|
||||
|
||||
The UART device drivers implement the UART-session interface.
|
||||
|
||||
:'os/src/drivers/uart/spec/pl011':
|
||||
:_os/src/drivers/uart/spec/pbxa9/_:
|
||||
Driver for the PL011 UART as found on many ARM-based platforms.
|
||||
|
||||
:'os/src/drivers/uart/spec/i8250':
|
||||
:_os/src/drivers/uart/spec/x86/_:
|
||||
Driver for the i8250 UART as found on PC hardware.
|
||||
|
||||
:'os/src/drivers/uart/spec/omap4':
|
||||
Driver for the UART as found on OMAP4-based hardware.
|
||||
|
||||
:'os/src/drivers/uart/spec/exynos5':
|
||||
Driver for the UART as found on Exynos-5-based hardware.
|
||||
|
||||
|
||||
Framebuffer and input drivers
|
||||
=============================
|
||||
|
||||
Framebuffer and input drivers implement the framebuffer-session interface and
|
||||
input-session interfaces respectively.
|
||||
Framebuffer and input drivers are implemented as clients of the
|
||||
capture-session and event-session interfaces respectively.
|
||||
|
||||
:'os/src/drivers/input/dummy':
|
||||
Pseudo input driver without accessing any hardware. This component is useful
|
||||
to resolve a dependency from an input session for scenarios where no user
|
||||
input is required.
|
||||
|
||||
:'os/src/drivers/input/spec/ps2/x86':
|
||||
:_os/src/drivers/ps2/x86/_:
|
||||
Driver for the 'i8042' PS/2 controller as found in x86 PCs. It supports both
|
||||
mouse (including ImPS/2, ExPS/2) and keyboard.
|
||||
|
||||
:'os/src/drivers/input/spec/ps2/pl050':
|
||||
:_os/src/drivers/ps2/pl050/_:
|
||||
Driver for the PL050 PS/2 controller as found on ARM platforms such as
|
||||
VersatilePB. The physical base address used by the driver is obtained at
|
||||
compile time from a header file called 'pl050_defs.h'. The version of the
|
||||
VersatilePB platform can be found at 'os/include/platform/vpb926/' and
|
||||
compile time from a header file called _pl050_defs.h_. The version of the
|
||||
VersatilePB platform can be found at _os/include/platform/vpb926/_ and
|
||||
is made available to the driver via the SPECS machinery of the Genode build
|
||||
system.
|
||||
|
||||
:'os/src/drivers/input/spec/imx53':
|
||||
Input driver for Egalaxy touchscreen and Freescale's MPR121
|
||||
capacitative touch buttons on i.MX53.
|
||||
|
||||
:'libports/src/drivers/framebuffer/vesa':
|
||||
:_libports/src/drivers/framebuffer/vesa/_:
|
||||
Driver using VESA mode setting on x86 PCs. For more information, please refer
|
||||
to the README file in the driver directory.
|
||||
|
||||
:'libports/src/drivers/framebuffer/boot':
|
||||
:_libports/src/drivers/framebuffer/boot/_:
|
||||
Driver for boot-time initialized framebuffers (e.g., UEFI GOP)
|
||||
discovered from the 'platform_info' ROM
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/pl11x':
|
||||
:_os/src/drivers/framebuffer/pl11x/_:
|
||||
Driver for the PL110/PL111 LCD display.
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/omap4':
|
||||
Driver for HDMI output on OMAP4 SoCs.
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/exynos5':
|
||||
Driver for HDMI output on Exynos-5 SoCs.
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/imx53':
|
||||
:_os/src/drivers/framebuffer/imx53/_:
|
||||
Driver for LCD output on i.MX53 SoCs.
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/rpi':
|
||||
:_os/src/drivers/framebuffer/rpi/_:
|
||||
Driver for the HDMI output of the Raspberry Pi.
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/sdl':
|
||||
:_os/src/drivers/framebuffer/sdl/_:
|
||||
Serves as both framebuffer and input driver on Linux using libSDL. This
|
||||
driver is only usable on the Linux base platform.
|
||||
|
||||
:'os/src/drivers/gpu/intel':
|
||||
Intel Graphics GPU multiplexer for Broadwell and newer.
|
||||
:_os/src/drivers/gpu/intel/_:
|
||||
An experimental Intel Graphics GPU multiplexer for Broadwell and newer.
|
||||
|
||||
:'dde_linux/src/drivers/framebuffer/intel':
|
||||
:_dde_linux/src/drivers/framebuffer/intel/_:
|
||||
Framebuffer driver for Intel i915 compatible graphic cards based on
|
||||
the Linux Intel KMS driver.
|
||||
|
||||
:'dde_linux/src/drivers/usb':
|
||||
USB driver that makes USB HID and USB storage devices available as input
|
||||
sessions and block session respectively. For examples of using this driver,
|
||||
refer to the run scripts at 'dde_linux/run/usb_hid' and
|
||||
'dde_linux/run/usb_storage'.
|
||||
:_dde_linux/src/drivers/usb_host/_:
|
||||
USB host-controller driver that provides an USB session interface to
|
||||
USB drivers.
|
||||
|
||||
:_dde_linux/src/drivers/usb_hid/_:
|
||||
USB Human Interface Device driver using the USB session interface.
|
||||
|
||||
|
||||
Timer drivers
|
||||
=============
|
||||
|
||||
The timer driver located at 'os/src/drivers/timer' implements the timer-session
|
||||
The timer driver located at _base/src/timer/_ implements the timer-session
|
||||
interface. Technically, it is both a device driver (accessing a timer
|
||||
device) and a resource multiplexer (supporting multiple timer-session clients
|
||||
at the same time). Depending on the base platform, the implementation uses
|
||||
@@ -198,13 +187,13 @@ Audio drivers
|
||||
=============
|
||||
|
||||
Audio drivers implement the Audio_out session interface defined at
|
||||
'os/include/audio_out_session/' for playback and optionally the audio_in
|
||||
_os/include/audio_out_session/_ for playback and optionally the audio_in
|
||||
interface for recording.
|
||||
|
||||
:'os/src/drivers/audio/spec/linux':
|
||||
:_os/src/drivers/audio/spec/linux/_:
|
||||
Uses ALSA as back-end on the Linux base platform and supports only playback.
|
||||
|
||||
:'dde_bsd/src/drivers/audio':
|
||||
:_dde_bsd/src/drivers/audio/_:
|
||||
Sound drivers ported from OpenBSD. Currently, the repository
|
||||
includes support for Intel HD Audio as well as for Ensoniq AudioPCI
|
||||
(ES1370) compatible sound cards.
|
||||
@@ -214,118 +203,111 @@ Block drivers
|
||||
=============
|
||||
|
||||
All block drivers implement the block-session interface defined at
|
||||
'os/include/block_session/'.
|
||||
_os/include/block_session/_.
|
||||
|
||||
:'os/src/drivers/sd_card/spec/pl180':
|
||||
:_os/src/drivers/sd_card/spec/pl180/_:
|
||||
Driver for SD-cards connected via the PL180 device as found on the PBX-A9
|
||||
platform.
|
||||
|
||||
:'os/src/drivers/sd_card/spec/omap4':
|
||||
Driver for SD-cards connected to the SD-card controller of the OMAP4 SoC.
|
||||
|
||||
:'os/src/drivers/sd_card/spec/exynos5':
|
||||
Driver for SD-cards and eMMC connected to Exynos-5-based platforms.
|
||||
|
||||
:'os/src/drivers/sd_card/spec/imx53':
|
||||
:_os/src/drivers/sd_card/spec/imx53/_:
|
||||
Driver for SD-cards connected to the Freescale i.MX53 platform like the
|
||||
Quick Start Board or the USB armory device.
|
||||
|
||||
:'os/src/drivers/sd_card/spec/rpi':
|
||||
:_os/src/drivers/sd_card/spec/rpi/_:
|
||||
Driver for SD-cards connected to the Raspberry Pi.
|
||||
|
||||
:'dde_linux/src/drivers/usb':
|
||||
USB driver that makes USB storage devices available as block sessions.
|
||||
For an example of using this driver, refer to the run script at
|
||||
'dde_linux/run/usb_storage'.
|
||||
|
||||
:'os/src/drivers/ahci':
|
||||
:_os/src/drivers/ahci/_:
|
||||
Driver for SATA disks and CD-ROMs on x86 PCs.
|
||||
|
||||
:'os/src/drivers/usb_block':
|
||||
USB Mass Storage Bulk-Only driver using the USB session interface.
|
||||
:_os/src/drivers/nvme/_:
|
||||
Driver for NVMe block devices on x86 PCs.
|
||||
|
||||
:_os/src/drivers/usb_block/_:
|
||||
USB Mass Storage Bulk-Only driver using the USB session interface and provides
|
||||
a block-session interface.
|
||||
|
||||
|
||||
Network interface drivers
|
||||
=========================
|
||||
|
||||
All network interface drivers implement the NIC session interface
|
||||
defined at 'os/include/nic_session'.
|
||||
defined at _os/include/nic_session/_.
|
||||
|
||||
:'os/src/drivers/nic/spec/linux':
|
||||
:_os/src/drivers/nic/spec/linux/_:
|
||||
Driver that uses a Linux tap device as back end. It is only useful on the
|
||||
Linux base platform.
|
||||
|
||||
:'os/src/drivers/nic/spec/lan9118':
|
||||
:_os/src/drivers/nic/spec/lan9118/_:
|
||||
Native device driver for the LAN9118 network adaptor as featured on the
|
||||
PBX-A9 platform.
|
||||
|
||||
:'os/src/drivers/nic/gem':
|
||||
Device driver for Cadence EMAC PS network adaptor as featured on the
|
||||
Xilinx Zynq.
|
||||
|
||||
:'dde_ipxe/src/drivers/nic':
|
||||
:_dde_ipxe/src/drivers/nic/_:
|
||||
Device drivers ported from the iPXE project. Supported devices are Intel
|
||||
E1000 and pcnet32.
|
||||
|
||||
:'dde_linux/src/drivers/wifi':
|
||||
:_dde_linux/src/drivers/wifi/_:
|
||||
The wifi_drv component is a port of the Linux mac802.11 stack, including the
|
||||
iwlwifi driver. It enables the use of Intel Wireless 6xxx and 7xxx cards.
|
||||
|
||||
:'dde_linux/src/drivers/usb':
|
||||
For the OMAP4 platform, the USB driver contains the networking driver.
|
||||
:_dde_linux/src/drivers/usb_net/_:
|
||||
USB network driver using the USB session interface.
|
||||
|
||||
:_dde_linux/src/drivers/nic/fec/_:
|
||||
Driver for ethernet NICs of the i.MX SoC family.
|
||||
|
||||
|
||||
General-purpose I/O drivers
|
||||
===========================
|
||||
|
||||
:'os/src/drivers/gpio/spec/omap4':
|
||||
Driver for accessing the GPIO pins of OMAP4 platforms.
|
||||
|
||||
:'os/src/drivers/gpio/spec/imx53':
|
||||
:_os/src/drivers/gpio/spec/imx53/_:
|
||||
Driver for accessing the GPIO pins of i.MX53 platforms.
|
||||
|
||||
:'os/src/drivers/gpio/spec/rpi':
|
||||
:_os/src/drivers/gpio/spec/rpi/_:
|
||||
Driver for accessing the GPIO pins of Raspberry Pi platforms.
|
||||
|
||||
:'os/src/drivers/gpio/spec/exynos5':
|
||||
Driver for accessing the GPIO pins of Exynos4 platforms, e.g.,
|
||||
Odroid-X2.
|
||||
|
||||
|
||||
Resource multiplexers
|
||||
#####################
|
||||
|
||||
By convention, resource multiplexers are located at the 'src/server'
|
||||
By convention, resource multiplexers are located at the _src/server/_
|
||||
subdirectory of a source repository.
|
||||
|
||||
:Framebuffer and input: The framebuffer and input session interfaces can be
|
||||
multiplexed using the Nitpicker GUI server, which allows multiple clients to
|
||||
create and manage rectangular areas on screen. Nitpicker uses one input
|
||||
session and one framebuffer session as back end and, in turn, provides
|
||||
so-called nitpicker sessions to one or multiple clients. Each nitpicker
|
||||
session contains a virtual framebuffer and a virtual input session. Nitpicker
|
||||
(including a README file) is located at 'os/src/server/nitpicker'.
|
||||
:Framebuffer and input: Framebuffer and input devices can be multiplexed using
|
||||
the Nitpicker GUI server, which allows multiple clients to create and manage
|
||||
rectangular areas on screen. Nitpicker serves as broker between input
|
||||
devices, output devices, and graphical applications. It provides an event
|
||||
service for input drivers, a capture service for output drivers, and a GUI
|
||||
service for the applications. Each GUI session contains a virtual
|
||||
framebuffer and a virtual input interface. Nitpicker (including a README
|
||||
file) is located at _os/src/server/nitpicker/_.
|
||||
|
||||
:Audio output: The audio mixer located at 'os/src/server/mixer' enables
|
||||
:Audio output: The audio mixer located at _os/src/server/mixer/_ enables
|
||||
multiple clients to use the audio-out interface. The mixing is done by simply
|
||||
adding and clamping the signals of all present clients.
|
||||
|
||||
:Networking: The NIC bridge located at 'os/src/server/nic_bridge' multiplexes
|
||||
:Networking: The NIC bridge located at _os/src/server/nic_bridge/_ multiplexes
|
||||
one NIC session to multiple virtual NIC sessions using a proxy-ARP
|
||||
implementation. Each client has to obtain a dedicated IP address visible to
|
||||
the physical network. DHCP requests originating from the virtual NIC sessions
|
||||
are delegated to the physical network.
|
||||
|
||||
:Block: The block-device partition server at 'os/src/server/part_blk' reads
|
||||
The NIC router located at _os/src/server/nic_router/_ multiplexes one NIC
|
||||
session to multiple virtual NIC sessions by applying network address
|
||||
translation (NAT).
|
||||
|
||||
:Block: The block-device partition server at _os/src/server/part_block/_ reads
|
||||
the partition table of a block session and exports each partition found as
|
||||
separate block session. For using this server, please refer to the run
|
||||
script at 'os/run/part_blk'.
|
||||
script at _os/run/part_block.run_.
|
||||
|
||||
:File system: The FAT file-system service allows multiple clients to
|
||||
concurrently access the same FAT-formatted block device. It is located
|
||||
at 'libports/src/server/fatfs_fs' and supports FAT, FAT32, and exFAT.
|
||||
:File system: The VFS file-system server allows multiple clients to
|
||||
concurrently access the same virtual file system. It is located at
|
||||
_os/src/server/vfs/_. The VFS can be assembled out of several builtin
|
||||
file-system types (like a RAM file system, or pseudo file systems for
|
||||
various Genode session interfaces) as well as external plugins such as rump
|
||||
(mounting file systems supported by the NetBSD kernel).
|
||||
|
||||
:Terminal: The terminal_mux service located at gems/src/server/terminal_mux
|
||||
:Terminal: The terminal_mux service located at _gems/src/server/terminal_mux/_
|
||||
is able to provide multiple terminal sessions over one terminal-client
|
||||
session. The user can switch between the different sessions using a keyboard
|
||||
shortcut, which brings up an ncurses-based menu.
|
||||
@@ -337,272 +319,311 @@ Protocol stacks
|
||||
Protocol stacks come either in the form of separate components that translate
|
||||
one session interface to another, or in the form of libraries.
|
||||
|
||||
Separate components:
|
||||
Separate components
|
||||
===================
|
||||
|
||||
:'os/src/server/nit_fb':
|
||||
Translates a nitpicker session to a pair of framebuffer and input sessions.
|
||||
Each 'nit_fb' instance is visible as a rectangular area on screen presenting
|
||||
:_os/src/server/gui_fb/_:
|
||||
Translates a GUI session to a pair of framebuffer and input sessions.
|
||||
Each 'gui_fb' instance is visible as a rectangular area on screen presenting
|
||||
a virtual frame buffer. The area is statically positioned. For more
|
||||
information, please refer to 'os/src/server/nit_fb/README'.
|
||||
information, please refer to _os/src/server/gui_fb/README_.
|
||||
|
||||
:'gems/src/server/wm':
|
||||
Window manager that implements the nitpicker session interface but manages
|
||||
:_gems/src/server/wm/_:
|
||||
Window manager that implements the GUI session interface but manages
|
||||
each client view as a separate window. The window decorations are provided
|
||||
by a so-called decorator (e.g., 'gems/src/app/decorator'). The behaviour
|
||||
by a so-called decorator (e.g., _gems/src/app/decorator/_). The behaviour
|
||||
is defined by a so-called window layouter such as the floating window
|
||||
layouter located at 'gems/src/app/floating_window_layouter/'.
|
||||
layouter located at _gems/src/app/floating_window_layouter/_.
|
||||
|
||||
:'demo/src/server/liquid_framebuffer':
|
||||
Implements the same translation as 'nit_fb' but by presenting an interactive
|
||||
:_demo/src/server/liquid_framebuffer/_:
|
||||
Implements the same translation as 'gui_fb' but by presenting an interactive
|
||||
window rather than a statically positioned screen area.
|
||||
|
||||
:'os/src/server/tar_rom':
|
||||
:_os/src/server/tar_rom/_:
|
||||
Provides each file contained in a tar file obtained via Genode's ROM session
|
||||
as separate ROM session.
|
||||
|
||||
:'os/src/server/iso9660':
|
||||
:_os/src/server/iso9660/_:
|
||||
Provides each file of an ISO9660 file system accessed via a block session as
|
||||
separate ROM session.
|
||||
|
||||
:'os/src/server/ram_fs':
|
||||
A file-system implementation that keeps all data in memory.
|
||||
|
||||
:'dde_rump/src/server/rump_fs':
|
||||
A file-system server that contains various file-systems ported from the
|
||||
NetBSD kernel.
|
||||
|
||||
:'os/src/server/lx_fs':
|
||||
:_os/src/server/lx_fs/_:
|
||||
A file system server that makes the file system of a Linux base platform
|
||||
available to Genode.
|
||||
|
||||
:'os/src/server/trace_fs':
|
||||
A pseudo file system that can be used as a front end to core's TRACE
|
||||
service.
|
||||
:_os/src/server/vfs_block/_:
|
||||
Provides the content of a file obtained from a VFS as a block session,
|
||||
similar to the loop-mount mechanism on Linux
|
||||
|
||||
:'os/src/server/rom_blk':
|
||||
Provides the content of a ROM file as a block session, similar to the
|
||||
loop-mount mechanism on Linux
|
||||
|
||||
:'os/src/server/ram_blk':
|
||||
Provides the content of a RAM dataspace as a block session. In contrast
|
||||
to 'rom_blk', this server provides a writeable block device.
|
||||
|
||||
:'os/src/server/terminal_log':
|
||||
:_os/src/server/terminal_log/_:
|
||||
Adapter for forwarding LOG messages to a terminal session.
|
||||
|
||||
:'os/src/server/log_terminal':
|
||||
:_os/src/server/log_terminal/_:
|
||||
Adapter for forwarding terminal output to a LOG session.
|
||||
|
||||
:'os/src/server/fs_log':
|
||||
:_os/src/server/fs_log/_:
|
||||
Adapter that writes LOG messages to files on a file system.
|
||||
|
||||
:'demo/src/server/nitlog':
|
||||
Provides a LOG session, printing log output on screen via a nitpicker
|
||||
session.
|
||||
:_demo/src/server/nitlog/_:
|
||||
Provides a LOG session, printing log output on screen via a GUI session.
|
||||
|
||||
:'os/src/app/rom_logger':
|
||||
:_os/src/app/rom_logger/_:
|
||||
The rom_logger component requests a ROM session and writes the
|
||||
content of the ROM dataspace to the LOG.
|
||||
|
||||
:'os/src/server/rom_filter':
|
||||
:_os/src/server/rom_filter/_:
|
||||
The ROM filter provides a ROM module that depends on the content of
|
||||
other ROM modules steered by the filter configuration, e.g., dynamic
|
||||
switching between configuration variants dependent on the state of
|
||||
the system.
|
||||
|
||||
:'os/src/server/vfs':
|
||||
A file-system server using the VFS library and plugins as backend.
|
||||
|
||||
:'os/src/server/log_terminal':
|
||||
:_os/src/server/log_terminal/_:
|
||||
Forwards terminal output to a LOG session.
|
||||
|
||||
:'gems/src/server/file_terminal':
|
||||
:_gems/src/server/file_terminal/_:
|
||||
Provides terminal sessions that target files on a file system.
|
||||
|
||||
:'gems/src/server/terminal':
|
||||
:_gems/src/server/terminal/_:
|
||||
Provides a terminal session via a graphical terminal using a framebuffer
|
||||
session and an input session.
|
||||
|
||||
:'gems/src/server/tcp_terminal':
|
||||
:_gems/src/server/tcp_terminal/_:
|
||||
Provides one or multiple terminal sessions over TCP connections.
|
||||
For further information, refer to 'gems/src/server/tcp_terminal/README'.
|
||||
For further information, refer to _gems/src/server/tcp_terminal/README_.
|
||||
|
||||
:'os/src/server/terminal_crosslink':
|
||||
:_os/src/server/terminal_crosslink/_:
|
||||
The terminal crosslink service allows to terminal clients to talk to each
|
||||
other.
|
||||
|
||||
:'gems/src/server/http_blk':
|
||||
:_gems/src/server/http_block/_:
|
||||
A block service that fetches a virtual block device over the network from
|
||||
a HTTP server.
|
||||
|
||||
:'os/src/server/fs_rom':
|
||||
:_os/src/server/fs_rom/_:
|
||||
A ROM service that translates the 'File_system' session interface to the
|
||||
'ROM' session' interface. Each request for a ROM file is handled by looking
|
||||
up an equally named file on the file system.
|
||||
Please refer to 'os/src/server/fs_rom' for more information.
|
||||
Please refer to _os/src/server/fs_rom/_ for more information.
|
||||
|
||||
:'os/src/server/dynamic_rom':
|
||||
For use cases where ROMs are known to be static, the
|
||||
_os/src/server/cached_fs_rom/_ can be considered as a faster alternative to
|
||||
the regular 'fs_rom' server. Note that 'cached_fs_rom' is not supported
|
||||
in base-linux though.
|
||||
|
||||
:_os/src/server/chroot/_:
|
||||
An intermediate file-system server that makes a sub directory of a file
|
||||
system available as the root of a file system handed out to its client.
|
||||
|
||||
:_os/src/server/dynamic_rom/_:
|
||||
A simple ROM service that provides ROM modules that change in time according
|
||||
to a configured timeline.
|
||||
|
||||
:'os/src/server/report_rom':
|
||||
:_os/src/server/report_rom/_:
|
||||
A service that implements both the report session interface and the ROM
|
||||
session interface. It reflects incoming reports as ROM modules.
|
||||
|
||||
:'os/src/server/fs_report':
|
||||
:_os/src/server/fs_report/_:
|
||||
Report server that writes reports to file-systems
|
||||
|
||||
:'os/src/server/clipboard':
|
||||
:_os/src/server/clipboard/_:
|
||||
This component is both a report service and a ROM service. The
|
||||
clients of the report service can issue new clipboard content, which
|
||||
is then propagated to the clients of the ROM service according to a
|
||||
configurable information-flow policy.
|
||||
|
||||
:'ports/src/app/openvpn':
|
||||
OpenVPN enables access to remote network resources through a secure tunnel
|
||||
by providing an encrypted connection to a remote host. It is plugged between
|
||||
NIC server (such as a network driver) and NIC client.
|
||||
:_os/src/server/event_filter/_:
|
||||
A component that transforms and merges input events from multiple sources
|
||||
into a single event stream.
|
||||
|
||||
:'os/src/server/input_merger':
|
||||
A component that merges input events from multiple sources into a single
|
||||
stream.
|
||||
|
||||
:'libports/src/server/acpi_input':
|
||||
:_libports/src/app/acpi_event/_:
|
||||
A component that transforms ACPI events into Genode input events.
|
||||
|
||||
:'gems/src/server/nit_fader':
|
||||
A wrapper for nitpicker's session interface that applies alpha-blending to
|
||||
the of views a nitpicker client.
|
||||
:_gems/src/server/gui_fader/_:
|
||||
A wrapper for nitpicker's GUI session interface that applies alpha-blending
|
||||
to the of views a GUI client.
|
||||
|
||||
Libraries:
|
||||
:_os/src/server/black_hole/_:
|
||||
Mockup implementation of Genode session interfaces.
|
||||
|
||||
:'libports/lib/mk/libc':
|
||||
|
||||
VFS plugins
|
||||
===========
|
||||
|
||||
VFS plugins are file-system drivers in the form of shared libraries that
|
||||
implement the VFS-plugin interface. They can be combined with any application
|
||||
based on Genode's C runtime, with the VFS server, and with non-POSIX
|
||||
components that use the Genode's VFS library directly.
|
||||
|
||||
:_gems/src/lib/vfs/trace/_:
|
||||
A VFS plugin that makes core's TRACE service accessible as a pseudo
|
||||
file system.
|
||||
|
||||
:_gems/src/lib/vfs/import/_:
|
||||
A VFS plugin that pre-populates a VFS with initial content.
|
||||
|
||||
:_gems/src/lib/vfs/pipe/_:
|
||||
A VFS plugin that provides bi-directional pipes for exchanging streamed
|
||||
data between components.
|
||||
|
||||
:_gems/src/lib/vfs/ttf/_:
|
||||
A VFS plugin that makes rendered pixel data of the glyphs of Truetype fonts
|
||||
available as a pseudo file system.
|
||||
|
||||
:_libports/src/lib/vfs/jitterentropy/_:
|
||||
A VFS plugin that provides random numbers based on the jitter of executing
|
||||
CPU instructions.
|
||||
|
||||
:_libports/src/lib/vfs/lwip/_:
|
||||
A VFS plugin that uses the light-weight IP (lwIP) stack to provide a
|
||||
network socket interface as a pseudo file system.
|
||||
|
||||
:_dde_linux/src/lib/vfs/lxip/_:
|
||||
A VFS plugin that uses the TCP/IP stack ported from the Linux kernel to
|
||||
provide a network socket interface as a pseudo file system.
|
||||
|
||||
:_libports/src/lib/vfs/fatfs/_:
|
||||
A VFS plugin that allows for the mounting of FAT-formatted block devices.
|
||||
|
||||
:_dde_rump/src/lib/vfs/rump/_:
|
||||
A VFS plugin that enables the use of NetBSD's file-system drivers such
|
||||
as ext2 or msdos.
|
||||
|
||||
|
||||
Libraries
|
||||
=========
|
||||
|
||||
:_libports/lib/mk/libc/_:
|
||||
C runtime ported from FreeBSD.
|
||||
|
||||
:'libports/lib/mk/libc_lwip_nic_dhcp':
|
||||
Translates the BSD socket API to a NIC session using the lwIP stack.
|
||||
|
||||
:'dde_linux/lib/mk/libc_lxip':
|
||||
Translates the BSD socket API to a NIC session using the Linux TCP/IP stack.
|
||||
|
||||
:'libports/lib/mk/libc_ffat':
|
||||
Accesses files on a block device that contains a FAT32 file system.
|
||||
|
||||
:'libports/lib/mk/libc_fuse_exfat':
|
||||
Accesses files on a block device that contains an exFAT file system.
|
||||
|
||||
:'libports/lib/mk/libc_fuse_ext2':
|
||||
Accesses files on a block device that contains an ext2 file system.
|
||||
|
||||
:'libports/lib/mk/libc_terminal':
|
||||
Connects the standard input and output from/to Genode's terminal session
|
||||
interface.
|
||||
|
||||
:'libports/lib/mk/stdcxx':
|
||||
:_libports/lib/mk/stdcxx/_:
|
||||
Standard C++ library
|
||||
|
||||
:'libports/lib/mk/mesa_api':
|
||||
:_libports/lib/mk/mesa_api/_:
|
||||
Mesa OpenGL API with backends for software rasterization (egl_swrast)
|
||||
and Intel Graphics (egl_i965)
|
||||
|
||||
:'libports/lib/mk/pthread':
|
||||
Subset of the POSIX thread and semaphore API.
|
||||
|
||||
:'libports/lib/mk/python':
|
||||
Runtime of the Python scripting language.
|
||||
|
||||
:'libports/lib/mk/mupdf':
|
||||
:_libports/lib/mk/mupdf/_:
|
||||
PDF rendering engine.
|
||||
|
||||
:'libports/lib/mk/sdl':
|
||||
Translates the libSDL API to framebuffer and input sessions.
|
||||
|
||||
:'libports/lib/mk/ncurses':
|
||||
:_libports/lib/mk/ncurses/_:
|
||||
Library for implementing pseudo-graphical applications (i.e., VIM) that
|
||||
run on a text terminal.
|
||||
|
||||
:'libports/lib/mk/avcodec':
|
||||
A library for video decoding, conversion, and streaming.
|
||||
:_libports/lib/mk/qt5_*/_:
|
||||
Qt5 framework, using GUI session and NIC session as back end.
|
||||
|
||||
:'libports/lib/mk/lua':
|
||||
Runtime for the Lua scripting language.
|
||||
|
||||
:'libports/lib/mk/qt5_*':
|
||||
Qt5 framework, using nitpicker session and NIC session as back end.
|
||||
|
||||
:'libports/lib/mk/vfs_jitterentropy.mk':
|
||||
:_libports/lib/mk/vfs_jitterentropy.mk_:
|
||||
A VFS plugin that makes a jitter-based random-number generator available
|
||||
as a file within the process-local VFS.
|
||||
|
||||
:_libports/lib/mk/libarchive.mk_:
|
||||
Library providing a common interface to a variety of archive
|
||||
formats.
|
||||
|
||||
:_libports/lib/mk/lz4.mk_:
|
||||
Library for processing LZ4 lossless compression archives.
|
||||
|
||||
:_libports/lib/mk/liblzma.mk_:
|
||||
Library for processing LZMA archives.
|
||||
|
||||
:_libports/lib/mk/libgcrypt.mk_:
|
||||
GnuPG library for OpenPGP processing, e.g., signature verification.
|
||||
|
||||
|
||||
Applications
|
||||
############
|
||||
|
||||
Applications are Genode components that use other component's services but
|
||||
usually do not provide services. They are typically located in the 'src/app/'
|
||||
usually do not provide services. They are typically located in the _src/app/_
|
||||
subdirectory of a repository. Most applications come with README files
|
||||
located in their respective directory.
|
||||
|
||||
:'gems/src/app/backdrop':
|
||||
Nitpicker client application that sets a composition of PNG images as
|
||||
desktop background.
|
||||
:_gems/src/app/backdrop/_:
|
||||
GUI client application that sets a composition of PNG images as desktop
|
||||
background.
|
||||
|
||||
:'demo/src/app/launchpad':
|
||||
:_demo/src/app/launchpad/_:
|
||||
Graphical application for interactively starting and killing subsystems.
|
||||
|
||||
:'gems/app/launcher': Graphical launcher of Genode subsystems.
|
||||
|
||||
:'os/app/cli_monitor': Command-line-based launcher of Genode subsystems.
|
||||
|
||||
:'demo/src/app/scout':
|
||||
:_demo/src/app/scout/_:
|
||||
Graphical hypertext browser used for Genode's default demonstration scenario.
|
||||
|
||||
:'libports/src/test/mesa_demo':
|
||||
Example programs for using the Mesa OpenGL graphics stack.
|
||||
|
||||
:'ports/src/app/arora':
|
||||
Arora is a Qt-based web browser using the Webkit engine.
|
||||
|
||||
:'ports/src/app/gdb_monitor':
|
||||
:_ports/src/app/gdb_monitor/_:
|
||||
Application that allows the debugging of a process via GDB over a remote
|
||||
connection.
|
||||
|
||||
:'libports/src/app/qt5/qt_launchpad':
|
||||
:_libports/src/app/qt5/qt_launchpad/_:
|
||||
Graphical application starter implemented using Qt.
|
||||
|
||||
:'libports/src/app/qt5/examples/':
|
||||
:_libports/src/app/qt5/examples/_:
|
||||
Several example applications that come with Qt.
|
||||
|
||||
:'os/src/app/sequence':
|
||||
:_os/src/app/sequence/_:
|
||||
Simple utility to serialize the execution of multiple components
|
||||
|
||||
:'ports/src/noux-pkg':
|
||||
:_ports/src/noux-pkg/_:
|
||||
Ports of popular commandline-based Unix software such as VIM, bash,
|
||||
coreutils, binutils, gcc, findutils, and netcat. The programs are supposed
|
||||
to be executed within the Noux runtime environment.
|
||||
|
||||
:'ports/src/app/lighttpd':
|
||||
:_ports/src/app/lighttpd/_:
|
||||
Lighttpd is a fast and feature-rich web server. The port of lighttpd uses
|
||||
a file-system session to access the website content and the web-server
|
||||
configuration.
|
||||
|
||||
:_os/src/app/trace_logger/_:
|
||||
Convenient, runtime-configurable frontend to the tracing facility.
|
||||
|
||||
:_os/src/app/rom_reporter/_:
|
||||
The ROM-reporter component requests a ROM session and reports the
|
||||
content of the ROM dataspace to a report session with the same label
|
||||
as the ROM session.
|
||||
|
||||
:_os/src/app/log_core/_:
|
||||
Component transforming core and kernel output to Genode LOG output.
|
||||
|
||||
|
||||
Package-management components
|
||||
=============================
|
||||
|
||||
:_gems/src/app/depot_query/_:
|
||||
Tool for querying subsystem information from a depot.
|
||||
|
||||
:_gems/src/app/depot_download_manager/_:
|
||||
Tool for managing the download of depot content.
|
||||
|
||||
:_gems/src/app/depot_deploy/_:
|
||||
Subsystem init configuration generator based on blueprints.
|
||||
|
||||
:_libports/src/app/fetchurl/_:
|
||||
A runtime-configurable frontend to the libcURL library for
|
||||
downloading content.
|
||||
|
||||
:_libports/src/app/extract/_:
|
||||
Tool for extracting archives using libarchive.
|
||||
|
||||
:_ports/src/app/verify/_:
|
||||
This component verifies detached OpenPGP signatures using libgcrypt.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
:'ports/src/noux': Noux is an experimental implementation of a UNIX-like API
|
||||
that enables the use of unmodified command-line based GNU software. For using
|
||||
noux, refer to the run script 'ports/run/noux.run'.
|
||||
|
||||
:'ports/src/app/seoul': Seoul is a virtual-machine monitor developed for
|
||||
:_ports/src/app/seoul/_: Seoul is a virtual-machine monitor developed for
|
||||
the use with the NOVA platform. It virtualizes 32bit x86 PC hardware
|
||||
including various peripherals.
|
||||
|
||||
:'os/src/server/loader': A service that allows the creation and destruction
|
||||
:_os/src/server/loader/_: A service that allows the creation and destruction
|
||||
of Genode subsystems via a session interface. For further information,
|
||||
refer to 'os/src/server/loader/README'.
|
||||
refer to _os/src/server/loader/README_.
|
||||
|
||||
:'ports/src/app/dosbox': A port of DosBox for executing DOS software.
|
||||
:_ports/src/virtualbox5/_: VirtualBox running on top of the NOVA hypervisor.
|
||||
|
||||
:'ports/src/virtualbox': VirtualBox running on top of the NOVA hypervisor.
|
||||
:_os/src/server/vmm/_: A virtual machine monitor that is based on
|
||||
hardware-assisted virtualization of ARM platforms. It is supported on
|
||||
the base-hw kernel only.
|
||||
|
||||
:_os/src/server/cpu_balancer/_: The CPU balancer intercepts the interaction
|
||||
of components with core's low-level services to migrate threads dynamically
|
||||
between CPU cores.
|
||||
|
||||
|
||||
@@ -131,21 +131,21 @@ Genode Contributors Agreement
|
||||
Before we will be able to incorporate your changes into Genode's mainline
|
||||
development, we require your permission to use your code.
|
||||
|
||||
Genode is publicly licensed under the terms of the GNU GPL with Genode Labs
|
||||
Genode is publicly licensed under the terms of the GNU AGPLv3 with Genode Labs
|
||||
maintaining the right to also distribute derivates under different licenses or
|
||||
update the public License (i.e., eventually switching from GPLv2 to GPLv3).
|
||||
update the public License.
|
||||
Contributions from outside Genode Labs can only be incorporated into Genode's
|
||||
mainline development if each individual contributor explicitly grants the
|
||||
permission to let Genode Labs redistribute his contributions under non-GPL
|
||||
permission to let Genode Labs redistribute his contributions under non-AGPLv3
|
||||
licenses. This permission is granted by signing the Genode Contributors
|
||||
Agreement:
|
||||
|
||||
:[http:gca.pdf - Genode Contributor's Agreement]:
|
||||
:[https://genode.org/community/gca.pdf - Genode Contributor's Agreement]:
|
||||
Genode Contributor's Agreement (GCA)
|
||||
|
||||
By signing the GCA, you don't lose any rights for your contribution. However,
|
||||
you enable Genode Labs to license Genode (including your contributions) under
|
||||
licenses other than the GPL. The GCA needs to be signed only once. The signed
|
||||
licenses other than the AGPLv3. The GCA needs to be signed only once. The signed
|
||||
GCA covers your future contributions. Of course, you may cancel this agreement
|
||||
at your will. Please make sure that you are in the legal position to sign
|
||||
the GCA (i.e., by making sure that your contribution to Genode is in line with
|
||||
|
||||
@@ -88,10 +88,10 @@ different kinds of content, each in a tailored and simple form. To avoid the
|
||||
clash of the notions of the common meaning of a "package", we speak of
|
||||
"archives" as the basic unit of delivery. The following subsections introduce
|
||||
the different categories.
|
||||
Archives are named with their version as suffix, appended via a dash. The
|
||||
Archives are named with their version as suffix, appended via a slash. The
|
||||
suffix is maintained by the author of the archive. The recommended naming
|
||||
scheme is the use of the release date as version suffix, e.g.,
|
||||
'report_rom-2017-05-14'.
|
||||
'report_rom/2017-05-14'.
|
||||
|
||||
|
||||
Raw-data archives
|
||||
@@ -141,9 +141,9 @@ called 'used_apis', which contains a list of API-archive names with each
|
||||
name on a separate line. For example, the 'used_apis' file of the 'report_rom'
|
||||
source archive looks as follows:
|
||||
|
||||
! base-2017-05-14
|
||||
! os-2017-05-13
|
||||
! report_session-2017-05-13
|
||||
! base/2017-05-14
|
||||
! os/2017-05-13
|
||||
! report_session/2017-05-13
|
||||
|
||||
The 'used_apis' file declares the APIs needed to incorporate into the build
|
||||
process when building the source archive. Hence, they represent _build-time_
|
||||
@@ -151,9 +151,9 @@ _dependencies_ on the specific API versions.
|
||||
|
||||
A source archive may be equipped with a top-level file called 'api' containing
|
||||
the name of exactly one API archive. If present, it declares that the source
|
||||
archive _implements_ the specified API. For example, the 'libc-2017-05-14'
|
||||
archive _implements_ the specified API. For example, the 'libc/2017-05-14'
|
||||
source archive contains the actual source code of the libc and libm as well as
|
||||
an 'api' file with the content 'libc-2017-04-13'. The latter refers to the API
|
||||
an 'api' file with the content 'libc/2017-04-13'. The latter refers to the API
|
||||
implemented by this version of the libc source package (note the differing
|
||||
versions of the API and source archives)
|
||||
|
||||
@@ -182,13 +182,13 @@ Package archive
|
||||
A package archive contains an 'archives' file with a list of archive names
|
||||
that belong together at runtime. Each listed archive appears on a separate line.
|
||||
For example, the 'archives' file of the package archive for the window
|
||||
manager 'wm-2017-05-31' looks as follows:
|
||||
manager 'wm/2018-02-26' looks as follows:
|
||||
|
||||
! genodelabs/raw/wm-2017-05-31
|
||||
! genodelabs/src/wm-2017-05-31
|
||||
! genodelabs/src/report_rom-2017-05-31
|
||||
! genodelabs/src/decorator-2017-05-31
|
||||
! genodelabs/src/floating_window_layouter-2017-05-31
|
||||
! genodelabs/raw/wm/2018-02-14
|
||||
! genodelabs/src/wm/2018-02-26
|
||||
! genodelabs/src/report_rom/2018-02-26
|
||||
! genodelabs/src/decorator/2018-02-26
|
||||
! genodelabs/src/floating_window_layouter/2018-02-26
|
||||
|
||||
In contrast to the list of 'used_apis' of a source archive, the content of
|
||||
the 'archives' file denotes the origin of the respective archives
|
||||
@@ -216,11 +216,11 @@ is structured as follows:
|
||||
|
||||
! <user>/pubkey
|
||||
! <user>/download
|
||||
! <user>/src/<name>-<version>/
|
||||
! <user>/api/<name>-<version>/
|
||||
! <user>/raw/<name>-<version>/
|
||||
! <user>/pkg/<name>-<version>/
|
||||
! <user>/bin/<arch>/<src-name>-<src-version>/
|
||||
! <user>/src/<name>/<version>/
|
||||
! <user>/api/<name>/<version>/
|
||||
! <user>/raw/<name>/<version>/
|
||||
! <user>/pkg/<name>/<version>/
|
||||
! <user>/bin/<arch>/<src-name>/<src-version>/
|
||||
|
||||
The <user> stands for the origin of the contained archives. For example, the
|
||||
official archives provided by Genode Labs reside in a _genodelabs/_
|
||||
@@ -231,7 +231,7 @@ from the user. The file 'download' specifies the download location as an URL.
|
||||
Subsuming archives in a subdirectory that correspond to their the origin
|
||||
(user) serves two purposes. First, it provides a user-local name space for
|
||||
versioning archives. E.g., there might be two versions of a
|
||||
'nitpicker-2017-04-15' source archive, one by "genodelabs" and one by
|
||||
'nitpicker/2017-04-15' source archive, one by "genodelabs" and one by
|
||||
"nfeske". However, since each version resides under its origin's subdirectory,
|
||||
version-naming conflicts between different origins cannot happen. Second, by
|
||||
allowing multiple archive origins in the depot side-by-side, package archives
|
||||
@@ -282,7 +282,7 @@ corresponding user subdirectory must contain two files:
|
||||
If both the public key and the download locations are defined, the download
|
||||
tool can be used as follows:
|
||||
|
||||
! ./tool/depot/download genodelabs/src/zlib-2017-05-31
|
||||
! ./tool/depot/download genodelabs/src/zlib/2018-01-10
|
||||
|
||||
The tool automatically downloads the specified archives and their
|
||||
dependencies. For example, as the zlib depends on the libc API, the libc API
|
||||
@@ -294,7 +294,7 @@ all binary archives for the 32-bit x86 architecture. Downloaded binary
|
||||
archives are always accompanied with their corresponding source and used API
|
||||
archives.
|
||||
|
||||
! ./tool/depot/download genodelabs/pkg/x86_32/wm-2017-05-31
|
||||
! ./tool/depot/download genodelabs/pkg/x86_64/wm/2018-02-26
|
||||
|
||||
Archive content is not downloaded directly to the depot. Instead, the
|
||||
individual archives and signature files are downloaded to a quarantine area in
|
||||
@@ -321,14 +321,14 @@ CPU architecture. For example, the following command builds the 'zlib'
|
||||
library for the 64-bit x86 architecture. It executes four concurrent jobs
|
||||
during the build process.
|
||||
|
||||
! ./tool/depot/build genodelabs/bin/x86_64/zlib-2017-05-31 -j4
|
||||
! ./tool/depot/build genodelabs/bin/x86_64/zlib/2018-01-10 -j4
|
||||
|
||||
Note that the command expects a specific version of the source archive as
|
||||
argument. The depot may contain several versions. So the user has to decide,
|
||||
which one to build.
|
||||
|
||||
After the tool is finished, the freshly built binary archive can be found in
|
||||
the depot within the _genodelabs/bin/<arch>/<src>-<version>/_ subdirectory.
|
||||
the depot within the _genodelabs/bin/<arch>/<src>/<version>/_ subdirectory.
|
||||
Only the final result of the built process is preserved. In the example above,
|
||||
that would be the _zlib.lib.so_ library.
|
||||
|
||||
@@ -339,7 +339,7 @@ found besides the binary archive's location named with a '.build' suffix.
|
||||
|
||||
By default, the build tool won't attempt to rebuild a binary archive that is
|
||||
already present in the depot. However, it is possible to force a rebuild via
|
||||
the 'FORCE=1' argument.
|
||||
the 'REBUILD=1' argument.
|
||||
|
||||
|
||||
Publishing archives
|
||||
@@ -358,28 +358,33 @@ be present in the key ring of your GNU privacy guard.
|
||||
To publish archives, one needs to specify the specific version to publish.
|
||||
For example:
|
||||
|
||||
! ./tool/depot/publish <you>/pkg/wm-2017-05-31
|
||||
! ./tool/depot/publish <you>/pkg/x86_64/wm/2018-02-26
|
||||
|
||||
The command checks that the specified archive and all dependencies are present
|
||||
in the depot. It then proceeds with the archiving and signing operations. For
|
||||
the latter, the pass phrase for your private key will be requested. The
|
||||
publish tool prints the information about the processed archives, e.g.:
|
||||
|
||||
! publish /.../genode/public/<you>/pkg/wm-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/src/decorator-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/src/floating_window_layouter-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/src/report_rom-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/src/wm-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/raw/wm-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/base-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/framebuffer_session-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/gems-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/input_session-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/nitpicker_gfx-2017-04-24.tgz
|
||||
! publish /.../genode/public/<you>/api/nitpicker_session-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/os-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/report_session-2017-05-30.tgz
|
||||
! publish /.../genode/public/<you>/api/scout_gfx-2017-04-24.tgz
|
||||
! publish /.../public/<you>/api/base/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/api/framebuffer_session/2017-05-31.tar.xz
|
||||
! publish /.../public/<you>/api/gems/2018-01-28.tar.xz
|
||||
! publish /.../public/<you>/api/input_session/2018-01-05.tar.xz
|
||||
! publish /.../public/<you>/api/nitpicker_gfx/2018-01-05.tar.xz
|
||||
! publish /.../public/<you>/api/nitpicker_session/2018-01-05.tar.xz
|
||||
! publish /.../public/<you>/api/os/2018-02-13.tar.xz
|
||||
! publish /.../public/<you>/api/report_session/2018-01-05.tar.xz
|
||||
! publish /.../public/<you>/api/scout_gfx/2018-01-05.tar.xz
|
||||
! publish /.../public/<you>/bin/x86_64/decorator/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/bin/x86_64/floating_window_layouter/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/bin/x86_64/report_rom/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/bin/x86_64/wm/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/pkg/wm/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/raw/wm/2018-02-14.tar.xz
|
||||
! publish /.../public/<you>/src/decorator/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/src/floating_window_layouter/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/src/report_rom/2018-02-26.tar.xz
|
||||
! publish /.../public/<you>/src/wm/2018-02-26.tar.xz
|
||||
|
||||
|
||||
According to the output, the tool populates a directory called _public/_
|
||||
at the root of the Genode source tree with the to-be-published archives.
|
||||
@@ -474,6 +479,15 @@ updates hash files of the involved recipes by taking the current date as
|
||||
version name. This is a valuable assistance in situations where a commonly
|
||||
used API changes. In this case, the versions of the API and all dependent
|
||||
archives must be increased, which would be a labour-intensive task otherwise.
|
||||
If the depot already contains an archive of the current version, the create
|
||||
tools won't re-create the depot archive by default. Local modifications of
|
||||
the source code in the repository do not automatically result in a new archive.
|
||||
To ensure that the depot archive is current, one can specify 'FORCE=1' to
|
||||
the create tool. With this argument, existing depot archives are replaced by
|
||||
freshly extracted ones and version updates are detected. When specified for
|
||||
creating binary archives, 'FORCE=1' normally implies 'REBUILD=1'. To prevent
|
||||
the superfluous rebuild of binary archives whose source versions remain
|
||||
unchanged, 'FORCE=1' can be combined with the argument 'REBUILD='.
|
||||
|
||||
|
||||
Accessing depot content from run scripts
|
||||
|
||||
@@ -25,7 +25,7 @@ that your system satisfies the following requirements:
|
||||
* 'libSDL-dev'
|
||||
* 'tclsh' and 'expect'
|
||||
* 'byacc' (only needed for the L4/Fiasco kernel)
|
||||
* 'qemu' and 'genisoimage' (for testing non-Linux platforms via Qemu)
|
||||
* 'qemu' and 'xorriso' (for testing non-Linux platforms via Qemu)
|
||||
|
||||
For using the entire collection of ported 3rd-party software, the following
|
||||
packages should be installed additionally: 'autoconf2.64', 'autogen', 'bison',
|
||||
@@ -44,18 +44,32 @@ build directory yet. For a quick start, let us create one for the Linux base
|
||||
platform:
|
||||
|
||||
! cd <genode-dir>
|
||||
! ./tool/create_builddir linux_x86 BUILD_DIR=build.lx
|
||||
! ./tool/create_builddir x86_64
|
||||
|
||||
The new build directory is called 'build.lx' and configured for the 'linux_x86'
|
||||
platform. To give Genode a try, build and execute a simple demo scenario via:
|
||||
This creates a new build directory for building x86_64 binaries in './build'.
|
||||
The build system creates unified binaries that work on the given
|
||||
architecture independent from the underlying base platform, in this case Linux.
|
||||
|
||||
! cd build.lx
|
||||
! make run/demo
|
||||
Now change into the fresh build directory:
|
||||
|
||||
! cd build/x86_64
|
||||
|
||||
Please uncomment the following line in 'etc/build.conf' to make the
|
||||
build process as smooth as possible.
|
||||
|
||||
! RUN_OPT += --depot-auto-update
|
||||
|
||||
To give Genode a try, build and execute a simple demo scenario via:
|
||||
|
||||
! make KERNEL=linux BOARD=linux run/demo
|
||||
|
||||
By invoking 'make' with the 'run/demo' argument, all components needed by the
|
||||
demo scenario are built and the demo is executed. If you are interested in
|
||||
looking behind the scenes of the demo scenario, please refer to
|
||||
'doc/build_system.txt' and the run script at 'os/run/demo.run'.
|
||||
demo scenario are built and the demo is executed. This includes all components
|
||||
which are implicitly needed by the base platform. The base platform that the
|
||||
components will be executed upon on is selected via the 'KERNEL' and 'BOARD'
|
||||
variables. If you are interested in looking behind the scenes of the demo
|
||||
scenario, please refer to 'doc/build_system.txt' and the run script at
|
||||
'os/run/demo.run'.
|
||||
|
||||
|
||||
Using platforms other than Linux
|
||||
@@ -85,10 +99,16 @@ tool:
|
||||
|
||||
! ./tool/ports/prepare_port x86emu
|
||||
|
||||
On x86 base platforms the GRUB2 boot loader is required and can be
|
||||
downloaded and prepared by invoking:
|
||||
|
||||
! ./tool/ports/prepare_port grub2
|
||||
|
||||
Now that the base platform is prepared, the 'create_builddir' tool can be used
|
||||
to create a build directory for your platform of choice by giving the platform
|
||||
as argument. To see the list of available platforms, execute 'create_builddir'
|
||||
with no arguments.
|
||||
to create a build directory for your architecture of choice by giving the
|
||||
architecture as argument. To see the list of available architecture, execute
|
||||
'create_builddir' with no arguments. Note, that not all kernels support all
|
||||
architectures.
|
||||
|
||||
For example, to give the demo scenario a spin on the OKL4 kernel, the following
|
||||
steps are required:
|
||||
@@ -97,13 +117,15 @@ steps are required:
|
||||
! cd <genode-dir>
|
||||
! ./tool/ports/prepare_port okl4
|
||||
# Create a build directory
|
||||
! ./tool/create_builddir okl4_x86 BUILD_DIR=build.okl4
|
||||
# Uncomment the following line in 'build.okl4/etc/build.conf'
|
||||
! ./tool/create_builddir x86_32
|
||||
# Uncomment the following line in 'x86_32/etc/build.conf'
|
||||
! REPOSITORIES += $(GENODE_DIR)/repos/libports
|
||||
# Build and execute the demo using Qemu
|
||||
! make -C build.okl4 run/demo
|
||||
! make -C build/x86_32 KERNEL=okl4 BOARD=pc run/demo
|
||||
|
||||
The procedure works analogously for the other base platforms.
|
||||
The procedure works analogously for the other base platforms. You can, however,
|
||||
reuse the already created build directory and skip its creation step if the
|
||||
architecture matches.
|
||||
|
||||
|
||||
How to proceed with exploring Genode
|
||||
|
||||
1006
doc/news.txt
1006
doc/news.txt
File diff suppressed because it is too large
Load Diff
@@ -1,830 +0,0 @@
|
||||
|
||||
|
||||
==============================================
|
||||
Release notes for the Genode OS Framework 8.11
|
||||
==============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
Summary
|
||||
#######
|
||||
|
||||
This document presents the new features and major changes introduced
|
||||
in version 8.11 of the Genode OS Framework. It is geared towards
|
||||
people interested in closely following the progress of the Genode
|
||||
project and to developers who want to adopt their software to our
|
||||
mainline development. The document aggregates important fragments
|
||||
of the updated documentation such that you won't need to scan existing
|
||||
documents for the new bits. Furthermore, it attempts to provide our
|
||||
rationale behind the taken design decisions.
|
||||
|
||||
The general theme for the release 8.11 is enabling the use of the
|
||||
Genode OS framework for real-world applications. Because we regard
|
||||
the presence of device drivers and a way to reuse existing library
|
||||
code as fundamental prerequisites for achieving this goal, the major
|
||||
new additions are an API for device drivers written in C, an API for
|
||||
handling asynchronous notifications, and a C runtime. Other noteworthy
|
||||
improvements are the typification of capabilities at the C++-language
|
||||
level, a way for receiving and handling application faults, the
|
||||
introduction of managed dataspaces, and a new API for scheduling
|
||||
timed events.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
This section documents the new features and changes affecting the
|
||||
'base' repository, in particular the base API.
|
||||
|
||||
|
||||
New features
|
||||
============
|
||||
|
||||
Connection handling
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The interaction of a client with a server involves the definition of
|
||||
session-construction arguments, the request of the session creation via
|
||||
its parent, the initialization of the matching RPC-client stub code
|
||||
with the received session capability, the actual use of the session
|
||||
interface, and the closure of the session. A typical procedure of
|
||||
using a service looks like this:
|
||||
|
||||
!#include <rom_session/client.h>
|
||||
!...
|
||||
!
|
||||
!/* construct session-argument string and create session */
|
||||
!char *args = "filename=config, ram_quota=4K");
|
||||
!Capability session_cap = env()->parent()->session("ROM", args);
|
||||
!
|
||||
!/* initialize RPC stub code */
|
||||
!Rom_session_client rsc(session_cap);
|
||||
!
|
||||
!/* invoke remote procedures, 'dataspace' is a RPC function */
|
||||
!Capability ds_csp = rsc.dataspace();
|
||||
!...
|
||||
!
|
||||
!/* call parent to close the session */
|
||||
!env()->parent()->close(session_cap);
|
||||
|
||||
Even though this procedure does not seem to be overly complicated,
|
||||
is has raised the following questions and criticism:
|
||||
|
||||
* The quota-donation argument is specific for each server. Most services
|
||||
use client-donated RAM quota only for holding little meta data and,
|
||||
thus, are happy with a donation of 4KB. Other services maintain larger
|
||||
client-specific state and require higher RAM-quota donations. The
|
||||
developer of a client has to be aware about the quota requirements for
|
||||
each service used by his application.
|
||||
|
||||
* There exists no formalism for documenting session arguments.
|
||||
|
||||
* Because session arguments are passed to the 'session'-call as a plain
|
||||
string, there are no syntax checks for the assembled string performed
|
||||
at compile time. For example, a missing comma would go undetected until
|
||||
a runtime test is performed.
|
||||
|
||||
* There are multiple lines of client code needed to open a session to
|
||||
a service and the session capability must be maintained manually for
|
||||
closing the session later on.
|
||||
|
||||
The new 'Connection' template provides a way to greatly simplify the
|
||||
handling of session arguments, session creation, and destruction on the
|
||||
client side. By implementing a service-specific connection class
|
||||
inherited from 'Connection', session arguments become plain constructor
|
||||
arguments, session functions can be called directly on the 'Connection'
|
||||
object, and the session gets properly closed when destructing the
|
||||
'Connection'. By convention, the 'Connection' class corresponding to a
|
||||
service resides in a file called 'connection.h' in the directory of the
|
||||
service's RPC interface. For each service, a corresponding 'Connection'
|
||||
class becomes the natural place where session arguments and quota
|
||||
donations are documented. With this new mechanism in place, the example
|
||||
above becomes as simple as:
|
||||
|
||||
!#include <rom_session/connection.h>
|
||||
!...
|
||||
!
|
||||
!/* create connection to the ROM service */
|
||||
!Rom_connection rom("config");
|
||||
!
|
||||
!/* invoke remote procedure */
|
||||
!Capability ds_csp = rom.dataspace();
|
||||
|
||||
[http://genode.org/documentation/api/base_index#Connecting_to_services - See the API documentation for the connection template...]
|
||||
|
||||
|
||||
Typed capabilities
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A plain 'Capability' is an untyped reference to a remote object of any
|
||||
type. For example, a capability can reference a thread object or a
|
||||
session to a service. It is loosely similar to a C void pointer, for which
|
||||
the programmer maintains the knowledge about which data type is actually
|
||||
referenced. To facilitate the type-safe use of RPC interfaces at the C++
|
||||
language level, we introduced a template for creating specialized
|
||||
capability types ('Typed_capability' in 'base/typed_capability.h') and
|
||||
the convention that each RPC interface declares a dedicated capability
|
||||
type. Note that type-safety is not maintained across RPC interfaces. As
|
||||
illustrated in Figure [layered_ipc], typification is done at the
|
||||
object-framework level on the server side and via in the 'Connection'
|
||||
classes at the client side.
|
||||
|
||||
[image layered_ipc]
|
||||
|
||||
From the application-developer's perspective, working with capabilities
|
||||
has now become type-safe, making the produced code more readable and robust.
|
||||
|
||||
[http://genode.org/documentation/api/base_index#Capability_representation - See the updated API documentation for the capability representation...]
|
||||
|
||||
|
||||
Fifo data structure
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Because the 'List' data type inserts new list elements at the list head,
|
||||
it cannot be used for implementing wait queues requiring first-in
|
||||
first-out semantics. For such use cases, we introduced a dedicated
|
||||
'Fifo' template. The main motivation for introducing 'Fifo' into the
|
||||
base API is the new semaphore described below.
|
||||
|
||||
[http://genode.org/documentation/api/base_index#Structured_data_types - See the new API documentation for the fifo template...]
|
||||
|
||||
|
||||
Semaphore
|
||||
~~~~~~~~~
|
||||
|
||||
Alongside lock-based mutual exclusion of entering critical sections,
|
||||
organizing threads in a producer-consumer relationship via a semaphore
|
||||
is a common design pattern for thread synchronization. Prior versions
|
||||
of Genode provided a preliminary semaphore implementation as part of
|
||||
the 'os' repository. This implementation, however, supported only one
|
||||
consumer thread (caller of the semaphore's 'down' function). We have
|
||||
now enhanced our implementation to support multiple consumer threads
|
||||
and added the semaphore to Genode's official base API. We have made
|
||||
the wake-up policy in the presence of multiple consumers configurable
|
||||
via a template argument. The default policy is first-in-first-out.
|
||||
|
||||
[http://genode.org/documentation/api/base_index#Synchronization - See the new API documentation for the semaphore...]
|
||||
|
||||
Thanks to Christian Prochaska for his valuable contributions to the new
|
||||
semaphore design.
|
||||
|
||||
|
||||
Asynchronous notifications
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Inter-process communication via remote procedure calls requires both
|
||||
communication partners to operate in a synchronous fashion. The caller
|
||||
of an RPC blocks as long as the RPC is not answered by the called
|
||||
server. In order to receive the call, the server has to explicitly
|
||||
wait for incoming messages. There are a number of situations where
|
||||
synchronous communication is not suited.
|
||||
|
||||
For example, a GUI server wants to deliver a notification to one of its
|
||||
clients about new input events being available. It does not want to
|
||||
block on a RPC to one specific client because it has work to do for
|
||||
other clients. Instead, the GUI server wants to deliver this
|
||||
_notification_ with _fire-and-forget_ semantics and continue with
|
||||
its operation immediately, regardless of whether the client received
|
||||
the notification or not. The client, in turn, does not want to poll
|
||||
for new input events at the GUI server but it wants to be _waken_up_
|
||||
when something interesting happens. Another example is a block-device
|
||||
driver that accepts many requests for read/write operations at once.
|
||||
The operations may be processed out of order and may take a long time.
|
||||
When having only synchronous communication available, the client and
|
||||
the block device driver would have to employ one distinct thread for
|
||||
each request, which is complicated and a waste of resources. Instead,
|
||||
the block device driver just wants to acknowledge the completeness of
|
||||
an operation _asynchronously_.
|
||||
|
||||
Because there are many more use cases for asynchronous inter-process
|
||||
communication, we introduced a new signalling framework that complements
|
||||
the existing synchronous RPC mode of communication with an interface for
|
||||
issuing and receiving asynchronous notifications. It defines interfaces
|
||||
for signal transmitters and signal receivers. A signal receiver can
|
||||
receive signals from multiple sources, whereas the sources of incoming
|
||||
signals are clearly distinguishable. One or multiple threads can either
|
||||
poll or block for incoming signals. Each signal receiver is addressable
|
||||
via a capability. The signal transmitter provides fire-and-forget
|
||||
semantics for submitting signals to exactly one signal receiver. Signals
|
||||
are communicated in a reliable fashion, which means that the exact number
|
||||
of signals submitted to a signal transmitter is communicated to the
|
||||
corresponding signal receiver. If notifications are generated at a higher
|
||||
rate than as they can be processed at the receiver, the transmitter
|
||||
counts the notifications and delivers the total amount with the next
|
||||
signal transmission. This way, the total number of notifications gets
|
||||
properly communicated to the receiver even if the receiver is not highly
|
||||
responsive. Notifications do not carry any payload because this payload
|
||||
would have to be queued at the transmitter.
|
||||
|
||||
[image signals]
|
||||
|
||||
Image [signals] illustrates the roles of signaller thread,
|
||||
transmitter, receiver, and signal-handler thread.
|
||||
|
||||
[http://genode.org/documentation/api/base_index#Asynchronous_notifications - See the new API documentation for asynchronous notifications...]
|
||||
|
||||
The current generic implementation of the signalling API employs one
|
||||
thread at each transmitter and one thread at each receiver. Because
|
||||
the used threads are pretty heavy weight with regard to resource usage,
|
||||
ports of Genode should replace this implementation with platform-
|
||||
specific variants, for example by using inter-process semaphores or
|
||||
native kernel support for signals.
|
||||
|
||||
|
||||
Region-manager faults
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In Genode, region-manager (RM) sessions are used to manage the
|
||||
address-space layout for processes. A RM session is an address-space
|
||||
layout that can be populated by attaching (portions of) dataspaces to
|
||||
(regions of) the RM session. Normally, the RM session of a process is
|
||||
first configured by the parent when decoding the process' ELF binary.
|
||||
During the lifetime of the process, the process itself may attach
|
||||
further dataspaces to its RM session to access the dataspace's content.
|
||||
Core as the provider of the RM service uses this information for
|
||||
resolving page faults raised by the process. In prior versions of
|
||||
Genode, core ignored unresolvable page faults, printed a debug message
|
||||
and halted the page-faulted thread. However, this condition may be of
|
||||
interest, in particular to the process' parent for reacting on the
|
||||
condition of a crashed child process. Therefore, we enhanced the RM
|
||||
interface by a fault-handling mechanism. For each RM session, a fault
|
||||
handler can be installed by registering a signal receiver capability.
|
||||
If an unresolvable page fault occurs, core delivers a signal to the
|
||||
registered fault handler. The fault handler, in turn, can request the
|
||||
actual state of the RM session (page-fault address) and react upon
|
||||
the fault. One possible reaction is attaching a new dataspace at the
|
||||
fault address and thereby implicitly resolving the fault. If core
|
||||
detects that a fault is resolved this way, it resumes the operation
|
||||
of the faulted thread.
|
||||
|
||||
This mechanism works analogously to how page faults are handled by
|
||||
CPUs, but on a more abstract level. A (n-level) page table corresponds
|
||||
to a RM session, a page-table entry corresponds to a dataspace-
|
||||
attachment, the RM-fault handler corresponds to a page-fault
|
||||
exception handler, and the resolution of page-faults (RM fault)
|
||||
follows the same basic scheme:
|
||||
|
||||
# Application accesses memory address with no valid page-table-entry
|
||||
(RM fault)
|
||||
# CPU generates page-fault exception (core delivers signal to fault
|
||||
handler)
|
||||
# Kernel reads exception-stack frame or special register to determine
|
||||
fault address (RM-fault handler reads RM state)
|
||||
# Kernel adds a valid page-table entry and returns from exception
|
||||
(RM-fault handler attaches dataspace to RM session, core resumes
|
||||
faulted thread)
|
||||
|
||||
The RM-fault mechanism is not only useful for detecting crashing child
|
||||
processes but it enables a straight-forward implementation of growing
|
||||
stacks and heap transparently for a child process. An example for
|
||||
using RM-faults is provided at 'base/src/test/rm_fault'.
|
||||
|
||||
Note that this mechanism is only available on platforms on which core
|
||||
resolves page faults. This is the case for kernels of the L4 family.
|
||||
On Linux however, the Linux kernel resolves page faults and suspends
|
||||
processes performing unresolvable memory accesses (segmentation fault).
|
||||
|
||||
|
||||
Managed dataspaces (experimental)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The RM-fault mechanism clears the way for an exciting new feature
|
||||
of Genode 8.11 called managed dataspaces. In prior versions of Genode,
|
||||
each dataspace referred to a contiguous area of physical memory (or
|
||||
memory-mapped I/O) obtained by one of core's RAM, ROM, or IO_MEM
|
||||
services, hence we call them physical dataspaces. We have now added
|
||||
a second type of dataspaces called managed dataspaces. In contrast
|
||||
to a physical dataspace, a managed dataspace is backed by the content
|
||||
described by an RM session. In fact, each RM session can be used as
|
||||
dataspace and can thereby be attached to other RM sessions.
|
||||
|
||||
Combined with the RM fault mechanism described above, managed
|
||||
dataspaces enable a new realm of applications such as dataspaces
|
||||
entirely managed by user-level services, copy-on-write dataspaces,
|
||||
non-contiguous large memory dataspaces that are immune to physical
|
||||
memory fragmentation, process-local RM fault handlers (e.g., managing
|
||||
the own thread-stack area as a sub-RM-session), and sparsely populated
|
||||
dataspaces.
|
||||
|
||||
Current limitations
|
||||
-------------------
|
||||
|
||||
Currently, managed dataspaces still have two major limitations. First,
|
||||
this mechanism allows for creating cycles of RM sessions. Core must
|
||||
detect such cycles during page-fault resolution. Although, a design for
|
||||
an appropriate algorithm exists, cycle-detection is not yet implemented.
|
||||
The missing cycle detection would enable a malicious process to force
|
||||
core into an infinite loop. Second, RM faults are implemented using the
|
||||
new signalling framework. With the current generic implementation, RM
|
||||
sessions are far more resource-demanding than they should be. Once the
|
||||
signalling framework is optimized for L4, RM sessions and thereby
|
||||
managed dataspaces will become cheap. Until then, we do not recommend
|
||||
to put this mechanism to heavy use.
|
||||
|
||||
Because of these current limitations, managed dataspaces are marked as
|
||||
an experimental feature. When building Genode, experimental features are
|
||||
disabled by default. To enable them, add a file called 'specs.conf'
|
||||
with the following content to the 'etc/' subdirectory of your build
|
||||
directory:
|
||||
|
||||
! SPECS += experimental
|
||||
|
||||
For an example of how to use the new mechanism to manage a part of a
|
||||
process' own address space by itself, you may take a look at
|
||||
'base/src/test/rm_nested'.
|
||||
|
||||
|
||||
Changes
|
||||
=======
|
||||
|
||||
Besides the addition of the new features described above, the following
|
||||
parts of the base framework underwent changes worth describing.
|
||||
|
||||
|
||||
Consistent use of typed capabilities and connection classes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We applied capability typification to all interfaces of Genode including
|
||||
the base API and the interfaces defined in the 'os' repository. Figure
|
||||
[base_cap_types] provides an overview about the capability types
|
||||
provided by the base API.
|
||||
|
||||
[image base_cap_types]
|
||||
Overview about the capability types provided by the base API
|
||||
|
||||
Furthermore, we have complemented all session interfaces with
|
||||
appropriate 'Connection' classes taking service-specific session
|
||||
arguments into account.
|
||||
|
||||
For session-interface classes, we introduced the convention to declare
|
||||
the service name as part of the session-interface via a static member
|
||||
function:
|
||||
! static const char *service_name();
|
||||
|
||||
|
||||
Allocator refinements
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Throughout Genode, allocators are not only used for allocating memory
|
||||
but also for managing address-space layouts and ranges of physical
|
||||
resources such as I/O-port ranges or IRQ ranges. In these cases, the
|
||||
address '0' may be a valid value. Consequently, this value cannot be
|
||||
used to signal allocation errors as done in prior versions of Genode.
|
||||
Furthermore, because managed dataspaces use the RM session interface to
|
||||
define the dataspace layout, the address-'0' problem applies here as
|
||||
well. We have now refined our allocator interfaces and the RM-session
|
||||
interface to make them fit better for problems other than managing
|
||||
virtual memory.
|
||||
|
||||
|
||||
Misc changes
|
||||
~~~~~~~~~~~~
|
||||
|
||||
We revised all interfaces to consistently use _exceptions_ to signal
|
||||
error conditions rather than delivering error codes as return values.
|
||||
This way, error codes become exception types that have a meaningful
|
||||
name and, in contrast to global 'errno' definitions, an error exception
|
||||
type can be defined local to the interface it applies to. Furthermore,
|
||||
the use of exceptions allows for creating much cleaner looking interfaces.
|
||||
|
||||
Traditionally, we have provided our custom _printf_ implementation as C
|
||||
symbol to make this function available from both C and C++ code. However,
|
||||
we observed that we never called this function from C code and that the
|
||||
'printf' symbol conflicts with the libc. Hence, we turned 'printf'
|
||||
into a C++ symbol residing in the 'Genode' namespace.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
This section documents the new features and changes affecting
|
||||
the 'os' repository.
|
||||
|
||||
New Features
|
||||
============
|
||||
|
||||
Device-driver framework for C device drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Genode's base API features everything needed to create user-level device
|
||||
drivers. For example, the 'os' repository's PS/2 input driver and the
|
||||
PCI bus driver are using Genode's C++ base API directly. However, most of
|
||||
today's device drivers are written in C. To ease the reuse of existing
|
||||
drivers on Genode, we have introduced a C API for device drivers into
|
||||
Genode's 'os' repository. The API is called DDE kit (DDE is an acronym
|
||||
for device-driver environment) and it is located at 'os/include/dde_kit'.
|
||||
|
||||
The DDE kit API is the result of long-year experiences with porting device
|
||||
drivers from Linux and FreeBSD to custom OS environments. The following
|
||||
references are the most significant contributions to the development of
|
||||
the API.
|
||||
;
|
||||
Christian Helmuth created the initial version of the Linux device-driver
|
||||
environment for L4. He describes his effort of reusing unmodified sound
|
||||
drivers on the L4 platform in his thesis
|
||||
[http://os.inf.tu-dresden.de/papers_ps/helmuth-diplom.pdf - Generische Portierung von Linux-Gerätetreibern auf die DROPS-Architektur].
|
||||
;
|
||||
Gerd Griessbach approached the problem of re-using Linux USB drivers
|
||||
by following the DDE approach in his diploma thesis
|
||||
[http://os.inf.tu-dresden.de/papers_ps/griessbach-diplom.pdf - USB for DROPS].
|
||||
;
|
||||
Marek Menzer adapted Linux DDE to Linux 2.6 and explored the DDE
|
||||
approach for block-device drivers in his student research project
|
||||
[http://os.inf.tu-dresden.de/papers_ps/menzer-beleg.pdf - Portierung des DROPS Device Driver Environment (DDE) für Linux 2.6 am Beispiel des IDE-Treibers ]
|
||||
and his diploma thesis
|
||||
[http://os.inf.tu-dresden.de/papers_ps/menzer-diplom.pdf - Entwicklung eines Blockgeräte-Frameworks für DROPS].
|
||||
;
|
||||
Thomas Friebel generalized the DDE approach and introduced the DDE kit
|
||||
API to enable the re-use of device driver from other platforms than
|
||||
Linux. In particular, he experimented with the block-device drivers of
|
||||
FreeBSD in his diploma thesis
|
||||
[http://os.inf.tu-dresden.de/papers_ps/friebel-diplom.pdf - Übertragung des Device-Driver-Environment-Ansatzes auf Subsysteme des BSD-Betriebssystemkerns].
|
||||
;
|
||||
Dirk Vogt successfully re-approached the port of USB device drivers
|
||||
from the Linux kernel to L4 in his student research project
|
||||
[http://os.inf.tu-dresden.de/papers_ps/beleg-vogt.pdf - USB for the L4 Environment].
|
||||
|
||||
The current incarnation of the DDE kit API provides the following
|
||||
features:
|
||||
|
||||
* General infrastructure such as init calls, assertions, debug output
|
||||
* Interrupt handling (attach, detach, disable, enable)
|
||||
* Locks, semaphores
|
||||
* Memory management (slabs, malloc)
|
||||
* PCI access (find device, access device config space)
|
||||
* Virtual page tables (translation between physical and virtual
|
||||
addresses)
|
||||
* Memory-mapped I/O, port I/O
|
||||
* Multi-threading (create, exit, thread-local storage, sleep)
|
||||
* Timers, jiffies
|
||||
|
||||
For Genode, we have created a complete reimplementation of the DDE kit
|
||||
API from scratch by fully utilizing the existing Genode infrastructure
|
||||
such as the available structured data types, core's I/O services,
|
||||
the synchronization primitives, and the thread API.
|
||||
|
||||
[image dde_kit]
|
||||
|
||||
Figure [dde_kit] illustrates the role of DDE kit when re-using an
|
||||
unmodified device driver taken from the Linux kernel. DDE kit translates
|
||||
Genode's C++ base API to the DDE kit C API. The DDE kit API, in turn, is
|
||||
used as back end by the Linux driver environment, which translates Linux
|
||||
kernel interfaces to calls into DDE kit. With this translation in place,
|
||||
an unmodified Linux device driver can be embedded into the Linux driver
|
||||
environment. The device API is specific for a class of devices such as
|
||||
NICs, block devices, or input devices. It can either be used directly as
|
||||
a function interface by an application that is using the device driver
|
||||
as a library, or it can be made accessible to external processes via an
|
||||
RPC interface.
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
The PCI sub system is not completely implemented, yet.
|
||||
|
||||
|
||||
Alarm API providing a timed event scheduler
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The scheduling of timed events is a recurring pattern found in device
|
||||
drivers, application frameworks such as Qt4 ('qeventdispatcher'), and
|
||||
applications. Therefore, we have added a timed event scheduler to the
|
||||
'os' repository. The new alarm API ('os/include/os/alarm.h') allows
|
||||
for the scheduling of both one-shot alarms and periodic alarms.
|
||||
|
||||
|
||||
Changes
|
||||
=======
|
||||
|
||||
PS/2 input driver
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The original PS/2 driver tried to switch the PS/2 keyboard to
|
||||
scan-code set 2 and assumed that all modern keyboards support this
|
||||
mode of operation. However, this assumption was wrong. We observed
|
||||
that the legacy PS/2 support of some USB keyboards covers only the
|
||||
emulated (xlate) scan-code set 1 mode. This is also case for the PS/2
|
||||
emulation in VirtualBox. Therefore, we changed our PS/2 driver to
|
||||
never touch the keyboard mode but to only detect the current mode
|
||||
of operation. The driver has now to support both, scan-code set 1 and
|
||||
scan-code set 2. This change comes along with a slightly more complex
|
||||
state machine in the driver. Hence, we moved the state machine from
|
||||
the IRQ handler to a distinct class and changed the control flow of
|
||||
the driver to fetch only one value from the i8042 PS/2 controller
|
||||
per received interrupt.
|
||||
|
||||
|
||||
PCI bus driver
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Until now, Genode's PCI bus driver was only used for experimentation
|
||||
purposes. With the forthcoming driver framework however, the PCI bus
|
||||
driver will play a central role in the system. Therefore, we adapted
|
||||
the interface of the PCI driver to these requirements. Specifically,
|
||||
the scanning of the PCI bus can now be performed without constraining
|
||||
the results by a specific vendor ID.
|
||||
|
||||
|
||||
Nitpicker GUI server
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We improved the _output_latency_ of the Nitpicker GUI server by flushing
|
||||
pixels eagerly and deferring the next periodically scheduled flush.
|
||||
This change has a positive effect on the responsiveness of the GUI to
|
||||
user input.
|
||||
|
||||
|
||||
Misc changes
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Prior versions of the 'os' repository came with a custom 'os/include/base'
|
||||
directory with interfaces extending the base API. To avoid confusion
|
||||
between the 'base' repository and the 'os' repository, 'os'-local API
|
||||
extensions are now located at 'os/include/os'. This way, the folder
|
||||
prefix of include statements indicates well from which repository the
|
||||
included header files comes from.
|
||||
|
||||
|
||||
C runtime
|
||||
#########
|
||||
|
||||
Most of existing libraries rely on the presence of a C library. For
|
||||
making the reuse of this software on Genode possible, we have now
|
||||
made a complete C library available for Genode. It comes as a separate
|
||||
source-code repository called 'libc' and is based on the code of FreeBSD.
|
||||
The original code is available at the official FreeBSD website.
|
||||
|
||||
:FreeBSD website:
|
||||
[http://www.freebsd.org/developers/cvs.html]
|
||||
|
||||
Our libc port comprises the libraries 'gdtoa', 'gen', 'locale', 'stdio',
|
||||
'stdlib', 'stdtime', 'string', and 'msun'. Currently, it supports the
|
||||
x86 architecture. Support for other architectures is planned as future
|
||||
addition. At the current stage, our back end is very basic and most of
|
||||
its functions are dummy stubs. We used Christian Prochaska's forthcoming
|
||||
Genode port of Qt4 as test case and successfully used the new libc as
|
||||
foundation for building graphical Qt4 applications. We will further
|
||||
extend the back end in correspondence to the growing feature set of the
|
||||
Genode OS framework.
|
||||
|
||||
:Usage:
|
||||
|
||||
To use the libc in your application, just add 'libc' to the 'LIBS'
|
||||
declaration in your build-description file. This declaration will make
|
||||
the libc headers available for the include path of your target and link
|
||||
the C library. When building, make sure that the 'libc' repository is
|
||||
included in your build configuration ('etc/build.conf').
|
||||
|
||||
:Limitations:
|
||||
|
||||
The current version of the C library is not thread-safe. For most
|
||||
string and math functions, this is not a problem (as these functions
|
||||
do not modify global state) but be careful with using more complex
|
||||
functions such as 'malloc' from multiple threads. Also, 'errno' may
|
||||
become meaningless when calling libc functions from multiple threads.
|
||||
|
||||
We have left out the following files from the Genode port of the
|
||||
FreeBSD libc: gdtoa 'strtodnrp.c' (gdtoa), 'getosreldate.c' (gen),
|
||||
'strcoll.c', 'strxfrm.c', 'wcscoll.c', 'wcsxfrm.c' (string),
|
||||
's_exp2l.c' ('msun').
|
||||
|
||||
The current back end is quite simplistic and it may help you to revisit
|
||||
the current state of the implementation in the 'libc/src/lib/libc'
|
||||
directory. If one of the functions in 'dummies.c' is called, you will
|
||||
see the debug message:
|
||||
! "<function-name> called, not yet implemented!"
|
||||
However, some of the back-end function implemented in the other files
|
||||
have dummy semantics but have to remain quiet because they are called
|
||||
from low-level libc code.
|
||||
|
||||
|
||||
Build infrastructure
|
||||
####################
|
||||
|
||||
Build-directory creation tool
|
||||
=============================
|
||||
|
||||
Because we think that each Genode developer benefits from knowing the
|
||||
basics about the functioning of the build system, the manual creation of
|
||||
build directories is described in Genode's getting-started document.
|
||||
However, for regular developers, creating build directories becomes a
|
||||
repetitive task. Hence, it should be automated. We have now added a
|
||||
simple build-directory creation tool that creates pre-configured build
|
||||
directories for some supported platforms. The tool is located at
|
||||
'tool/builddir/create_builddir'. To print its usage information, just
|
||||
execute the tool without arguments.
|
||||
|
||||
|
||||
Improved linking of binary files
|
||||
================================
|
||||
|
||||
For linking binary data, binary file have to be converted to object
|
||||
files. Over the time, we have used different mechanisms for this
|
||||
purpose. Originally, we used 'ld -r -b binary'. Unfortunately, these
|
||||
linker options are not portable. Therefore, the mechanism was changed
|
||||
to a 'hexdump' and 'sed' magic that generated a C array from binary data.
|
||||
This solution however, is complicated and slow. Now, we have adopted
|
||||
an idea of Ludwig Hähne to use the 'incbin' directive of the GNU
|
||||
assembler, which is a very clean, flexible, and fast solution.
|
||||
|
||||
|
||||
Lib-import mechanism
|
||||
====================
|
||||
|
||||
Libraries often require specific include files to be available at the
|
||||
default include search location. For example, users of a C library
|
||||
expect 'stdio.h' to be available at the root of the include search
|
||||
location. Placing the library's include files in the root of the
|
||||
default search location would pollute the include name space for
|
||||
all applications, regardless if they use the library or not. To
|
||||
keep library-include files well separated from each other, we have
|
||||
enhanced our build system by a new mechanism called lib-import.
|
||||
For each library specified in the 'LIBS' declaration of a build
|
||||
description file, the build system incorporates a corresponding
|
||||
'import-<libname>.mk' file into the build process. Such as file
|
||||
defines library-specific compiler options, in particular additional
|
||||
include-search locations. The build system searches for lib-import
|
||||
files in the 'lib/import/' subdirectories of all used repositories.
|
||||
|
||||
|
||||
Using 'ar' for creating libraries
|
||||
=================================
|
||||
|
||||
The previous versions of Genode relied on incremental linking ('ld -r')
|
||||
for building libraries. This approach is convenient because the linker
|
||||
resolves all cross-dependencies between libraries regardless of the
|
||||
order of how libraries are specified at the linker's command line.
|
||||
However, incremental linking prevents the linker from effectively
|
||||
detecting dead code. In contrast, when linking '.a' files, the linker
|
||||
detects unneeded object files. Traditionally, we have only linked our
|
||||
own framework containing no dead code. This changed with the new 'libc'
|
||||
support. When linking the 'libc', the presence of dead code becomes
|
||||
the normal case rather than the exception. Consequently, our old
|
||||
incremental-linking approach produced exceedingly large binaries
|
||||
including all functions that come with the 'libc'. We have now adopted
|
||||
the classic 'ar' mechanism for assembling libraries and use the linker's
|
||||
'start-group' 'end-group' feature to resolve inter-library-dependencies.
|
||||
This way, dead code gets eliminated at the granularity of object files.
|
||||
In the future, we will possible look into the '-ffunction-sections' and
|
||||
'-gc-sections' features of the GNU tool chain to further improve the
|
||||
granularity to function level.
|
||||
|
||||
If your build-description files rely on custom rules referring to
|
||||
'lib.o' files, these rules must be adapted to refer to 'lib.a' files
|
||||
instead.
|
||||
|
||||
|
||||
Misc changes
|
||||
============
|
||||
|
||||
* Added sanity check for build-description files overriding 'INC_DIR'
|
||||
instead of extending it.
|
||||
|
||||
* Restrict inclusion of dependency files to those that actually matter
|
||||
when building libraries within 'var/libcache'. This change significantly
|
||||
speeds up the build process in the presence of large libraries such as
|
||||
Qt4 and libc.
|
||||
|
||||
* Added rule for building 'cpp' files analogously to the 'cc' rule.
|
||||
Within Genode, we name all C++ implementation files with the 'cc'
|
||||
suffix. However, Qt4 uses 'cpp' as file extension so we have to
|
||||
support both.
|
||||
|
||||
* Build-description files do no longer need the declaration
|
||||
'REQUIRES = genode'. Genode's include search locations are now
|
||||
incorporated into the build process by default.
|
||||
|
||||
|
||||
Applications
|
||||
############
|
||||
|
||||
This section refers to the example applications contained in Genode's
|
||||
'demo' repository.
|
||||
|
||||
We have enhanced the _Scout_widgets_ as used by the launchpad and the
|
||||
Scout tutorial browser to perform all graphical output double-buffered,
|
||||
which effectively eliminates drawing artifacts that could occur when
|
||||
exposing intermediate drawing states via direct (unbuffered) output.
|
||||
Furthermore, we have added a way to constrain the maximum size of
|
||||
windows to perform pixel-buffer allocations on realistic window sizes.
|
||||
|
||||
Both launchpad and Scout can now start child applications. In Scout
|
||||
this functionality is realized by special "execute" links. We have
|
||||
generalized the underlying application logic for creating and
|
||||
maintaining child processes between both applications and placed
|
||||
the unification into a separate 'launchpad' library.
|
||||
|
||||
We have replaced the default document presented in Scout with an
|
||||
_interactive_walk-through_guide_ explaining the basic features of Genode.
|
||||
The document uses the new "execute" link facility to let the user start
|
||||
a launchpad instance by clicking on a link.
|
||||
|
||||
|
||||
Platform-specific changes
|
||||
#########################
|
||||
|
||||
Genode used to define _fixed-width_integer_types_ in a file 'stdint.h'
|
||||
placed in a directory corresponding to bit-width of the platform, for
|
||||
example 'include/32bit/stdint.h'. When building for a 32bit platform,
|
||||
the build system included the appropriate directory into the
|
||||
include-search path and thereby made 'stdint.h' available at the root
|
||||
of the include location. Unfortunately, this clashes with the 'stdint.h'
|
||||
file that comes with the C library. To avoid conflict with libc header
|
||||
files, we moved the definition of fixed-width integer types to
|
||||
'32bit/base/fixed_stdint.h'.
|
||||
|
||||
For the L4/Fiasco version of Genode, there existed some x86-specific
|
||||
header files that did not specifically depend on L4/Fiasco, for example
|
||||
atomic operations. Because these files are not L4/Fiasco-specific and
|
||||
may become handy for other platforms as well, we moved them to the
|
||||
generic 'base' repository.
|
||||
|
||||
|
||||
Linux 32bit
|
||||
===========
|
||||
|
||||
:Dissolving Genode's dependency from the glibc:
|
||||
|
||||
The port of the C runtime to Genode posed an interesting challenge to
|
||||
the Linux version of Genode. This version used to rely on certain
|
||||
functions provided by the underlying glibc:
|
||||
|
||||
* For creating and destroying threads, we used to rely on POSIX threads
|
||||
as provided by the 'pthread' library
|
||||
|
||||
* The lock implementation was based on the POSIX semaphore functions
|
||||
'sem_init', 'sem_wait', and 'sem_post'
|
||||
|
||||
* Shared memory was realized by using files ('open', 'close',
|
||||
'ftruncate') and the 'mmap' interface
|
||||
|
||||
* Starting and killing processes was implemented using 'fork' and 'kill'
|
||||
|
||||
* Inter-process communication used the glibc's socket functions
|
||||
|
||||
For our custom C runtime, we want to override the glibc functionality
|
||||
with our own implementation. For example, we want to provide the 'mmap'
|
||||
interface to a Genode application by implementing 'mmap' with
|
||||
functions of our base API. On Linux, however, this base API, in turn,
|
||||
used to rely on 'mmap'. This is just an example. The problem applies
|
||||
also for the other categories mentioned above. We realized that we cannot
|
||||
rely on the glibc on one hand but at the same time replace it by a custom
|
||||
C runtime (in fact, we believe that such a thing is possible by using
|
||||
awkward linker magic but we desire a clean solution). Consequently, we
|
||||
have to remove the dependency of Genode from the glibc on Linux. Step
|
||||
by step, we replaced the used glibc functions by custom Linux system-call
|
||||
bindings. Each binding function has a prefix 'lx_' such that the symbol
|
||||
won't collide with 'libc' symbols. The new bindings are located at the file
|
||||
'base-linux/src/platform/linux_syscalls.h'. It consist of 20 functions,
|
||||
most of them resembling the original interface ('socket', 'connect',
|
||||
'bind', 'getsockname', 'recvfrom', 'write', 'close', 'open', 'fork',
|
||||
'execve', 'mmap', 'ftruncate', 'unlink', 'tkill', 'nanosleep').
|
||||
For other functions, we simplified the semantics for our use case
|
||||
('sigaction', 'sigpending', 'sigsetmask', 'create_thread'). The most
|
||||
noteworthy changes are the creation and destruction of threads by
|
||||
directly using the 'clone' and 'tkill' system calls, and the lock
|
||||
implementation. Because we cannot anymore rely on the convenience of
|
||||
using futexes indirectly through the POSIX semaphore interface, we
|
||||
have adopted the simple locking approach that we already use for the
|
||||
L4/Fiasco version. This lock implementation is a simple sleeping
|
||||
spinlock.
|
||||
|
||||
|
||||
:Compromises:
|
||||
|
||||
The introduction of custom Linux system-call bindings for Genode has
|
||||
several pros and cons. With this change, The Linux version of Genode is
|
||||
not anymore easy to port to other POSIX platforms such as the Darwin
|
||||
kernel. For each POSIX kernel used as Genode platform, a custom
|
||||
implementation of our system-call bindings must be created. The
|
||||
original POSIX variant could still be reanimated, but this version
|
||||
would inherently lack support for Genode's C runtime, and thus would
|
||||
have limited value. A positive side effect of this solution, however,
|
||||
is that 'linux_syscalls.h' documents well the subset of the Linux'
|
||||
kernel interface that we are actually using.
|
||||
|
||||
The replacement of POSIX semaphores with sleeping spinlocks decreases
|
||||
locking performance quite significantly. In the contention case, the
|
||||
wakeup from sleeping introduces a high latency of up to one millisecond.
|
||||
Furthermore, fairness is not guaranteed and the spinning produces a bit
|
||||
of system load. If this approach turns out to become a serious performance
|
||||
bottleneck, we will consider creating custom bindings for Linux' futexes.
|
||||
|
||||
|
||||
L4/Fiasco
|
||||
=========
|
||||
|
||||
The concepts of _RM_faults_ and _managed_dataspaces_ as described in
|
||||
Section [Base framework], had been implemented into the L4/Fiasco
|
||||
version of core. Although the introduction of these concepts involved
|
||||
only minimal changes at the API level, the required core-internal
|
||||
changes had been quite invasive, affecting major parts of the pager
|
||||
and RM-session implementations.
|
||||
|
||||
Prior versions of the L4/Fiasco version of core did not implement
|
||||
the _cancel-blocking_mechanism_ as specified by the CPU-session API.
|
||||
The missing implementation resulted in lock-ups when destructing a
|
||||
thread that blocks for lock. With the new implementation based on
|
||||
L4/Fiasco's inter-task ex-regs system call, such threads can now
|
||||
be gracefully destructed.
|
||||
@@ -1,460 +0,0 @@
|
||||
|
||||
==============================================
|
||||
Release notes for the Genode OS Framework 9.02
|
||||
==============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
Summary
|
||||
#######
|
||||
|
||||
Whereas the focus of the previous release 8.11 was the refinement of
|
||||
Genode's base API and the creation of the infrastructure needed to build
|
||||
real-world applications, the release 9.02 is focused on functional
|
||||
enhancements in two directions. The first direction is broadening the
|
||||
number of possible base platforms for the framework. At present, most
|
||||
microkernels bring along a custom user land, which is closely tied to the
|
||||
particular kernel. Our vision is to establish Genode as a common ground for
|
||||
developing applications, protocol stacks, and device drivers in such a way
|
||||
that the software becomes easily portable among different kernels. This
|
||||
release makes Genode available on the L4ka::Pistachio kernel. Hence,
|
||||
software developed with the Genode API can now run unmodified on
|
||||
Linux/x86, L4/Fiasco, and L4ka::Pistachio. In the second direction, we
|
||||
are steadily advancing the functionality available on top of Genode. With
|
||||
this release, we introduce a basic networking facility and support for
|
||||
native Qt4 applications as major new features. Thanks to Genode's
|
||||
portability, these features become automatically available on all
|
||||
supported base platforms.
|
||||
|
||||
Our original plan for the release 9.02 also comprised the support of a
|
||||
Linux-on-Genode (para-)virtualization solution. Initially, we intended to
|
||||
make [http://os.inf.tu-dresden.de/L4/LinuxOnL4/ - L4Linux] available on
|
||||
the L4/Fiasco version of Genode. However, we identified several downsides
|
||||
with this approach. Apparently, the development of the officially available
|
||||
version of L4/Fiasco has become slow and long-known issues remain unfixed.
|
||||
L4Linux, however, is closely tied to L4/Fiasco and the L4 environment. For
|
||||
us at Genode Labs, maintaining both a custom port of L4Linux for Genode
|
||||
and L4/Fiasco by ourself in addition to developing Genode is unfeasible.
|
||||
In contrast, the Pistachio kernel features more advanced options for
|
||||
virtualization ([http://l4ka.org/projects/virtualization/afterburn/ - Afterburner]
|
||||
and VT support) that we want to explore. Furthermore, there exists another
|
||||
version of L4Linux called OKLinux for the OKL4 kernel developed at
|
||||
[http://ok-labs.com - OK-Labs], which is very interesting as well.
|
||||
Therefore, we decided against an ad-hoc solution and deferred this feature
|
||||
to the next release. [http:/about/road-map - See our updated road map...]
|
||||
|
||||
|
||||
Major new Features
|
||||
##################
|
||||
|
||||
Genode on L4ka::Pistachio
|
||||
=========================
|
||||
|
||||
From the very beginning, the base API of the Genode OS Framework was
|
||||
designed for portability. We put a lot of effort into finding API
|
||||
abstractions that are both implementable on a wide range of kernels and as
|
||||
close to the hardware as possible to keep the abstraction overhead low. For
|
||||
this reason, we developed the framework in parallel for the Linux kernel and
|
||||
the L4/Fiasco kernel. To validate our claim that Genode is highly portable,
|
||||
Julian Stecklina ported the framework to another member of the L4 family,
|
||||
namely the [http://l4ka.org/projects/pistachio/ - L4ka::Pistachio kernel].
|
||||
This high-performance kernel implements the latest official L4 API called
|
||||
L4.x2 and has a number of advanced features such as multi-processor support
|
||||
and virtualization support.
|
||||
|
||||
After Julian successfully created the first Pistachio version of Genode,
|
||||
we successively refined his work and conducted further unifications among
|
||||
the platform-dependent code for the different kernels. The result of this
|
||||
effort is included in this release and comes in the form of the
|
||||
'base-pistachio' source-code repository.
|
||||
|
||||
;Interesting technical notes:
|
||||
|
||||
* The IRQ handling on Pistachio is slightly different from L4/Fiasco.
|
||||
On L4/Fiasco, an IRQ becomes unmasked only when the user-level IRQ
|
||||
handler thread blocks for an IRQ by issuing an IPC call to the
|
||||
kernel's corresponding IRQ thread. In contrast, Pistachio unmasks an
|
||||
IRQ as soon as the user-level IRQ handler associates itself with an
|
||||
IRQ. Thus, an IRQ message may occur not only when the user-level IRQ
|
||||
handler blocks for any IRQ but anytime. In particular, IRQ messages
|
||||
may interfere with the IRQ handler's IPC communication with other
|
||||
threads. To ensure that IRQ messages do only occur when expecting
|
||||
them, we lazily associate the IRQ handler thread to the IRQ the
|
||||
first time we wait for an IRQ and issue an unmasking IPC call
|
||||
subsequent times.
|
||||
|
||||
* Genode provides a mechanism for gracefully destructing threads that
|
||||
are in a blocking state, for example waiting for an IPC message.
|
||||
Such a thread may hold locks or other resources that would not
|
||||
get properly freed when just killing the thread by force. Therefore,
|
||||
Genode provides a way to issue the cancellation of a blocking
|
||||
operation by another thread (e.g., the thread calling the destructor).
|
||||
Once, a blocking operation got canceled, a C++ exception
|
||||
('Blocking_canceled') is raised such the thread can fall back into
|
||||
a defined state and then be destructed. On L4ka::Pistachio, we use
|
||||
Pistachio's pager-exchange-registers feature in combination with
|
||||
the user-defined UTCB handle for cancelling blocking operations and
|
||||
detecting cancellations. The interesting code bits can be found in
|
||||
'src/base/ipc/ipc.cc', 'src/base/lock/lock.cc',
|
||||
'src/core/platform_thread.cc', and in the Pistachio-specific
|
||||
timer-service implementation.
|
||||
|
||||
* During the refinement of the Pistachio version, we were able to further
|
||||
generalize code that was previously specific for L4/Fiasco and
|
||||
L4ka::Pistachio respectively. Now, the platform-specific code comprises
|
||||
less than 3,000 lines of code (LOC) for L4/Pistachio, circa 2,000 LOC
|
||||
for L4/Fiasco, and circa 1,000 LOC for Linux. Hence, we expect that
|
||||
porting the framework to further kernels is possible at reasonable
|
||||
engineering costs.
|
||||
|
||||
:Current limitations:
|
||||
|
||||
* The current version does not use superpages (4M mappings) because we
|
||||
experienced problems with mapping 4K pages out of 4M pages. This is an
|
||||
issue that we like to investigate further because using 4M mappings
|
||||
would improve the boot time and reduce the kernel-memory usage.
|
||||
|
||||
* Currently, we use a simple sleeping spinlock for synchronization, which
|
||||
is not optimal for several reasons. There are no fairness guarantees,
|
||||
the spinning consumes CPU time, and threads that got blocked in the
|
||||
contention case are woken up at the coarse granularity of the kernel's
|
||||
timer tick, which is typically one millisecond.
|
||||
|
||||
* Nested RM sessions as introduced as an experimental feature in the
|
||||
Genode release 8.11 are not yet supported.
|
||||
|
||||
:Further details:
|
||||
|
||||
You can find further technical details and usage instructions at this
|
||||
dedicated [http://genode.org/documentation/platforms/pistachio - page].
|
||||
|
||||
|
||||
Qt4 on Genode
|
||||
=============
|
||||
|
||||
The minimalism of the Genode OS Framework with regard to its code
|
||||
complexity raised the question of whether this framework is feasible
|
||||
for hosting real-world applications and widely used runtime environments.
|
||||
Christian Prochaska took the challenge to port Trolltech's Qt4 application
|
||||
framework, which serves as the basis for the popular KDE desktop, to Genode.
|
||||
|
||||
Because Christian started his work more than a year ago at a time when no
|
||||
C library was available on Genode, several intermediate steps were needed.
|
||||
The first step was the integration of the Qt4 tools such as the meta-object
|
||||
compiler (moc) and resource compiler properly into the our build systion.
|
||||
With the tools in place, the Linux version of Genode came to an advantage.
|
||||
In this environment, a Genode application is able to use glibc functionality.
|
||||
So the problem of a missing C library could be deferred and Christian was
|
||||
able to focus on interfacing Qt with the existing Genode services such as
|
||||
the Nitpicker GUI sever. Next, the glibc dependencies were successively
|
||||
replaced by custom implementations or simple dummy stubs. Thereby, all
|
||||
needed functionalities such as timed semaphores and thread-local storage
|
||||
had to be mapped to existing Genode API calls. Once, all glibc dependencies
|
||||
had been dissolved, Qt could be compiled for the L4/Fiasco version.
|
||||
|
||||
Since a C library has become available in Genode 8.11, we were able to
|
||||
replace Christian's intermediate stub codes with a real C library. We also
|
||||
utilize recently added features of Genode such as its alarm framework to
|
||||
simplify the Qt4 port. Furthermore, we were able to remove all
|
||||
platform-specific bits such that the Qt4 port has now become completely
|
||||
generic with regard to the underlying kernel. Qt4 can be executed on Linux,
|
||||
L4/Fiasco, and L4ka::Pistachio without any changes. Figure [qt4_screenshot]
|
||||
shows a screenshot of Qt's Tetrix example running side-by-side with native
|
||||
Genode applications.
|
||||
|
||||
[image qt4_screenshot]
|
||||
|
||||
:Current state:
|
||||
|
||||
* The Qt4 port comes in the form of a source-code repository, which contains
|
||||
all Qt source codes, and some example programs such as Tetrix. You can
|
||||
download the Qt4 repository as a separate archive at the download page of
|
||||
the Genode release 9.2. For the next release, we plan to separate the
|
||||
Genode-specific parts from Qt original code and make the Genode-specific
|
||||
parts a regular component of the Genode main line.
|
||||
|
||||
* The Qt4 port consists of Qt's Core library, GUI library, Script library,
|
||||
XML library, and the UI tools library. Other libraries such as Webkit
|
||||
are not ported yet.
|
||||
|
||||
* This first version of Qt4 on Genode is not to be considered as stable.
|
||||
There are several known issues yet to be addressed. In particular,
|
||||
the 'QEventDispatcher' is still work in progress and not fully stabilized.
|
||||
|
||||
* Because, we use to statically link programs, the binaries of Qt
|
||||
applications are exceedingly large. For example the Tetrix binary is
|
||||
100MB including debug information and 11MB in the stripped form. For
|
||||
employing Qt on Genode at a larger scale, Genode should be enhanced with
|
||||
shared-library support.
|
||||
|
||||
|
||||
Networking
|
||||
==========
|
||||
|
||||
With Genode 8.11, we introduced the Device-Driver-Environment Kit (DDE Kit)
|
||||
API, which is a C API specifically designed for implementing and porting
|
||||
device drivers written in plain C. We have now complemented DDE Kit with an
|
||||
environment for executing Linux device drivers natively on Genode. This
|
||||
library is called 'dde_linux26' and contained in our new 'linux_drivers'
|
||||
source-code repository. The environment consists of several parts, which
|
||||
correspond to the different sub systems of the Linux kernel 2.6, such as
|
||||
'arch', 'drivers', 'kernel'.
|
||||
|
||||
The first class of device-drivers supported by DDE Linux 2.6 is networking.
|
||||
At the current stage, the DDE Linux network library comprises general
|
||||
network-device infrastructure as well as an exemplary driver for the PCnet32
|
||||
network device.
|
||||
|
||||
Based on this library, we have created a basic TCP/IP test utilizing the
|
||||
uIP stack, which uses the DDE Linux network library as back end. The test
|
||||
program implements a basic web server displaying uIP packet statistics.
|
||||
When executed on Qemu, you can use your host's web browser to connect to
|
||||
the web server running on Genode:
|
||||
|
||||
For booting Genode on L4/Fiasco with the web-server demo, use a GRUB
|
||||
entry in your 'menu.lst' file as follows.
|
||||
|
||||
! title Genode: DDE Linux 2.6 NET on L4/Fiasco
|
||||
! kernel /fiasco/bootstrap -maxmem=64 -modaddr=0x02000000
|
||||
! module /fiasco/fiasco -nokd -serial -serial_esc
|
||||
! module /fiasco/sigma0
|
||||
! module /genode/core
|
||||
! module /genode/init
|
||||
! module /config
|
||||
! module /genode/timer
|
||||
! module /genode/pci_drv
|
||||
! module /genode/test-dde_linux26_net
|
||||
|
||||
The first four lines are L4/Fiasco specific. When using L4ka::Pistachio,
|
||||
the 'menu.lst' entry looks like this:
|
||||
|
||||
! title Genode: DDE Linux 2.6 NET on L4/Pistachio
|
||||
! kernel /pistachio/kickstart
|
||||
! module /pistachio/x86-kernel
|
||||
! module /pistachio/sigma0
|
||||
! module /genode/core
|
||||
! module /genode/init
|
||||
! module /config
|
||||
! module /genode/timer
|
||||
! module /genode/pci_drv
|
||||
! module /genode/test-dde_linux26_net
|
||||
|
||||
The web-server test requires the PCI bus driver and the timer service.
|
||||
Therefore, the 'config' file for Genode's init should have following
|
||||
content:
|
||||
! <config>
|
||||
! <start>
|
||||
! <filename>timer</filename>
|
||||
! <ram_quota>512K</ram_quota>
|
||||
! </start>
|
||||
! <start>
|
||||
! <filename>pci_drv</filename>
|
||||
! <ram_quota>512K</ram_quota>
|
||||
! </start>
|
||||
! <start>
|
||||
! <filename>test-dde_linux26_net</filename>
|
||||
! <ram_quota>16M</ram_quota>
|
||||
! </start>
|
||||
! </config>
|
||||
|
||||
Now, its time to create an ISO image from all files specified in
|
||||
the GRUB configuration. For this, the new utility 'tool/create_iso'
|
||||
becomes handy. The ISO image can then be booted on Qemu using the
|
||||
following arguments:
|
||||
! qemu -m 64 -serial stdio -no-kqemu -cdrom <iso-image> \
|
||||
! -net nic,model=pcnet -net user -redir tcp:5555::80
|
||||
|
||||
The '-redir' argument tells qemu to redirect TCP connections with
|
||||
localhost:5555 to the guest OS at port 80. After having booted
|
||||
up Genode on Qemu, you can use your host's web browser to access
|
||||
the web server:
|
||||
! firefox http://localhost:5555
|
||||
|
||||
:Notes about using the TAP version:
|
||||
|
||||
* Preparations
|
||||
* You must be permitted to sudo and have installed the tunctl
|
||||
utility. Under Debian/Ubuntu execute
|
||||
|
||||
! sudo apt-get install uml-utilities
|
||||
|
||||
* Create TAP device
|
||||
! TAPDEV=$(sudo tunctl -b -u $USER)
|
||||
! sudo /sbin/ifconfig $TAPDEV 10.0.0.1
|
||||
|
||||
* setup DHCP server on $TAPDEV and 10.0.0.0/8
|
||||
|
||||
* Run qemu
|
||||
! qemu -m 64 -serial stdio -no-kqemu -cdrom dde.iso \
|
||||
! -net nic,model=pcnet \
|
||||
! -net tap,ifname=$TAPDEV,script=no,downscript=no
|
||||
|
||||
* Ping
|
||||
|
||||
* Cleanup
|
||||
* Stop DHCP server
|
||||
* Remove TAP device
|
||||
! sudo tunctl -d $TAPDEV
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
C Runtime
|
||||
=========
|
||||
|
||||
We have replaced the 'malloc' implementation of the original FreeBSD C
|
||||
library with a custom implementation, which relies on Genode's 'Heap' as
|
||||
allocator. The FreeBSD libc reserves a default memory pool of 1MB, which
|
||||
is no problem on FreeBSD because virtual memory is backed lazily with
|
||||
physical pages on demand. On Genode however, we immediately account the
|
||||
allocated memory, which implicates high quota requirements even for
|
||||
applications that use little memory. In contrast, Genode's heap allocates
|
||||
and accounts its backing store in relatively small chunks of a few KB.
|
||||
Therefore, the quota accounting for applications is much more in line with
|
||||
the actual memory usage. Furthermore, our custom 'malloc' implementation
|
||||
has the additional benefit of being thread safe.
|
||||
|
||||
* Added i386-specific parts of gen lib, in particular longjmp, setjmp.
|
||||
|
||||
|
||||
Device-Driver-Environment Kit
|
||||
=============================
|
||||
|
||||
* The DDE Kit uses our alarm framework (located in the 'os' repository) now
|
||||
rather than its own event-scheduler implementation formerly called 'Tick'.
|
||||
|
||||
* We refined the DDE Kit API and reduced the number of custom types. For
|
||||
example, we removed the custom 'dde_kit_lock_t' and using
|
||||
'struct dde_kit_lock' instead, and replaced 'dde_kit_thread_t' with
|
||||
'struct dde_kit_thread'.
|
||||
|
||||
Because of the apparent stabilization of the DDE Kit API, we have now added
|
||||
this API to Genode's official API reference.
|
||||
[http://genode.org/documentation/api/dde_kit_index - See the documentation of the DDE Kit API...]
|
||||
|
||||
|
||||
PS/2 input driver
|
||||
=================
|
||||
|
||||
We improved the PS/2 keyboard driver by adding missing scan-code translations
|
||||
for the scan code set 1, in particular the cursor keys.
|
||||
|
||||
|
||||
Applications
|
||||
############
|
||||
|
||||
Launchpad configuration
|
||||
=======================
|
||||
|
||||
Launchpad is a graphical application for interactively starting and killing
|
||||
programs. It is used for the default demonstration of Genode. By default,
|
||||
launchpad displays a preconfigured list of programs and their respective
|
||||
default memory quotas. The user can tweak the memory quota for each entry
|
||||
with mouse and then start a program by clicking on its name. As an
|
||||
alternative to using the default list, you can now define the list manually
|
||||
by supplying a configuration to Launchpad. The following example tells
|
||||
launchpad to display a list of two launcher entries:
|
||||
|
||||
!<config>
|
||||
! <launcher>
|
||||
! <filename>sdl_pathfind</filename>
|
||||
! <ram_quota>10M</ram_quota>
|
||||
! </launcher>
|
||||
! <launcher>
|
||||
! <filename>liquid_fb</filename>
|
||||
! <ram_quota>10M</ram_quota>
|
||||
! </launcher>
|
||||
!</config>
|
||||
|
||||
To use this configuration for a Launchpad started via init, you can simply
|
||||
insert the launchpad configuration into the '<start>' node of the launchpad
|
||||
entry in init's 'config' file.
|
||||
|
||||
|
||||
Platform-specific changes
|
||||
#########################
|
||||
|
||||
L4/Fiasco
|
||||
=========
|
||||
|
||||
* Raise 'Blocking_canceled' exceptions on canceled IPC calls
|
||||
|
||||
32-bit Linux
|
||||
============
|
||||
|
||||
* We continued dissolving the dependency of Genode from the glibc by using
|
||||
a custom 'getenv' implementation used during process creation.
|
||||
* By default, we compile now with '-nostdinc' and explicitly specify
|
||||
'/usr/include' as include search directory only when needed. Previously,
|
||||
a Genode application, which included a host include file by mistake, has
|
||||
not raised any compilation error when compiled for the Linux version of
|
||||
Genode. Now, all Genode platforms behave equally with regard to include
|
||||
search directories.
|
||||
* We enforce using the actual compiler's C++ support libraries rather than
|
||||
the default libraries installed on the host.
|
||||
|
||||
|
||||
Tools and build infrastructure
|
||||
##############################
|
||||
|
||||
Official tool chain
|
||||
===================
|
||||
|
||||
At the download section of our website, we used to provide a crosstool-based
|
||||
tool chain as pre-compiled binaries. Since we got several requests about
|
||||
how to build such a tool chain from scratch, we created custom utility for
|
||||
downloading, building, and installing the official Genode tool chain. You
|
||||
can find the utility at 'tool/tool_chain'. For usage instructions, just
|
||||
start 'tool_chain' without arguments. Because this utility is a plain script,
|
||||
you can follow and verify each step that we use for creating the Genode tool
|
||||
chain. Currently, this official tool chain is based on binutils 2.18 and
|
||||
gcc 4.2.4.
|
||||
|
||||
As an alternative to installing the tool chain from source, we also
|
||||
provide pre-compiled binaries at the download section of our website.
|
||||
[http://genode.org/download/tool-chain - Visit our tool-chain download website...]
|
||||
|
||||
For the Linux version of Genode, we still use the host's default gcc
|
||||
as tool chain. This way, we spare the hassle of downloading and installing
|
||||
a custom tool chain for somebody who wants to give Genode a quick try.
|
||||
With this is mind, we have fixes several small issues with gcc 4.3.2:
|
||||
|
||||
* Fixed dependency generation for gcc-4.3.2. Older version of gcc used to
|
||||
append a '.o' dependency at the target of '.d'-files. However, gcc-4.3.2
|
||||
seems to handle the option '-MT' differently, resulting in a rule that
|
||||
contains only the '.d' as target. Now, we explicitly specify both the
|
||||
'.o' file and the '.d' file as target. Consequently, on older gcc
|
||||
versions, the '.o' file appears twice but that is no problem.
|
||||
|
||||
* Fixed assembler issue with the 'fnstsw' instruction in the C library.
|
||||
This instruction does not accept eax but only ax as argument.
|
||||
|
||||
Build-directory creation tool
|
||||
=============================
|
||||
|
||||
We added a rule for creating a pre-configured build directory for the
|
||||
Pistachio version to our build-directory creation tool
|
||||
('tool/builddir/create_builddir'). Furthermore, we changed the default
|
||||
build configuration such that the official Genode tool chain is used for
|
||||
L4/Fiasco and L4ka::Pistachio.
|
||||
|
||||
Build system
|
||||
============
|
||||
|
||||
* Improved clean rule - visit each target directory only once
|
||||
* Stop the build process on the first error by default, for continuing
|
||||
the build process depite of an error, you can use the '-i' argument
|
||||
of make.
|
||||
* Compiler flags can now be set specific for compiling C and C++ sources.
|
||||
This is needed because both variants allow different sets of warning
|
||||
options. The new variables are called 'CC_CXX_OPT' and 'CC_C_OPT'.
|
||||
|
||||
ISO image creation tool
|
||||
=======================
|
||||
|
||||
We have created a convenient front end for 'genisoimage', which we
|
||||
use for testing Genode on Qemu. You can find this ISO-image-creation
|
||||
tool at 'tool/create_iso'. For usage instructions, simply start the
|
||||
tool without arguments.
|
||||
|
||||
@@ -1,585 +0,0 @@
|
||||
|
||||
==============================================
|
||||
Release notes for the Genode OS Framework 9.05
|
||||
==============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
Shortly after including support for the L4ka::Pistachio kernel in the
|
||||
previous release, the Genode version 9.05 gives a further evidence of
|
||||
Genode's high portability by making the framework available on top of
|
||||
the OKL4 kernel. This kernel is a commercial-grade microkernel
|
||||
developed by [http://ok-labs.com - Open Kernel Labs]. In Section
|
||||
[Supporting the OKL4 kernel as new base platform], we elaborate on the
|
||||
new base platform and summarize the experiences made during our porting
|
||||
work.
|
||||
|
||||
The previous Genode release was accompanied by a source-code archive containing
|
||||
the initial version of Qt4 for Genode. Our approach is to make the Qt4
|
||||
framework available for building Genode applications running natively on the
|
||||
microkernel rather than within a virtualization environment. As advertised in
|
||||
our [http://genode.org/about/road-map - road map], we have now seamlessly
|
||||
integrated the Qt4 framework into our mainline source tree. Furthermore, we
|
||||
have adapted our port to the Qt4 version 4.5.1. Section [Integration of Qt4
|
||||
into the mainline repository] gives a rough overview of the changes and an
|
||||
introduction on how to use the Qt4 framework with Genode.
|
||||
|
||||
The third major feature of the release is the addition of preliminary USB
|
||||
support. We have been able to port major parts of Linux' USB infrastructure
|
||||
to Genode using the DDE Kit introduced in autumn 2008. Section [USB support]
|
||||
presents an overview about the pursued design and the current state of
|
||||
implementation.
|
||||
|
||||
Section [OKLinux on Genode] outlines our ongoing efforts of running Linux
|
||||
as a node in Genode's process tree.
|
||||
|
||||
|
||||
Supporting the OKL4 kernel as new base platform
|
||||
###############################################
|
||||
|
||||
The OKL4 kernel developed by Open Kernel Labs started as a fork of the
|
||||
L4ka::Pistachio kernel. Whereas L4ka::Pistachio remained true to the L4
|
||||
x.2 specification, OKL4 was subject of major API changes geared towards high
|
||||
performance on the ARM architecture. OKL4 earned much fame for executing a
|
||||
user-level variant of Linux (OKLinux) on top the microkernel, which turned out
|
||||
to be faster than executing Linux natively on the ARM9 architecture. Even
|
||||
though OKL4 is primary targeted at the ARM architecture, we wanted to go for
|
||||
the x86 variant because of two reasons. First, there exists the just mentioned
|
||||
user-level port of Linux for OKL4, which looks like an attractive way to execute
|
||||
Linux on Genode once Genode runs on OKL4. Second, we think that distributing
|
||||
Genode in the form of ISO images bootable on plain PC hardware is the best
|
||||
way to reach the OS community. Therefore, we decided to use OKL4 version 2.1 as
|
||||
the base for our work. In contrast to later releases, this version supports
|
||||
both x86 and ARM. The following section reviews the unique features of the
|
||||
OKL4 kernel from our perspective.
|
||||
|
||||
|
||||
OKL4 viewed from the angle of a Genode developer
|
||||
================================================
|
||||
|
||||
On the kernel-API level, OKL4 has several interesting properties that had been
|
||||
both welcome and challenging. We want to highlight the following points:
|
||||
|
||||
In contrast to prior L4 kernels, OKL4 has *removed wall-clock timeouts* from
|
||||
the kernel interface. On L4, timeouts were used as arguments for for blocking
|
||||
IPC operations serving two purposes. First, specifying IPC timeouts allowed the
|
||||
IPC caller for regaining control over the blocking thread after the specified
|
||||
time elapsed. This is considered as important in the case that the called
|
||||
thread misbehaves and never answers the call. However, the problem of choosing
|
||||
an appropriate timeout was never properly resolved. When dimensioning the
|
||||
timeout too small, the called thread may miss the timeout just because it had
|
||||
no chance to be selected by the scheduler in time. Such timeouts rely on the
|
||||
presumption that there is low load on the system. On the other hand, when
|
||||
dimensioning the timeout too high, the system will become sluggish when the
|
||||
called thread misbehaves. For example, a simple GUI server may want to send
|
||||
input events to its clients with a timeout to be robust against misbehaving
|
||||
clients that never wait for events. When choosing a timeout too small, chances
|
||||
are high that an event will occur at a time when the receiver is handling a
|
||||
previous event. The timeout would trigger and the event would get lost. When
|
||||
choosing the timeout too large, say 1 second, any misbehaving client could make
|
||||
the GUI server freeze for 1 second. Therefore, timeouts for regaining control
|
||||
over a blocked thread seem to be a bad idea. So we welcome their absence in
|
||||
OKL4. The second use of timeouts is their use as user-level time source. On L4,
|
||||
sleep is typically implemented as a blocking IPC with a timeout set to the
|
||||
sleep value. For this purpose, a system built on top of OKL4 has to employ a
|
||||
user level device driver accessing a timer device. In Genode, we already have a
|
||||
timer service for this purpose. So we won't miss timeouts at all.
|
||||
|
||||
Classical L4 kernels provide two variants of *synchronous IPC*. So called long
|
||||
IPC could copy any amount of memory from the sending to the receiving address
|
||||
space. This is complicated operation because either communication partner may
|
||||
specify communication buffers that contain unmapped pages. Hence, page faults
|
||||
may occur during long-IPC operations. On L4, page faults, in turn, are handled
|
||||
by the user land. Not until a user-level pager thread resolves the page fault
|
||||
by establishing a mapping at the faulting address, the kernel can proceed the
|
||||
IPC operation. This sounds pretty complicated, and it is. The second IPC
|
||||
variant is called short IPC. It constrains the transferable payload to CPU
|
||||
registers. Hence, these IPC operations should only be used for messages with a
|
||||
payload of a maximum of 2 machine words. Because short IPCs are never touching
|
||||
user-level memory pages, no page faults can occur.
|
||||
On OKL4, there is only one IPC operation, which copies payload from the
|
||||
sender's user-level thread-control block (UTCB) to the receiver's UTCB. An
|
||||
UTCB is an always-mapped memory region. Hence no page faults can occur during
|
||||
IPC operations. On Genode, the UTCB size of 256 bytes may become a limitation
|
||||
when RPC messages get large. For example, session requests may include large
|
||||
session-argument strings specifying session-constructor arguments. Current
|
||||
services rely only on a few arguments so the size limitation is not an
|
||||
apparent problem. But that may change for future services. Furthermore, in
|
||||
contrast to L4 x.2, OKL4 does not allow for transferring payload other than
|
||||
plain data. In particular, OKL4 does not support the transfer of memory
|
||||
mappings via IPC. Removing memory mappings from the IPC operation is a very
|
||||
good idea. On Genode, only roottask (core) establishes mappings and shared
|
||||
memory is implemented as a user-level protocol (data spaces). There is no need
|
||||
to allow arbitrary processes to establish memory mapping via IPC.
|
||||
|
||||
The *boot procedure* of OKL4 largely differs from other L4 kernels. This is
|
||||
attributed to Open Kernel Labs' focus on embedded systems, which mostly rely on
|
||||
single-image boot loading. OKL4 employs a tool (elfweaver) for creating a
|
||||
bootable image from a bunch of files and an XML configuration file. Among the
|
||||
declarations about which processes to be loaded and which policies to enforce,
|
||||
the configuration file contains platform parameters such as the amount of
|
||||
physical memory of the machine. This static approach to configure a system is
|
||||
certainly useful for embedded systems but PC hardware uses to vary a lot. In
|
||||
this case, evaluating boot-time memory descriptors would be the preferred
|
||||
solution.
|
||||
|
||||
OKL4 introduces kernel support for *user-level synchronization*. Prior L4
|
||||
kernels facilitated user-level synchronization through a combination of
|
||||
synchronous IPC operations with either priorities or delayed preemption.
|
||||
OKL4's mutexes can make the life in the user land much easier. However, we have
|
||||
not looked into OKL4 mutexes yet.
|
||||
|
||||
There does not exist a recursive *map operation* as the source operand of the
|
||||
map operation is a physical memory descriptor rather than a virtual address in
|
||||
the mapper's address space. Consequently, this design eliminates the need for
|
||||
having a recursive unmap operation and thereby, the need to maintain a mapping
|
||||
data base in the kernel. This is cool because Genode keeps track of the
|
||||
mappings at the user level anyway (within core). From our perspective, there is
|
||||
no need to maintain mapping relationships in the kernel. Removing the mapping
|
||||
database effectively discards a lot of much-discussed problems about how to
|
||||
manage the mapping database in a clever way.
|
||||
|
||||
There exists *no root memory manager* (sigma0). Because the map operation
|
||||
takes a physical memory descriptor as argument instead of a virtual address
|
||||
in the mapper's address space. The mapper does not need to have the mapped
|
||||
page locally mapped within its own address space. In fact, core (as the only
|
||||
mapper in a Genode system) does only have very little memory mapped locally.
|
||||
This design accelerates the boot time because there is no need to map each
|
||||
physical page in core at startup as performed when running core on the other
|
||||
L4 kernels.
|
||||
|
||||
These differences of OKL4 compared with the microkernels already supported
|
||||
by Genode posed a number of interesting challenges and opportunities. We have
|
||||
thoroughly documented the process in
|
||||
[http://genode.org/documentation/articles/genode-on-okl4 - Bringing Genode to OKL4].
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
For using Genode with OKL4, please refer to the following dedicated page:
|
||||
|
||||
:[http://genode.org/documentation/platforms/okl4 - Genode on the OKL4 microkernel]:
|
||||
Site about building and using Genode with the OKL4 kernel.
|
||||
|
||||
|
||||
Limitations of the current implementation
|
||||
=========================================
|
||||
|
||||
The current implementation is able to execute the complete Genode demonstration
|
||||
scenario on OKL4. This means, we can build and destroy arbitrary trees of
|
||||
processes, have all the needed infrastructure in place to execute user-level
|
||||
device drivers such as VESA and PS/2, perform inter-process communication
|
||||
via RPC and shared memory, and have all basic framework API functions available.
|
||||
We regard the current state as the first functional version. However, there are
|
||||
the following points that need improvement and are subject to our future work.
|
||||
|
||||
:Incomplete timer driver:
|
||||
|
||||
On x86, the timer driver should program the PIT to dispatch sleep requests.
|
||||
However, the I/O ports of the PIT can only by made available to one party in
|
||||
the system (which naturally would be the timer driver). Unfortunately, there
|
||||
are some VESA BIOSes around, which try using the PIT directly. The current
|
||||
version of our VESA driver does not virtualize these accesses. It rather
|
||||
tries to gain direct access to the I/O ports from core. This would not work
|
||||
if the timer already uses this device resource. Our plan is to supplement
|
||||
our VESA driver with a virtual PIT that uses the timer service as back end.
|
||||
Then we can safely use the PIT by the timer driver.
|
||||
|
||||
:Signalling framework not yet implemented:
|
||||
|
||||
We have not yet implemented Genode's API for asynchronous notifications
|
||||
in the OKL4 version. In fact, the goal of the initial version of the
|
||||
OKL4 support was running the default demonstration scenario, which does
|
||||
not rely on signals. The second and more technical reason is that we
|
||||
consider exploiting OKL4's event mechanism for implementing the signalling
|
||||
API but have not finalized the design. The generic implementation as used
|
||||
on the other platforms cannot be used on OKL4 because this implementation
|
||||
utilizes one helper thread per signal transmitter. Within core, each RM
|
||||
session is a potential signal transmitter, which means that we need to
|
||||
create a helper thread per process. Unfortunately, by default, OKL4
|
||||
limits the number of threads within roottask (core) to only 8 threads,
|
||||
which would impose a severe limit on the number of processes we could
|
||||
run on OKL4.
|
||||
|
||||
:OKL4's kernel mutexes yet to be used:
|
||||
|
||||
We have not yet explored the use of mutexes provided by the OKL4 kernel
|
||||
for implementing Genode synchronization APIs but we rather rely on a
|
||||
yielding spin lock for now. This has a number of drawbacks such as high
|
||||
wake-up latencies in the contention case (depending on the scheduling
|
||||
time slice), no support for priorities, and no fairness. Although it
|
||||
is a simple and robust solution to start with, we plan to facilitate
|
||||
the OKL4 kernel feature with our upcoming work.
|
||||
|
||||
:Overly simplistic UTCB allocation:
|
||||
|
||||
Right now, we allocate a fixed amount of 32 UTCBs per address space and
|
||||
thereby limit the maximum number of threads per process. In the future,
|
||||
this limit should be made configurable.
|
||||
|
||||
:Managed dataspaces not yet supported:
|
||||
|
||||
The support of managed dataspaces relies on the signal API, which is
|
||||
not yet available for OKL4.
|
||||
|
||||
:Message buffers are limited to 256 bytes:
|
||||
|
||||
Because OKL4 performs message-based inter-process communication by
|
||||
copying data between the UTCBs of the communicating threads, the
|
||||
UTCB size constaints the maximum message size. Therefore, message
|
||||
must not exceed 256 bytes. This is not a huge problem for the currently
|
||||
available Genode programs but we can imagine session argument-lists
|
||||
to become larger in the future.
|
||||
|
||||
:Advanced thread functions are incomplete:
|
||||
|
||||
Thread functions such as querying registers of remote threads are not yet
|
||||
implemented.
|
||||
|
||||
|
||||
Integration of Qt4 into the mainline repository
|
||||
###############################################
|
||||
|
||||
Qt4 is a tool kit for developing platform-independent applications. It
|
||||
comprises a complete platform-abstraction layer and a rich GUI tool kit
|
||||
widely used for commercial and open-source applications. It is particularly
|
||||
known as the technical foundation of the KDE project. The previous Genode
|
||||
release was accompanied by a snapshot of our initial port of Qt4 to Genode. For
|
||||
the current release, we have turned this proof-of-concept implementation into a
|
||||
properly integrated part of the Genode mainline development. This enables Qt4
|
||||
applications to be executed natively on the full range of kernels supported by
|
||||
Genode.
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
We complemented Genode's source tree with the new 'qt4' source-code repository,
|
||||
which contains the Genode-specific parts of the Qt4 framework. The most
|
||||
portions for the Qt4 framework are used unmodified and thereby have not been
|
||||
made part of the Genode source tree. Instead, we fetch the original Qt4 source
|
||||
code from Trolltech's FTP server. This way, our source tree remains tidy and
|
||||
neat.
|
||||
|
||||
For using Qt4 for your Genode applications, you first need to download and
|
||||
prepare the original Qt4 source codes and build a few Qt4 tools such as the
|
||||
meta-object compiler and the resource compiler. The makefile found in the
|
||||
top-level directory of the 'qt4' repository automates this task:
|
||||
|
||||
! make prepare
|
||||
|
||||
To include the 'qt4' repository into the Genode build process, just add the
|
||||
'qt4' directory to the 'REPOSITORIES' declaration of the 'etc/build.conf' file
|
||||
within your build directory. Make sure that the repositories 'demo' and 'libc'
|
||||
are included as well. The 'qt4' repository comes with a couple of demo applications.
|
||||
The 'qt_launchpad' is especially interesting because it makes use of both the
|
||||
Qt4 framework and the Genode framework in one application.
|
||||
|
||||
|
||||
Features and limitations
|
||||
========================
|
||||
|
||||
The Qt4 port comprises Qt's Core library, GUI library, Script library, XML
|
||||
library, and the UI tools library.
|
||||
|
||||
For using Qt4 on the Linux version of Genode, we recommend using the Genode
|
||||
tool chain rather than your host's tool chain. Qt4 makes use of a lot of libc
|
||||
functionality, supplied by Genode's 'libc' repository. However, on Linux we
|
||||
still link against your host's libc. This becomes a problem if your host
|
||||
compiler's C++ support code references libc functionality that is not part of
|
||||
Genode's libc. Thereby the linker will silently create references to glibc
|
||||
symbols, making both libraries collide. So if using Qt4, we recommend using the
|
||||
Genode tool chain:
|
||||
|
||||
:[http://genode.org/download/tool-chain]:
|
||||
Information about downloading and using the Genode tool chain
|
||||
|
||||
|
||||
USB support
|
||||
###########
|
||||
|
||||
This release introduces the first fragments of USB support to Genode, taking
|
||||
the USB human-interface device (HID) class as starting point. With this work,
|
||||
we follow our approach of reusing unmodified Linux device drivers executed
|
||||
within a device-driver environment called DDE Linux. In the previous release,
|
||||
we already utilized this approach for realizing basic networking on Genode.
|
||||
With this release, we complement DDE Linux with support required by USB
|
||||
drivers. We are grateful for being able to base our implementation on the
|
||||
excellent foundation laid by Dirk Vogt. He described his work in
|
||||
[http://os.inf.tu-dresden.de/papers_ps/beleg-vogt.pdf - USB for the L4 environment].
|
||||
|
||||
For USB HID support, we added the Linux USB and input subsystems to the DDE
|
||||
Linux 2.6 framework. Besides the 'dde_linux26/net.h' API for network drivers
|
||||
added in Genode 9.02, the current version also includes APIs for input
|
||||
('dde_linux26/input.h') and USB ('dde_linux26/usb.h'). We intend these
|
||||
interfaces to mature towards generic driver-library APIs in the future. For
|
||||
example, BSD-based drivers shall transparently provide the same functionality
|
||||
as the current Linux drivers, which permits the simple reuse of driver server
|
||||
implementations.
|
||||
|
||||
[image usb_current]
|
||||
|
||||
Image [usb_current] illustrates the current implementation of the USB-based
|
||||
human-interface device (HID) driver. In this monolithic setup, all parts of the
|
||||
USB stack and the device API are executed within one address space. These parts
|
||||
are
|
||||
|
||||
* Input server glue code
|
||||
* HID driver and input subsystem
|
||||
* Core functions for management of USB request buffers (URBs),
|
||||
attached devices, and registered drivers
|
||||
* Host controller drivers for UHCI, OHCI, and EHCI
|
||||
|
||||
[image usb_aspired]
|
||||
|
||||
We regard this as an intermediate step towards our goal to decompose the USB
|
||||
stack. Image [usb_aspired] shows our aspired design. In this design, the
|
||||
USB server and one or more USB gadget drivers run in dedicated address spaces.
|
||||
The USB server provides two interfaces called USB session interface and USB
|
||||
device interface. A USB session interface corresponds to a virtual root hub,
|
||||
from which USB devices can be queried. The client of the USB session interface
|
||||
is usually an USB gadget driver that uses the USB device interface. Because
|
||||
this interface is used for transferring the actual payload at a potentially
|
||||
high bandwidth, it is based on shared memory and signals. The USB server
|
||||
consists of the following components:
|
||||
|
||||
* USB server glue code
|
||||
* Virtual USB device driver managing all attached devices
|
||||
* Core functions including hardware hub management
|
||||
* Host controller drivers
|
||||
|
||||
The USB server presents a virtual USB hub to each USB gadget driver. Such
|
||||
a driver consists of:
|
||||
|
||||
* Device interface, e.g., input server glue code
|
||||
* Gadget driver, e.g., HID driver and input subsystem
|
||||
* Core functions
|
||||
* Virtual host controller
|
||||
* USB client glue code
|
||||
|
||||
The HID driver uses the USB session API to monitor ports of its virtual root
|
||||
hub and submit URBs to attached devices. The session interface facilitates the
|
||||
signalling framework for event notification and a shared-memory dataspace for
|
||||
URB transmission.
|
||||
|
||||
The 'os' repository already contains the USB session and USB device interfaces.
|
||||
However, the decomposition is not yet in a functional state.
|
||||
|
||||
|
||||
:Current limitations:
|
||||
|
||||
The current monolithic implementation of the USB HID service can already be
|
||||
used as a replacement of the PS/2 driver. However, both drivers cannot be used
|
||||
at the same time, yet. To enable the use of both USB HID and PS/2, we plan to
|
||||
create a further component that merges multiple streams of input events and
|
||||
passes the result to the GUI server.
|
||||
|
||||
|
||||
OKLinux on Genode
|
||||
#################
|
||||
|
||||
According to our road map, we pursued the goal to run Linux as a node in
|
||||
Genode's process tree. We explored two approaches:
|
||||
|
||||
:Reanimating the Afterburner project conducted by the [http://l4ka.org - L4Ka group]:
|
||||
This approach is the result of the L4Ka groups's long-year experience with
|
||||
manually supporting L4Linux on top of the L4ka::Pistachio kernel. Because of
|
||||
the high costs of maintaining the paravirtualized Linux kernel, a
|
||||
semiautomatic paravirtualization technique was created. According to the
|
||||
impressive results presented in
|
||||
[http://www.l4ka.org/l4ka/publ_2006_levasseur-ua_soft-layering.pdf - Pre-Virtualization: Soft Layering for Virtual Machines],
|
||||
this approach is able to drastically reduce maintenance costs while retaining
|
||||
good performance. Furthermore, the approach was applied not only to Linux
|
||||
running on the L4 kernel but also for using Xen or Linux as underlying
|
||||
host operating systems.
|
||||
|
||||
:Porting the OKL4-specific version of L4Linux to Genode:
|
||||
Open Kernel Labs maintain a custom version of L4Linux that runs on OKL4. This
|
||||
version is mostly referred to as OKLinux aka Wombat. Since Genode can now use OKL4
|
||||
as base platform, the reuse of OKLinux in combination with Genode has become
|
||||
a feasible option.
|
||||
|
||||
Both approaches have pros and cons. Whereas Afterburner is a intriguing
|
||||
approach, this project seems to be stalled. It relies on a rather old tool
|
||||
chain, and recent Linux features such as thread-local storage support are not
|
||||
considered, yet. To pick up this solution for Genode will require us to fully
|
||||
understand the mechanisms and the code. So we consider this as a mid-term
|
||||
solution. In short term, running OKLinux on Genode is more feasible. We were
|
||||
already able to create a prototype version of OKLinux running on Genode. This
|
||||
version starts up the kernel including all Linux kernel threads, mounts the
|
||||
boot partition supplied as memory image, and starts the init process. The
|
||||
engineering costs had been rather low. We replaced the Iguana user land
|
||||
libraries as originally used by Wombat by a Genode-specific reimplementation to
|
||||
keep our manual adaptions of the Linux kernel code as small as possible.
|
||||
Our custom reimplementation of the needed Iguana APIs consists of less than
|
||||
1,000 lines of code (SLOC). The diff for our changes to the OKLinux kernel code
|
||||
comprises less than 1,000 lines. We plan to make a snapshot of this prototype
|
||||
publicly available soon.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
Nitpicker GUI server
|
||||
====================
|
||||
|
||||
We optimized the performance of the 'refresh' call, which updates all views of
|
||||
a session, which display a given buffer portion. The new implementation restricts
|
||||
the redraw operations to the fragment of each view that displays the specified
|
||||
buffer portion. The performance improvement becomes most visible when updating
|
||||
only small parts of a buffer.
|
||||
|
||||
|
||||
USB session interface
|
||||
=====================
|
||||
|
||||
Genode's emerging USB support introduces two new interfaces to the 'os' repository,
|
||||
which are called USB session and USB device.
|
||||
|
||||
An _USB_session_ is a virtual USB bus with just one root hub with 'MAX_PORTS'
|
||||
downstream ports. The client of such as session submits USB request blocks
|
||||
(URBs) and is, in turn, informed about port changes on the root hub as well as
|
||||
request completion. Connected USB devices can be referenced by USB device
|
||||
capabilities and are associated with one port at the virtual root hub on
|
||||
server side.
|
||||
|
||||
An _USB_device_ references a hardware device connected to a virtual USB bus's
|
||||
root hub. The device capability enables the client to send USB request
|
||||
blocks to the hardware device.
|
||||
|
||||
|
||||
Input interface
|
||||
===============
|
||||
|
||||
We updated the key codes of the input interface in response to recent changes
|
||||
of Linux' 'dev/event' definitions.
|
||||
|
||||
|
||||
VESA driver
|
||||
===========
|
||||
|
||||
Until now, there existed different processes that tried to access the PCI bus
|
||||
via I/O ports, in particular the VESA framebuffer driver and the PCI bus
|
||||
driver.
|
||||
|
||||
Since core enforces that each I/O port can only be assigned exclusively to one
|
||||
component in the system, multiple processes that need access to the same I/O
|
||||
ports cannot run at the same time. For our default demonstration scenario, we
|
||||
had been able to allow the VESA driver to use the PCI I/O ports because nobody
|
||||
else needed them. However, our growing base of device drivers relies on the
|
||||
PCI bus driver. To be able to use the VESA driver together with other drivers,
|
||||
we virtualized the access to the PCI bus from within the VESA driver.
|
||||
|
||||
Our current PCI virtualization code is pretty limited. The VESA driver sees a
|
||||
virtual PCI bus with only the VGA card attached. For now, we only allow reading
|
||||
the PCI configuration space of this device, but not writing to it. Apparently,
|
||||
this simple approach is sufficient to run the VESA BIOS of Qemu. However, other
|
||||
VESA BIOS implementations may need further access to the PCI device's
|
||||
configuration space. For example, for querying the size of a PCI resource,
|
||||
write access to base address registers is required. In such an event, the VESA
|
||||
driver will print a message about the missing virtualization feature:
|
||||
! writing data register not supported
|
||||
If you see such a message, we are very interested to see your log output such
|
||||
that we can enhance our PCI virtualization code as needed. Please contact us!
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
In the process of bringing Genode to the OKL4 kernel, we have generalized much
|
||||
of former platform-specific code:
|
||||
|
||||
* The initialization of C++ exception handling has now become part of the
|
||||
generic 'cxx' library in the 'base' repository. All platforms except
|
||||
Linux are using this generic library now.
|
||||
|
||||
* The 'server' library used to contain a platform-specific part that
|
||||
implemented the 'manage' function of a 'Server_entrypoint'. The
|
||||
generalized version of this library is now being used on all platforms
|
||||
other than Linux.
|
||||
|
||||
* We unified core-internal interfaces and their implementations such as
|
||||
'Dataspace_component', 'Cap_session_component', 'Rm_session_component',
|
||||
and 'Irq_session_component'. The result has become part of the 'base'
|
||||
repository.
|
||||
|
||||
* On OKL4, threads need to execute small startup code for querying their
|
||||
own thread IDs. Therefore, we have extended the 'Thread_base' interface
|
||||
with a platform-specific hook function called '_thread_bootstrap'.
|
||||
|
||||
* The types defined in 'base/native_types.h' had been complemented by a
|
||||
new 'Native_thread_id' type. This type is exclusively used by core and the
|
||||
framework libraries. For using the Genode API, this type is meaningless.
|
||||
|
||||
* For the 64bit support, we slightly refined the interfaces of some utility
|
||||
template functions in 'util/misc_math.h'. Furthermore, parts of the generic
|
||||
marshalling code of the IPC framework needed refinement, but no API changes
|
||||
were needed.
|
||||
|
||||
|
||||
Linux-specific changes
|
||||
######################
|
||||
|
||||
Adaptation to 64 bit
|
||||
====================
|
||||
|
||||
Because most Genode developers tend to work with the Linux version of Genode,
|
||||
supporting 64-bit Linux becomes increasingly important. With the current release,
|
||||
we start to officially support 64-bit Linux as base platform. This comes
|
||||
along with the following changes:
|
||||
|
||||
* We replaced the 'spec-x86.mk' file with new 'spec-x86_32.mk' and 'spec-x86_64.mk'
|
||||
files. The default version of 'base-linux/etc/specs.conf' automatically
|
||||
chooses the right spec file according to the output of 'uname -m'. Therefore,
|
||||
output of the build processes matches your host architecture. This behaviour
|
||||
can be changed by placing a customized 'spec.conf' file in your build directory's
|
||||
'etc/' subdirectory.
|
||||
|
||||
* We added type definitions for 64-bit-specific fixed-size integers in the form
|
||||
of a 64-bit-specific 'fixed_stdint.h' file.
|
||||
|
||||
* Because using 64 bit instead of 32 bit changes the payload size of RPC
|
||||
messages, we had to adjust several message buffers such as 'Ram_session_client'
|
||||
and 'Input::Session_client', and adapted the used stack sizes.
|
||||
|
||||
* Towards the goal of completely dissolving Genode's dependency on the Linux' glibc,
|
||||
we implemented custom system-call bindings. Apparently, Linux' syscall interface
|
||||
differs between 32 bit and 64 bit. For example, the 32-bit version handles
|
||||
all socket-related calls via a compound 'socketcall' whereas the 64-bit
|
||||
version uses distinct syscalls. Another difference is the handling of the
|
||||
'mmap' syscall and different behaviour of 'tkill'. The latter problem was
|
||||
resolved by replacing 'tkill' with 'tgkill' and setting the thread-group
|
||||
argument of the corresponding PID. Therefore, a 'Native_thread_id' on Linux
|
||||
now comprises both the TID and the PID.
|
||||
|
||||
* The 'Platform_env' on Linux contains a local implementation of the 'Rm_session'
|
||||
interface, which uses 'mmap' to attach dataspaces to the process' address
|
||||
space and maintains the region list in the form of a static array. This array
|
||||
was dimensioned to 256 entries, which constrained the maximum amount of
|
||||
usable memory when allocating a lot of small blocks via Genode's heap. Since
|
||||
the heap allocates backing store at the granularity of only 16KB, the worst
|
||||
case for reaching this limit was about 4MB. This was OK for our simple test
|
||||
applications. But for using Qt4, in particular on 64 bit, this has become a
|
||||
serious limitation. For now, we increased the region limit to 4096 and plan
|
||||
to replace the static array with a dynamically growing data structure.
|
||||
Furthermore, we made the heap granularity depend on the actual machine-word
|
||||
size. Therefore, the heap allocates its backing store in 32KB blocks when
|
||||
running on 64 bit.
|
||||
|
||||
|
||||
Debugging hooks
|
||||
===============
|
||||
|
||||
On Linux, we use gdb for debugging Genode. This is feasible as long as the
|
||||
targeted process is running. However, during low-level debugging, we had the
|
||||
recurring problem of a thread dying shortly after starting up. So we added a hook
|
||||
for halting a thread at the startup in order to be able to attach gdb to the
|
||||
thread before it dies. This simple hook lets the thread wait for a key press by
|
||||
directly calling the 'read' syscall. We also added a simple debug facility for
|
||||
printing debug messages bypassing Genode's LOG service by calling the 'write'
|
||||
syscall directly. Both hooks are now part of the Linux version of the 'env'
|
||||
library (see 'base-linux/src/base/env/debug.cc'). Note that these hooks are not
|
||||
part of the Genode API. There exists no header file.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,871 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 10.11
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
During the past three months, the Genode project was primarily driven by our
|
||||
desire to create a bigger picture out of the rich set of components that we
|
||||
introduced over time, in particular over the last year. Looking back at the
|
||||
progress made since mid 2009, there were many functional additions to the
|
||||
framework, waiting to get combined. To name a few, we added support for
|
||||
networking, audio output, real-time priorities, mandatory access control,
|
||||
USB, ATAPI block devices, Python, hardware-accelerated 3D graphics, Qt4,
|
||||
the WebKit-based Arora browser, and the paravirtualized OKLinux kernel.
|
||||
So many wonderful toys waiting to get played with. This is how the idea of
|
||||
creating [http://genode.org/download/live-cds - the new Genode Live CD] was
|
||||
born. In the past, Genode was mostly used in settings with a relatively static
|
||||
configuration consisting of several components orchestrated to fulfill
|
||||
a few special-purpose functions. Now, the time has come for the next step,
|
||||
creating one dynamic setup that allows for the selection of different subsystems
|
||||
at runtime rather than at boot time.
|
||||
|
||||
This step is challenging in several ways. First, the processes that form
|
||||
the base system have to run during the entire time of all demo setups. If
|
||||
any of those processes contained stability problems or leaked memory, it would
|
||||
subvert the complete system. Second, the components of all subsystems combined
|
||||
are far too complex to be loaded into memory at boot time. This would not
|
||||
only take too long but would consume a lot of RAM. Instead, those components
|
||||
and their data had to be fetched from disk (CDROM) on demand. Third, because
|
||||
multiple demo subsystems can be active at a time, low-level resources such as
|
||||
networking and audio output must be multiplexed to prevent different
|
||||
subsystems from interfering with each other. Finally, we had to create a
|
||||
single boot and configuration concept that is able to align the needs of all
|
||||
demos, yet staying manageable.
|
||||
|
||||
Alongside these challenges, we came up with a lot of ideas about how Genode's
|
||||
components could be composed in new creative ways. Some of these ideas such
|
||||
as the browser-plugin concept and the http-based block server made it onto
|
||||
the Live CD. So for producing the Live CD, we not only faced the said
|
||||
technical challenges but also invested substantial development effort in new
|
||||
components, which contributed to our overall goal. Two weeks ago, we released
|
||||
the Live CD. This release-notes document is the story about how we got there.
|
||||
|
||||
To keep ourself focused on the mission described above, we deferred the
|
||||
original roadmap goal for this release, which was the creation of a Unix-like
|
||||
runtime environment to enable compiling Genode on Genode. This will be the
|
||||
primary goal for the next release.
|
||||
|
||||
|
||||
Execution environment for gPXE drivers
|
||||
######################################
|
||||
|
||||
Up to now, DDE Linux provided Genode with drivers for hardware devices
|
||||
ranging from USB HID to WLAN. In preparation of the live CD, we
|
||||
noticed the demand for support of a broader selection of ethernet
|
||||
devices. Intel's e1000 PCI and PCIe cards seemed to mark the bottom
|
||||
line of what we had to support. The major advantage of NIC drivers
|
||||
from Linux is their optimization for maximum performance. This emerges
|
||||
a major downside if DDE Linux comes into play: We have to provide all
|
||||
the nifty interfaces used by the driver in our emulation framework. To
|
||||
achieve our short-term goal of a great live CD experience, we had to
|
||||
walk a different path.
|
||||
|
||||
[http://gpxe.org/ - gPXE] is a lovely network boot loader / open-source
|
||||
PXE ROM project and the successor of the famous Etherboot
|
||||
implementation. Besides support for DNS, HTTP, iSCSI and AoE, gPXE
|
||||
includes dozens of NIC drivers and applies a plain driver framework.
|
||||
As we were also itching to evaluate DDE kit and the DDE approach at
|
||||
large with this special _donator OS_, we went for implementing the
|
||||
device-driver environment for gPXE (DDE gPXE).
|
||||
|
||||
The current version provides drivers for e1000, e1000e, and pcnet
|
||||
devices. The emulation framework comprises just about 600 lines of
|
||||
code compared to more than 22,000 LOC reused unmodified from gPXE.
|
||||
Benchmarks with the PCNet32 driver showed that DDE gPXE's performance
|
||||
is comparable to DDE Linux.
|
||||
|
||||
The gPXE driver environment comes in the form of the new 'dde_gpxe'
|
||||
repository. For building DDE gPXE, you first need to download and patch
|
||||
the original sources. The top-level makefile of this repository automates
|
||||
this task. Just issue:
|
||||
|
||||
! make prepare
|
||||
|
||||
Now, you need to include the DDE gPXE repository into your Genode
|
||||
build process. Just add the path to this directory to the
|
||||
'REPOSITORIES' declaration of the 'etc/build.conf' file within your
|
||||
build directory, for example
|
||||
|
||||
! REPOSITORIES += $(GENODE_DIR)/dde_gpxe
|
||||
|
||||
After successful build the DDE gPXE based ethernet driver is located
|
||||
at 'bin/gpxe_nic_drv'.
|
||||
|
||||
|
||||
On-demand paging
|
||||
################
|
||||
|
||||
In the [http://genode.org/documentation/release-notes/8.11#section-8 - release 8.11],
|
||||
we laid the foundation for implementing user-level dataspace managers.
|
||||
But so far, the facility remained largely unused except for managing thread
|
||||
contexts. This changed with this release.
|
||||
|
||||
So what is a user-level dataspace manager and who needs it? In short,
|
||||
Genode's memory management is based on dataspaces. A dataspace is a
|
||||
container for memory. Normally, it is created via core's RAM or ROM
|
||||
services. The RAM service hands out dataspaces containing contiguous
|
||||
physical memory. After allocating such a RAM dataspace, the creator can
|
||||
attach the dataspace to its own address space to access the dataspace
|
||||
content. In addition, it can pass a dataspace reference (called dataspace
|
||||
capability) to other processes, which, in turn, can than attach the same
|
||||
dataspace to their local address space, thereby establishing shared memory.
|
||||
Similarly, core's ROM service hands out boot-time binary data as dataspaces.
|
||||
|
||||
For the most use cases of Genode so far, these two core services were the
|
||||
only dataspace providers needed. However, there are use cases that require
|
||||
more sophisticated memory management. For example, to implement swapping,
|
||||
the content of a dataspace must be transferred to disk in a way that
|
||||
is transparent to the users of the dataspace. In monolithic kernels, such
|
||||
functionality is implemented in the kernel. But on a multi-server OS
|
||||
such as Genode, this is no option. Implementing such a feature into
|
||||
core would increase the trusted computing base of all applications
|
||||
including those who do not need swapping. Core would need a hard-disk
|
||||
driver, effectively subverting the Genode concept. Other examples for
|
||||
advanced memory-management facilities are copy-on-write memory and
|
||||
non-contiguous memory - complexity we wish to avoid at the root of the
|
||||
process tree. Instead of implementing such memory management facilities
|
||||
by itself, core provides a mechanism to let any process manage dataspaces.
|
||||
This technique is also called user-level page-fault handling.
|
||||
|
||||
For the Live CD, we decided to give Genode's user-level page-fault handling
|
||||
facility a go. The incentive was accessing files stored on CDROM in an
|
||||
elegant way. We wanted to make the CDROM access completely transparent to
|
||||
the applications. An application should be able to use a ROM session as
|
||||
if the file was stored at core's ROM service. But instead of being
|
||||
provided by core, the session request would be delegated to an
|
||||
alternative ROM service implementation that reads the data from disk
|
||||
as needed. Some of the files stored in the CDROM are large. For example,
|
||||
the disk image that we use for the Linux demo is 160MB. So reading
|
||||
this file at once and keeping it in memory is not an option. Instead, only
|
||||
those parts of the file should be read from disk, which are actually
|
||||
needed. To uphold the illusion of dealing with plain ROM files for
|
||||
the client, we need to employ on-demand-paging in the CDROM server.
|
||||
Here is how it works.
|
||||
|
||||
# The dataspace manager creates an empty managed dataspace. Core
|
||||
already provides a tool for managing address spaces called
|
||||
region manager (RM service). A RM session is an address space,
|
||||
to which dataspaces can be attached. This is exactly what is
|
||||
needed for a managed dataspace. So a dataspace manager uses the
|
||||
same core service to define the layout of a managed dataspace
|
||||
as is used to manage the address space of a process. In fact,
|
||||
any RM session can be converted into a managed dataspace.
|
||||
! enum { MANAGED_DS_SIZE = 64*1024*1024 };
|
||||
! Rm_connection rm(0, MANAGED_DS_SIZE);
|
||||
This code creates a RM session with the size of 64MB. This is an empty
|
||||
address space. A dataspace capability that corresponds to this address
|
||||
space can then be requested via
|
||||
! Dataspace_capability ds = rm.dataspace();
|
||||
|
||||
# The dataspace capability can be passed to a client, which may
|
||||
attach the dataspace to its local address space. Because the
|
||||
managed dataspace is not populated by any backing store, however,
|
||||
an access would trigger a page fault, halting the execution of
|
||||
the client. Here, the page-fault protocol comes into play.
|
||||
|
||||
# The dataspace manager registers itself for receiving a signal each time
|
||||
a fault occurs:
|
||||
! Signal_receiver rec;
|
||||
! Signal_context client;
|
||||
! Signal_context_capability sig_cap = rec.manage(client);
|
||||
! rm.fault_handler(sig_cap);
|
||||
When an empty part of the managed dataspace is accessed by any
|
||||
process, a signal is delivered. The dataspace manager can then
|
||||
retrieve the fault information (access type, fault address) and
|
||||
dispatch the page fault by attaching a real dataspace at the
|
||||
fault address of the managed dataspace. In a simple case, the code
|
||||
looks as follows:
|
||||
! while (true) {
|
||||
! Signal signal = rec.wait_for_signal();
|
||||
! for (int i = 0; i < signal.num(); i++) {
|
||||
! Rm_session::State state = rm.state();
|
||||
! ds = alloc_backing_store_dataspace(PAGE_SIZE);
|
||||
! rm.attach_at(ds, state.addr & PAGE_MASK);
|
||||
! }
|
||||
! }
|
||||
This simple page-fault handler would lazily allocate a page of
|
||||
backing store memory each time a fault occurs. When the backing
|
||||
store is attached to the managed dataspace, core will automatically
|
||||
wake up the faulted client.
|
||||
|
||||
# The example above has the problem that the dataspace manager has
|
||||
to pay for the backing store that is indirectly used by the client.
|
||||
To prevent the client from exhausting the dataspace manager's memory,
|
||||
the dataspace manager may choose to use a limited pool of backing
|
||||
store only. If this pool is exceeded, the dataspace manager can reuse
|
||||
an already used backing-store block by first revoking it from its
|
||||
current managed dataspace:
|
||||
! rm.detach(addr);
|
||||
This will flush all mappings referring to the specified address
|
||||
from all users of the managed dataspace. The next time, this
|
||||
address region is accessed, a new signal will be delivered.
|
||||
|
||||
This page-fault protocol has the following unique properties. First,
|
||||
because core is used as a broker between client and dataspace manager, the
|
||||
dataspace manager remains completely unaware of the identity of its client.
|
||||
It does not even need to possess the communication right to the client. In
|
||||
contrast, all other user-level page-fault protocols that we are aware of
|
||||
require direct communication between client and dataspace manager. Second,
|
||||
because dataspaces are used as first-level objects to resolve page faults,
|
||||
page faults can be handed at an arbitrary granularity (of course, a multiple
|
||||
of the physical page size). For example, a dataspace manager may decide to
|
||||
attach backing-store dataspaces of 64K to the managed dataspace. So the
|
||||
overhead produced by user-level page-fault handler can be traded for the
|
||||
page-fault granularity. But most importantly, the API is the same across
|
||||
all kernels that support user-level page fault handling. Thus the low-level
|
||||
page-fault handling code becomes inherently portable.
|
||||
|
||||
Having said that, we have completed the implementation of the described
|
||||
core mechanisms, in particular the 'detach' facility, for OKL4. The ISO9660
|
||||
driver as featured on the Live CD implements the 'ROM' interface and
|
||||
reads the contents of those files from CDROM on demand. It uses a
|
||||
fixed pool of backing store, operates at a page-fault granularity of
|
||||
64KB, and implements a simple fifo replacement strategy.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
There had been only a few changes to the base framework described as
|
||||
follows.
|
||||
|
||||
We unified the core-specific console implementation among all
|
||||
base platforms and added synchronization of 'vprintf' calls.
|
||||
The kernel-specific code resides now in the respective
|
||||
'base-<platform>/src/base/console/core_console.h' files.
|
||||
|
||||
We removed the argument-less constructor from 'Allocator_avl_tpl'.
|
||||
This constructor created an allocator that uses itself for
|
||||
meta-data allocation, which is the usual case when creating
|
||||
local memory allocators. However, on Genode, this code is typically
|
||||
used to build non-memory allocators such as address-space regions.
|
||||
For these use cases, the default policy is dangerous. Hence, we
|
||||
decided to remove the default policy.
|
||||
|
||||
The 'printf' helper macros have been unified and simplified. The
|
||||
available macros are 'PINF' for status information, 'PWRN' for warnings,
|
||||
'PLOG' for log messages, and 'PERR' for errors. By default, the message
|
||||
types are colored differently to make them easily distinguishable.
|
||||
In addition to normal messages, there is the 'PDBG' for debugging
|
||||
purposes. It remains to be the only macro that prints the function name
|
||||
as message prefix and is meant for temporary messages, to be removed
|
||||
before finalizing the code.
|
||||
|
||||
Genode's on-demand-paging mechanism relies on the signalling framework.
|
||||
Each managed dataspace is assigned to a distinct signal context.
|
||||
Hence, signal contexts need to be created and disposed alongside
|
||||
with managed dataspaces. We complemented the signalling framework
|
||||
with a 'dissolve' function to enable the destruction of signal
|
||||
contexts.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
Finished transition to new init concept
|
||||
=======================================
|
||||
|
||||
With the release 10.05, we introduced the
|
||||
[http://genode.org/documentation/release-notes/10.05#section-0 - current configuration concept of init].
|
||||
This concept supports mandatory access control and provides flexible
|
||||
ways for defining client-server relationships. Until now, we maintained
|
||||
the old init concept. With the current release, the transition to the
|
||||
new concept is finished and we removed the traditional init.
|
||||
We retained the support for loading configurations for individual subsystems
|
||||
from different files but adopted the syntax to the use of attributes.
|
||||
Instead of
|
||||
! <configfile>subsystem.config</configfile>
|
||||
the new syntax is
|
||||
! <configfile name="subsystem.config"/>
|
||||
|
||||
|
||||
Virtual network bridge (Proxy ARP)
|
||||
==================================
|
||||
|
||||
Since we originally added networking support to Genode, only one program could
|
||||
use the networking facilities at a time. In the simplest form, such a program
|
||||
included the network driver, protocol stack, and the actual application. For
|
||||
example, the uIP stack featured with release 9.02 followed this approach.
|
||||
In release 9.11 we added the 'Nic_session' interface to decouple the network
|
||||
driver from the TCP/IP protocol stack. But the 1-to-1 relation between
|
||||
application and network interface remained. With the current release, we
|
||||
introduce the 'nic_bridge' server, which is able to multiplex the 'Nic_session'
|
||||
interface.
|
||||
|
||||
The implementation is roughly based on the proxy ARP RFC 1027. At startup, the
|
||||
'nic_bridge' creates a 'Nic_session' to the real network driver and, in turn,
|
||||
announces a 'Nic' service at its parent. But in contrast to a network driver
|
||||
implementing this interface, 'nic_bridge' supports an arbitrary number of
|
||||
'Nic_sessions' to be opened. From the client's perspective, such a session
|
||||
looks like a real network adaptor.
|
||||
|
||||
This way, it has become possible to run multiple TCP/IP stacks in
|
||||
parallel, each obtaining a distinct IP address via DHCP. For example,
|
||||
is has become possible to run multiple paravirtualized Linux kernels
|
||||
alongside an lwIP-based web browser, each accessing the network via a
|
||||
distinct IP address.
|
||||
|
||||
As a side effect for developing the 'nic_bridge', we created a set
|
||||
of utilities for implementing network protocols. The utilities are
|
||||
located at 'os/include/net' and comprise protocol definitions for
|
||||
ethernet, IPv4, UDP, ARP, and DHCP.
|
||||
|
||||
|
||||
Nitpicker GUI server
|
||||
====================
|
||||
|
||||
Our work on the Live CD motivated several improvements of the Nitpicker
|
||||
GUI server.
|
||||
|
||||
|
||||
Alpha blending
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
In addition to nitpicker's plain pixel buffer interface that is compatible
|
||||
with a normal framebuffer session, each nitpicker session can now have
|
||||
an optional alpha channel as well as an corresponding input-mask channel
|
||||
associated. Both the alpha channel and the input mask are contained in the
|
||||
same dataspace as the pixel buffer. The pixel buffer is followed by
|
||||
the 8-bit alpha values, which are then followed by the input-mask values.
|
||||
This way, the presence of an alpha channel does not interfere with the
|
||||
actual pixel format. Each 8-bit input mask value specifies the user-input
|
||||
policy for the respective pixel. If the value is zero, user input
|
||||
referring to the pixel is not handled by the client but "falls through"
|
||||
the view that is visible in the background of the pixel. This is typically
|
||||
the case for drop shadows. If the input-mask value is '1', the input
|
||||
is handled by the client.
|
||||
|
||||
With the input-mask mechanism in place, we no longer have a definitive
|
||||
assignment of each pixel to a single client anymore. In principle, an
|
||||
invisible client is able to track mouse movements by creating a full-screen
|
||||
view with all alpha values set to '0' and all input-mask values set to '1'.
|
||||
Once, the user clicks on this invisible view, the user input gets routed
|
||||
to the invisible client instead of the actually visible view. This
|
||||
security risk can be addressed at two levels:
|
||||
* In X-Ray mode, nitpicker completely disables alpha blending
|
||||
and the input-mask mechanism such that the user can identify the
|
||||
client that is responsible for each pixel on screen.
|
||||
* The use of the alpha channel is a session argument, which is specified
|
||||
by nitpicker clients at session-creation time. Consequently, this
|
||||
session argument is subjected to the policy of all processes involved
|
||||
with routing the session request to nitpicker. Such a policy may permit
|
||||
the use of an alpha channel only for trusted applications.
|
||||
|
||||
_Caution:_ The use of alpha channels implies read operations from
|
||||
the frame buffer. On typical PC graphics hardware, such operations are
|
||||
extremely slow. For this reason, the VESA driver should operate in
|
||||
buffered mode when using alpha blending in Nitpicker.
|
||||
|
||||
|
||||
Tinted views in X-Ray mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We added support for tinting individual clients or groups of clients
|
||||
with different colors based on their label as reported at session-creation
|
||||
time. By using session colors, nitpicker assists the user to tell apart
|
||||
different security domains without reading textual information. In
|
||||
addition to the tinting effect, the title bar presents the session
|
||||
color of the currently focused session.
|
||||
|
||||
The following nitpicker configuration tints all views of the launchpad
|
||||
subsystem in blue except for those views that belong to the testnit
|
||||
child of launchpad. Those are tinted red.
|
||||
! <config>
|
||||
! <policy label="launchpad" color="#0000ff"/>
|
||||
! <policy label="launchpad -> testnit" color="#ff0000"/>
|
||||
! </config>
|
||||
|
||||
|
||||
Misc Nitpicker changes
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We introduced a so-called 'stay-top' session argument, which declares
|
||||
that views created via this session should stay on top of other views.
|
||||
This function is useful for menus that should always remain accessible
|
||||
or banner images as used for Live CD.
|
||||
|
||||
Nitpicker's reserved region at the top of the screen used to cover up
|
||||
the screen area as seen by the clients. We have now excluded this area
|
||||
from the coordinate system of the clients.
|
||||
|
||||
We implemented the 'kill' mode that can be activated by the 'kill' key.
|
||||
(typically this is the 'Print Screen' key) This feature allows the user
|
||||
to select a client to be removed from the GUI. The client is not
|
||||
actually killed but only locked out. The 'kill' mode is meant as an
|
||||
emergency brake if an application behaves in ways not wanted by the
|
||||
user.
|
||||
|
||||
|
||||
ISO9660 server
|
||||
==============
|
||||
|
||||
As outlined in Section [On-demand paging], we revisited the ISO9660 server
|
||||
to implement on-demand-paged dataspaces. It is the first real-world
|
||||
use case for Genode's user-level page-fault protocol. The memory pool
|
||||
to be used as backing store for managed dataspaces is dimensioned according
|
||||
to the RAM assigned to the iso9660 server. The server divides this backing
|
||||
store into blocks of 64KB and assigns those blocks to the managed dataspaces
|
||||
in a fifo fashion. We found that using a granularity of 64KB improved the
|
||||
performance over smaller block sizes because this way, we profit from reading
|
||||
data ahead for each block request. This is particularly beneficial for
|
||||
CDROM drives because of their extremely long seek times.
|
||||
|
||||
|
||||
Audio mixer
|
||||
===========
|
||||
|
||||
We added a new *channel synchronization* facility to the 'Audio_out_session'
|
||||
interface. An 'Audio_out_session' refers to a single channel. For stereo
|
||||
playback, two sessions must be created. At session-creation time, the
|
||||
client can provide a hint about the channel type such as "front-left" as
|
||||
session-construction argument. This design principally allows for supporting
|
||||
setups with an arbitrary amount of channels. However, those channels must
|
||||
be synchronized. For this reason, we introduced the 'sync_session' function
|
||||
to the 'Audio_out_session' interface. It takes the session capability of
|
||||
another 'Audio_out_session' as argument. The specified session is then
|
||||
used as synchronization reference.
|
||||
|
||||
To reduce the latency when stopping audio replay, we introduced a new *flush*
|
||||
function to the 'Audio_out_session' interface. By calling this function,
|
||||
a client can express that it is willing to discard all audio data already
|
||||
submitted to the mixer.
|
||||
|
||||
Furthermore, we improved the audio mixer to support both long-running
|
||||
streams of audio and sporadic sounds. For the latter use case, low latency
|
||||
is particularly critical. In this regard, the current implementation is a
|
||||
vast improvement over the initial version. However, orchestrating the
|
||||
mixer with audio drivers as well as with different clients (in particular
|
||||
ALSA programs running on a paravirtualized Linux) is not trivial. In the
|
||||
process, we learned a lot, which will eventually prompt us to further
|
||||
optimize the current solution.
|
||||
|
||||
|
||||
Nitpicker-based virtual Framebuffer
|
||||
===================================
|
||||
|
||||
To support the browser-plugin demo, we introduced 'nit_fb', which is a
|
||||
framebuffer service that uses the nitpicker GUI server as back end. It
|
||||
is similar to the liquid framebuffer as featured in the 'demo' repository
|
||||
but in contrast to liquid framebuffer, 'nit_fb' is non-interactive.
|
||||
It has a fixed screen position and size. Furthermore, it does not
|
||||
virtualize the framebuffer but passes through the framebuffer portion of
|
||||
the nitpicker session, yielding better performance and lower latency.
|
||||
|
||||
If instantiated multiple times, 'nit_fb' can be used to statically arrange
|
||||
multiple virtual frame buffers on one physical screen. The size and screen
|
||||
position of each 'nit_fb' instance can be defined via Genode's configuration
|
||||
mechanism using the following attributes of the 'nit_fb' config node:
|
||||
! <config xpos="100" ypos="150"
|
||||
! width="300" height="200"
|
||||
! refresh_rate="25"/>
|
||||
If 'refresh_rate' isn't set, the server will not trigger any refresh
|
||||
operations by itself.
|
||||
|
||||
On the Live CD, each browser plugin instantiates a separate instance of
|
||||
'nit_fb' to present the plugin's content on screen. In this case, the
|
||||
view position is not fixed because the view is further virtualized by the
|
||||
loader, which imposes its policy onto 'nit_fb' - Genode's nested
|
||||
policies at work!
|
||||
|
||||
|
||||
TAR ROM service
|
||||
===============
|
||||
|
||||
For large setups, listing individual files as boot modules in single-image
|
||||
creation tools (e.g., elfweaver) or multiboot boot loaders can be
|
||||
cumbersome, especially when many data files or shared libraries are
|
||||
involved. To facilitate the grouping of files, 'tar_rom' is an
|
||||
implementation of the 'ROM' interface that operates on a 'tar' file.
|
||||
|
||||
The name of the TAR archive must be specified via the 'name' attribute of
|
||||
an 'archive' tag, for example:
|
||||
|
||||
! <config>
|
||||
! <archive name="archive.tar"/>
|
||||
! </config>
|
||||
|
||||
The backing store for the dataspaces exported via ROM sessions is accounted
|
||||
on the 'rom_tar' service (not on its clients) to make the use of 'rom_tar'
|
||||
transparent to the regular users of core's ROM service. Hence, this service
|
||||
must not be used by multiple clients that do not trust each other.
|
||||
Typically, 'tar_rom' is instantiated per client.
|
||||
|
||||
The Live CD uses the 'tar_rom' service for the browser demo. Each plugin
|
||||
is fetched from the web as a tar file containing the config file of the
|
||||
plugin subsystem as well as supplemental binary files that are provided
|
||||
to the plugin subsystem as ROM files. This way, a plugin can carry along
|
||||
multiple components and data that form a complete Genode subsystem.
|
||||
|
||||
|
||||
DDE Kit
|
||||
=======
|
||||
|
||||
The DDE kit underwent slight modifications since the previous release.
|
||||
It now provides 64-bit integer types and a revised virtual PCI bus
|
||||
implementation.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
PCI bus
|
||||
=======
|
||||
|
||||
Genode was tested on several hardware platforms in preparation of the
|
||||
current release. This revealed some deficiencies with the PCI bus
|
||||
driver implementation. The revised driver now efficiently supports
|
||||
platforms with many PCI busses (as PCIe demands) and correctly handles
|
||||
multi-function devices.
|
||||
|
||||
|
||||
VESA framebuffer
|
||||
================
|
||||
|
||||
We updated the configuration syntax of the VESA driver to better match
|
||||
the style of new init syntax, preferring the use of attributes rather than
|
||||
XML sub nodes. Please refer to the updated documentation at
|
||||
'os/src/drivers/framebuffer/vesa/README'.
|
||||
|
||||
:Buffered output:
|
||||
|
||||
To accommodate framebuffer clients that need to read from the frame buffer,
|
||||
in particular the nitpicker GUI server operating with alpha channels, we
|
||||
introduced a buffered mode to the VESA driver. If enabled, the VESA driver
|
||||
will hand out a plain memory dataspace to the client rather than the
|
||||
physical framebuffer. Each time, the client issues as 'refresh' operation
|
||||
on the framebuffer-session interface, the VESA driver copies the corresponding
|
||||
screen region from the client-side virtual framebuffer to the physical
|
||||
framebuffer. Note that the VESA driver will require additional RAM quota
|
||||
to allocate the client buffer. If the quota is insufficient, the driver will
|
||||
fall back to non-buffered output.
|
||||
|
||||
:Preinitialized video modes:
|
||||
|
||||
As an alternative to letting the VESA driver set up a screen mode, the
|
||||
driver has become able to reuse an already initialized mode, which is useful
|
||||
if the VESA mode is already initialized by the boot loader. If the screen
|
||||
is initialized that way, the 'preinit' attribute of the 'config' node can
|
||||
be set to '"yes"' to prevent the driver from changing the mode. This way,
|
||||
the driver will just query the current mode and make the already
|
||||
initialized framebuffer available to its client.
|
||||
|
||||
|
||||
Audio
|
||||
=====
|
||||
|
||||
We observed certain hardware platforms (in particular VirtualBox) to
|
||||
behave strangely after ALSA buffer-underrun conditions. It seems that the
|
||||
VirtualBox audio driver plays actually more frames than requested by
|
||||
ALSA's 'writei' function, resulting in recurring replay of data that
|
||||
was in the buffer at underrun time. As a work-around for this problem,
|
||||
we zero-out the sound-hardware buffer in the condition of an ALSA buffer
|
||||
underrun. This way, the recurring replay is still there, but it is
|
||||
replaying silence.
|
||||
|
||||
To improve the support for sporadic audio output, we added a check for the PCM
|
||||
state for buffer underruns prior issuing the actual playback. In the event of
|
||||
an underrun, we re-prepare the sound card before starting the playback.
|
||||
|
||||
Furthermore, we implemented the new flush and channel-synchronization
|
||||
abilities of the 'Audio_out_session' interface for the DDE Linux driver.
|
||||
|
||||
|
||||
Paravirtualized Linux
|
||||
#####################
|
||||
|
||||
To support the demo scenarios that showcase the paravirtualized Linux kernel,
|
||||
we enhanced our custom stub drivers of the OKLinux kernel. Thereby, we have
|
||||
reached a high level of integration of OKLinux with native Genode services,
|
||||
including audio output, block devices, framebuffer output, seamless integration
|
||||
with the Nitpicker GUI, and networking. All stub drivers are compiled in by
|
||||
default and are ready to use by specifying a device configuration in the config
|
||||
node for the Linux kernel. This way, one Linux kernel image can be easily used
|
||||
in different scenarios.
|
||||
|
||||
:Integration with the Nitpicker GUI:
|
||||
|
||||
We enhanced our fbdev stub driver with a mechanism to merge view reposition
|
||||
events. If a X11 window is moved, a lot of subsequent events of this type are
|
||||
generated. Using the new optimization, only the most recent state gets
|
||||
reported to Nitpicker, making the X11 GUI more responsive.
|
||||
|
||||
:UnionFS:
|
||||
|
||||
As we noticed that unionfs is required by all our Linux scenarios, we decided
|
||||
to include and enable the patch by default.
|
||||
|
||||
:Network support:
|
||||
|
||||
With the introduction of the 'nic_bridge', multiple networking stacks can run
|
||||
on Genode at the same time, which paves the way for new use cases. We have now
|
||||
added a stub driver using Genode's 'Nic_session' interface to make the new
|
||||
facility available to Linux.
|
||||
|
||||
:Audio output:
|
||||
|
||||
We adapted the ALSA stub driver to the changes of the 'Audio_out_session'
|
||||
interface, using the new channel synchronization and flush functions.
|
||||
Thereby, we optimized the stub driver to keep latency and seek times of
|
||||
Linux userland applications reasonably low.
|
||||
|
||||
:Removed ROM file driver:
|
||||
|
||||
With the addition of the 'Block_session' stub driver, the original ROM file
|
||||
driver is no longer required. So we removed the stub. For using ROM files as
|
||||
disk images for Linux, there is the 'rom_loopdev' server, which provides a
|
||||
block session that operates on a ROM file.
|
||||
|
||||
:Asynchronous block interface:
|
||||
|
||||
To improve performance, we changed the block stub driver to facilitate the
|
||||
asynchronous mode of operation as provided by the 'Block_session' interface.
|
||||
This way, multiple block requests can be issued at once, thereby shadowing
|
||||
the round trip times for individual requests.
|
||||
|
||||
|
||||
Protocol stacks and libraries
|
||||
#############################
|
||||
|
||||
Gallium3D / Intel GEM
|
||||
=====================
|
||||
|
||||
We improved the cache handling of our DRM emulation code (implementing
|
||||
'drm_clflush_pages') and our EGL driver, thereby fixing caching
|
||||
artifacts on i945 GPUs. Furthermore, we added a temporary work-around
|
||||
for the currently dysfunctional sequence-number tracking with i945 GPUs.
|
||||
On this chipset, issuing the 'MI_STORE_DWORD_INDEX' GPU command used
|
||||
for tracking sequence numbers apparently halts the processing the command
|
||||
stream. This condition is normally handled by an interrupt. However,
|
||||
we have not enabled interrupts yet.
|
||||
|
||||
To prepare the future support for more Gallium drivers than i915, we
|
||||
implemented a driver-selection facility in the EGL driver. The code
|
||||
scans the PCI bus for a supported GPU and returns the name of the
|
||||
corresponding driver library. If no driver library could be found,
|
||||
the EGL driver falls back to softpipe rendering.
|
||||
|
||||
|
||||
lwIP
|
||||
====
|
||||
|
||||
We revised our port of the lwIP TCP/IP stack, and thereby improved its
|
||||
stability and performance.
|
||||
|
||||
* The lwIP library is now built as shared object, following the convention
|
||||
for libraries contained in the 'libports' repository.
|
||||
* By default (when using the 'libc_lwip_nic_dhcp' library), lwIP will
|
||||
issue a DHCP request at startup. If this request times out, the loopback
|
||||
device is set as default.
|
||||
* If there is no 'Nic' service available, the lwIP stack will fall back to
|
||||
the loopback device.
|
||||
* We increased the default number of PCBs in lwIP to 64.
|
||||
* We removed a corner case of the timed semaphore that could occur
|
||||
when a timeout was triggered at the same time ,'up' was called.
|
||||
In this case, the semaphore was unblocked but the timeout condition
|
||||
was not reflected at the caller of 'down'. However, the lwIP code
|
||||
relies on detecting those timeouts.
|
||||
|
||||
|
||||
Qt4
|
||||
====
|
||||
|
||||
We implemented a custom *nitpicker plugin widget*, which allows for the
|
||||
seamless integration of arbitrary nitpicker clients into a Qt4 application.
|
||||
The primary use case is the browser plugin mechanism presented at
|
||||
the Live CD. In principle, the 'QNitpickerViewWidget' allows for creating
|
||||
mash-up allocations consisting of multiple native Genode programs. As shown
|
||||
by the browser plugin demo, a Qt4 application can even integrate other
|
||||
programs that run isolated from the Qt4 application, and thereby depend on
|
||||
on a significantly less complex trusted computing base than the Qt4
|
||||
application itself.
|
||||
|
||||
[image nitpicker_plugin]
|
||||
|
||||
The image above illustrates the use of the 'QNitpickerViewWidget' in the
|
||||
scenario presented on the Live CD. The browser obtains the Nitpicker view to be
|
||||
embedded into the website from the loader service, which virtualizes the
|
||||
Nitpicker session interface for the loaded plugin subsystem. The browser then
|
||||
tells the loader about where to present the plugin view on screen. But it has
|
||||
neither control over the plugin's execution nor can it observe any user
|
||||
interaction with the plugin.
|
||||
|
||||
|
||||
New Gems repository with HTTP-based block server
|
||||
################################################
|
||||
|
||||
To give the web-browser demo of our Live CD a special twist, and to show off
|
||||
the possibilities of a real multi-server OS, we decided to implement the
|
||||
somewhat crazy idea of letting a Linux OS run on a disk image fetched at
|
||||
runtime from a web server. This way, the Linux OS would start right away and
|
||||
disk blocks would be streamed over the network as needed. Implementing this
|
||||
idea was especially attractive because such a feature would be extremely hard
|
||||
to implement on a classical OS but is a breeze to realize on Genode where all
|
||||
device drivers and protocol stacks are running as distinct user-level
|
||||
components. The following figure illustrates the idea:
|
||||
|
||||
[image http_block]
|
||||
|
||||
The block stub driver of the Linux kernel gets connected to a special block
|
||||
driver called 'http_block', which does not access a real block device but
|
||||
rather uses TCP/IP and HTTP to fetch disk blocks from a web server.
|
||||
|
||||
Because the 'http_block' server is both user of high-level functionality (the
|
||||
lwIP stack) and provider of a low-level interface ('Block_session'), the
|
||||
program does not fit well into one of the existing source-code repositories.
|
||||
The 'os' repository, which is normally hosting servers for low-level interfaces
|
||||
is the wrong place for 'http_block' because this program would make the 'os'
|
||||
repository depend on the higher-level 'libports' repository where the 'lwip'
|
||||
stack is located. On the other hand, placing 'http_block' into the 'libports'
|
||||
repository is also wrong because the program is not a ported library. It merely
|
||||
uses libraries provided by 'libports'. In the future, we expect that native
|
||||
Genode components that use both low-level and high-level repositories will
|
||||
become rather the norm than an exception. Therefore, we introduced a new
|
||||
repository called 'gems' for hosting such programs.
|
||||
|
||||
|
||||
Tools
|
||||
#####
|
||||
|
||||
Automated coding-style checker
|
||||
==============================
|
||||
|
||||
As Genode's code base grows and new developers start to get involved,
|
||||
we noticed recurring questions regarding coding style. There is a
|
||||
[http://genode.org/documentation/developer-resources/coding_style - document]
|
||||
describing our coding style but for people just starting to get involved,
|
||||
adhering all the rules can become tedious. However, we stress the importance
|
||||
of a consistent coding style for the project. Not only does a consistent style
|
||||
make the framework more approachable for users, but it also eases the work
|
||||
of all regular developers, who can feel right at home at any part of
|
||||
the code.
|
||||
|
||||
To avoid wasting precious developer time with coding-style fixes, we
|
||||
have created a tool for the automated checking and (if possible) fixing
|
||||
the adherence of source code to Genode's coding style. The tool is
|
||||
located at 'tool/beautify'. It takes a source file as argument and
|
||||
reports coding-style violations. The checks are fairly elaborative:
|
||||
* Placement of braces and parenthesis
|
||||
* Indentation and alignment, trailing spaces
|
||||
* Vertical spacing (e.g., between member functions, above comments)
|
||||
* Naming of member variables and functions (e.g., private members start with '_')
|
||||
* Use of upper and lower case
|
||||
* Presence of a file header with the mandatory fields
|
||||
* Policy for function-header comments (comment at declaration, not
|
||||
at implementation)
|
||||
* Style of single-line comments, function-header comments, multi-line comments
|
||||
|
||||
The user of 'beautify' may opt to let the tool fix most of the violations
|
||||
automatically by specifying the command line arguments '-fix' and '-write'.
|
||||
With only the '-fix' argument, the tool will output the fixed version of
|
||||
the code via stdout. By specifying the '-write' argument, the changes will
|
||||
be written back to the original file. In any case, we strongly recommend
|
||||
to manually inspect all changes made by the tool.
|
||||
|
||||
Under the hood, the tool consists of two parts. A custom C++ parser called
|
||||
'parse_cxx' reads the source code and converts it to a syntax tree. In the
|
||||
syntax tree, all formating information such as whitespaces are preserved.
|
||||
The C++ parser is a separate command-line tool, which we also use for
|
||||
other purposes (e.g., generating the API documentation at the website).
|
||||
The actual 'beautify' tool calls 'parse_cxx', and applies its checks and
|
||||
fixes to the output of 'parse_cxx'. For this reason, both tools have to
|
||||
reside in the same directory.
|
||||
|
||||
|
||||
Platform-specific changes
|
||||
#########################
|
||||
|
||||
OKL4
|
||||
====
|
||||
|
||||
:Added support for shared interrupts:
|
||||
|
||||
The Genode Live CD operates on a large number of devices that trigger
|
||||
interrupts (USB, keyboard, mouse, ATAPI, timer, network). On most
|
||||
platforms, the chances are extremely high that some of them use
|
||||
the same IRQ line. Therefore, we enhanced core's IRQ service to
|
||||
allow multiple clients to request the same IRQ. If the interrupt occurs,
|
||||
all clients referring to this interrupt are notified. The interrupt
|
||||
gets cleared after all of those clients responded. Even though, we regard
|
||||
PIC interrupts as a legacy, the support of shared interrupts enables
|
||||
us to use OKL4 with such complex usage scenarios.
|
||||
|
||||
:Revised page-fault handling:
|
||||
|
||||
If a page fault occurs, the OKL4 kernel delivers a message to the page-fault
|
||||
handler. The message contains the page-fault address and type as well as the
|
||||
space ID where the fault happened. However, the identity of the faulting
|
||||
thread is not delivered. Instead, the sender ID of the page fault message
|
||||
contains the KTCB index of the faulting thread, which is only meaningful
|
||||
within the kernel. This KTCB index is used as a reply token for answering the
|
||||
page fault message. We wondered about why OKL4 choose to deliver the KTCB
|
||||
index rather then the global thread ID as done for plain IPC messages. The
|
||||
only reasonable answer is that by using the KTCB index directly in OKL4's
|
||||
page-fault protocol, one lookup from the userland-defined thread ID to the
|
||||
KTCB index can be avoided. However, this comes at the cost of losing the
|
||||
identity of the faulting thread. We used to take the space ID as a key for
|
||||
the fault context within core. However, with Genode's user-level page-fault
|
||||
mechanism, this simplification does not suffice anymore. We have to know the
|
||||
faulting thread as a page fault may not be answered immediately but at a
|
||||
later time. During that time, the page-fault state has to be stored at core's
|
||||
representation of the faulting thread. Our solution is reverting OKL4's
|
||||
page-fault protocol to operate with global thread IDs only and to never make
|
||||
kernel-internal KTCB indices visible at the user land. You can find the patch
|
||||
for the OKL4 kernel at 'base-okl4/patches/reply_tid.patch'.
|
||||
|
||||
:Reboot via kernel debugger:
|
||||
|
||||
We fixed the reboot code of OKL4's kernel debugger to improve our work
|
||||
flow. The patch can be found at 'base-okl4/patches/kdb_reboot.patch'.
|
||||
|
||||
:Relieved conflict with libc 'limits.h':
|
||||
|
||||
For some reason, the OKL4 kernel bindings provide definitions
|
||||
normally found in libc headers. This circumstance ultimately leads
|
||||
to trouble when combining OKL4 with a real C runtime. We have
|
||||
relieved the problem with the patch 'base-okl4/patches/char_bit.patch'.
|
||||
|
||||
:Exception handling:
|
||||
|
||||
We added a diagnostic message to core that reports about exceptions
|
||||
such as division by zero.
|
||||
|
||||
|
||||
Pistachio
|
||||
=========
|
||||
|
||||
Our revised syscall bindings for supporting position-independent code
|
||||
on L4ka::Pistachio have been integrated into the mainline development
|
||||
of the kernel. Therefore, the patch is not needed anymore when using
|
||||
a kernel revision newer than 'r791:0d25c1f65a3a'.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
On Linux, we let the kernel manage all virtual address spaces for us,
|
||||
except for the thread-context area. Because the kernel does not know
|
||||
about the special meaning of the thread-context area, it may choose to
|
||||
use this part of the virtual address space as target for 'mmap'. This
|
||||
may lead to memory corruption. Fortunately, there is a way to tell the
|
||||
kernel about virtual address regions that should be reserved. The
|
||||
trick is to pre-populate the said region with anonymous memory using
|
||||
the 'mmap' arguments 'MAP_PRIVATE', 'MAP_FIXED', 'MAP_ANONYMOUS', and
|
||||
'PROT_NONE'. The kernel will still accept a fixed-address mapping
|
||||
within such a reserved region (overmap) but won't consider using the
|
||||
region by itself. The reservation must be done at the startup of each
|
||||
process and each time when detaching a dataspace from the thread
|
||||
context area. For the process startup, we use the hook function
|
||||
'main_thread_bootstrap' in 'src/platform/_main_helper.h'. For reverting
|
||||
detached dataspaces to a reserved region within the context area, we
|
||||
added as special case to 'src/base/env/rm_session_mmap.cc'.
|
||||
For hybrid programs (Genode processes that link against native
|
||||
shared libraries of the Linux system), which are loaded by the dynamic
|
||||
linker of Linux, we must further prevent the dynamic linker from
|
||||
populating the thread-context area. This is achieved by adding a
|
||||
special program segment at the linking stage of all elf binaries.
|
||||
|
||||
@@ -1,876 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 11.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
One year ago, the release 10.02 was our break-through with regard to the support
|
||||
of multiple kernels as base platform for Genode. With the added support for
|
||||
the NOVA hypervisor and the Codezero kernel, Genode applications could be executed
|
||||
on 6 different kernels. With the current release, we take our commitment to
|
||||
kernel platform support even further. With the added support for the Fiasco.OC
|
||||
kernel, we make Genode available on one of the most feature-rich modern microkernels.
|
||||
Additionally, we entered the realms of kernel design with our new platform support
|
||||
for the Xilinx MicroBlaze architecture. This platform support comes in the shape
|
||||
of a custom kernel specifically targeted to the MicroBlaze CPU architecture.
|
||||
Furthermore, we updated our support for the NOVA Hypervisor to the bleeding-edge
|
||||
version 0.3, which has been released earlier this month.
|
||||
|
||||
With the current support for 8 different kernel platforms (L4/Fiasco, Linux,
|
||||
L4ka::Pistachio, OKL4, NOVA, Codezero, Fiasco.OC, and native MicroBlaze), testing
|
||||
and integrating application scenarios across all platforms becomes increasingly
|
||||
challenging. Therefore, we introduce a new framework for automating such tasks.
|
||||
Thanks to the tight integration of the automation tool with Genode's build system,
|
||||
going back and forth between different kernels becomes an almost seamless
|
||||
experience.
|
||||
|
||||
Functionality-wise, the release carries on our vision to create a highly secure
|
||||
yet easy to use general-purpose operating system. Because the Genode framework
|
||||
is developed on Linux using the wonderful GNU tools, we consider the
|
||||
availability of the GNU user land on Genode as crucial for using the system by
|
||||
ourself. This motivation drives the creation of a custom execution environment
|
||||
for GNU software on top of Genode. With the current release, we are proud to
|
||||
present the first pieces of this execution environment. Even though not fully
|
||||
functional yet, it clearly shows the direction of where we are heading.
|
||||
|
||||
|
||||
Support for Fiasco.OC
|
||||
#####################
|
||||
|
||||
The OC in the name of the Fiasco.OC kernel stands for "object capability", hinting
|
||||
at the most significant feature that sets current-generation microkernels such as
|
||||
NOVA, seL4, and Fiasco.OC apart from their predecessors. Whereas previous L4 kernels
|
||||
succeeded in protecting subsystems from each other, the new generation of kernels
|
||||
is geared towards strict security policies. Traditionally, two protection domains
|
||||
were able to communicate with each other if they both agreed. Communication partners
|
||||
were typically globally known via their respective thread/task IDs. Obviously, this
|
||||
policy is not able to guarantee the separation of subsystems. If two subsystems
|
||||
conspire, they could always share information. Object-capability-based kernels
|
||||
are taking the separation much further by prohibiting any communication between
|
||||
protection domains by default. Two protection domains can communicate only if
|
||||
a common acquaintance of both agrees. This default-deny policy facilitates the
|
||||
creation of least-privilege security policies. From the ground up, Genode has
|
||||
been designed as a capability-based system which is naturally capable of leveraging
|
||||
kernel-based object-capability support if present. After NOVA, Fiasc.OC is the
|
||||
second of Genode's base platforms that provides this feature.
|
||||
|
||||
Apart from being a capability-based kernel, Fiasco.OC has a number of compelling
|
||||
features such as thorough support for ARM platforms and the x86 32/64 bit
|
||||
architectures. It supports SMP, hardware virtualization, and provides special
|
||||
optimizations for running paravirtualized operating systems.
|
||||
|
||||
Technically, Fiasco.OC is the successor of the L4/Fiasco kernel developed by
|
||||
the OS group of the TU-Dresden. However, the kernel interface of Fiasco.OC has
|
||||
not much in common with L4/Fiasco. Some heritages are still there (e.g., IPC
|
||||
timeouts) but the kernel API has evolved to a fully object-oriented model.
|
||||
|
||||
:Thanks:
|
||||
|
||||
We are indebted to the main developer of Fiasco.OC Alexander Warg for being
|
||||
very reponsive to our inquiries while doing the porting work. Thanks to his
|
||||
support, the adaptation of Genode to this kernel has been an almost smooth
|
||||
ride.
|
||||
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
You need GNU C & C++ Compilers, GNU Binutils, GNU Make, and Perl to use the
|
||||
Fiasco.OC build system. On Debian/Ubuntu systems, you have to install the
|
||||
following packages:
|
||||
|
||||
! apt-get install make gawk g++ binutils pkg-config subversion
|
||||
|
||||
Moreover, you need to download and install the tool-chain used by Genode. Have
|
||||
a look at this page:
|
||||
|
||||
:[http://genode.org/download/tool-chain]:
|
||||
Genode tool-chain
|
||||
|
||||
|
||||
Downloading and building Fiasco.OC
|
||||
==================================
|
||||
|
||||
Checkout the Fiasco.OC sources and tool-chain to an appropriated directory:
|
||||
|
||||
! export REPOMGR_SVN_REV=27
|
||||
! svn cat http://svn.tudos.org/repos/oc/tudos/trunk/repomgr |\
|
||||
! perl - init http://svn.tudos.org/repos/oc/tudos fiasco l4re
|
||||
|
||||
|
||||
Building the kernel
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create the build directory for the kernel:
|
||||
|
||||
! cd <path_to_fiasco_src_dir>/src/kernel/fiasco
|
||||
! make BUILDDIR=<path_to_kernel_build_dir>
|
||||
|
||||
Go to the build directory, configure the kernel:
|
||||
|
||||
! cd mybuild
|
||||
! make config
|
||||
|
||||
This will launch the configuration menu. Here you can configure your kernel.
|
||||
The default config is just fine to test the Genode port. It will build a
|
||||
uniprocessor IA32 kernel with debugging features enabled. You can exit the menu and
|
||||
save the configuration by simply typing 'x'.
|
||||
|
||||
Now, build Fiasco.OC by invoking:
|
||||
|
||||
! make
|
||||
|
||||
|
||||
Building necessary tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To practically use Fiasco.OC, you need in addition to the kernel a tool to
|
||||
bootstrap it, and the initial pager of the system, namely 'sigma0'. Both tools
|
||||
can be found in the L4 runtime environment's base directory. Outgoing from
|
||||
the directory where you checked out the sources, you have to change to the
|
||||
following directory:
|
||||
|
||||
! cd <path_to_fiasco_src_dir>/src/l4
|
||||
|
||||
Create another build directory:
|
||||
|
||||
! make B=<path_to_l4re_build_dir>
|
||||
|
||||
Again, you might want to tweak the configuration:
|
||||
|
||||
! make O=<path_to_l4re_build_dir> config
|
||||
|
||||
Finally, build the tools:
|
||||
|
||||
! make O=<path_to_l4re_build_dir>
|
||||
|
||||
|
||||
Building the Fiasco.OC version of Genode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Fiasco.OC version of Genode is available at the Genode public subversion repository:
|
||||
|
||||
:http://genode.org/download/subversion-repository:
|
||||
Information about accessing the Genode public subversion repository
|
||||
|
||||
Go to a directory where you want the Genode/Fiasco.OC build directory to remain. Use
|
||||
the helper script in the 'tool/builddir' directory of the Genode source tree to
|
||||
create the initial build environment. You need to state the absolute path to the
|
||||
build directory of the L4 runtime environment as 'L4_DIR', as it contains the kernel
|
||||
bindings needed by the Genode port.
|
||||
|
||||
! <path_to_genode_src_dir>/tool/builddir/create_builddir foc_x86_32 \
|
||||
! L4_DIR=<path_to_l4re_build_dir> \
|
||||
! GENODE_DIR=<path_to_genode_src_dir> \
|
||||
! BUILD_DIR=<path_to_genode_build_dir>
|
||||
|
||||
Now, go to the newly created build directory and type make.
|
||||
|
||||
! cd <path_to_genode_build_dir>
|
||||
! make
|
||||
|
||||
|
||||
Booting Genode on top of Fiasco.OC
|
||||
==================================
|
||||
|
||||
Example GRUB configuration entry:
|
||||
|
||||
! timeout 0
|
||||
! default 0
|
||||
!
|
||||
! title Genode on Fiasco.OC
|
||||
! kernel /bootstrap -modaddr=0x01100000
|
||||
! module /fiasco -serial_esc
|
||||
! module /sigma0
|
||||
! module /core
|
||||
! module /init
|
||||
! module /config
|
||||
! module /pci_drv
|
||||
! module /vesa_drv
|
||||
! module /ps2_drv
|
||||
! module /timer
|
||||
! module /nitpicker
|
||||
! module /launchpad
|
||||
! module /liquid_fb
|
||||
! module /scout
|
||||
! module /testnit
|
||||
! module /nitlog
|
||||
|
||||
For an example of a matching Genode 'config' file, please take a look
|
||||
at 'os/config/demo'.
|
||||
|
||||
The Genode binaries are located in '<path_to_genode_build_dir>/bin',
|
||||
the 'fiasco' kernel in '<path_to_kernel_build_dir>'. Assuming you compiled
|
||||
for x86/586 (the default), you can find the 'bootstrap' binary in
|
||||
'bin/x86_586' and 'sigma0' in 'bin/x86_586/l4f' within the
|
||||
'<path_to_l4re_build_dir>' directory.
|
||||
|
||||
|
||||
Current state
|
||||
=============
|
||||
|
||||
The adaptation of Genode to Fiasco.OC covers most parts of the Genode API
|
||||
including advanced semantics such as cancelable locks and support for
|
||||
real-time priorities. So far, it has been tested on the x86 architecture.
|
||||
Because 'base-foc' does not contain x86-specific code, we expect no major
|
||||
roadblocks for running Genode on Fiasco.OC on ARM. However, we have not
|
||||
exercised tests in this regard.
|
||||
|
||||
As of today, there exist the following limitations of the Fiasco.OC support:
|
||||
|
||||
* The dynamic linker is not yet adapted to Fiasco.OC. Special care must
|
||||
be taken for handling the parent capability for dynamically loaded
|
||||
programs. We have already covered this issue for the NOVA version but
|
||||
the adaptation to Fiasco.OC remains yet to be done.
|
||||
|
||||
* The destruction of sub systems is not yet fully stable. Because Genode
|
||||
forms a more dynamic workload than the original userland accompanied with
|
||||
the kernel, the usage pattern of the kernel API triggers different
|
||||
effects. We are working with the Fiasco.OC developers to remedy this
|
||||
issue.
|
||||
|
||||
* The signalling framework is not yet supported. A design exist but it is
|
||||
not implemented yet.
|
||||
|
||||
We believe however that none of these limitations are a significant hurdle for
|
||||
starting to use Genode with this kernel. Please expect this issues to be
|
||||
resolved with the upcoming Genode release.
|
||||
|
||||
|
||||
Technical details about 'base-foc'
|
||||
==================================
|
||||
|
||||
The following technical bits are worth noting when exploring the use of
|
||||
Genode with the 'base-foc' platform.
|
||||
|
||||
* The timer implementation uses a one thread-per-client mode of operation.
|
||||
We use IPC timeouts as time source. Hence, the timer driver is hardware
|
||||
independent and should work out of the box on all hardware platforms
|
||||
supported by Fiasco.OC.
|
||||
|
||||
* Each 'Server_object' of Genode corresponds to a so-called IPC gate,
|
||||
which is the Fiasco.OC kernel object used for capability invocation.
|
||||
Therefore, protection and object integrity is provided at the fine
|
||||
granularity of single 'Server_objects'. This is in line with our
|
||||
support for NOVA's implementation of capability-based security.
|
||||
|
||||
* In contrast to the lock implementation that we used with the original
|
||||
L4/Fiasco kernel, the 'base-foc' lock is a fully-featured Genode lock
|
||||
with support for lock cancellation and blocking. For blocking and
|
||||
waking up lock applicants, we use Fiasco.OC's IRQ objects.
|
||||
|
||||
* The allocator used for managing process-local capability selectors
|
||||
does not yet support the reuse of capability selectors.
|
||||
|
||||
|
||||
Further Information
|
||||
===================
|
||||
|
||||
:genode/tool/builddir/README:
|
||||
Reference manual for the 'create_builddir' script
|
||||
|
||||
:[http://os.inf.tu-dresden.de/fiasco]:
|
||||
Official website for the Fiasco.OC microkernel.
|
||||
|
||||
|
||||
Noux - an execution environment for the GNU userland
|
||||
####################################################
|
||||
|
||||
Even though Genode is currently mainly geared to the classical special-purpose
|
||||
application domains for microkernel-based systems, the main property that sets
|
||||
Genode apart from traditional systems is the thorough support for dynamic
|
||||
workloads and the powerful mechanisms for handling hardware resources and
|
||||
security policies in highly dynamic setting. We are convinced that Genode's
|
||||
architecture scales far beyond static special-purpose domains and believe in
|
||||
the feasibility of Genode as a solid foundation for a fully-fledged general
|
||||
purpose operating system. Internally at Genode Labs, we set up the ultimate
|
||||
goal to switch from Linux to Genode for our day-to-day work. We identified
|
||||
several functionalities that we could not live without and systematically try
|
||||
to bring those features to Genode. Of course, the most fundamental programs
|
||||
are the tools needed to develop and build Genode. Currently we are developing
|
||||
on Linux and enjoy using the GNU userland.
|
||||
|
||||
Consequently, we require a solution for using this rich tool set on Genode.
|
||||
The straight-forward way for making these tools available on Genode would be
|
||||
running them within a virtualized Linux instance (e.g., using OKLinux on OKL4).
|
||||
However, this approach would defeat our actual goal to create a highly secure
|
||||
yet easy to use working environment because adding Linux to the picture would
|
||||
involve administering the virtualized Linux system. We would prefer a native
|
||||
solution that makes the overall system less, not more, complicated. This way
|
||||
the idea for a native execution environment for the GNU userland on Genode
|
||||
was born. The implementation is called Noux and the first bits of code are
|
||||
featured in the 'ports' repository. Noux consists of two parts, a build
|
||||
environment for compiling GNU programs such that they can be run as Genode
|
||||
processes and an execution environment that provides the classical UNIX
|
||||
functionality to these programs.
|
||||
|
||||
|
||||
Noux build environment
|
||||
======================
|
||||
|
||||
From our experience, porting existing UNIX applications to a non-UNIX system
|
||||
tends to be a task of manual and time-consuming labour. One has to loosely
|
||||
understand the build system and the relationship of the involved source codes,
|
||||
implement dummy functions for unresolved references, and develop custom glue
|
||||
code that interfaces the ported application to the actual system. Taking the
|
||||
shortcut of changing the original code has to be avoided at any cost because
|
||||
this produces recurring costs in the future when updating the application. In
|
||||
short, this long-winding process does not scale. For porting a tool set such as
|
||||
the GNU userland consisting of far more than a three-digit number of individual
|
||||
programs, this manual approach becomes unfeasible. Therefore, we have created
|
||||
a build environment that facilitates the use of the original procedure of
|
||||
invoking './configure && make'. The challenge is to supply configure with
|
||||
the right arguments and environment variables ('CFLAGS' and the like) such that
|
||||
the package is configured against the Genode environment. The following
|
||||
considerations must be taken:
|
||||
|
||||
* Configure must not detect any global headers (e.g., '/usr/include/')
|
||||
or libraries (e.g., '/usr/lib/'). This can be achieved by the '-nostdinc' and
|
||||
'-nostdlib' options
|
||||
* Configure has to use the same include-search paths as used for compiling
|
||||
normal libc-using Genode programs
|
||||
* Configure must use the Genode tool chain
|
||||
* The final linking stage must use the Genode linker script, the Genode
|
||||
base libraries, and other Genode-specific linker arguments.
|
||||
|
||||
Thanks to the power of the GNU build system, all this can be achieved by
|
||||
supplying arguments to './configure' and indirectly to the 'make' process via
|
||||
environment variables. The new Noux build environment takes care of these
|
||||
precautions. It comes in the form of the 'ports/mk/noux.mk' file which enables
|
||||
the seamless integration of GNU packages with the Genode build system. To
|
||||
compile a GNU package, the manual steps needed are reduced to the creation of a
|
||||
'target.mk' file representing the package. This 'target.mk' defines the name
|
||||
of the package (by default, the basename of the 'target.mk' enclosing directory
|
||||
is assumed) and the location of the source package. With this approach, we
|
||||
managed to build 'coreutils' (over 100 small UNIX utilities such as 'ls', 'cp',
|
||||
'sort'), 'binutils' (GNU linker, assembler, object-file tools), 'findutils'
|
||||
('find', 'xargs'), 'bash', 'dash', GNU make, and finally the GNU compiler
|
||||
collection including 'g++'. The resulting binaries are ready to be executed as
|
||||
native Genode processes. However, without the right environment that presents
|
||||
the program the needed UNIX functionality, those programs won't do much.
|
||||
This leads us to the Noux execution environment.
|
||||
|
||||
|
||||
Noux execution environment
|
||||
==========================
|
||||
|
||||
The Noux execution environment plays the role of a UNIX kernel for programs
|
||||
built via the Noux build environment. In contrast to a real kernel, the Noux
|
||||
environment is a plain Genode user-level process that plays the role of being
|
||||
the parent of one or multiple Noux processes. In addition of providing the
|
||||
'Genode::Parent' interface, Noux also provides a locally implemented service called
|
||||
'Noux::Session' that offers UNIX-like system-calls via an RPC interface. Each
|
||||
hosted program is linked against a special Noux libc plugin that catches all
|
||||
libc calls that would normally result in a system call. It then transparently
|
||||
forwards this function call to the 'Noux::Session' interface.
|
||||
|
||||
Currently the Noux execution environment implements the following
|
||||
system calls: 'getcwd', 'write', 'stat', 'fstat', 'fcntl', 'open',
|
||||
'close', 'dirent', 'fchdir', 'read', and 'execve'.
|
||||
|
||||
The execution environment submits arguments (argc, argv, environment) to the
|
||||
hosted program, manages its current working directory and receives its exit
|
||||
code. File operations are targeted to a custom VFS infrastructure, which
|
||||
principally allows a flexible configuration of the virtual file system visible
|
||||
to the hosted programs. At the current stage, Noux supports mounting plain tar
|
||||
archives obtained from core's ROM service as read-only file system. On startup,
|
||||
the Noux environment starts one process (the init process) and connects the
|
||||
file descriptor 1 (stdout) to Genode's LOG service.
|
||||
|
||||
State of the implementation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The infrastructure implemented so far already allows the execution of many simple
|
||||
UNIX tools such as 'ls -lRa', 'echo', 'seq', 'find'. The 'execve' system call
|
||||
is implemented such that a new process is started that inherits the file
|
||||
descriptors and the PID of the calling process. This allows using the exec
|
||||
functionality of the 'bash' shell. However, because 'fork' is not implemented
|
||||
yet, there is currently no way to start multiple programs hosted in a single
|
||||
Noux execution environment.
|
||||
|
||||
As of today, the Noux environment is not considered to be usable for practical
|
||||
purposes. However, it clearly shows the feasibility of the path we are walking.
|
||||
With the foundation laid, we are looking forward to expanding Noux to a capable
|
||||
solution for running our beloved GNU userland tools on Genode.
|
||||
|
||||
Vision
|
||||
~~~~~~
|
||||
|
||||
The most significant intermediate result of pursuing the development of Noux is
|
||||
the realization that such an environment is not exceedingly complex. Because of
|
||||
the combination with Genode, we only need to provide a comfortable runtime as
|
||||
expected by user processes but we can leave much of intricate parts of UNIX out
|
||||
of the picture. For example, because we handle device drivers on Genode, we do
|
||||
not need to consider device-user interaction in Noux. As another example,
|
||||
because the problem of bootstrapping the OS is already solved by Genode, there
|
||||
is no need to run an 'init' process within Noux. Our vision foresees that Noux
|
||||
runtimes are to be created on demand for individual tasks such as editing a
|
||||
file (starting a custom Noux instance containing only the file to edit and the
|
||||
text editor), compiling source code (starting a custom Noux instance with only
|
||||
the source code and the build tools). Because Noux is so simple, we expect the
|
||||
runtime overhead of starting a Noux instance to be not more than the time
|
||||
needed to spawn a shell in a normal UNIX-like system.
|
||||
|
||||
Test drive
|
||||
~~~~~~~~~~
|
||||
|
||||
To give Noux a spin, we recommend using Linux as base platform as this is
|
||||
the platform we use for developing it. First, you will need to download the
|
||||
source code of the GNU packages. From within the 'ports' repository,
|
||||
use the following command:
|
||||
|
||||
! make prepare PKG=coreutils
|
||||
|
||||
This command will download the source code of the GNU coreutils. You may
|
||||
also like to give the other packages a try. To see what is available,
|
||||
just call 'make' without any argument.
|
||||
|
||||
Create a build directory (e.g., using tool/builddir/create_builddir).
|
||||
Change to the build directory and issue the command
|
||||
|
||||
! make run/noux
|
||||
|
||||
This command will execute the run script provided at 'ports/run/noux.run'.
|
||||
First it builds core, init, and coreutils. Then it creates a tar archive
|
||||
containing the installed coreutils. Finally, it starts the Noux environment on
|
||||
Genode. Noux then mounts the TAR archive as file system and executes 'ls -laR',
|
||||
showing the directory tree.
|
||||
|
||||
|
||||
Approaching platform support for Xilinx MicroBlaze
|
||||
##################################################
|
||||
|
||||
With the release 11.02, we are excited to include the first version of our
|
||||
custom platform support for the Xilinx MicroBlaze CPU architecture. MicroBlaze
|
||||
is a so-called softcore CPU, which is commonly used as part of FPGA-based
|
||||
System-on-Chip designs. At Genode Labs, we are regularly using this IP core,
|
||||
in particular for our Genode FPGA Graphics Project, which is a GUI software stack
|
||||
and a set of IP cores for implementing fully-fledged windowed GUIs on FPGAs:
|
||||
|
||||
:Website of the Genode FPGA Graphics Project:
|
||||
|
||||
[http://genode-labs.com/products/fpga-graphics]
|
||||
|
||||
Ever since we first released the Genode FPGA project, we envisioned to combine
|
||||
it with the Genode OS Framework. In Spring 2010, Martin Stein joined our team
|
||||
at Genode Labs and accepted the challenge to bring the Genode OS Framework to
|
||||
the realms of FPGA-based SoCs. Technically, this implies porting the framework
|
||||
to the MicroBlaze CPU architecture. In contrast to most softcore CPUs such as
|
||||
the popular Lattice Mico32, the MicroBlaze features a MMU, which is a fundamental
|
||||
requirement for implementing a microkernel-based system. Architecturally-wise
|
||||
MicroBlaze is a RISC CPU similar to MIPS. Many system parameters of the CPU
|
||||
(caches, certain arithmetic and shift instructions) can be parametrized at
|
||||
synthesizing time of the SoC. We found that the relatively simple architecture
|
||||
of this CPU provides a perfect playground for pursuing some of our ideas about
|
||||
kernel design that go beyond the scope of current microkernels. So instead of
|
||||
adding MicroBlaze support into one of the existing microkernels already
|
||||
supported by Genode, we went for a new kernel design. Deviating from the typical
|
||||
microkernel, which is a self-sufficient program running in kernel mode that
|
||||
executes user-level processes on top, our design regards the kernel as a part of
|
||||
Genode's core. It is not a separate program but a library that implements the
|
||||
glue between user-level core and the raw CPU. Specifically, it provides the
|
||||
entrypoint for hardware exceptions, a thread scheduler, an IPC mechanism, and
|
||||
functions to manipulate virtual address spaces (loading and flushing entries
|
||||
from the CPU's software-loaded TLB). It does not manage any physical memory
|
||||
resources or the relationship between processes. This is the job of core.
|
||||
From the kernel-developer's point of view, the kernel part can be summarized as
|
||||
follows:
|
||||
|
||||
* The kernel provides user-level threads that are scheduled in a round-robin
|
||||
fashion.
|
||||
* Threads can communicate via synchronous IPC.
|
||||
* There is a mechanism for blocking and waking up threads. This mechanism
|
||||
can be used by Genode to implement locking as well as asynchronous
|
||||
inter-process communication.
|
||||
* There is a single kernel thread, which never blocks in the kernel code paths.
|
||||
So the kernel acts as a state machine. Naturally, there is no concurrency in the
|
||||
execution paths traversed in kernel mode, vastly simplifying these code parts.
|
||||
However, all code paths are extremely short and bounded with regard to
|
||||
execution time. Hence, we expect the interference with interrupt latencies
|
||||
to be low.
|
||||
* The IPC operation transfers payload between UTCBs only. Each thread has a
|
||||
so-called user-level thread control block which is mapped transparently by
|
||||
the kernel. Because of this mapping, user-level page faults cannot occur
|
||||
during IPC transfers.
|
||||
* There is no mapping database. Virtual address spaces are manipulated by
|
||||
loading and flushing physical TLB entries. There is no caching of mappings
|
||||
done in the kernel. All higher-level information about the interrelationship
|
||||
of memory and processes is managed by the user-level core.
|
||||
* Core runs in user mode, mapped 1-to-1 from the physical address space
|
||||
except for its virtual thread-context area.
|
||||
* The kernel paths are executed in physical address space (MicroBlaze).
|
||||
Because both kernel code and user-level core code are observing the same
|
||||
address-space layout, both worlds appear to run within a single address
|
||||
space.
|
||||
* User processes can use the entire virtual address space (4G) except for a
|
||||
helper page for invoking syscalls and a page containing atomic operations.
|
||||
There is no reservation used for the kernel.
|
||||
* The MicroBlaze architecture lacks an atomic compare-and-swap instruction. On
|
||||
user-level, this functionality is emulated via delayed preemption. A kernel-
|
||||
provided page holds the sequence of operations to be executed atomically and
|
||||
prevents (actually delays) the preemption of a thread that is currently
|
||||
executing instructions at that page.
|
||||
* The MicroBlaze MMU supports several different page sizes (1K up to 16MB).
|
||||
Genode fully supports this feature for page sizes >= 4K. This way, the TLB
|
||||
footprint can be minimized by choosing sensible alignments of memory
|
||||
objects.
|
||||
|
||||
Current state
|
||||
=============
|
||||
|
||||
The MicroBlaze platform support resides in the 'base-mb' repository. At the
|
||||
current stage, core is able to successfully start multiple nested instances of
|
||||
the init process. Most of the critical kernel functionality is working. This
|
||||
includes inter-process communication, address-space creation, multi-threading,
|
||||
thread synchronization, page-fault handling, and TLB eviction.
|
||||
|
||||
This simple scenario already illustrates the vast advantage of
|
||||
using different page sizes supported by the MicroBlaze CPU. If using
|
||||
4KB pages only, a scenario with three nested init processes produces more than
|
||||
300.000 page faults. There is an extremely high pressure on the TLB, which
|
||||
only contains 64 entries. Those entries are constantly evicted so that
|
||||
threshing effects are likely to occur. By making use of flexible page
|
||||
sizes (4K, 16K, 64K, 256K, 1M, 4M, 16M), the number of page faults gets
|
||||
slashed to only 1.800, speeding up the boot time by factor 10.
|
||||
|
||||
Currently, there is no restriction of IPC communication rights. Threads are
|
||||
addressed using their global thread IDs (in fact, using their respective
|
||||
indices in the KTCB array). For the future, we are planning to add
|
||||
capabilty-based delegation of communication rights.
|
||||
|
||||
Building and using Genode on MicroBlaze
|
||||
=======================================
|
||||
|
||||
For building Genode for the MicroBlaze platform, you need the MicroBlaze
|
||||
tool chain as it comes with the Xilinx EDK. The tool chain is typically
|
||||
prefixed with 'mb-'. Please make sure that the tool chain's 'bin/' directory
|
||||
is included in your 'PATH' environment variable.
|
||||
|
||||
For building and starting Genode on MicroBlaze, you first need to create
|
||||
a build directory using the build-directory creation tool:
|
||||
|
||||
! tool/builddir/create_builddir microblaze \
|
||||
! BUILD_DIR=</path/to/build/dir> \
|
||||
! GENODE_DIR=</path/to/genode/dir>
|
||||
|
||||
The 'base-mb' repository comes with support for Genode's run tool. In order to
|
||||
use it, you will first need to declare the location of your qemu binary using
|
||||
the 'QEMU=/path/to/qemu' variable in the '<build-dir>/etc/microblaze.conf'
|
||||
file. Then you will be able to start an example scenario by issuing the
|
||||
following command from within your build directory:
|
||||
|
||||
! make run/nested_init
|
||||
|
||||
Thereby, the 'run' tool will attempt to start core using the microblaze version
|
||||
of qemu.
|
||||
|
||||
You can also find a simple hello-world example at 'base-mb/src/test/hello'.
|
||||
The corresponding run script is located at 'base-mb/run/hello.run'. You can
|
||||
execute it via 'make run/hello' from the build directory.
|
||||
|
||||
Note that currently, all boot modules are linked against the core binary.
|
||||
To change the boot modules, the file 'base-mb/src/core/boot_modules.s' must
|
||||
be modified.
|
||||
|
||||
For reference, we are using the following tools:
|
||||
|
||||
* mb-g++ (GCC) 4.1.1 20060524 (Xilinx 11.2 Build EDK_LS2.2
|
||||
20 Apr 2009 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009)
|
||||
* GNU ld version 2.16 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009
|
||||
* GNU assembler 2.16 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009
|
||||
* QEMU emulator version 0.14.50, Copyright (c) 2003-2008 Fabrice Bellard
|
||||
Petalogix linux reference design targeting Xilinx Spartan 3ADSP-1800 boards.
|
||||
|
||||
|
||||
Supporting the NOVA hypervisor version 0.3
|
||||
##########################################
|
||||
|
||||
NOVA is a so called microhypervisor - a modern capability-based microkernel
|
||||
with special support for hardware-based virtualization and IOMMUs. Since we
|
||||
incorporated the initial support for the NOVA hypervisor in Genode one year
|
||||
ago, this kernel underwent multiple revisions. The latest version was released
|
||||
earlier this month. To our delight, much of the features that we missed from
|
||||
the initial release had been implemented during the course of the last year. We
|
||||
are especially happy about the fully functional 'revoke' system call and the
|
||||
support for remote kernel-object creation.
|
||||
|
||||
With the Genode release 11.02, we officially support the latest NOVA version.
|
||||
The update of Genode to the new version required two steps. First, because many
|
||||
details of the kernel interface were changed between version 0.1 and version
|
||||
0.3, we had to revisit our syscall bindings and adapting our code to changed
|
||||
kernel semantics. Second, we filled our 'base-nova' code related to object
|
||||
destruction and unmapping with life to benefit from NOVA's 'revoke' system
|
||||
call. Consequently, we are now able to run the complete Genode software stack
|
||||
including the dynamic linker on NOVA.
|
||||
|
||||
Note that for using Genode on NOVA, you will need to apply a small patch to the
|
||||
NOVA source code. This patch enables the re-use of user-level thread control
|
||||
blocks in the kernel. The patch can be found at 'base-nova/patches/utcb.patch'.
|
||||
|
||||
When executing NOVA on qemu, please specify the '-cpu coreduo' argument to the
|
||||
qemu command line. When using Genode 'run' tool, you may assign this argument
|
||||
to the 'QEMU_OPT' variable in '<build-dir>/etc/build.conf'.
|
||||
|
||||
:Thanks:
|
||||
|
||||
We are grateful for the ongoing very pleasant collaboration with Udo Steinberg
|
||||
who is the driving force behind NOVA. Thanks for the ultra-fast responses to our
|
||||
questions and for considering our suggestions regarding the feature set of
|
||||
NOVA's kernel interface!
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Upgrading existing sessions
|
||||
===========================
|
||||
|
||||
Genode enables a client of a service to lend parts of its own resources to
|
||||
the service when opening a session. This way, servers do not need to allocate
|
||||
own resources on behalf of their clients and become inherently robust against
|
||||
resource-exhaustion-based denial-of-service attacks.
|
||||
|
||||
However, there are cases when the client can not decide about the amount of
|
||||
resources to lend at session-creation time. In such cases, we used to devise an
|
||||
overly generous client policy. Now, we have added a new 'upgrade' function to
|
||||
the 'Parent' and 'Root' interfaces that enables a client to upgrade the
|
||||
resources of an existing session.
|
||||
|
||||
For the 'env()->rm_session()' and 'env()->ram_session()' of processes using
|
||||
the Genode 'env' library, we implemented a transparent quota upgrade that kicks in
|
||||
in the event of an exceeded metadata backing store.
|
||||
|
||||
|
||||
Comprehensive accounting of core resources
|
||||
==========================================
|
||||
|
||||
We changed all services of core to limit their respective resource usage
|
||||
specifically for each individual session. For example, the number of dataspaces
|
||||
that can be handled by a particular region-manager (RM) session depends on the
|
||||
resource donation attached to the session. To implement this accounting scheme
|
||||
throughout core, we added a generic 'Allocator_guard' utility to
|
||||
'base/include/'. We recommend using this utility when implementing resource
|
||||
multiplexers, in particular multi-level services. Thanks to this change in
|
||||
core, the need for a slack memory reservation in core has vanished.
|
||||
|
||||
|
||||
Various changes
|
||||
===============
|
||||
|
||||
The remaining parts of the base API underwent no fundamental revision. The
|
||||
changes are summarized as follows.
|
||||
|
||||
:C++ Support:
|
||||
|
||||
We removed 'libgcc' from our C++ support library ('cxx') and link
|
||||
it to each individual final target and shared library instead. This change alleviates
|
||||
the need to abuse the 'KEEP_SYMBOLS' mechanism that we used in 'cxx' to
|
||||
keep libc-dependencies of GCC's support libraries local to the 'cxx'
|
||||
library. Besides the benefit of reducing heuristics, this change improves
|
||||
the compatibility with recent cross-compiling tool chains.
|
||||
Furthermore, we added 'realloc' to the local libc support of the 'cxx'
|
||||
library because recent ARM tool chains tend to use this function.
|
||||
|
||||
:Argument handling for 'main()':
|
||||
|
||||
We added a hook to the startup code to enable the implementation of
|
||||
custom facilities for passing arguments to the main function. The
|
||||
hook uses the global variables 'genode_argc' and 'genode_argv'.
|
||||
|
||||
:Child-exit policy hook:
|
||||
|
||||
We enhanced the 'Child_policy' with a new policy interface that allows
|
||||
a simplified implementation of policies related to program termination.
|
||||
|
||||
:Changed API of 'Range_allocator':
|
||||
|
||||
We changed the return value of 'alloc_addr' to distinguish different error
|
||||
conditions. Note that the boolean meaning of the return value is inverted.
|
||||
Please check your uses of 'alloc_addr'!
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
C Runtime
|
||||
=========
|
||||
|
||||
In conjunction with our work on Noux, we improved Genode's C runtime at many
|
||||
places. First, we added libstdtime and some previously missing bits of libgdtoa
|
||||
to the libc. These additions largely alleviate the need for dummy stubs, in
|
||||
particular time-related functions. Second, we added the following functions to
|
||||
our libc plugin interface: 'dup2', 'fchdir', 'fcntl', 'fstat', 'stat', and
|
||||
'write'. This enables the creation of advanced libc plugins simulating a whole
|
||||
file system as done with Noux. Still, there are a number of dummy stubs found
|
||||
at 'libc/src/lib/libc/dummy.cc'. However, those stubs are now all defined as
|
||||
weak symbols such that they can be overridden by libc plugins. Finally, we have
|
||||
replaced the original 'exit' implementation that comes with the libc with a
|
||||
Genode-specific version. The new version reports the exit code of the
|
||||
application to the parent process via an 'Parent::exit()' RPC call.
|
||||
|
||||
Until now, Genode's libc magically handled output to stdout and stderr by
|
||||
printing messages via Genode's LOG interface. We have now replaced this
|
||||
hard-wired interface by an optional libc plugin called 'libc_log'. If present, write
|
||||
operations to stdout are caught at the libc plugin interface and delegated to
|
||||
the plugin, which implements the output to the LOG interface. If you have an
|
||||
application using Genode's libc, you might consider adding the 'libc_log'
|
||||
library to your 'target.mk' file.
|
||||
|
||||
|
||||
Support for big numbers by the means of libgmp and libmpfr
|
||||
==========================================================
|
||||
|
||||
We have now include both the GNU Multiple Precision Arithmetic Library and
|
||||
(GMP) and MPFR to the 'ports' repository. This work was specifically motivated
|
||||
by our port of GCC to Genode as GCC version 4.4.5 requires both libraries.
|
||||
Because we intend to use those libraries primarily on x86_32, the current port
|
||||
covers only this architecture. However, expanding the port to
|
||||
further CPU architectures should be straight-forward if needed.
|
||||
|
||||
Furthermore, you can now also find GCC's 'longlong.h' header at
|
||||
'libports/include/gcc'.
|
||||
|
||||
|
||||
Qt4 updated to version 4.7.1
|
||||
############################
|
||||
|
||||
The current release bumps the supported Qt4 version from 4.6.2 to 4.7.1 and the
|
||||
Arora web browser (located at the ports repository) from version 0.10.2 to
|
||||
version 0.11. Of course, we updated our custom additions such as our custom
|
||||
Nitpicker plugin widget that enables the seamless integration of native
|
||||
Nitpicker GUI clients into Qt4 applications to work with the new Qt4 version.
|
||||
|
||||
|
||||
Tools
|
||||
#####
|
||||
|
||||
Tool chain update to GCC 4.4.5 and Binutils 2.21
|
||||
================================================
|
||||
|
||||
We upgraded the official Genode tool chain from gcc 4.2.4 to gcc 4.4.5. Please
|
||||
update your tool chain by downloading the new binary archive (available for x86_32)
|
||||
or building the tool chain from source using our 'tool/tool_chain' utility.
|
||||
|
||||
New support for automated integration and testing
|
||||
=================================================
|
||||
|
||||
With the growing number of supported base platforms, the integration and testing
|
||||
of Genode application scenarios across all kernels becomes
|
||||
increasingly challenging. Each kernel has a different boot mechanism and
|
||||
specific requirements such as the module order of multiboot modules (Fiasco's
|
||||
bootstrap, Pistachio's sigma0 and kickstart), kernel parameters, or the
|
||||
invocation of a single-image creation tool (OKL4's elfweaver). To make our
|
||||
life supporting all those platforms easier, we have created a tool called
|
||||
'run', which is tightly integrated within Genode's build system. In short 'run'
|
||||
gathers the intrinsics in the form of a 'run/env' file specific for the
|
||||
platform used by the current build directory from the respective
|
||||
'base-<platform>' repository. It then executes a so-called run script, which
|
||||
contains all steps needed to configure, build, and integrate an application
|
||||
scenario. For example, a typical run script for building and running a test
|
||||
case resides in a file called '<any-repository>/run/<run-script-name>.run' and
|
||||
looks as follows:
|
||||
|
||||
! build "core init test/exception"
|
||||
! create_boot_directory
|
||||
! install_config {
|
||||
! <config>
|
||||
! <parent-provides>
|
||||
! <!--<service name="ROM"/>-->
|
||||
! <service name="LOG"/>
|
||||
! </parent-provides>
|
||||
! <default-route>
|
||||
! <any-service> <parent/> </any-service>
|
||||
! </default-route>
|
||||
! <start name="test-exception">
|
||||
! <resource name="RAM" quantum="1M"/>
|
||||
! </start>
|
||||
! </config>
|
||||
! }
|
||||
! build_boot_image "core init test-exception"
|
||||
! append qemu_args "-nographic -m 64"
|
||||
! run_genode_until {.*Exception \(label 0xffb0\) occured.*} 10
|
||||
|
||||
First, the build system is instructed to create the targets specified as argument
|
||||
for the 'build' function. Next, for the integration part, a new boot directory is
|
||||
created. On most kernel platform, the respective location of the boot directory
|
||||
is '<build-dir>/var/run/<run-script-name>'. Initially, this directory is empty.
|
||||
It gets populated with a 'config' file specified as argument of the 'install_config'
|
||||
command, and by the boot modules specified at the 'build_boot_image' command.
|
||||
Now that the integration is complete, the scenario is executed via the
|
||||
'run_genode_until' command. This command takes a regular expression as
|
||||
argument, which determines the successful termination of the test case. The
|
||||
second argument is a timeout (is seconds). In the example, the test case will
|
||||
fail if its output does not match the regular expression within the execution
|
||||
time of 10 seconds.
|
||||
|
||||
The command 'append qemu_args' specifies run-script-specific qemu arguments in
|
||||
the case that qemu is used to execute the scenario. This is the case for most
|
||||
kernel platforms (except for Linux where core gets executed directly on the host).
|
||||
Additional build-directory-specific qemu arguments can be specified in the
|
||||
'etc/build.conf' file by defining the 'QEMU_OPT' variable. For example, to
|
||||
prevent KVM being used on Ubuntu Linux, specify:
|
||||
|
||||
! QEMU_OPT = -no-kvm
|
||||
|
||||
To execute the run script from with build directory, you need to have Expect
|
||||
installed. Typically, the Linux package is called 'expect'. Simply issue
|
||||
the following command from within your build directory:
|
||||
|
||||
! make run/<run-script>
|
||||
|
||||
Note that you will need to have a GRUB 'stage2_eltorito' binary available
|
||||
at '<genode-dir>/tool/grub' on base platforms that use an ISO image as boot
|
||||
stategy.
|
||||
|
||||
Because the whole chain of actions, building, integrating, executing, and
|
||||
validating an application scenario is now at the fingertips of issuing a
|
||||
single command with no kernel-specific considerations needed, it has never
|
||||
been easier to run the same scenario on a wide range of different kernels.
|
||||
Please find further instructive examples at 'os/run/'. The 'ldso' run
|
||||
script executes the test of the dynamic linker. It is completely generic.
|
||||
The 'demo' run script starts Genode's default demo scenario and shows how
|
||||
platform-specific considerations (e.g., which device drivers to use) can be
|
||||
taken into account.
|
||||
|
||||
We found that the 'run' tool significantly boosted our productivity not
|
||||
only for testing purposes but also for accelerating the development-test
|
||||
cycle during our day-to-day work.
|
||||
|
||||
:Technical notes:
|
||||
|
||||
The 'run' tool uses Expect as automation tool. Expect is a Tcl interpreter,
|
||||
which is accompanied by special functionality for automating interactive
|
||||
command-line applications. Technically, a run script is an Expect script
|
||||
which gets included by the 'tool/run' script. For the reference of
|
||||
run-specific functions, please revise the documentation in the 'tool/run'
|
||||
script. Because each run script is actual Expect source code, it is possible
|
||||
to use all Tcl and Expect scripting features in a run script.
|
||||
In particular, a run script may issue shell commands using Tcl's 'exec'
|
||||
function. This way, even complex integration tasks can be accomplished.
|
||||
For example, the integration of the Genode Live CD was done via a single
|
||||
run script.
|
||||
|
||||
|
||||
Build system
|
||||
============
|
||||
|
||||
To facilitate the integration of 3rd-party build systems into the Genode build
|
||||
process, we added support for pseudo targets that do not require any 'SRC'
|
||||
declaration. Such 'target.mk' may contain custom rules that will be executed
|
||||
when the target is revisited by the build system. The bindings are as follows:
|
||||
|
||||
! build_3rd_party:
|
||||
! ...custom commands...
|
||||
!
|
||||
! $(TARGET): build_3rd_party
|
||||
!
|
||||
! clean_3rd_party:
|
||||
! ...custom commands...
|
||||
!
|
||||
! clean_prg_objects: clean_3rd_party:
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,703 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 11.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
One of Genode's most distinctive properties is its support for various
|
||||
different kernels as base platforms. Each of the 8 currently supported kernels
|
||||
differs with regard to features, security, hardware support, complexity, and
|
||||
resource management. Even though different applications call for different
|
||||
kernel properties, through Genode, those properties can be leveraged using a
|
||||
unified API. The growing number of supported base platforms, however, poses two
|
||||
challenges, which are the comprehension of the large diversity of tools and
|
||||
boot concepts, and capturing of the semantic differences of all the kernels.
|
||||
|
||||
With the version 11.08, the framework mitigates the former challenge by
|
||||
introducing a unified way to download, build, and use each of the
|
||||
kernels with Genode's user-level infrastructure. The new tools empower users of
|
||||
the framework to instantly change the underlying kernel without the need to know
|
||||
the peculiarities of the respective kernels. Using microkernels has never been
|
||||
easier.
|
||||
|
||||
The second challenge of translating each kernel's specific behaviour to the
|
||||
framework's unified API longs for an automated testing infrastructure that
|
||||
systematically exercises all the various facets of the API on all base
|
||||
platforms. The new version introduces the tooling support especially designed
|
||||
for conducting such quality-assurance measures. These tools largely remove the
|
||||
burden of manual testing while helping us to uphold the stability and quality
|
||||
of the framework as it grows in terms of functional complexity and number of
|
||||
base platforms.
|
||||
|
||||
Speaking of functional enhancements, the work on version 11.08 was focused
|
||||
on our block-device infrastructure and ARM support. The block-device-related
|
||||
work is primarily motivated by our fundamental goal to scale Genode to a
|
||||
general-purpose computing platform. The additions comprise new drivers for
|
||||
SD-cards, IDE, SATA, USB storage as well as a new partition server. All those
|
||||
components provide Genode's generic block interface, which is meant to be used
|
||||
as back end for file systems. On file-system level, a new libc plugin utilizes
|
||||
libffat to enable the straight-forward use of VFAT partitions by libc-using
|
||||
programs.
|
||||
|
||||
The current release comes with far-reaching improvements with respect to
|
||||
ARM-based platforms. The paravirtualized L4Linux kernel has been updated to
|
||||
Linux version 2.6.39 running on both x86_32 and ARM. Also, Qt4 including Webkit
|
||||
has become functional on ARMv6-based platforms.
|
||||
|
||||
Among the further improvements are many new examples in the form of
|
||||
ready-to-use run scripts as well as a comprehensive documentation update.
|
||||
|
||||
Originally, we had planned to complement the Noux runtime environment to
|
||||
support interactive command-line applications by the time of the current
|
||||
release. However, we realized that the current users of the framework would
|
||||
value the new streamlined tooling support, the enhanced documentation, and the
|
||||
new quality-assurance infrastructure over such a functional addition. Hence, we
|
||||
prioritized the topics accordingly. Even though you will find the first bits of
|
||||
interactive GNU application support in this release, we deferred working on
|
||||
this topic in full steam to the upcoming version 11.11.
|
||||
|
||||
|
||||
Blurring the boundaries between different kernels
|
||||
#################################################
|
||||
|
||||
Before the Genode project was born, each microkernel carried along its own
|
||||
userland. For example, the L4/Fiasco kernel came with the L4 environment, the
|
||||
OKL4 kernel came with Iguana, or the L4ka::Pistachio kernel came with a small
|
||||
set of example components. Those user-level counterparts of the kernel
|
||||
complemented their respective kernels with a runtime for user-level
|
||||
applications and components while exposing significant parts of the kernel
|
||||
interface at API level. Consequently, most if not all applications developed
|
||||
against these APIs were tied to a particular kernel. On the one hand, this
|
||||
approach enabled developers to fine-tune their programs using kernel-specific
|
||||
features. On the other hand, much effort was wasted by duplicating other
|
||||
people's work. Eventually, all of the mentioned userlands stayed limited to
|
||||
special purposes - for the most part the purposes of operating-systems
|
||||
researchers. Consequently, none of the microkernels gained much attention in
|
||||
general-purpose computing. Another consequence of the highly fragmented
|
||||
microkernel community was the lack of a common ground to compare different
|
||||
kernels in an unbiased way because each userland provided a different set of
|
||||
components and libraries.
|
||||
|
||||
Different application areas call for different kernel features such as
|
||||
security mechanisms, scheduling, resource management, and hardware support.
|
||||
Naturally, each kernel exhibits a specific profile of these parameters
|
||||
depending on its primary purpose. If one microkernel attempted to accommodate
|
||||
too many features, it would certainly sacrifice the fundamental idea of being
|
||||
minimally complex. Consequently, kernels happen to be vastly different. During
|
||||
the past three years, however, Genode has demonstrated that one carefully
|
||||
crafted API can target highly diverse kernels, and thereby enables users of
|
||||
the framework to select the kernel that fits best with the requirements
|
||||
dictated by each application scenario individually. For us Genode developers,
|
||||
it was extremely gratifying to see that kernels as different as Linux and NOVA
|
||||
can be reconciled at the programming-interface level. Still, each kernel comes
|
||||
with different tools, configuration mechanisms, and boot concepts. Even though
|
||||
Genode programs can be developed in a kernel-independent way, the deployment of
|
||||
such programs still required profound insights into the peculiarities of the
|
||||
respective kernel.
|
||||
|
||||
With the current release, we introduce a fundamentally new way of using
|
||||
different microkernels by unifying the procedures of downloading and building
|
||||
kernels as well as integrating and running Genode programs with each of them.
|
||||
Existing Genode application scenarios can be ported between kernels in an
|
||||
instant without the need for deep insights into the kernel's technicalities. As
|
||||
a teaser, consider the following commands for building and running Genode's
|
||||
graphical demo scenario on the OKL4 microkernel:
|
||||
|
||||
! # check out Genode
|
||||
! svn co https://genode.svn.sourceforge.net/svnroot/genode/trunk genode
|
||||
!
|
||||
! # download the kernel, e.g., OKL4
|
||||
! make -C genode/base-okl4 prepare
|
||||
!
|
||||
! # create Genode build directory
|
||||
! genode/tool/create_builddir \
|
||||
! okl4_x86 BUILD_DIR=build
|
||||
!
|
||||
! # build everything and execute the interactive demo
|
||||
! make -C build run/demo
|
||||
|
||||
The same principle steps can be used for any of the OKL4, NOVA,
|
||||
L4/Fiasco, Fiasco.OC, L4ka::Pistachio, or Codezero kernels. You should
|
||||
nevertheless consult the documentation at 'base-<platform>/doc/' before
|
||||
starting to use a specific kernel because some base platforms require
|
||||
the installation of additional tools.
|
||||
|
||||
Under the hood, this seamless way of dealing with different kernels is made
|
||||
possible by the following considerations:
|
||||
|
||||
:Repository preparation:
|
||||
|
||||
Each kernel comes from a different source such as a Git/SVN/Mercurial
|
||||
repository or a packaged archive. Some kernels require additional patches. For
|
||||
example, OKL4 needs to be patched to overcome problems with modern tool chains.
|
||||
Now, each 'base-<platform>' repository hosts a 'Makefile' that automates the
|
||||
download and patch procedure. To download the source code of a kernel,
|
||||
issue 'make prepare' from within the kernel's 'base-<platform>' directory. The
|
||||
3rd-party source code will be located at 'base-<platform>/contrib/'.
|
||||
|
||||
:Building the kernel:
|
||||
|
||||
Each kernel has a different approach when it comes to configuration and
|
||||
compilation. For example, NOVA comes with a simple 'Makefile', OKL4 relies on a
|
||||
complex SCons-based build system, L4ka::Pistachio uses CML2 and autoconf (for
|
||||
the userland tools). Furthermore, some kernels require the setting of specific
|
||||
configuration values. We have streamlined all these procedures into the Genode
|
||||
build process by the means of a 'kernel' pseudo target and a 'platform' pseudo
|
||||
library. The kernel can be compiled directly from the Genode build directory by
|
||||
issuing 'make kernel'. The 'platform' pseudo library takes care of making the
|
||||
kernel headers available to Genode. For some kernels such as OKL4 and NOVA, we
|
||||
replaced the original build mechanism with a Genode target. For other kernels
|
||||
such as L4ka::Pistachio or Fiasco.OC, we invoke the kernel's build system.
|
||||
|
||||
:Genode build directory:
|
||||
|
||||
Genode build directories are created via the 'tool/create_builddir' tool.
|
||||
This tool used to require certain kernel-specific arguments such as the
|
||||
location of the kernel source tree. Thanks to the unified way of preparing
|
||||
kernels, the need for such arguments has vanished. Now, the only remaining
|
||||
arguments to 'create_builddir' are the actual platform and the location
|
||||
of the build directory to create.
|
||||
|
||||
:System integration and booting:
|
||||
|
||||
As diverse the build systems of the kernels are, so are the boot concepts. Some
|
||||
kernels rely on a multiboot-compliant boot loader whereas others have special
|
||||
tools for creating boot images. Thankfully, Genode's run concept allows us to
|
||||
hide the peculiarities of booting behind a neat and easy-to-use facade. For
|
||||
each platform we have crafted a dedicated run environment located at
|
||||
'base-<platform>/run/env', which contains the rules for system integration and
|
||||
booting. Therefore, one and the same run script can be used to build and
|
||||
execute one application scenario across various different kernels. For an
|
||||
illustrative example, the 'os/src/run/demo.run' script can be executed on all
|
||||
base platforms (except for base-mb) by issuing 'make run/demo' from within the
|
||||
build directory.
|
||||
|
||||
|
||||
Emerging block-device infrastructure
|
||||
####################################
|
||||
|
||||
Since version 10.08, Genode is equipped with a block-session interface. Its
|
||||
primary use cases so far were the supply of the paravirtualized OKLinux kernel
|
||||
with backing store, and the access of the content of a bootable Live CD.
|
||||
However, for our mission to use Genode as general-purpose computing platform,
|
||||
disk device access is crucial. Therefore, we dedicated our attention to
|
||||
various aspects of Genode's block-device infrastructure, reaching from
|
||||
programming APIs for block drivers, over partition handling, to file-system
|
||||
access.
|
||||
|
||||
:Block session interface:
|
||||
|
||||
The glue that holds all block-device-related components together is the generic
|
||||
block interface 'os/include/block_session'. It is based on the framework's
|
||||
packet-stream facility, which allows the communication of bulk data via shared
|
||||
memory and a data-flow protocol using asynchronous notifications. The interface
|
||||
supports arbitrary allocation schemes and the use of multiple outstanding
|
||||
requests. Hence, it is generally suited for scatter-gather DMA and the use of
|
||||
command queuing as offered by the firmware of modern block-device controllers.
|
||||
(albeit the current drivers do not exploit this potential yet)
|
||||
|
||||
:Block component framework:
|
||||
|
||||
Our observation that components implementing the block session interface share
|
||||
similar code patterns prompted us to design a framework API for implementing
|
||||
this family of components. The set of classes located at 'os/include/block'
|
||||
facilitate the separation of device-specific code from application logic.
|
||||
Whereas 'component.h' provides the application logic needed to implement the
|
||||
block service, the 'driver.h' is an abstract interface to be implemented by the
|
||||
actual device driver. This new infrastructure significantly reduces code
|
||||
duplication among new block-device drivers.
|
||||
|
||||
:Device-driver implementations:
|
||||
|
||||
The new block-device drivers introduced with the current release address
|
||||
common types of block devices:
|
||||
|
||||
* By adding ATA read/write support to the ATAPI driver ('os/src/drivers/atapi'),
|
||||
this driver can be used to access IDE disks now.
|
||||
* The new fully-functional SD-card driver ('os/src/drivers/sdcard') enables the
|
||||
use of SD-cards connected via the PL180 controller.
|
||||
* The USB storage driver ('linux_drivers/src/drivers/usb') has been adapted
|
||||
to the block-session interface and can be used on PC hardware.
|
||||
* The new AHCI driver ('os/src/drivers/ahci') enables the access of disks
|
||||
connected via SATA on PC hardware.
|
||||
|
||||
Because all drivers are providing the generic block-session interfaces, they
|
||||
can be arbitrarily combined with components that use this interface as back
|
||||
end, for example, the partition server and file systems.
|
||||
|
||||
:Partition manager as resource multiplexer:
|
||||
|
||||
The new partition manager ('os/src/server/part_blk') multiplexes one back-end
|
||||
block session to multiple block sessions, each accessing a different partition.
|
||||
Its natural role is being "plugged" between a block-device driver and a file
|
||||
system.
|
||||
|
||||
:File-system access:
|
||||
|
||||
Even though a session interface for file systems does not exist yet, we
|
||||
enabled the use of VFAT partitions through a libc plugin. This libc plugin uses
|
||||
the ffat library to access files stored on a block device. An
|
||||
application using this plugin can be directly connected to a block session.
|
||||
|
||||
|
||||
New documentation
|
||||
#################
|
||||
|
||||
The new way of dealing with different kernels motivated us to revisit and
|
||||
complement our exiting documentation. The following documents are new or
|
||||
have received considerable attention:
|
||||
|
||||
:[http://genode.org/documentation/developer-resources/getting_started - Getting started]:
|
||||
The revised guide of how to explore Genode provides a quick way to
|
||||
test drive Genode's graphical demo scenario with a kernel of your
|
||||
choice and gives pointers to documents needed to proceed your
|
||||
exploration.
|
||||
|
||||
:[http://genode.org/documentation/developer-resources/build_system - Build system manual]:
|
||||
The new build-system manual explains the concepts behind Genode's
|
||||
build system, provides guidance with creating custom programs and
|
||||
libraries, and covers the tool support for the automated integration
|
||||
and testing of application scenarios.
|
||||
|
||||
:[http://genode.org/documentation/components - Components overview]:
|
||||
The new components-overview document explains the categorization of
|
||||
Genode's components and lists all components that come with the framework.
|
||||
|
||||
:[http://genode.org/documentation/developer-resources/init - Configuration of the init process]:
|
||||
The document describes Genode's configuration concept, the routing of
|
||||
service requests, and the expression of mandatory access-control policies.
|
||||
|
||||
:[http://genode.org/community/wiki - Wiki]:
|
||||
The platform-specific Wiki pages for L4/Fiasco, L4ka::Pistachio, NOVA,
|
||||
Codezero, Fiasco.OC, and OKL4 have been updated to reflect the new flows of
|
||||
working with the respective base platforms.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
The RPC API for performing procedure calls across process boundaries
|
||||
introduced with the version 11.05 was the most significant API change
|
||||
in Genode's history. To make the transition from the old client-server
|
||||
API to the new RPC API as smooth as possible, we temporarily upheld
|
||||
compatibility to the old API. Now, the time has come to put the old
|
||||
API at rest. The changes that are visible at API level are as follows:
|
||||
|
||||
* The old client-server API in the form of 'base/server.h' is no more.
|
||||
The functionality of the original classes 'Server_entrypoint' and
|
||||
'Server_activation' is contained in the 'Rpc_entrypoint' class provided
|
||||
via 'base/rpc_server.h'.
|
||||
|
||||
* When introducing the RPC API, we intentionally left the actual session
|
||||
interfaces as unmodified as possible to proof the versatility of the new
|
||||
facility. However, it became apparent that some of the original interfaces
|
||||
could profit from using a less C-ish style. For example, some interfaces used
|
||||
to pass null-terminated strings as 'char const *' rather than via a dedicated
|
||||
type. The methodology of using the new RPC API while leaving the original
|
||||
interfaces intact was to implement such old-style functions as wrappers
|
||||
around new-style RPC functions. These wrappers were contained in
|
||||
'rpc_object.h' files, e.g. for 'linux_dataspace', 'parent', 'root',
|
||||
'signal_session', 'cpu_session'. Now, we have taken the chance to modernise
|
||||
the API by disposing said wrappers. Thereby, the need for 'rpc_object.h'
|
||||
files has (almost) vanished.
|
||||
|
||||
* The remaining users of the old client-server API have been adapted to the
|
||||
new RPC API, most prominently, the packet-stream-related interfaces such as
|
||||
'block_session', 'nic_session', and 'audio_session'.
|
||||
|
||||
* We removed 'Typed_capability' and the second argument of the 'Capability'
|
||||
template. The latter was an artifact that was only used to support the
|
||||
transition from the old to the new API.
|
||||
|
||||
* The 'ipc_client' has no longer an 'operator int'. The result of an IPC can
|
||||
be requested via the 'result' function.
|
||||
|
||||
* We refined the accessors of 'Rpc_in_buffer' in 'base/rpc_args.h'. The
|
||||
'addr()' has been renamed to 'base()', 'is_valid_string()' considers the
|
||||
buffer's capacity, and the new 'string()' function is guaranteed to return a
|
||||
null-terminated string.
|
||||
|
||||
* We introduced a new 'Rm_session::Local_addr' class, which serves two
|
||||
purposes. It allows the transfer of the bit representation of pointers across
|
||||
RPC calls and effectively removes the need for casting the return type of
|
||||
'Rm_session::attach' to the type needed at the caller side.
|
||||
|
||||
* The 'Connection' class template has been simplified, taking the session
|
||||
interface as template argument (rather than the capability type). This change
|
||||
simplified the 'Connection' classes of most session interfaces.
|
||||
|
||||
* The never-used return value of 'Parent::announce' has been removed. From the
|
||||
child's perspective, an announcement always succeeds. The way of how the
|
||||
announcement is treated is entirely up to the parent. The client should never
|
||||
act differently depending on the parent's policy anyway.
|
||||
|
||||
* The new 'Thread_base::cap()' accessor function allows obtaining the thread's
|
||||
capability as used for the argument to CPU-session operations.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
Dynamic linker
|
||||
==============
|
||||
|
||||
As a follow-up to the major revision of the dynamic linker that was featured
|
||||
with the previous release, we addressed several corner cases related to
|
||||
exception handling and improved the handling of global symbols.
|
||||
|
||||
The dynamic linker used to resolve requests for global symbols by handing out
|
||||
its own symbols if present. However, in some cases, this behaviour is
|
||||
undesired. For example, the dynamic linker contains a small set of libc
|
||||
emulation functions specifically for the ported linker code. In the presence of
|
||||
the real libc, however, these symbols should never be considered at all. To
|
||||
avoid such ambiguities during symbol resolution, the set of symbols to be
|
||||
exported is now explicitly declared by the white-list contained in the
|
||||
'os/src/lib/ldso/symbol.map' file.
|
||||
|
||||
We changed the linkage of the C++ support library ('cxx') against dynamic
|
||||
binaries to be consistent with the other base libraries. Originally, the 'cxx'
|
||||
library was linked to both the dynamic linker and the dynamic binary, which
|
||||
resulted in subtle problems caused by the duplication of cxx-internal data
|
||||
structures. By linking 'cxx' only to the dynamic linker and exporting the
|
||||
'__cxa' ABI as global symbols, these issues have been resolved. As a positive
|
||||
side effect, this change reduces the size of dynamic binaries.
|
||||
|
||||
C++ exception handling in the presence of shared libraries turned out to be
|
||||
more challenging than we originally anticipated. For example, the
|
||||
'_Unwind_Resume' symbol is exported by the compiler's 'libsupc++' as a hidden
|
||||
global symbol, which can only be resolved when linking this library to the
|
||||
binary but is not seen by the dynamic linker. This was the actual reason of why
|
||||
we used to link 'cxx' against both dynamic binaries and shared libraries
|
||||
causing the problem mentioned in the previous paragraph. Normally, this problem
|
||||
is addressed by a shared library called 'libgcc_s.so' that comes with the
|
||||
compiler. However, this library depends on glibc, which prevents us from using
|
||||
it on Genode. Our solution is renaming the hidden global symbol using a
|
||||
'_cxx__' prefix and introducing a non-hidden global wrapper function
|
||||
('__cxx__Unwind_Resume' in 'unwind.cc'), which is resolved at runtime by the
|
||||
dynamic linker.
|
||||
|
||||
Another corner case we identified is throwing exceptions from within the
|
||||
dynamic linker. In contrast to the original FreeBSD version of the dynamic
|
||||
linker, which is a plain C program that can never throw a C++ exception,
|
||||
Genode's version relies on C++ code that makes use of exceptions. To support
|
||||
C++ exceptions from within the dynamic linker, we have to relocate the
|
||||
linkers's global symbols again after having loaded the dynamic binary. This
|
||||
way, type information that is also present within the dynamic binary becomes
|
||||
relocated to the correct positions.
|
||||
|
||||
|
||||
Block partition server
|
||||
======================
|
||||
|
||||
The new block-partition server uses Genode's block-session interfaces as both
|
||||
front and back end, leading to the most common use case where this server will
|
||||
reside between a block driver and a higher level component like a file-system
|
||||
server.
|
||||
|
||||
At startup, the partition server will try to parse the master boot record (MBR)
|
||||
of its back-end block session. If no partition table is found, the whole block
|
||||
device is exported as partition '0'. In the other case, the MBR and possible
|
||||
extended boot records (EBRs) are parsed and offered as separate block sessions
|
||||
to the front-end clients. The four primary partitions will receive partition
|
||||
numbers '1' to '4' whereas the first logical partition will be assigned to '5'.
|
||||
|
||||
The policy of which partition is exposed to which client can be expressed
|
||||
in the config supplied to the 'part_blk' server. Please refer to the
|
||||
documentation at 'os/src/server/part_blk/README' for further details. As an
|
||||
illustration of the practical use of the 'part_blk' server, you can find a run
|
||||
script at 'os/run/part_blk.run'.
|
||||
|
||||
|
||||
Skeleton of text terminal
|
||||
=========================
|
||||
|
||||
As part of the ongoing work towards using interactive text-based GNU software
|
||||
on Genode, we created the first bits of the infrastructure required for
|
||||
pursuing this quest:
|
||||
|
||||
The new terminal-session interface at 'os/include/terminal_session/' is the
|
||||
designated interface to be implemented by terminal programs.
|
||||
|
||||
After investigating the pros and cons of various terminal protocols and
|
||||
terminal emulators, we settled for implementing a custom terminal emulator
|
||||
implementing the Linux termcap. This termcap offers a reasonable small set of
|
||||
commands while providing all essential features such as function-key support
|
||||
and mouse support. Thanks to Peter Persson for pointing us to the right
|
||||
direction! The preliminary code for parsing the escape sequences for the Linux
|
||||
termcap is located at 'gems/include/terminal/'.
|
||||
|
||||
We have created a simplistic terminal service that implements the
|
||||
terminal-session interface using a built-in font. Please note that the
|
||||
implementation at 'gems/src/server/terminal/' is at an early stage. It is
|
||||
accompanied by a simple echo program located at 'gems/src/test/terminal_echo'.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
USB HID and USB storage
|
||||
=======================
|
||||
|
||||
We replaced the former DDE-Linux-based USB-related driver libraries (at the
|
||||
'linux_drivers/' repository) by a single USB driver server that offers the
|
||||
'Input' and 'Block' services. This enables us to use both USB HID and USB
|
||||
storage at the same time. The new USB driver is located at
|
||||
'linux_drivers/src/drivers/usb/'.
|
||||
|
||||
For using the USB driver as input service (supporting USB HID), add the
|
||||
'<hid/>' tag to the 'usb_drv' configuration. Analogously, for using the driver
|
||||
as block service, add the '<storage/>' tag. Both tags can be combined.
|
||||
|
||||
For testing the USB stack, the 'linux_drivers' repository comes with the run
|
||||
scripts 'usb_hid.run' and 'usb_storage.run'.
|
||||
|
||||
|
||||
ATA read/write support
|
||||
======================
|
||||
|
||||
The ATAPI driver has been extended to support IDE block devices for both
|
||||
read and write transactions. To use the new facility, supply 'ata="yes"'
|
||||
as XML attribute to the config node of 'atapi_drv'. Please note that this
|
||||
driver was primarily tested on Qemu. Use it with caution.
|
||||
|
||||
|
||||
SATA driver
|
||||
===========
|
||||
|
||||
The new SATA driver at 'os/src/drivers/ahci/' implements the block-driver
|
||||
API ('os/include/block'), thus exposing the block-session interface as
|
||||
front-end. AHCI depends on Genode's PCI driver as well as the timer server. For
|
||||
a usage example see: 'os/run/ahci.run'.
|
||||
|
||||
Limitations and known issues
|
||||
----------------------------
|
||||
|
||||
Currently, the server scans the PCI bus at startup and retrieves the first available
|
||||
AHCI controller, scans the controller ports and uses the first non-ATAPI port
|
||||
where a device is present.
|
||||
|
||||
On real hardware and on kernels taking advantage of I/O APICs (namely NOVA and
|
||||
Fiasco.OC) we still lack support for ACPI parsing and thus for interrupts,
|
||||
leading to a non-working driver.
|
||||
|
||||
|
||||
SD-card driver
|
||||
==============
|
||||
|
||||
The first fragments of our SD-card driver that we introduced with the previous
|
||||
release have been complemented. The new SD-card driver located at
|
||||
'os/src/drivers/sd_card/' implements the block-session interface by using
|
||||
MMC/SD-cards and the PL180 controller as back end. Currently the driver
|
||||
supports single-capacity SD cards. Therefore, the block file for Qemu should
|
||||
not exceed 512 MB. Because the driver provides the generic block-session
|
||||
interface, it can be combined with the new 'libc_ffat' plugin in a
|
||||
straight-forward way. To give the driver a quick spin, you may give the
|
||||
'libports/run/libc_ffat.run' script on the 'foc_pbxa9' platform a try.
|
||||
|
||||
|
||||
ARM Realview PL011 UART driver
|
||||
==============================
|
||||
|
||||
The new PL011 UART driver at 'os/src/drivers/uart/' implements the LOG session
|
||||
interface using the PL011 device. Up to 4 UARTs are supported. The assignment
|
||||
of UARTs to clients can be defined via a policy supplied to the driver's config
|
||||
node. For further information, please refer to the README file within the
|
||||
'uart' directory.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Hello tutorial
|
||||
==============
|
||||
|
||||
The 'hello_tutorial/' repository contains a step-by-step guide for building
|
||||
a simple client-server scenario. The tutorial has been rewritten for the new
|
||||
RPC API and is now complemented by a run script for testing the final scenario
|
||||
on various base platforms.
|
||||
|
||||
C and C++ runtimes
|
||||
==================
|
||||
|
||||
:Support for standard C++ headers:
|
||||
|
||||
Triggered by public demand for using standard C++ headers for Genode applications,
|
||||
we introduced a generally usable solution in the form of the 'stdcxx' library
|
||||
to the 'libc' repository. The new 'stdcxx' library is not a real library. (you
|
||||
will find the corresponding 'lib/mk/stdcxx.mk' file empty) However, it comes
|
||||
with a 'lib/import/import-stdcxx.mk' file that adds the compiler's C++ includes
|
||||
to the default include-search path for any target that has 'stdcxx' listed in
|
||||
its 'LIBS' declaration.
|
||||
|
||||
:Libc back end for accessing VFAT partitions:
|
||||
|
||||
The new 'libc_ffat' libc plugin uses a block session via the ffat library. It
|
||||
can be used by a Genode application to access a VFAT file system via the libc
|
||||
file API. The file-system access is performed via the 'ffat' library. To
|
||||
download this library and integrate it with Genode, change to the 'libports'
|
||||
repository and issue the following command:
|
||||
! make prepare PKG=ffat
|
||||
For an example of how to use the libc-ffat plugin, please refer to the run
|
||||
script 'libports/run/libc_ffat.run'. The source code of the test program can be
|
||||
found at 'libports/src/test/libc_ffat/'.
|
||||
|
||||
Qt4
|
||||
===
|
||||
|
||||
Qt4 version 4.7.1 has been enabled on ARMv6-based platforms, i.e., PBX-A9 on
|
||||
Fiasco.OC. The support comprises the entire Qt4 framework including qt_webcore
|
||||
(Webkit).
|
||||
|
||||
L4Linux
|
||||
=======
|
||||
|
||||
L4Linux enables the use of one or multiple instances of Linux-based operating
|
||||
systems as subsystems running on the Fiasco.OC kernel. The Genode version of
|
||||
L4Linux has seen the following improvements:
|
||||
|
||||
:Kernel version: has been updated to Linux 2.6.39.
|
||||
|
||||
:ARM support: The L4Linux kernel can be used on ARM-based platforms now.
|
||||
The PBX-A9 platform is supported via the 'l4linux.run' script as found
|
||||
at 'ports-foc/run/'. Please find more information at 'ports-foc/README'.
|
||||
|
||||
:Genode-specific stub drivers outside the kernel tree:
|
||||
The stub drivers that enable the use of Genode's services as virtual
|
||||
devices for L4Linux have been moved outside the kernel patch, which
|
||||
makes them much easier to maintain. These stub drivers are located
|
||||
under 'ports-foc/src/drivers/'.
|
||||
|
||||
|
||||
Platform support
|
||||
################
|
||||
|
||||
All base platforms are now handled in a unified fashion. Downloading 3rd-party
|
||||
source code is performed using the 'prepare' rule of the 'Makefile' provided by
|
||||
the respective kernel's 'base-<platform>' repository. Once, the platform's base
|
||||
repository is prepared, the kernel can be built directly from the Genode
|
||||
build directory using 'make kernel'. All base platforms are now supported by
|
||||
Genode's run mechanism that automates the tasks of system integration and
|
||||
testing. For more details about each specific kernel, please revisit the
|
||||
updated documentation within the respective 'base-<platform>/doc/' directory.
|
||||
|
||||
:L4/Fiasco:
|
||||
|
||||
The kernel has been updated to revision 472, enabling the use of recent
|
||||
GNU tool chains.
|
||||
|
||||
:Fiasco.OC:
|
||||
|
||||
The kernel as been updated to revision 36, which remedies stability problems
|
||||
related to interaction of the IPC path with thread destruction. The new version
|
||||
improves the stability of highly dynamic workloads that involve the frequent
|
||||
creation and destruction of subsystems. However, we experienced the new kernel
|
||||
version to behave instable on the x86_64 architecture. If you depend on x86_64,
|
||||
we recommend to temporarily stick with Genode 11.05 and Fiasco.OC revision 31.
|
||||
|
||||
:L4ka::Pistachio:
|
||||
|
||||
The kernel has been updated to revision 803, enabling the use of recent
|
||||
versions of binutils.
|
||||
|
||||
:OKL4:
|
||||
|
||||
OKL4v2 is showing its age. Apparently, the use of the original distribution
|
||||
requires tools (i.e., python 2.4) that do not ship with current Linux
|
||||
distributions anymore. This makes it increasingly difficult to use this kernel.
|
||||
Still, we find ourselves frequently using it for our day-to-day development. To
|
||||
streamline the use of OKL4v2, we have now incorporated the kernel compilation
|
||||
into the Genode build system and thereby weakened the kernel's dependency on
|
||||
ancient tools. However, we decided to drop support for OKL4/ARM for now. We
|
||||
figured that the supported GTA01 platform is hardly used anymore and hard to
|
||||
test because it is unsupported by Qemu. Newer ARM platforms are supported by
|
||||
other kernels anyway.
|
||||
|
||||
:Codezero:
|
||||
|
||||
Even though B-Labs apparently abandoned the idea of developing the Codezero
|
||||
kernel in the open, we adapted Genode to the kernel's most recent Open-Source
|
||||
version that is still available at the official Git repository. Furthermore,
|
||||
the kernel is now fully supported by Genode's new 'make prepare' procedure and
|
||||
run environment. Therefore, run scripts such as 'run/demo' can now easily be
|
||||
executed on Codezero without the need to manually configure the kernel.
|
||||
|
||||
Note that, for now, we have disabled Codezero's capabilities because they do
|
||||
not allow the assignment of device resources. Consequently, 'sys_map' fails for
|
||||
MMIO regions when performing the capability check (calling 'cap_map_check').
|
||||
Furthermore, the current version of the kernel requires a workaround for a
|
||||
current limitation regarding the definition of a thread's pager. At some point,
|
||||
Codezero abandoned the facility to define the pager for a given thread via the
|
||||
exregs system call. Instead, the kernel hard-wires the creator of the thread as
|
||||
the thread's pager. This is conflicting with Genode's way of creating and
|
||||
paging threads. In the current version of Genode for this kernel, all threads
|
||||
are paged by one thread (thread 3 happens to be the global pager) within core.
|
||||
As a workaround to Codezero's current limitation, we define thread 3 to be the
|
||||
pager of all threads. The patch of the upstream code is automatically being
|
||||
applied by the 'make prepare' mechanism.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
In addition to the major change with respect to the integration of the various
|
||||
base platforms, Genode's tool support received the following incremental
|
||||
improvements:
|
||||
|
||||
|
||||
Build system
|
||||
============
|
||||
|
||||
:Simplification of 'create_builddir' tool:
|
||||
|
||||
The 'create_builddir' tool has been relocated from
|
||||
'tool/builddir/create_builddir' to 'tool/create_builddir' to make it more
|
||||
readily accessible. Furthermore, we simplified the usage of the tool by
|
||||
removing the mandatory 'GENODE_DIR' argument. If not explicitly specified, the
|
||||
tool deduces 'GENODE_DIR' from the its known location within the Genode source
|
||||
tree.
|
||||
|
||||
:Booting from USB sticks:
|
||||
|
||||
For most x86-based base platforms, their respective run environments execute
|
||||
Genode from an ISO image via Qemu. Naturally, such an ISO image can be burned
|
||||
onto a CD-ROM to be used to boot a real machine. However, booting from CD-ROM
|
||||
is slow and optical drives are becoming scarce. Therefore we changed the
|
||||
procedure of creating ISO images to support writing the resulting images to a
|
||||
USB stick. Under the hood, the boot mechanism chain-loads GRUB via ISOLinux.
|
||||
The files to implement the boot concept are located at 'tool/boot/'.
|
||||
|
||||
:Support for source files in target sub directories:
|
||||
|
||||
Until now, the 'SRC_*' declarations in target description files contained
|
||||
a list of plain file names. The location of the files within the directory
|
||||
tree had to be defined via 'vpath'. This led to inconveniences when building
|
||||
3rd-party code that contains files with the same name at different subdirectories.
|
||||
To resolve such an ambiguity, the target had to be decomposed into multiple
|
||||
libraries each building a different set of subdirectories. To make the
|
||||
build system more convenient to use, we have now added support for specifying
|
||||
source codes with a relative pathname. For example, instead of using
|
||||
! SRC_CC = main.cc addon.cc
|
||||
! vpath addon.cc $(PRG_DIR)/contrib
|
||||
we can now use
|
||||
! SRC_CC = main.cc contrib/addon.cc
|
||||
|
||||
|
||||
Automated testing across multiple kernels
|
||||
=========================================
|
||||
|
||||
To execute one or multiple test cases on more than one base platform, we
|
||||
introduced a dedicated tool located at 'tool/autopilot'. Its primary purpose is
|
||||
the nightly execution of test cases. The tool takes a list of platforms and a
|
||||
list of run scripts as arguments and executes each run script on each platform.
|
||||
The build directory for each platform is created at
|
||||
'/tmp/autopilot.<username>/<platform>' and the output of each run script is
|
||||
written to a file called '<platform>.<run-script>.log'. On stderr, autopilot
|
||||
prints the statistics about whether or not each run script executed
|
||||
successfully on each platform. If at least one run script failed, autopilot
|
||||
returns a non-zero exit code, which makes it straight forward to include
|
||||
autopilot into an automated build-and-test environment.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,862 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 12.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The release of Genode 12.02 marks an exciting point in the history of the
|
||||
project as it is the first version developed in the open rather than within the
|
||||
chambers of Genode Labs. Thereby, we have embraced GitHub as central facility
|
||||
for discussion and source-code management. This change has benefits for users
|
||||
and developers of the framework alike. For users, it has become possible to get
|
||||
hold of the latest developments using the official 'genodelabs/master' branch and
|
||||
get involved with discussing the current activities. For regular Genode
|
||||
developers, the public Git repository replaces a former mix of public
|
||||
Subversion and company-internal Mercurial repositories, making life much
|
||||
easier. In Section [Liberation of the development process], we outline the
|
||||
motivation behind this change and give pointers to the new resources.
|
||||
|
||||
The major new additions to the base system are a new framework API for accessing
|
||||
memory-mapped I/O resources, special support for using Genode as user-level
|
||||
component framework on Linux, and API support for the reuse of existing
|
||||
components in the form of sandboxed libraries. These changes are accompanied
|
||||
with new device-driver infrastructure such as the first version of a device
|
||||
driver manager and a new ACPI parser.
|
||||
|
||||
Feature-wise, the current release takes the first steps towards the goal of the
|
||||
[http://genode.org/about/road-map - Roadmap for 2012], turning Genode into a
|
||||
general-purpose OS ready for everyday use by its developers. According to the
|
||||
roadmap, we enhanced the Noux runtime with fork semantics so that we can run
|
||||
command-line based GNU programs such as the bash shell and coreutils unmodified
|
||||
and natively on various microkernels. Furthermore, the library infrastructure
|
||||
has been enhanced by porting and updating libraries such as Qt 4.7.4 and the
|
||||
MuPDF PDF rendering engine.
|
||||
|
||||
|
||||
Liberation of the development process
|
||||
#####################################
|
||||
|
||||
In summer 2011, we started a discussion within Genode Labs about changing the
|
||||
mode of how Genode is developed. Until then, most design discussions and the
|
||||
actual development work took place locally at the company. At quarterly
|
||||
intervals, we used to publish our work in the form of official Genode
|
||||
releases. This way of development seemed to work quite well for us, we were
|
||||
satisfied about the pace of development, and with each release, our project got
|
||||
more recognition.
|
||||
|
||||
However, the excellent book [http://producingoss.com/ - Producing Open Source Software]
|
||||
made us realize that even though we released our work under an Open-Source
|
||||
license, our development process was actually far from being open and may have
|
||||
discouraged participation of people outside the inner circle of developers.
|
||||
Because we believe that the framework has reached a state where it becomes
|
||||
interesting for a wider audience of users and developers, the idea was born
|
||||
to liberate the project from its closed fashion of development.
|
||||
|
||||
In the beginning of December, the vague idea has become a plan. So we finally
|
||||
brought the topic to our mailing list
|
||||
([http://genode.org/news/steps-towards-an-open-development-process - Steps towards an open development process]).
|
||||
We decided to take the release cycle for Genode 12.02 as the opportunity to put
|
||||
our plan to practice. The central element of this endeavour was moving the
|
||||
project over to GitHub and adapt our workflows and tooling support accordingly.
|
||||
First, we started to embrace GitHub's issue tracker for the management of
|
||||
working topics:
|
||||
|
||||
:[http://github.com/genodelabs/genode/issues]: Issue Tracker
|
||||
|
||||
The most significant step was leaving our Genode-Labs-internal code
|
||||
repositories behind and starting a completely public Git repository instead:
|
||||
|
||||
:[https://github.com/genodelabs]: Genode Labs at GitHub
|
||||
|
||||
With the code repository going public, the way was cleared to opening up design
|
||||
discussions as well. Instead of having such discussions internally at Genode
|
||||
Labs, we try to increasingly take them to our mailing list and issue tracker.
|
||||
With this new way of development, we hope to make the project much more
|
||||
approachable for people who want to get involved and let Genode reach far out
|
||||
beyond the reach of our little company.
|
||||
|
||||
The changes mentioned above are actually just the tip of the iceberg. For
|
||||
example, the transition phase required us to rethink the way the project
|
||||
website is maintained. From now on, almost all of the content of genode.org
|
||||
comes directly from the project's Git repository. So maintaining website
|
||||
content is done in the same coherent and transparent way as working on Genode's
|
||||
code base. So we could finally put the old Wiki to rest. In the process, we
|
||||
largely revisited the existing content. For example, we rewrote the
|
||||
[http://genode.org/community/contributions - contributions] document in a
|
||||
tutorial-like style and incorporated several practical hints, in particular
|
||||
related to the recommended use of Git.
|
||||
|
||||
Although it is probably too early to judge the outcome of our transition, we
|
||||
are excited how smooth this massive change went. We attribute this pleasant
|
||||
experience mostly to the excellent GitHub hosting platform, which instantly
|
||||
ignited a spirit of open collaboration among us. We are excited to see new
|
||||
people approaching us and showing their interest for teaming up, and we are
|
||||
curious about where this new model of development will take Genode in the
|
||||
future.
|
||||
|
||||
|
||||
Base framework, low-level OS infrastructure
|
||||
###########################################
|
||||
|
||||
RPC framework refinements
|
||||
=========================
|
||||
|
||||
Until now, the RPC framework did not support const RPC functions. Rather than
|
||||
being a limitation inherent to the concept, const RPC functions plainly did not
|
||||
exist. So supporting them was not deemed too important. However, there are uses
|
||||
of RPC interfaces that would benefit from a way to declare an RPC function as
|
||||
const. Candidates are functions like 'Framebuffer::Session::mode()' and
|
||||
'Input::Session::is_pending()'.
|
||||
|
||||
With the current version, we clear the way towards declaring such functions as
|
||||
const. Even though the change is pretty straight-forward, the thorough support
|
||||
for const-qualified RPC functions would double the number of overloads for the
|
||||
'call_member' function template (in 'base/include/util/meta.h'). For this
|
||||
reason, as of now, the support of const functions is limited to typical getter
|
||||
functions with no arguments. This appears to be the most common use of such
|
||||
functions.
|
||||
|
||||
|
||||
API support for enslaving services
|
||||
==================================
|
||||
|
||||
While evolving and using the framework, we always keep an eye on recurring
|
||||
patterns of how its API is used. Once such a pattern becomes obvious, we try
|
||||
to take a step back, generalize the observed pattern, and come up with a new
|
||||
building block that unifies the former repetitive code fragments.
|
||||
|
||||
One of those patterns that was far from obvious when we designed Genode years
|
||||
ago is the use of a service running as child of its own client. At the first
|
||||
glance, this idea seems counter-intuitive because normally, services are
|
||||
understood as components that operate independently and protected from their
|
||||
(untrusted) clients. But there is a class of problems where this approach
|
||||
becomes extremely useful: The reuse of protocol implementations as a
|
||||
library-like building block. Most services are actually protocol stacks that
|
||||
translate a low-level protocol to a more abstract API. For example, a block
|
||||
device driver translates a specific device API to the generic 'Block_session'
|
||||
interface. Or the 'iso9660' service translates the 'Block_session' interface to
|
||||
the 'Rom_session' interface by parsing the ISO9660 file system. Or similarly,
|
||||
the 'tar_rom' service parses the tar file format to make its content available
|
||||
via the 'Rom_session' interface.
|
||||
|
||||
If a particular functionality is needed by multiple programs, it is common
|
||||
practice to move this functionality into a dedicated library to avoid the
|
||||
duplication of the same code at many places. For example, if a program would
|
||||
need to parse a tar archive, it might be tempting to move the tar-parsing code
|
||||
from the 'tar_rom' service into a dedicated library, which can then be used by
|
||||
both the 'tar_rom' service and the new program. An alternative approach is to
|
||||
just re-use the 'tar_rom' service as a black box and treat it like it was a
|
||||
library. That is, start the 'tar_rom' service as a child process, supply the
|
||||
resources the component needs to operate and, in turn, use its API (now in the
|
||||
form of an RPC interface) to get work done. Because the service is started as a
|
||||
mere tool at the discretion of its client, we call it *slave*. It turns out
|
||||
that this idea works exceedingly well in many cases. In a way, it resembles the
|
||||
Unix philosophy to solve complex problems by combining many small tools each
|
||||
with a specific purpose. In contrast to the use of libraries, the reuse of
|
||||
entire components has benefits with regard to fault isolation. Because the
|
||||
reused functionality is sandboxed within a distinct process, the environment
|
||||
exposed to this code can be tailored to a rigid subset of the host program's
|
||||
environment. In the event of a fault within the reused component, the reach of
|
||||
problem is therefore limited.
|
||||
|
||||
On the other hand, we observed that even though this idea works as intended,
|
||||
implementing the idea for a particular use case involved a good deal of
|
||||
boiler-plate code where most of this code is needed to define the slave's
|
||||
environment and resources. Hence, we reviewed the existing occurrences of the
|
||||
slave pattern and condensed their common concerns into the 'Slave_policy' and
|
||||
'Slave' classes residing in 'os/include/os/slave.h'. The 'Slave' class is meant
|
||||
to be used as is. It is merely a convenience wrapper for a child process and
|
||||
its basic resources. The 'Slave_policy' is meant as a hook for service-specific
|
||||
customizations. The best showcase is the new 'd3m' component located at
|
||||
'gems/src/server/d3m'. D3m extensively uses the slave pattern by instantiating
|
||||
and destroying drivers and file-system instances on-the-fly. A further instance
|
||||
of this pattern can be found in the new ACPI driver introduced with the current
|
||||
release.
|
||||
|
||||
|
||||
Support for resizable framebuffers
|
||||
==================================
|
||||
|
||||
The framebuffer-session interface has remained largely untouched since the
|
||||
original release of Genode in 2008. Back then, we were used to rely on C-style
|
||||
out parameters in RPC functions. The current RPC framework, however, promotes
|
||||
the use of a more object-oriented style. So the time has come to revisit the
|
||||
framebuffer session interface. Instead of using C-style out parameters, the new
|
||||
'mode()' RPC call returns the mode information as an object of type 'Mode'.
|
||||
Consequently, mode-specific functions such as 'bytes_per_pixel()' have been
|
||||
moved to the new 'Framebuffer::Mode' class. The former 'info()' function is
|
||||
gone.
|
||||
|
||||
In addition to the overhaul of the RPC interface, we introduced basic support
|
||||
for resizable framebuffers. The new 'mode_sigh()' function enables a client to
|
||||
register a signal handler at the framebuffer session. This signal handler gets
|
||||
notified in the event of server-side mode changes. Via the new 'release()'
|
||||
function, the client is able to acknowledge a mode change. By calling it, the
|
||||
client tells the framebuffer service that it no longer uses the original
|
||||
framebuffer dataspace. So the server can replace it by a new one. After having
|
||||
called 'release()', the client can obtain the dataspace for the new mode by
|
||||
calling 'dataspace()' again.
|
||||
|
||||
|
||||
MMIO access framework
|
||||
=====================
|
||||
|
||||
As the arsenal of native device drivers for Genode grows, we are observing
|
||||
an increased demand to formalize the style of how drivers are written to
|
||||
foster code consistency. One particular cause of inconsistency used to be
|
||||
the way of how memory-mapped I/O registers are accessed. C++ has poor support
|
||||
for defining bit-accurate register layouts in memory. Therefore, driver code
|
||||
usually carries along a custom set of convenience functions for reading and
|
||||
writing registers of different widths as well as a list of bit definitions in
|
||||
the form of enum values or '#define' statements. To access parts of a register,
|
||||
the usual pattern is similar to the following example (taken from the pl011
|
||||
UART driver:
|
||||
|
||||
! enum {
|
||||
! UARTCR = 0x030, /* control register */
|
||||
! UARTCR_UARTEN = 0x0001, /* enable bit in control register */
|
||||
! ...
|
||||
! }
|
||||
! ...
|
||||
!
|
||||
! /* enable UART */
|
||||
! _write_reg(UARTCR, _read_reg(UARTCR) | UARTCR_UARTEN);
|
||||
|
||||
This example showcases two inconveniences: The way the register layout is
|
||||
expressed and the manual labour needed to access parts of registers. In the
|
||||
general case, a driver needs to also consider 'MASK' and 'SHIFT' values to
|
||||
implement access to partial registers properly. This is not just inconvenient
|
||||
but also error prone. For lazy programmers as ourselves, it's just too easy to
|
||||
overwrite "undefined" bits in a register instead of explicitly masking the
|
||||
access to the actually targeted bits. Consequently, the driver may work fine
|
||||
with the current generation of devices but break with the next generation.
|
||||
|
||||
So the idea was born to introduce an easy-to-use formalism for this problem. We
|
||||
had two goals: First, we wanted to cleanly separate the declaration of register
|
||||
layouts from the program logic of the driver. The actual driver program should
|
||||
be free from any intrinsics in the form of bit-masking operations. Second, we
|
||||
wanted to promote uncluttered driver code that uses names (i.e., in the form of
|
||||
type names) rather than values to express its operations. The latter goal is
|
||||
actually achieved by the example above by the use of enum values, but this is
|
||||
only achieved through discipline. We would prefer to have an API that
|
||||
facilitates the use of proper names as the most convenient way to express an
|
||||
operation.
|
||||
|
||||
The resulting MMIO API comes in the form of two new header files located at
|
||||
'base/include/util/register.h' and 'base/include/util/mmio.h'.
|
||||
|
||||
|
||||
Register declarations
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The class templates found in 'util/register.h' provide a means to express
|
||||
register layouts using C++ types. In a way, these templates make up for
|
||||
C++'s missing facility to define accurate bitfields. Let's take a look at
|
||||
a simple example of the 'Register' class template that can be used to define
|
||||
a register as well as a bitfield within this register:
|
||||
|
||||
! struct Vaporizer : Register<16>
|
||||
! {
|
||||
! struct Enable : Bitfield<2,1> { };
|
||||
! struct State : Bitfield<3,3> {
|
||||
! enum{ SOLID = 1, LIQUID = 2, GASSY = 3 };
|
||||
! };
|
||||
!
|
||||
! static void write (access_t value);
|
||||
! static access_t read ();
|
||||
! };
|
||||
|
||||
In the example, 'Vaporizer' is a 16-bit register, which is expressed via the
|
||||
'Register' template argument. The 'Register' class template allows for
|
||||
accessing register content at a finer granularity than the whole register
|
||||
width. To give a specific part of the register a name, the 'Register::Bitfield'
|
||||
class template is used. It describes a bit region within the range of the
|
||||
compound register. The bit 2 corresponds to true if the device is enabled and
|
||||
bits 3 to 5 encode the 'State'. To access the actual register, the methods
|
||||
'read()' and 'write()' must be provided as backend, which performs the access
|
||||
of the whole register. Once defined, the 'Vaporizer' offers a handy way to
|
||||
access the individual parts of the register, for example:
|
||||
|
||||
! /* read the whole register content */
|
||||
! Vaporizer::access_t r = Vaporizer::read();
|
||||
!
|
||||
! /* clear a bit field */
|
||||
! Vaporizer::Enable::clear(r);
|
||||
!
|
||||
! /* read a bit field value */
|
||||
! unsigned old_state = Vaporizer::State::get(r);
|
||||
!
|
||||
! /* assign new bit field value */
|
||||
! Vaporizer::State::set(r, Vaporizer::State::LIQUID);
|
||||
!
|
||||
! /* write whole register */
|
||||
! Vaporizer::write(r);
|
||||
|
||||
|
||||
Memory-mapped I/O
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The utilities provided by 'util/mmio.h' use the 'Register' template class as
|
||||
a building block to provide easy-to-use access to memory-mapped I/O registers.
|
||||
The 'Mmio' class represents a memory-mapped I/O region taking its local base
|
||||
address as constructor argument. Let's take a simple example to see how it is
|
||||
supposed to be used:
|
||||
|
||||
! class Timer : Mmio
|
||||
! {
|
||||
! struct Value : Register<0x0, 32> { };
|
||||
! struct Control : Register<0x4, 8> {
|
||||
! struct Enable : Bitfield<0,1> { };
|
||||
! struct Irq : Bitfield<3,1> { };
|
||||
! struct Method : Bitfield<1,2>
|
||||
! {
|
||||
! enum { ONCE = 1, RELOAD = 2, CYCLE = 3 };
|
||||
! };
|
||||
! };
|
||||
!
|
||||
! public:
|
||||
!
|
||||
! Timer(addr_t base) : Mmio(base) { }
|
||||
!
|
||||
! void enable();
|
||||
! void set_timeout(Value::access_t duration);
|
||||
! bool irq_raised();
|
||||
! };
|
||||
|
||||
The memory-mapped timer device consists of two registers: The 32-bit 'Value'
|
||||
register and the 8-bit 'Control' register. They are located at the MMIO offsets
|
||||
0x0 and 0x4, respectively. Some parts of the 'Control' register have specific
|
||||
meanings as expressed by the 'Bitfield' definitions within the 'Control'
|
||||
struct.
|
||||
|
||||
Using these declarations, accessing the individual bits becomes almost a
|
||||
verbatim description of how the device is used. For example:
|
||||
|
||||
! void enable()
|
||||
! {
|
||||
! /* access an individual bitfield */
|
||||
! write<Control::Enable>(true);
|
||||
! }
|
||||
!
|
||||
! void set_timeout(Value::access_t duration)
|
||||
! {
|
||||
! /* write complete content of a register */
|
||||
! write<Value>(duration);
|
||||
!
|
||||
! /* write all bitfields as one transaction */
|
||||
! write<Control>(Control::Enable::bits(1) |
|
||||
! Control::Method::bits(Control::Method::ONCE) |
|
||||
! Control::Irq::bits(0));
|
||||
! }
|
||||
!
|
||||
! bool irq_raised()
|
||||
! {
|
||||
! return read<Control::Irq>();
|
||||
! }
|
||||
|
||||
In addition to those basic facilities, further noteworthy features of the new
|
||||
API are the support for register arrays and the graceful overflow handling
|
||||
with respect to register and bitfield boundaries.
|
||||
|
||||
|
||||
C Runtime
|
||||
=========
|
||||
|
||||
We extended our FreeBSD-based C runtime to accommodate the needs of the Noux
|
||||
runtime environment and our port of the MuPDF application.
|
||||
|
||||
* The dummy implementation of '_ioctl()' has been removed. This function is
|
||||
called internally within the libc, i.e., by 'tcgetattr()'. For running
|
||||
libreadline in Noux, we need to hook into those ioctl operations via the
|
||||
libc plugin interface.
|
||||
|
||||
* The 'libc/regex' and 'libc/compat' modules have been added to the libc.
|
||||
These libraries are needed by the forthcoming port of Slashem to Noux.
|
||||
|
||||
* We added a default implementation of 'chdir()'. It relies on the sequence of
|
||||
'open()', 'fchdir()', 'close()'.
|
||||
|
||||
* The new libc plugin 'libc_rom' enables the use of libc file I/O functions
|
||||
to access ROM files as provided by Genode ROM session.
|
||||
|
||||
* We changed the libc dummy implementations to always return ENOSYS. Prior
|
||||
this change, 'errno' used to remain untouched by those functions causing
|
||||
indeterministic behaviour of code that calls those functions, observes the
|
||||
error return value (as returned by most dummies), and evaluates the error
|
||||
condition reported by errno.
|
||||
|
||||
* If using the libc for Noux programs, the default implementations of
|
||||
time-related functions such as 'gettimeofday()' cannot be used because they
|
||||
rely on a dedicated timeout-scheduler thread. Noux programs, however, are
|
||||
expected to contain only the main thread. By turning the functions into weak
|
||||
symbols, we enabled the noux libc-plugin to provide custom implementations.
|
||||
|
||||
|
||||
DDE Kit
|
||||
=======
|
||||
|
||||
Linux DDE used to implement Linux spin locks based on 'dde_kit_lock'. This
|
||||
works fine if a spin lock is initialized only once and used from then on. But
|
||||
if spin locks are initialized on-the-fly at a high rate, each initialization
|
||||
causes the allocation of a new 'dde_kit_lock'. Because in contrast to normal
|
||||
locks, spinlocks cannot be explicitly destroyed, the spin-lock emulating locks
|
||||
are never freed. To solve the leakage of locks, we complemented DDE Kit with
|
||||
the new 'os/include/dde_kit/spin_lock.h' API providing the semantics as
|
||||
expected by Linux drivers.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New and updated libraries
|
||||
=========================
|
||||
|
||||
:Qt4 updated to version 4.7.4:
|
||||
|
||||
We updated Qt4 from version 4.7.1 to version 4.7.4. For the most part, the
|
||||
update contains bug fixes as detailed in the release notes for the versions
|
||||
[http://qt.nokia.com/products/changes/changes-4.7.2 - 4.7.2],
|
||||
[http://qt.nokia.com/products/changes/changes-4.7.3 - 4.7.3], and
|
||||
[http://labs.qt.nokia.com/2011/09/01/qt-4-7-4-released - 4.7.4].
|
||||
|
||||
:Update of zlib to version 1.2.6:
|
||||
|
||||
Because zlib 1.2.5 is no more available at zlib.net, we bumped the zlib
|
||||
version to 1.2.6.
|
||||
|
||||
:New ports of openjpeg, jbig2dec, and mupdf:
|
||||
|
||||
MuPDF is a fast and versatile PDF rendering library with only a few
|
||||
dependencies. It depends on openjpeg (JPEG2000 codec) and jbig2dec (b/w image
|
||||
compression library). With the current version, we integrated those libraries
|
||||
alongside the MuPDF library to the 'libports' repository.
|
||||
|
||||
|
||||
GDB monitor refinements and automated test
|
||||
==========================================
|
||||
|
||||
We improved the support for GDB-based user-level debugging as introduced with
|
||||
the previous release.
|
||||
|
||||
For the x86 architecture, we fixed a corner-case problem with using the
|
||||
two-byte 'INT 0' instruction for breakpoints. The fix changes the breakpoint
|
||||
instruction to the single-byte 'HLT'. 'HLT' is a privileged instruction and
|
||||
triggers an exception when executed in user mode.
|
||||
|
||||
The new 'gdb_monitor_interactive.run' script extends the original
|
||||
'gdb_monitor.run' script with a startup sequence that automates the
|
||||
initial break-in at the 'main()' function of a dynamically linked binary.
|
||||
|
||||
The revised 'gdb_monitor.run' script has been improved to become a full
|
||||
automated test case for GDB functionalities. It exercises the following
|
||||
features (currently on Fiasco.OC only):
|
||||
* Breakpoint in 'main()'
|
||||
* Breakpoint in a shared-library function
|
||||
* Stack trace when not in a syscall
|
||||
* Thread info
|
||||
* Single stepping
|
||||
* Handling of segmentation-fault exception
|
||||
* Stack trace when in a syscall
|
||||
|
||||
|
||||
PDF viewer
|
||||
==========
|
||||
|
||||
According to our road map for 2012, we pursued the port of an existing PDF
|
||||
viewer as native application to Genode.
|
||||
|
||||
We first looked at the [http://poppler.freedesktop.org - libpoppler],
|
||||
which seems to be the most popular PDF rendering engine in the world of
|
||||
freedesktop.org. To get a grasp on what the porting effort of this engine may
|
||||
be, we looked at projects using this library as well as the library source
|
||||
code. By examining applications such as the light-weight epdfview
|
||||
application, we observed that libpoppler's primary design goal is to integrate
|
||||
well with existing freedesktop.org infrastructure rather than to reimplement
|
||||
functionality that is provided by another library. For example, fontconfig is
|
||||
used to obtain font information and Cairo is used as rendering backend. In the
|
||||
context of freedesktop.org, this makes perfect sense. But in our context,
|
||||
porting libpoppler would require us to port all this infrastructure to Genode
|
||||
as well. To illustrate the order of magnitude of the effort needed, epdfview
|
||||
depends on 65 shared libraries. Of course, at some point in the future, we will
|
||||
be faced to carry out this porting work. But for the immediate goal to have a
|
||||
PDF rendering engine available on Genode, it seems overly involved. Another
|
||||
criterion to evaluate the feasibility of integrating libpoppler with Genode is
|
||||
its API. By glancing at the API, it seems to be extremely feature rich and
|
||||
complex - certainly not a thing to conquer in one evening with a glass of wine.
|
||||
The Qt4 backend of the library comprises circa 8000 lines of code. This value
|
||||
can be taken as a vague hint at the amount of work needed to create a custom
|
||||
backend, i.e., for Genode's framebuffer-session interface.
|
||||
|
||||
Fortunately for us, there exists an alternative PDF rendering engine named
|
||||
MuPDF. The concept of MuPDF is quite the opposite of that of libpoppler.
|
||||
MuPDF tries to be as self-sufficient as possible in order to be suitable
|
||||
for embedded systems without comprehensive OS infrastructure. It comes with a
|
||||
custom vector-graphics library (instead of using an existing library such as
|
||||
Cairo) and it even has statically linked-in all font information needed to
|
||||
display PDF files that come with no embedded fonts. That said, it does not
|
||||
try to reinvent the wheel in every regard. For example, it relies on
|
||||
common libraries such as zlib, libpng, jpeg, freetype, and openjpeg. Most
|
||||
of them are already available on Genode. And the remaining libraries are rather
|
||||
free-standing and easy to port. To illustrate the low degree of dependencies,
|
||||
the MuPDF application on GNU/Linux depends on only 15 shared libraries. The
|
||||
best thing about MuPDF from our perspective however, is its lean and clean API,
|
||||
and the wonderfully simple example application. Thanks to this example, it was
|
||||
a breeze to integrate the MuPDF engine with Genode's native framebuffer-session
|
||||
and input-session interfaces. The effort needed for this integration work lies
|
||||
in the order of less than 300 lines of code.
|
||||
|
||||
At the current stage, the MuPDF rendering engine successfully runs on Genode
|
||||
in the form of a simple interactive test program, which can be started
|
||||
via the 'libports/run/mupdf' run script. The program supports the basic key
|
||||
handling required to browse through a multi-page PDF document
|
||||
(page-up or enter -> next page, page-down or backspace -> previous page).
|
||||
|
||||
|
||||
Improved terminal performance
|
||||
=============================
|
||||
|
||||
The terminal component used to make all intermediate states visible to the
|
||||
framebuffer in a fully synchronous fashion. This is an unfortunate behaviour
|
||||
when scrolling through large text outputs. By decoupling the conversion of the
|
||||
terminal state to pixels from the 'Terminal::write()' RPC function,
|
||||
intermediate terminal states produced by sub sequential write operations do not
|
||||
end up on screen one by one but only the final state becomes visible. This
|
||||
improvement drastically improves the speed in situations with a lot of
|
||||
intermediate states.
|
||||
|
||||
|
||||
Noux support for fork semantics
|
||||
===============================
|
||||
|
||||
Genode proclaims to be a framework out of which operating systems can be built.
|
||||
There is no better way of putting this claim to the test than to use the
|
||||
framework for building a Unix-like OS. This is the role of the Noux runtime
|
||||
environment.
|
||||
|
||||
During the past releases, Noux evolved into a runtime environment that is able
|
||||
to execute complex command-line-based GNU software such as VIM with no
|
||||
modification. However, we cannot talk of Unix without talking about its
|
||||
fundamental concept embodied in the form of the 'fork()' system call. We did
|
||||
not entirely dismiss the idea of implementing 'fork()' into Noux but up to now,
|
||||
it was something that we willingly overlooked. However, the primary goal of
|
||||
Noux is to run the GNU userland natively on Genode. This includes a good deal
|
||||
of programs that rely on fork semantics. We could either try to change all the
|
||||
programs to use a Genode-specific way of starting programs or bite in the
|
||||
bullet and implement fork. With the current release, we did the latter.
|
||||
|
||||
The biggest challenge of implementing fork was to find a solution that is not
|
||||
tied to one kernel but one that works across all the different base platforms.
|
||||
The principle problem of starting a new process in a platform-independent
|
||||
manner is already solved by Genode in the form of the 'Process' API. But this
|
||||
startup procedure is entirely different from the semantics of fork. The key to
|
||||
the solution was Genode's natural ability to virtualize the access to low-level
|
||||
platform resources. To implement fork semantics, all Noux has to do is to
|
||||
provide local implementations of core's RAM, RM, and CPU session interfaces.
|
||||
|
||||
The custom implementation of the CPU session interface is used to tweak the
|
||||
startup procedure as performed by the 'Process' class. Normally, processes
|
||||
start execution immediately at creation time at the ELF entry point. For
|
||||
implementing fork semantics, however, this default behavior does not work.
|
||||
Instead, we need to defer the start of the main thread until we have finished
|
||||
copying the address space of the forking process. Furthermore, we need to start
|
||||
the main thread at a custom trampoline function rather than at the ELF entry
|
||||
point. Those customizations are possible by wrapping core's CPU service.
|
||||
|
||||
The custom implementation of the RAM session interface provides a pool of RAM
|
||||
shared by Noux and all Noux processes. The use of a shared pool alleviates the
|
||||
need to assign RAM quota to individual Noux processes. Furthermore, the custom
|
||||
implementation is needed to get hold of the RAM dataspaces allocated by each
|
||||
Noux process. When forking a process, the acquired information is used to
|
||||
create a shadow copy of the forking address space.
|
||||
|
||||
Finally, a custom RM service implementation is used for recording all RM
|
||||
regions attached to the region-manager session of a Noux process. Using the
|
||||
recorded information, the address-space layout can then be replayed onto a new
|
||||
process created via fork.
|
||||
|
||||
With the virtualized platform resources in place, the only puzzle piece that
|
||||
is missing is the bootstrapping of the new process. When its main thread is
|
||||
started, it has an identical address-space content as the forking process but
|
||||
it has to talk to a different parent entrypoint and a different Noux session.
|
||||
The procedure of re-establishing the relationship of the new process to its
|
||||
parent is achieved via a small trampoline function that re-initializes the
|
||||
process environment and then branches to the original forking point via
|
||||
setjmp/longjmp. This mechanism is implemented in the libc_noux plugin.
|
||||
|
||||
As the immediate result of this work, a simple fork test can be executed across
|
||||
all base platforms except for Linux (Linux is not supported yet). The test
|
||||
program is located at 'ports/src/test/noux_fork' and can be started with the
|
||||
'ports/run/noux_fork.run' script.
|
||||
|
||||
Furthermore, as a slightly more exciting example, there is a run script for
|
||||
running a bash shell on a tar file system that contains coreutils. By starting
|
||||
the 'ports/run/noux_bash.run' script, you get presented an interactive bash
|
||||
shell. The shell is displayed via the terminal service and accepts user input.
|
||||
It allows you to start one of the coreutils programs such as ls or cat. Please
|
||||
note that the current state is still largely untested, incomplete, and flaky.
|
||||
But considering that Noux is comprised of less than 2500 lines of code, we are
|
||||
quite surprised of how far one can get with such little effort.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Driver improvements to accommodate dynamic (re-)loading
|
||||
=======================================================
|
||||
|
||||
To support the dynamic probing of devices as performed by the new d3m
|
||||
component, the ATAPI and USB device drivers have been enhanced to support the
|
||||
subsequent closing and re-opening of sessions.
|
||||
|
||||
|
||||
First bits of the d3m device-driver manager
|
||||
===========================================
|
||||
|
||||
The abbreviation d3m stands for demo device-driver manager. It is our current
|
||||
solution for the automated loading of suitable drivers as needed for running
|
||||
Genode from a Live CD or USB stick. Because of the current narrow focus of d3m,
|
||||
it is not a generic driver-management solution but a first step in this
|
||||
direction. We hope that in the long run, d3m will evolve to become a generic
|
||||
driver-management facility so that we can remove one of the "D"s from its name.
|
||||
In the current form d3m solves the problems of merging input-event streams,
|
||||
selecting the boot device, and dealing with failing network drivers.
|
||||
|
||||
When using the live CD, we expect user input to come from USB HID devices or
|
||||
from a PS/2 mouse and keyboard. The live system should be operational if at
|
||||
least one of those sources of input is available. In the presence of multiple
|
||||
sources, we want to accumulate the events of all of them.
|
||||
|
||||
The live CD should come in the form of a single ISO image that can be burned onto a CDROM or
|
||||
alternatively copied to an USB stick. The live system should boot fine in both
|
||||
cases. The first boot stage is accommodated by syslinux and the GRUB boot
|
||||
loader using BIOS functions. But once Genode takes over control, it needs to
|
||||
figure out on its own from where to fetch data. A priori, there is no way to
|
||||
guess whether the ATAPI driver or the USB storage driver should be used.
|
||||
|
||||
[image d3m_what_next]
|
||||
|
||||
Therefore, d3m implements a probing mechanism that starts each of the drivers,
|
||||
probes for the presence of a particular file on an iso9660 file system.
|
||||
|
||||
[image d3m_probing]
|
||||
|
||||
Once d3m observes a drivers that is able to successfully access the magic file,
|
||||
it keeps the driver and announces the driver's service to its own parent. For
|
||||
the system outside of d3m, the probing procedure is completely transparent. D3m
|
||||
appears to be just a service that always provides the valid block session for
|
||||
the boot medium.
|
||||
|
||||
[image d3m_ready]
|
||||
|
||||
The network device drivers that we ported from the iPXE project cover the
|
||||
range of most common wired network adaptors, in particular the E1000 family.
|
||||
But we cannot presume that a computer running the live system comes equipped
|
||||
with one of the supported devices. If no supported network card could be
|
||||
detected the driver would simply fail. Applications requesting a NIC session
|
||||
would block until a NIC service becomes available, which won't happen. To
|
||||
prevent this situation, d3m wraps the NIC driver and provides a dummy NIC
|
||||
service in the event the drivers fails. This way, the client application won't
|
||||
block infinitely but receive an error on the first attempt to use the NIC.
|
||||
|
||||
|
||||
ACPI support
|
||||
============
|
||||
|
||||
To accommodate kernels like Fiasco.OC or NOVA that take advantage of x86's
|
||||
APIC, we have introduced a simple ACPI parser located at 'os/src/drivers/acpi'.
|
||||
The server traverses the ACPI tables and sets the interrupt line of devices
|
||||
within the PCI config space to the GSIs found in the ACPI tables. Internally it
|
||||
uses Genode's existing PCI driver as a child process for performing PCI access
|
||||
and, in turn, announces a PCI service itself.
|
||||
|
||||
For obtaining the IRQ routing information from the ACPI tables without
|
||||
employing a full-blown ACPI interpreter, the ACPI driver uses an ingenious
|
||||
technique invented by Bernhard Kauer, which is described in the following
|
||||
paper:
|
||||
|
||||
:[http://os.inf.tu-dresden.de/papers_ps/tr-atare-2009.pdf - ATARE - ACPI Tables and Regular Expressions]:
|
||||
_TU Dresden technical report TUD-FI09-09, Dresden, Germany, August 2009_
|
||||
|
||||
:Usage:
|
||||
|
||||
Start the 'acpi_drv' in your Genode environment. Do not start the 'pci_drv'
|
||||
since this will be used as a slave of the 'acpi_drv'. You still must load the
|
||||
'pci_drv' in your boot loader. To integrate the ACPI driver into your boot
|
||||
configuration, you may take the following snippet as reference:
|
||||
|
||||
!<start name="acpi">
|
||||
! <resource name="RAM" quantum="2M"/>
|
||||
! <binary name="acpi_drv"/>
|
||||
! <provides><service name="PCI"/></provides>
|
||||
! <route>
|
||||
! <service name="ROM"> <parent/> </service>
|
||||
! <any-service> <any-child/> <parent/> </any-service>
|
||||
! </route>
|
||||
!</start>
|
||||
|
||||
:Limitations and known issues:
|
||||
|
||||
Currently there is no interface to set the interrupt mode for core's IRQ
|
||||
sessions (e.g., level or edge triggered). This is required by Fiasco.OCs kernel
|
||||
interface. We regard this as future work.
|
||||
|
||||
|
||||
Platform support
|
||||
################
|
||||
|
||||
Fiasco.OC microkernel
|
||||
=====================
|
||||
|
||||
The support for the Fiasco.OC base platform is still lacking proper handling
|
||||
for releasing resources such as kernel capabilities. Although this is a known
|
||||
issue, we underestimated the reach of the problem when Genode's signal API is
|
||||
used. Each emitted signal happens to consume one kernel capability within core,
|
||||
ultimately leading to a resource outage when executing signal-intensive code
|
||||
such as the packet-stream interface. The current release comes with an interim
|
||||
solution. To remedy the acute problem, we extended the 'Capability_allocator'
|
||||
class with the ability to register the global ID of a Genode capability so
|
||||
that the ID gets associated with a process-local kernel capability. Whenever
|
||||
a Genode capability gets unmarshalled from an IPC message, the
|
||||
capability-allocator is asked, with the global ID as key, whether the
|
||||
kernel-cap already exists. This significantly reduces the waste of
|
||||
kernel-capability slots.
|
||||
|
||||
To circumvent problems of having one and the same ID for different kernel
|
||||
objects, the following problems had to be solved:
|
||||
|
||||
* Replace pseudo IDs with unique ones from core's badge allocator
|
||||
* When freeing a session object, free the global ID _after_ unmapping
|
||||
the kernel object, otherwise the global ID might get re-used in some
|
||||
process and the registry will find a valid but wrong capability
|
||||
for the ID
|
||||
|
||||
Because core aggregates all capabilities of all different processes, its
|
||||
capability registry needs much more memory compared to a regular process.
|
||||
By parametrizing capability allocators differently for core and non-core
|
||||
processes, the global memory overhead for capability registries is kept
|
||||
at a reasonable level.
|
||||
|
||||
Please note that this solution is meant as an interim fix until we have
|
||||
resolved the root of the problem, which is the proper tracking and releasing
|
||||
of capability selectors.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Linux is one of the two original base platforms of Genode. The original
|
||||
intension behind supporting Linux besides a microkernel was to facilitate
|
||||
portability of the API design and to have a convenient testing environment for
|
||||
platform-independent code. Running Genode in the form of a bunch of plain Linux
|
||||
processes has become an invaluable feature for our fast-paced development.
|
||||
|
||||
To our delight, we lately discovered that the use of running Genode on Linux
|
||||
can actually go far beyond this original incentive. Apparently, on Linux, the
|
||||
framework represents an equally powerful component framework as on the other
|
||||
platforms. Hence, Genode has the potential to become an attractive option for
|
||||
creating complex component-based user-level software on Linux.
|
||||
|
||||
For this intended use, however, the framework has to fulfill the following
|
||||
additional requirements:
|
||||
|
||||
* Developers on Linux expect that their components integrate seamlessly with
|
||||
their existing library infrastructure including all shared libraries
|
||||
installed on Linux.
|
||||
|
||||
* The use of a custom tool chain is hard to justify to developers who regard
|
||||
Genode merely as an application framework. Hence, a way to use the normal
|
||||
tool chain as installed on the Linux host system is desired.
|
||||
|
||||
* Application developers are accustomed with using GDB for debugging and expect
|
||||
that GDB can be attached to an arbitrary Genode program in an intuitive way.
|
||||
|
||||
Genode's original support for Linux as base platform did not meet those
|
||||
expectations. Because Genode's libc would ultimately collide with the Linux
|
||||
glibc, Genode is built with no glibc dependency at all. It talks to the kernel
|
||||
directly using custom kernel bindings. In particular, Genode threads are created
|
||||
directly via the 'clone()' system call and thread-local storage (TLS) is managed
|
||||
in the same way as for the other base platforms. This has two implications.
|
||||
First, because Genode's TLS mechanism is different than the Linux TLS
|
||||
mechanism, Genode cannot be built with the normal host tool chain. This
|
||||
compiler would generate code that would simply break on the first attempt to
|
||||
use TLS. We solved this problem with our custom tool chain, which is configured
|
||||
for Genode's needs. The second implication is that GDB is not able to handle
|
||||
threads created differently than those created via the pthread library. Even
|
||||
though GDB can be attached to each thread individually, the debugger would not
|
||||
correctly handle a multi-threaded Genode process as a multi-threaded Linux
|
||||
program. With regard to the use of Linux shared libraries, Genode used to
|
||||
support a few special programs that used both the Genode API and Linux
|
||||
libraries. Those programs (called hybrid Linux/Genode programs) were typically
|
||||
pseudo device drivers that translate a Linux API to a Genode service. For
|
||||
example, there exists a framebuffer service that uses libSDL as back end.
|
||||
Because those programs were a rarity, the support by the build system for such
|
||||
hybrid targets was rather poor.
|
||||
|
||||
Fortunately, all the problems outlined above could be remedied pretty easily.
|
||||
It turns out that our custom libc is simply not relevant when Genode is
|
||||
used as plain application framework on Linux. For this intended use, we always
|
||||
want to use the host's normal libc. This way, the sole reason for using plain
|
||||
system calls instead of the pthread library vanishes, which, in turn,
|
||||
alleviates the need for a custom tool chain. Genode threads are then simply
|
||||
pthreads compatible with the TLS code as emitted by the host compiler and
|
||||
perfectly recognised by GDB. With the surprisingly little effort of creating a
|
||||
new implementation of Genode's thread API to target pthreads instead of using
|
||||
syscalls, we managed to provide a decent level of support for using Genode as
|
||||
user-level component framework on Linux.
|
||||
|
||||
These technical changes alone, however, are not sufficient to make Genode
|
||||
practical for real-world use. As stated above, the few hybrid Linux/Genode
|
||||
programs used to be regarded as some leprous artifacts. When using Genode as
|
||||
Linux application framework, however, this kind of programs are becoming the
|
||||
norm rather than an exception. For this reason, we introduced new support for
|
||||
such hybrid programs into the build system. By listing the 'lx_hybrid'
|
||||
library in the 'LIBS' declaration of a target, this target magically becomes a
|
||||
hybrid Linux/Genode program. It gets linked to the glibc and uses pthreads
|
||||
instead of direct syscalls. Furthermore, host libraries can be linked to the
|
||||
program by stating their respective names in the 'LX_LIBS' variable. For an
|
||||
example, please refer to the libSDL-based framebuffer at
|
||||
'os/src/drivers/framebuffer/sdl/target.mk'.
|
||||
|
||||
To enforce the build of all targets as hybrid Linux/Genode programs, the build
|
||||
system features the 'alyways_hybrid' 'SPEC' value. To make it easy to create a
|
||||
build directory with all targets forced to be hybrid, we have added the new
|
||||
'lx_hybrid_x86' platform to the 'create_builddir' tool.
|
||||
|
||||
|
||||
OKL4
|
||||
====
|
||||
|
||||
:Sending an invalid-opcode exception IPC on OKL4:
|
||||
|
||||
When an invalid opcode gets executed, OKL4 switches to the kernel debugger
|
||||
console instead of sending an exception IPC to the userland. We fixed this
|
||||
problem by removing the code that invokes the debugger console from the kernel.
|
||||
|
||||
:Hard-wire OKL4 elfweaver to Python 2:
|
||||
|
||||
Recent Linux distributions use Python version 3 by default. But OKL4's
|
||||
elfweaver is not compatible with this version of Python. For this reason, we
|
||||
introduced a patch for pinning the Python version used by elfweaver to
|
||||
version 2.
|
||||
|
||||
Both patches get automatically applied when preparing the 'base-okl4'
|
||||
repository via 'make prepare'.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
:Facility for explicitly building all libraries:
|
||||
|
||||
During its normal operation, the build system creates libraries as mere side
|
||||
effects of building targets. There is no way to explicitly trigger the build of
|
||||
libraries only. However, in some circumstances (for example for testing the
|
||||
thorough build of all libraries), a mechanism for explicitly building libraries
|
||||
would be convenient. Hence we introduced this feature in the form of the pseudo
|
||||
target located at 'base/src/lib/target.mk'. By issuing 'make lib' in a build
|
||||
directory, this target triggers the build of all libraries available for the
|
||||
given platform.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,665 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 12.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
With Genode 12.08, the project focused on platform support. It enters the world
|
||||
of OMAP4-based ARM platforms, revived and vastly enhanced the support for the
|
||||
NOVA hypervisor, and becomes able to run directly on ARM platforms without the
|
||||
need for an underlying kernel.
|
||||
|
||||
The new 'base-hw' platform is a deviation from Genode's traditional approach to
|
||||
complement existing kernels with user-land infrastructure. It completely leaves
|
||||
the separate kernel out of the picture and thereby dwarfs the base line of the
|
||||
trusted computing base of Genode-based systems to approximately the half. The
|
||||
new base platform is described in Section [Genode on naked ARM hardware].
|
||||
|
||||
Speaking of base platforms, we are happy to have promoted the NOVA hypervisor
|
||||
to a first-class citizen among the base platforms. During the last months, this
|
||||
kernel underwent fundamental changes regarding its mode of development and its
|
||||
feature set. This prompted us to vastly improve Genode's support for this
|
||||
platform and leverage its unique features. If considering the use of Genode on
|
||||
x86-based hardware, NOVA has become a very attractive foundation. Section
|
||||
[Embracing the NOVA Hypervisor] describes the NOVA-specific changes.
|
||||
|
||||
The improvement of platform support with the current release does not entail
|
||||
the base platforms only but extends to profound additions of device drivers, in
|
||||
particular for the ARM-based OMAP4 SoC as used on the popular Pandaboard. We
|
||||
are proud to announce the availability of device drivers for HDMI output,
|
||||
SD-card, USB HID, and networking for this platform.
|
||||
|
||||
Beyond the low-level platform improvements, the new version comes with several
|
||||
new services, optimizations of existing components, and new ported libraries.
|
||||
In particular, the Noux runtime has reached a point where we can principally
|
||||
execute serious networking applications such as the Lynx web browser natively
|
||||
on Genode. Another example is the new FFAT-based file-system service, which
|
||||
makes persistent storage available via Genode's file-system interface. By
|
||||
combining this new service with existing components such as the partition
|
||||
service, Noux, or the file-system plugin of the libc, a lot of new application
|
||||
scenarios become available. Thanks to these new components, the framework has
|
||||
become able to perform on-target debugging via GDB running in Noux, or host
|
||||
the genode.org website via the lighttpd web server,
|
||||
|
||||
|
||||
:What about the road map?:
|
||||
|
||||
Those of you who track the milestones laid out in our [http:/about/road-map - road map]
|
||||
may wonder how Genode 12.08 relates to the stated goals. In fact, several
|
||||
points of the road map haven't received the attention as originally planned.
|
||||
As an explanation, let us quote the paragraph right atop of the road-map page:
|
||||
"The road map is not fixed. If there is commercial interest of pushing the
|
||||
Genode technology to a certain direction, we are willing to revisit our plans."
|
||||
Well, this is what happened. So we traded the work on the tiled window manager,
|
||||
the Intel wireless driver, and SMP support for the work on the platform topics
|
||||
outlined above. Nevertheless, we stick to our overall plan to turn Genode into
|
||||
a general-purpose OS that is fit for use by its developers by the end of the
|
||||
year. If looking closely at the additions that come with the current release,
|
||||
it will become apparent how well they fit into the big picture.
|
||||
|
||||
|
||||
Genode on naked ARM hardware
|
||||
############################
|
||||
|
||||
One of Genode's most distinguishing properties is the ability to use the framework
|
||||
on top of a range of different kernels. This way, users of the framework
|
||||
benefit from the wide variety of features provided by those kernels while
|
||||
only dealing with a single API and configuration concept. For example, we
|
||||
frequently find ourselves using the Linux kernel as base platform while
|
||||
developing services, interfaces, and protocol stacks. By being able to start
|
||||
Genode as a regular program, we effectively eliminate the reboot-time for each
|
||||
test run and enjoy using commodity debugging and profiling tools. On the other
|
||||
hand, if high security is a concern, NOVA and Fiasco.OC provide
|
||||
capability-based security at kernel-level. So the use of one of those kernels
|
||||
is desirable. Genode allows for switching between those vastly different
|
||||
kernels almost seamlessly.
|
||||
|
||||
In general, a Genode system consists of a kernel, Genode's core, and the
|
||||
largely generic components on top of core. Core abstracts away the
|
||||
peculiarities of the respective kernel and provides a unified API to the
|
||||
components on top. From the application's point of view both kernel and core
|
||||
are always at the root of the process tree and thereby are a inherent part of
|
||||
the application's trusted computing base (TCB). The distinction of both
|
||||
programs is almost superficial.
|
||||
|
||||
Since both the kernel and core must be ultimately trusted, the complexity of
|
||||
both programs is critical for each Genode-based system. On our quest for
|
||||
minimizing the TCB complexity so far, however, we did not question the role of
|
||||
the kernel as an inherent part of the TCB and focused our attention to the
|
||||
software stack on top. However, with more and more kernels entering the
|
||||
picture, we identified that there is typically a considerable overlap in
|
||||
functionality between kernel and core. For example, both need to know about
|
||||
address spaces and their relationship to physical memory objects. Most kernels
|
||||
keep track of memory mappings in an in-kernel database. Core also needs to keep
|
||||
track of this information. Consequently, we found several information
|
||||
replicated without a clear benefit. With this comes a seemingly significant
|
||||
redundancy of code for data structures, allocators, and utility functions.
|
||||
Furthermore, there exists a class of problems that must be solved by the kernel
|
||||
and core alike. In particular the resource management of dynamically allocated
|
||||
in-kernel objects respectively in-core objects. Whereas core uses Genode's
|
||||
resource-trading concept to solve this problem, most kernels lack a good
|
||||
solution for the management of in-kernel resources and are consequently prone
|
||||
to resource exhaustion problems.
|
||||
|
||||
Out of these observations, the idea was born to explore the opportunities of
|
||||
merging both programs into one and thereby eliminating the redundancies. Our
|
||||
first attempt to go into this direction was the 'base-mb' platform, which
|
||||
enabled us to run Genode on the Xilinx MicroBlaze softcore CPU. With this
|
||||
experiment, we gained confidence that the approach is generally feasible. So we
|
||||
took on the challenge to implement the idea of a hybrid kernel/core on a more
|
||||
complex architecture namely ARM Cortex-A9.
|
||||
|
||||
The 'base-hw' platform introduced with the current release is the intermediate
|
||||
result of our experiment. With this base platform, core plays the role of core
|
||||
and the kernel within one program. A few code paths that require execution in
|
||||
privileged mode are executed in kernel mode whereas most code paths are
|
||||
executed in user mode. Both user mode code and kernel mode code run in the same
|
||||
address space. The kernel portion merely provides a few basic mechanisms
|
||||
without performing complex operations such as dynamic memory allocations. For
|
||||
example, if core is requested to create a new thread via core's CPU session
|
||||
interface, the user-level code within core allocates a KTCB (kernel thread
|
||||
control block) and UTCB (user-level thread-control block) from the physical
|
||||
memory allocator and passes both physical addresses to the kernel function that
|
||||
spawns the actual thread. This way, we can employ Genode's resource-trading
|
||||
concept for managing typical kernel resources.
|
||||
|
||||
The experiment turned out to be a great success. Traditionally, we would account
|
||||
at least 10,000 lines of code (LOC) for the kernel. Most kernels are actually
|
||||
much larger than that. Core comes at a complexity of another 10,000 LOC. So
|
||||
both kernel and core make up a base line of TCB complexity of more than 20,000
|
||||
LOC. By co-locating core with the kernel, we end up with a program of just
|
||||
about 13,000 LOC. The vast reduction of TCB complexity compared to having
|
||||
kernel and core as separate programs strikes us.
|
||||
|
||||
The 'base-hw' version of core supports the complete Genode API covering support
|
||||
for user-level device drivers, synchronous RPCs, asynchronous notifications,
|
||||
shared memory, and managed dataspaces. It is thereby able to execute the
|
||||
sophisticated Genode scenarios on top including the GUI, the dynamic linker,
|
||||
and user-level device drivers. That said, we regard the current version still
|
||||
as work in progress. We successfully use it as an experimentation platform for
|
||||
ongoing research activities (i.e., for exploring ARM TrustZone) but some
|
||||
important features such as capability-based security are not yet implemented.
|
||||
|
||||
:Using the base-hw platform:
|
||||
|
||||
The new base platform is fully integrated with Genode's build system.
|
||||
When listing the supported base platforms via the 'tool/create_builddir' tool,
|
||||
you will see the new 'hw_panda_a2', 'hw_vea9x4', 'hw_pbxa9' choices of
|
||||
build-directory templates. The latter platform enables you to run a
|
||||
'base-hw' Genode system on Qemu.
|
||||
|
||||
[http://genode.org/documentation/platforms/hw - Learn more about using the new base-hw platform...]
|
||||
|
||||
For running Genode directly on the Pandaboard, please refer to the
|
||||
[http://genode.org/documentation/platforms/hw_panda_a2 - Pandaboard-specific documentation...]
|
||||
|
||||
|
||||
Embracing the NOVA Hypervisor
|
||||
#############################
|
||||
|
||||
NOVA is a so-called microhypervisor for the x86 architecture. It combines the
|
||||
principles of microkernels with capability-based security and hardware-assisted
|
||||
virtualization. Among the various base platforms supported by Genode, NOVA's
|
||||
kernel interface stands out for being extremely minimalistic and orthogonal,
|
||||
even by microkernel standards.
|
||||
|
||||
Genode has supported NOVA as base platform since 2010. But because we used NOVA
|
||||
solely for sporadic research activities and NOVA's lack of a regular release
|
||||
schedule, the framework's platform support received only little attention. This
|
||||
has changed now. NOVA's main developer Udo Steinberg moved from TU Dresden to
|
||||
Intel Labs where he leads the development of NOVA as a true Open-Source
|
||||
project. In fact, the code is now being hosted at GitHub:
|
||||
|
||||
:[https://github.com/IntelLabs/NOVA]:
|
||||
NOVA hypervisor at GitHub
|
||||
|
||||
Since its move to GitHub, the hypervisor has already seen significant
|
||||
improvements. The repository is continuously updated, which enables us to stay
|
||||
in a close feedback loop with the NOVA developers. This change of how NOVA's
|
||||
development is conducted ignited our renewed interest in promoting this
|
||||
platform to a first-level citizen of our framework. The first noteworthy
|
||||
improvement is the recently added 64-bit support of NOVA. We enabled Genode to
|
||||
work with both variants of the kernel - 32 bit and 64 bit.
|
||||
|
||||
But this was just the first step. The second major change addresses the
|
||||
allocation of kernel resources. Early versions of the hypervisor allowed each
|
||||
process to create kernel objects and thereby indirectly consume the limited
|
||||
memory resources of the kernel. This is perfectly fine for a research project
|
||||
but it becomes a potential denial-of-service problem in real-world use cases.
|
||||
For this reason, newer versions introduced the ability to retain the allocation
|
||||
of kernel objects within a trusted component only. In the Genode world, this
|
||||
component is naturally core. Even though NOVA still lacks a flexible concept for
|
||||
kernel-resource management as of now, Genode has become able to use NOVA
|
||||
without suffering the inherent resource management limitation. This is achieved
|
||||
because core is able to arbitrate the allocation of kernel resources.
|
||||
|
||||
The third fundamental change is the abolishment of the last traces of global
|
||||
names in a NOVA-based Genode system. There are no thread IDs, object IDs, or
|
||||
any other kind of globally meaningful names. Each process has a local view on
|
||||
(a small part of) the system only. If a process interacts with another process,
|
||||
the kernel translates the references to remote objects from one namespace to
|
||||
the other. The security implications are eminent. First, a process can only
|
||||
interact with or refer to objects for which it has a name, which vastly reduces
|
||||
problems of ambient authority. Second, because the kernel translates names, it
|
||||
becomes impossible to forge object identities. If a process tried to pass a
|
||||
forged object reference to another process, the translation would simply fail,
|
||||
rendering the attack ineffective.
|
||||
|
||||
The described changes do not come without issues, though. To make the NOVA
|
||||
kernel fit with Genode's requirements, minor patches of the hypervisor are
|
||||
needed. The patches are located at 'base-nova/patches/'. However, those patches
|
||||
are meant as interim solutions until we find mechanisms that fit well with the
|
||||
design of the hypervisor and also fulfil our requirements.
|
||||
|
||||
So far, we greatly enjoyed the revived collaboration with the NOVA developers
|
||||
and congratulate Udo Steinberg for the new mode of development of the
|
||||
hypervisor.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
In the following, we describe changes of the base API that may affect users of
|
||||
the framework.
|
||||
|
||||
:Allocation of DMA buffers:
|
||||
|
||||
We extended the RAM session interface with the ability to allocate DMA buffers.
|
||||
The client specifies the type of RAM dataspace to allocate via the new 'cached'
|
||||
argument of the 'Ram_session::alloc()' function. By default, 'cached' is true,
|
||||
which corresponds to the common case and the original behavior. When setting
|
||||
'cached' to 'false', core takes the precautions needed to register the memory
|
||||
as uncached in the page table of each process that has the dataspace attached.
|
||||
|
||||
Currently, the support for allocating DMA buffers is implemented for Fiasco.OC
|
||||
only. On x86 platforms, it is generally not needed. But on platforms with more
|
||||
relaxed cache coherence (such as ARM), user-level device drivers should always
|
||||
use uncacheable memory for DMA transactions.
|
||||
|
||||
|
||||
:MMIO framework improvements:
|
||||
|
||||
As we find ourselves increasingly using the 'Register' and 'Mmio' templates
|
||||
provided by 'util/register.h' and 'util/mmio.h' for dealing with memory-mapped
|
||||
devices, we extended the utilities with support for 64-bit registers and a new
|
||||
interface for polling bit states. The latter functionality is provided by the
|
||||
new 'wait_for' function template. To decouple the MMIO-related utility code
|
||||
from an actual timer facility, the function takes a so-called 'delayer' functor
|
||||
as argument. This way the user of the MMIO framework is able to pick a timer
|
||||
facility that fits best with the device.
|
||||
|
||||
|
||||
:New 'memcpy' implementation:
|
||||
|
||||
The memory-copy functions provided by 'util/string.h' are extremely simple
|
||||
and arguably slow, particularly on platforms where byte-wise copy operations
|
||||
are not supported by the CPU (i.e., ARM). Hence, we have added a CPU-specific
|
||||
memcpy function ('memcpy_cpu') to 'cpu/string.h', which enables us to
|
||||
provide optimized implementations. So far, we did so for the ARM architecture.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
FFat-based file-system service
|
||||
==============================
|
||||
|
||||
With the previous release, we introduced Genode's file-system interface
|
||||
accompanied with a simple in-memory file-system service. With the addition of
|
||||
'ffat_fs', the current release adds the first persistent file system to the
|
||||
framework. The service is located at 'libports/src/server/ffat_fs'. It uses
|
||||
Genode's 'Block::Session' interface as back end. Therefore, it can be combined
|
||||
with any of Genode's block-device drivers and the partition service called
|
||||
'part_blk'. To see the new 'ffat_fs' service in action, please refer to the new
|
||||
'libports/run/libc_ffat_fs.run' script.
|
||||
|
||||
On the course of our work on the 'ffat_fs' service, we enabled support for long
|
||||
file names in libffat and added 'lseek' support to the 'libc_ffat' plugin.
|
||||
|
||||
|
||||
TAR-based file-system service
|
||||
=============================
|
||||
|
||||
The new 'tar_fs' service located at 'os/src/server/tar_fs' provides a read-only
|
||||
file-system session interface by reading data from a TAR archive, which, in
|
||||
turn, is fetched from a ROM service. By combining 'tar_fs' with the 'libc_fs'
|
||||
plugin, it becomes easy to provide customized pseudo file systems to individual
|
||||
Genode programs. For example, one instance of 'tar_fs' containing a static
|
||||
website and a web-server configuration can be provided as file system to a web
|
||||
server. The configuration is similar to the patterns known from the 'tar_rom'
|
||||
and 'ram_fs' servers:
|
||||
|
||||
! <config>
|
||||
! <archive name="tar_archive.tar" />
|
||||
! <policy label="label_of_client" root="/rootdir/for/client" />
|
||||
! </config>
|
||||
|
||||
The policy node allows for assigning different parts of one TAR archive to
|
||||
different clients. For a practical usage example of 'tar_fs', please refer to
|
||||
the 'libports/run/libc_fs_tar_fs.run' script.
|
||||
|
||||
|
||||
Terminal improvements
|
||||
=====================
|
||||
|
||||
Our work on running a growing number of command-line-based Unix programs via
|
||||
Noux prompted us to improve our terminal implementation as needed. To ease
|
||||
debugging for terminal colors, we changed the previous default color scheme to
|
||||
fully saturated combinations of red, green, and blue. Albeit this looks quite
|
||||
painful on the eyes, it is easier to spot wrong colors when using a program
|
||||
that uses ncurses, for example Lynx. Furthermore, we added the handling of
|
||||
sgr0 and sgr escape sequences and thereby enabled Lynx to become almost
|
||||
usable when running within Noux.
|
||||
|
||||
|
||||
Terminal cross-link service
|
||||
===========================
|
||||
|
||||
The 'Terminal::Session' interface gets increasingly popular within Genode.
|
||||
It is used by the UART drivers, the graphical terminal, GDB monitor, the TCP
|
||||
terminal, and Noux. For most of these programs, their respective client or
|
||||
server role is quite clear but we find ourselves tempted to combine components
|
||||
in unusual ways. For example, to let Noux run an instance of GDB, which operates
|
||||
on a terminal via a virtual character device. For remote debugging, GDB plays
|
||||
the role of a terminal client and the UART driver plays the role of the server.
|
||||
But when running GDB monitor on the same machine, GDB monitor will also
|
||||
expect to play the role of the client. In order to connect GDB monitor
|
||||
to a local instance of GDB, both of them being terminal clients, we need an
|
||||
adapter component. This is where the new terminal cross-link service enters
|
||||
the picture. It plays the role of a terminal server between exactly two
|
||||
clients. The output of one client ends up as input to the other and vice
|
||||
versa. Data sent to the server gets stored in a buffer of 4096 bytes (one
|
||||
buffer per client). As long as the data to be written fits into the buffer, the
|
||||
'write()' call returns immediately. If no more data fits into the buffer, the
|
||||
'write()' call blocks until the other client has consumed some of the data from
|
||||
the buffer via the 'read()' call. The 'read()' call never blocks. A signal
|
||||
receiver can be used to block until new data is ready for reading.
|
||||
|
||||
The new terminal crosslink can be tested via the 'os/run/terminal_crosslink.run'
|
||||
script. It is also used for the just mentioned on-target debugging scenario
|
||||
demonstrated by the 'ports/run/noux_gdb.run' script.
|
||||
|
||||
|
||||
DMA-aware and optimized packet streams
|
||||
======================================
|
||||
|
||||
Motivated by our work on OMAP4 platform support, we introduced API extensions
|
||||
for handling of DMA buffers to the following interfaces:
|
||||
|
||||
:'Attached_ram_dataspace':
|
||||
|
||||
The convenience utility for allocating and locally mapping a RAM dataspace
|
||||
has been enhanced with the 'cached' constructor argument, which is true
|
||||
by default. When using 'Attached_ram_dataspace' for allocating DMA buffers,
|
||||
this argument should be set to false.
|
||||
|
||||
:Block and network packet stream:
|
||||
|
||||
The 'Block::Session' and 'Nic::Session' interfaces use Genode's packet stream
|
||||
facility for transferring bulk payload between processes. A packet stream
|
||||
combines shared memory with asynchronous notifications and thereby facilitates
|
||||
the use of batched packet processing. To principally enable zero-copy semantics
|
||||
for device drivers, the packet-stream buffer is now explicitly allocated as DMA
|
||||
buffer. This clears the way to let the SD-card driver direct DMA transactions
|
||||
right into the packet stream buffer. Consequently, when attaching the SD-card
|
||||
driver directly to a file system, there is no copy of payload needed.
|
||||
|
||||
The 'Nic::Session' interface has further been improved by using a fast
|
||||
bitmap allocator for allocations within the packet-stream buffer. This is
|
||||
possible because networking packets have the MTU size as an upper limit.
|
||||
In contrast to the 'Block::Session' interface where requests are relatively
|
||||
large, 'Nic::Session' packets are tiny, and thus, greatly benefit from the
|
||||
optimized allocator.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
:File I/O:
|
||||
|
||||
We complemented our C runtime with support for the 'pread', 'pwrite', 'readv',
|
||||
and 'writev' functions. The 'pread' and 'pwrite' functions are shortcuts for
|
||||
randomly accessing different parts of a file. Under the hood, the functions are
|
||||
implemented via 'lseek' and 'read/write'. To provide the atomicity of the
|
||||
functions, a lock guard prevents the parallel execution of either or both
|
||||
functions if called concurrently by multiple threads. The 'readv' and 'writev'
|
||||
functions principally enable the chaining of multiple I/O requests.
|
||||
Furthermore, we added 'ftruncate', 'poll', and basic support for (read-only)
|
||||
mmapped files to the C runtime.
|
||||
|
||||
:Libc RPC framework headers:
|
||||
|
||||
Certain RPC headers of the libc are needed for compiling 'getaddrinfo.c'.
|
||||
Unfortunately that means we have to generate a few header files, which we do
|
||||
when we prepare the libc.
|
||||
|
||||
|
||||
New and updated 3rd-party libraries
|
||||
===================================
|
||||
|
||||
:Expat:
|
||||
|
||||
[http://expat.sourceforge.net - Expat] is an XML parsing library. The port of
|
||||
this library was motivated by our goal to use the GNU debugger for on-target
|
||||
debugging. GDB depends on this library.
|
||||
|
||||
:MPC and GMP:
|
||||
|
||||
We complemented our existing port of the
|
||||
[http://gmplib.org - GNU multiple precision arithmetic library (libgmp)] with
|
||||
support for the x86_64 and ARM architectures. This change combined with the
|
||||
port of the [http://www.multiprecision.org/index.php?prog=mpc - MPC library]
|
||||
enables us to build the Genode tool chain for these architectures.
|
||||
|
||||
:OpenSSL:
|
||||
|
||||
Our port of OpenSSL has been updated to version 1.0.1c. Because libcrypto
|
||||
provides certain optimized assembler functions, which unfortunately are not
|
||||
expressed with position-independent code, we removed this assembler code and
|
||||
build libcrypto with '-DOPENSSL_NO_ASM'. Because the assembler code is not
|
||||
needed anymore, its generation is also removed from 'openssl.mk'.
|
||||
|
||||
:Light-weight IP stack (lwIP):
|
||||
|
||||
We enabled the lwIP TCP/IP stack for 64-bit machines and updated the library to
|
||||
version 1.4.1-rc1. With the new version, the call of 'lwip_loopback_init' is
|
||||
not needed anymore because lwIP always creates a loopback device. Hence, we
|
||||
will be able to remove the 'libc_lwip_loopback' in the future. For now, we keep
|
||||
it around so we currently do not need to update the other targets that depend
|
||||
on it.
|
||||
|
||||
:PCRE:
|
||||
|
||||
[http://www.pcre.org/ - PCRE] is a library for parsing regular rexpressions. We
|
||||
require this library for our ongoing work on porting the lighttpd webserver.
|
||||
|
||||
|
||||
Lighttpd web server
|
||||
===================
|
||||
|
||||
The [http://www.lighttpd.net/ - Lighttpd] web server has been added to the
|
||||
'ports' repository. The port runs as a native Genode application and ultimately
|
||||
clears the way to hosting the genode.org website on Genode. To test drive this
|
||||
scenario, please give the 'ports/run/genode_org.run' script a try.
|
||||
|
||||
At the current stage, the port is still quite limited. For example, it does not
|
||||
make use of non-blocking sockets yet. But the 'genode_org.run' run script
|
||||
already showcases very well how simple a Genode-based web-server appliance can
|
||||
look like.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
OMAP4 platform drivers
|
||||
======================
|
||||
|
||||
:HDMI output:
|
||||
|
||||
The new HDMI driver at 'os/src/drivers/framebuffer/omap4' implements Genode's
|
||||
'Framebuffer::Session' interface by using the HDMI output of OMAP4. The current
|
||||
version sets up a fixed XGA screen mode of 1024x768 with the RGB565 pixel
|
||||
format.
|
||||
|
||||
|
||||
:SD-card:
|
||||
|
||||
The new SD card driver at 'os/src/drivers/sd_card/omap4' allows the use of a
|
||||
HDSD card with the Pandaboard as block service. The driver can be tested using
|
||||
the 'os/run/sd_card.run' script. Because it implements the generic
|
||||
'Block::Session' interface, it can be combined with a variety of other
|
||||
components such as 'part_blk' (for accessing individual partitions) or
|
||||
'ffat_fs' for accessing a VFAT file system on the SD card.
|
||||
|
||||
The driver uses the master DMA facility of the OMAP4 SD-card controller, which
|
||||
yields to good performance at low CPU utilization. The throughput matches (and
|
||||
in some cases outperforms) the Linux kernel driver. In the current version,
|
||||
both modes of operation PIO and DMA are functional. However, PIO mode is
|
||||
retained for benchmarking purposes only and will possibly be removed to further
|
||||
simplify the driver.
|
||||
|
||||
|
||||
:USB HID:
|
||||
|
||||
The OMAP4-based Pandaboard relies on USB for attaching input devices.
|
||||
Therefore, we need a complete USB stack to enable the interactive use of the
|
||||
board. Instead of implementing a USB driver from scratch, we built upon the USB
|
||||
driver introduced with the Genode release 12.05. This driver was ported from the
|
||||
Linux kernel.
|
||||
|
||||
|
||||
:Networking:
|
||||
|
||||
The Pandaboard realizes network connectivity via the SMSC95xx chip attached to
|
||||
the USB controller. Therefore, we enhanced our USB driver with support for USB
|
||||
net and the smsc95xx driver. In addition to enabling the actual device-driver
|
||||
functionality, the USB stack has received much attention concerning performance
|
||||
optimizations. To speed up the allocation of SKBs, we replaced the former
|
||||
AVL-tree based allocator with a fast bitmap allocator. For anonymous
|
||||
allocations, we introduced a slab-based allocator. Furthermore, we introduced
|
||||
the distinction between memory objects that are subjected to DMA operations
|
||||
from non-DMA memory objects. The most profound conceptual optimization is the
|
||||
use of transmit bursts by the driver. The Linux kernel, which our driver
|
||||
originates from, does not provide an API for transmitting multiple packets as a
|
||||
burst. For our driver, however, this optimization opportunity opened up thanks
|
||||
to Genode's packet stream interface, which naturally facilitates the batching
|
||||
of networking packets. So the driver has all the information needed to create
|
||||
burst transactions.
|
||||
|
||||
|
||||
USB driver
|
||||
==========
|
||||
|
||||
By testing our new USB driver on a variety of real PC hardware, we discovered
|
||||
several shortcomings, which we resolved. In particular, we added support for
|
||||
more than one UHCI controller, make sure that the 'PIRQ' bit in the legacy
|
||||
support register (PCI config space) of the UHCI controller is enabled and that
|
||||
the 'Trap on IRQ' bit is disabled.
|
||||
|
||||
With those modifications in place, the USB driver works reliably on the tested
|
||||
platforms.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Noux
|
||||
====
|
||||
|
||||
Noux enables the easy reuse of unmodified GNU software on Genode by providing
|
||||
a Unix-like kernel interface as user-level service. Because Noux is pivotal for
|
||||
our plan to use Genode for productive work, we significantly enhanced and
|
||||
complemented its feature set.
|
||||
|
||||
|
||||
:Noux on ARM and x86_64:
|
||||
|
||||
For keeping the scope of the development manageable, the initial version of
|
||||
Noux was tied to the x86_32 platform. This was not a principal limitation of
|
||||
the approach but rather an artificial restriction to keep us focused on
|
||||
functionality first. Now that Noux reaches a usable state, we desire to use it
|
||||
on platforms other than x86_32. The current release enables Noux for the 64-bit
|
||||
x86 and ARM architectures.
|
||||
|
||||
The level of support is pretty far-reaching and even includes the building and
|
||||
execution of the Genode tool chain on those platforms. In the process of
|
||||
enabling these platforms, we updated the Noux package for GCC to version 4.6.1,
|
||||
which matches the version of the current Genode tool chain.
|
||||
|
||||
|
||||
:Terminal file system:
|
||||
|
||||
Noux supports the concept of stacked file systems. The virtual file system
|
||||
is defined at the start of a Noux instance driven by the static Noux
|
||||
configuration. This way, arbitrary directory structures can be composed out
|
||||
of file-system sessions and TAR archives. The VFS concept allows for the
|
||||
easy addition of new file system types. To allow programs running in a Noux
|
||||
instance to communicate over a dedicated terminal session, we added a new
|
||||
file-system type that corresponds to a virtual character device node attached
|
||||
to a terminal session.
|
||||
|
||||
|
||||
:GDB running in the Noux environment:
|
||||
|
||||
With the terminal file system in place, we are ready to execute GDB within
|
||||
Noux and let it talk to a GDB monitor instance over the terminal session
|
||||
interface. From GDB's point of view, the setup looks like a remote debugging
|
||||
session. But in reality both the debugging target and GDB reside in different
|
||||
subtrees of the same Genode system.
|
||||
|
||||
|
||||
:Executing shell scripts:
|
||||
|
||||
By inspecting the program specified to the execve system call, Noux has become
|
||||
able to spawn scripts that use the '#!' syntax. If such a file is detected, it
|
||||
executes the specified interpreter instead and passes the arguments specified
|
||||
after the '#!' marker, followed by command-line arguments.
|
||||
|
||||
|
||||
:Networking support:
|
||||
|
||||
Our work on porting various networking tools to Noux triggers us to steadily
|
||||
improve the networking support introduced with Genode 12.05. In particular, we
|
||||
added proper support for DNS resolving, which enables us to execute the
|
||||
command-line based Lynx web browser within Noux.
|
||||
|
||||
|
||||
:User information:
|
||||
|
||||
Because there are certain programs, which need the information that is stored
|
||||
in 'struct passwd', we introduced configurable user information support to
|
||||
Noux. One can set the user information via the '<user>' node in the Noux
|
||||
config:
|
||||
|
||||
! <config>
|
||||
! <user name="baron" uid="1" gid="1">
|
||||
! <shell name="/bin/bash" />
|
||||
! <home name="/home" />
|
||||
! </user>
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
When '<user>' is not specified, default values are used. Currently these
|
||||
are 'root', 0, 0, '/bin/bash', '/'. Note that this is just a single user
|
||||
implementation because each Noux instance has only one user or rather one
|
||||
identity and there will be no complete multi-user support in Noux. If you need
|
||||
different users, just start new Noux instances for each of them.
|
||||
|
||||
|
||||
:New '/dev/null' and '/dev/zero' pseudo devices:
|
||||
|
||||
These device are mandatory for most programs (well, at least null is required
|
||||
to be present for a POSIX compliant OS, which Noux is actually not). But for
|
||||
proper shell-script support we will need them anyway. Under the hood, both
|
||||
pseudo devices are implemented as individual file-systems and facilitate Noux's
|
||||
support for stacked file systems. The following example configuration snippet
|
||||
creates the pseudo devices under the '/dev' directory.
|
||||
|
||||
! <config>
|
||||
! <fstab>
|
||||
! <dir name="dev" >
|
||||
! <null /> <zero />
|
||||
! </dir>
|
||||
! ...
|
||||
! <fstab>
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
|
||||
Vancouver
|
||||
=========
|
||||
|
||||
The comprehensive rework of the NOVA base platform affected the Genode version
|
||||
of the Vancouver virtual machine monitor as this program used to speak directly
|
||||
to the NOVA kernel. Since no kernel objects can be created outside of core
|
||||
anymore, the Vancouver port had to be adjusted to solely use Genode interfaces.
|
||||
|
||||
|
||||
L4Linux
|
||||
=======
|
||||
|
||||
To improve the stability and performance of L4Linux on OMAP4 platforms, we
|
||||
reworked parts of the Genode-specific stub drivers, in particular the
|
||||
networking code. Among the improvements are the use of a high-performance
|
||||
allocator for networking packets, improved IRQ safety of IPC calls (to
|
||||
the Genode world), and tweaks of the TCP rmem and wmem buffer sizes to
|
||||
achieve good TCP performance when running Linux with little memory.
|
||||
|
||||
Furthermore, we added two ready-to-use run scripts residing within
|
||||
'ports-foc/run' as examples for executing L4Linux on the OMAP4-based
|
||||
Pandaboard. The 'linux_panda.run' script is meant as a blue print for
|
||||
experimentation. It integrates one instance of L4Linux with the native SD-card
|
||||
driver, the HDMI driver, and the USB HID input driver. The
|
||||
'two_linux_panda.run' script is a more elaborative example that executes two
|
||||
instances of L4Linux, a block-device test, and a simple web server. Each of
|
||||
the L4Linux instances accesses a different SD-card partition whereas the
|
||||
block-device test operates on a third partition.
|
||||
|
||||
|
||||
@@ -1,735 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 12.11
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The central theme of version 12.11 of the Genode OS Framework is
|
||||
self-hosting Genode on Genode. With self-hosting, we understand the execution of the
|
||||
entire Genode build system within the Genode environment. There are two motivations
|
||||
for pursing this line of work. First, it is a fundamental prerequisite for the
|
||||
Genode developers to move towards using Genode as a day-to-day OS. Of course,
|
||||
this prerequisite could be realized using one of the available virtualization
|
||||
solutions. For example, we could run L4Linux on top of Genode on the Fiasco.OC
|
||||
kernel and use the Genode build system from within an L4Linux instance.
|
||||
However, this defeats the primary incentive behind Genode to reduce system
|
||||
complexity. By having both Genode and L4Linux in the picture, we would indeed
|
||||
increase the overall complexity in configuring, maintaining, and using the
|
||||
system. Therefore, we would largely prefer to remove the complex Linux user
|
||||
land from the picture. The second motivation is to prove that the framework and
|
||||
underlying base platforms are suited and stable enough for real-world use.
|
||||
If the system is not able to handle a workload like the build system,
|
||||
there is little point in arguing about the added value of having a
|
||||
microkernel-based system over current commodity OSes such as GNU/Linux.
|
||||
|
||||
We are happy to have reached the state where we can execute the unmodified
|
||||
Genode build system directly on Genode running on a microkernel. As the
|
||||
build system is based on GNU utilities and the GNU compiler collection,
|
||||
significant effort went into the glue between those tools and the Genode API.
|
||||
Section [Building Genode on Genode] provides insights into the way we achieved
|
||||
the goal and the current state of affairs.
|
||||
|
||||
Along with the work on bringing the build system to Genode came numerous
|
||||
stability improvements and optimizations all over the place, reaching from the
|
||||
respective kernels, over the C runtime, the file-system implementations, memory
|
||||
allocators, up to the actual programs the tool chain is composed of. Speaking
|
||||
of the tool chain, the official Genode tool chain has been updated from GCC
|
||||
version 4.6.1 to version 4.7.2. Thereby, all 3rd-party code packages were
|
||||
subjected to testing and fixing activities.
|
||||
|
||||
For running the build system, the project currently focuses on NOVA and
|
||||
Fiasco.OC as base platforms. However, our custom kernel platform for the ARM
|
||||
architecture has also received significant improvements. With added support for
|
||||
Freescale i.MX and Texas Instruments OMAP4, this platform proved to be very
|
||||
well adaptable to new SoCs whereas new cache handling brings welcome
|
||||
performance improvements. Furthermore, we have added experimental support for
|
||||
ARM TrustZone technology, which principally enables the execution of Genode in
|
||||
the so-called secure world of TrustZone while executing Linux in the so-called
|
||||
normal world.
|
||||
|
||||
As we discovered the increasing interest in using Genode as a middleware
|
||||
solution on Linux, we largely revisited the support for this kernel platform
|
||||
and discovered amazing new ways to align the concept of Genode with the
|
||||
mechanisms provided by the Linux kernel. Section [Linux] provides a summary
|
||||
of the new approaches taken for supporting this platform.
|
||||
|
||||
Functionality-wise, the new version introduces support for audio drivers of
|
||||
the Open Sound System, a new OMAP4 GPIO driver, improvements of the graphical
|
||||
terminal, and the initial port of an SSH client.
|
||||
|
||||
|
||||
Building Genode on Genode
|
||||
#########################
|
||||
|
||||
On the Genode developer's way towards using Genode as a day-to-day OS, the
|
||||
ability to execute the Genode build system within the Genode environment is a
|
||||
pivotal step - a step that is highly challenging because the build system is
|
||||
based on the tight interplay of many GNU programs. Among those
|
||||
programs are GNU make, coreutils, findutils, binutils, gcc, and bash. Even
|
||||
though there is a large track record of individual programs and libraries ported
|
||||
to the environment, those programs used to be self-sustaining applications that
|
||||
require only little interaction with other programs. In contrast, the build
|
||||
system relies on many utilities working together using mechanisms such as
|
||||
files, pipes, output redirection, and execve. The Genode base system does not
|
||||
come with any of those mechanisms let alone the subtle semantics of the POSIX
|
||||
interface as expected by those utilities. Being true to microkernel principles,
|
||||
Genode's API has a far lower abstraction level and is much more rigid in scope.
|
||||
|
||||
To fill the gap between the requirements of the build system and the bare
|
||||
Genode mechanisms, the Noux runtime environment was created. Noux is a Genode
|
||||
process that acts like a Unix kernel. When started, it creates a child process,
|
||||
which plays a similar role as the init process of Unix. This process communicates
|
||||
via RPC messages to Noux. Using those messages, the process can perform all the
|
||||
operations normally provided by a classical Unix kernel. When executed under
|
||||
Noux, a process can even invoke functionalities such as fork and execve, which
|
||||
would normally contradict with Genode's principles of resource management.
|
||||
|
||||
Over the course of the past year, more and more programs have been ported to
|
||||
the Noux environment. Thereby, the semantics provided by Noux have been
|
||||
successively refined so that those program behave as expected. This was an
|
||||
iterative process. For example, at the beginning, Noux did not consider the
|
||||
differences between 'lstat' and 'stat' as they did not matter for the first
|
||||
batch of GNU programs ported to Noux. As soon as the programs got more
|
||||
sophisticated, such shortcuts had to be replaced by the correct semantics. The
|
||||
Genode build system is by far the most complex scenario exposed to Noux so far.
|
||||
It revealed many shortcomings by both functionality implemented in Noux or the
|
||||
C runtime as well as the underlying base platforms. So it proved to be a great
|
||||
testing ground for analysing and improving those platform details. Therefore,
|
||||
the secondary effects of self-hosting Genode on Genode in terms of stability
|
||||
turned out to be extremely valuable.
|
||||
|
||||
The release comes with two ready-to-use run scripts for building bootable
|
||||
system images that are able to execute the Genode tool chain, one for targeting
|
||||
NOVA and one for targeting Fiasco.OC. Those run scripts are located at
|
||||
'ports/run/' and called 'noux_tool_chain_nova.run' and 'noux_tool_chain_foc.run'
|
||||
respectively. Each of those run scripts can be executed on either of those base
|
||||
platforms. For example, by executing 'noux_tool_chain_nova' on Fiasco.OC, the
|
||||
image will run Genode on Fiasco.OC and the tool chain will build binaries for
|
||||
NOVA. When started, a build directory will be created at '/home/build'.
|
||||
The Genode source code is located at '/genode'. In the '/bin' directory,
|
||||
there are all the GNU programs needed to execute the tool chain. For
|
||||
taking a look into the source code, 'vim' is available. To build core,
|
||||
change to the build directory '/home/build' and issue 'make core'.
|
||||
|
||||
On Fiasco.OC, the complete Genode demo scenario can be compiled. On NOVA, the
|
||||
incomplete life-time management of kernel objects will still result in an
|
||||
out-of-memory error of the kernel. This kernel issue is currently being worked
|
||||
on. Executing the tool chain on either of those platforms is still relatively
|
||||
slow as extensive trace output is being generated and no actions have been taken to
|
||||
optimize the performance so far. There are many opportunities for such
|
||||
optimizations, which will be taken on as the next step.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Genode's base framework has received new support for extending session
|
||||
interfaces and gained improvements with regard to interrupt handling on the x86
|
||||
platform. At the API level, there are minor changes related to the CPU session
|
||||
and 'Range_allocator' interfaces.
|
||||
|
||||
|
||||
Support for specializing session interfaces
|
||||
===========================================
|
||||
|
||||
With increasingly sophisticated application scenarios comes the desire to
|
||||
extend Genode's existing session interface with new functionality. For example,
|
||||
the 'Terminal::Session' interface covers plain read and write operations. It is
|
||||
implemented by services such as a graphical terminal, the telnet-like TCP
|
||||
terminal, or UART drivers. However, for the latter category, the breadth of the
|
||||
interface is severely limited as UART drivers tend to supplement the read / write
|
||||
interface with additional control functions, e.g., for setting the baud rate.
|
||||
|
||||
One way to go would be to extend the existing 'Terminal::Session' interface
|
||||
with those control functions. However, these functions would be meaningless for
|
||||
most implementations. Some of those other implementations may even desire their
|
||||
own share of additions. In the longer term, this approach might successively
|
||||
broaden the interface and each implementation will cover a subset only.
|
||||
|
||||
Because Genode aspires to keep interfaces as low-complex as possible while, at
|
||||
the same time, it wants to accommodate the growing sophistication of usage
|
||||
scenarios, we need a solution that scales. The solution turns out to be
|
||||
strikingly simple. The RPC framework already supports the inheritance of RPC
|
||||
interfaces. So it is possible to model the problem such that a new
|
||||
'Uart::Session' interface derived from the existing 'Terminal::Session' will
|
||||
be the host of UART-specific functionality. The only piece missing is the
|
||||
propagation of both 'Uart' and 'Terminal' through the parent interface while
|
||||
announcing the service. To spare the work of manually announcing the chain of
|
||||
inherited interfaces from the implementor, the 'Parent::announce()' function has
|
||||
been enhanced to automatically announce all service types implemented by the
|
||||
announced interface. This way, a UART driver will always announce a "Uart"
|
||||
and a "Terminal" service.
|
||||
|
||||
|
||||
Improved interrupt handling
|
||||
===========================
|
||||
|
||||
To accommodate modern x86 platforms, the session arguments of core's IRQ
|
||||
service have been supplemented with the IRQ mode. There are two degrees of
|
||||
freedom, namely the trigger (level / edge) and polarity (high / low). Thanks to
|
||||
this addition, device drivers have become able to supply their knowledge of
|
||||
devices to core.
|
||||
|
||||
In system scenarios with many peripherals, in particular when using the USB
|
||||
driver, IRQ lines are shared between devices. Until now, Genode supported
|
||||
shared interrupts for the OKL4 base platform only. To also cover the other
|
||||
x86 kernels, we have generalized the interrupt sharing code and enabled this
|
||||
feature on Fiasco.OC and NOVA.
|
||||
|
||||
|
||||
Revised CPU session interface
|
||||
=============================
|
||||
|
||||
We revisited the CPU session interface, removed no-longer used functions and
|
||||
added support for assigning threads to CPUs.
|
||||
|
||||
The original CPU session interface contained functions for iterating through
|
||||
the threads of a session. This interface was originally motivated by an
|
||||
experimental statistical profiling tool that was developed at an early stage of
|
||||
Genode. In the meanwhile, we discovered that the virtualization of the CPU
|
||||
session interface is much more elegant to cover this use case than the
|
||||
thread-iterator interface. Because the iteration has no transactional
|
||||
semantics, it was unsafe to use it anyway.
|
||||
|
||||
To enable the use of multiple CPUs on multi-processor systems, the CPU
|
||||
session interface has been enhanced with two functions, namely 'affinity'
|
||||
and 'num_cpus'. The interface extension principally allows the assignment of
|
||||
individual threads to CPUs. It is currently implemented on Fiasco.OC only.
|
||||
On all other base platforms, 'num_cpus' returns one CPU. Note that on
|
||||
the Linux platform, multiple CPUs will be used transparently.
|
||||
|
||||
The 'Cpu_session::state' function has been split into two functions, one
|
||||
for retrieving information and one for propagating state information. The
|
||||
prior interface was less explicit about the semantics of the 'state' function
|
||||
as it took a non-const pointer to a 'Thread_state' object as argument.
|
||||
|
||||
|
||||
Platform-tailored protection domains
|
||||
====================================
|
||||
|
||||
Genode tries to provide a uniform API across all the different base platforms.
|
||||
Yet, it also strives to make genuine platform features available to the
|
||||
users of the framework. Examples for such features are the virtualization
|
||||
support of the NOVA hypervisor or the special support for paravirtualizing
|
||||
Linux on Fiasco.OC. Another example is the security model as found on the Linux
|
||||
platform. Even though the security mechanisms of plain Linux are not as strong
|
||||
as Genode's capability concept on a conceptual level, we still want to leverage
|
||||
the available facilities such as user IDs and chroot as far as possible.
|
||||
Consequently, we need a way to assign platform-specific properties to PD
|
||||
sessions. With the new 'Native_pd_args' type introduced into
|
||||
'base/native_types.h', there is now a way to express those platform-specific
|
||||
concerns. This type is now used at all the places that deal with the creation
|
||||
of protection domains such as 'Process', 'Child', and the loader.
|
||||
|
||||
|
||||
Revised 'Range_allocator' interface
|
||||
===================================
|
||||
|
||||
The handling of allocation errors has been refined in order to distinguish
|
||||
different error conditions, in particular out-of-metadata and out-of-memory
|
||||
conditions. The user of the allocator might want to handle both cases
|
||||
differently. Hence we return an 'Alloc_return' value as result. In prior
|
||||
versions, this type was just an enum value. With the new version, the type has
|
||||
been changed to a class. This makes the differentiation of error conditions at
|
||||
the caller side more robust because, in contrast to enum values, typed objects
|
||||
don't get implicitly converted to bool values.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
New UART session interface
|
||||
==========================
|
||||
|
||||
To accommodate UART specific extensions of the 'Terminal::Session' interface,
|
||||
in particular setting the baud rate, we introduced the new 'Uart::Session'
|
||||
interface and changed the existing UART drivers to implement this
|
||||
interface instead of the 'Terminal::Session' interface. Because 'Uart::Session'
|
||||
inherits the 'Terminal::Session' interface, 'Uart' services announce both
|
||||
"Uart" and "Terminal" at their parent.
|
||||
|
||||
|
||||
New GPIO session interface
|
||||
==========================
|
||||
|
||||
Embedded SoCs such as OMAP4 provide many general-purpose I/O pins, which can be
|
||||
used for different purposes depending on the board where they are soldered on.
|
||||
For example, the Pandaboard uses such GPIO pins to detect the presence of a
|
||||
HDMI plug or control the power supply for the USB. If only one driver deals
|
||||
with GPIO pins, the GPIO programming can reside in the driver. However, if
|
||||
multiple drivers are used, the GPIO device resources cannot be handed out to
|
||||
more than one driver. This scenario calls for the creation of a GPIO driver as
|
||||
a separate component, which intermediates (and potentially multiplexes) the
|
||||
access to the physical GPIO pins. The new 'Gpio::Session' interface allows one
|
||||
or multiple clients to configure I/O pins, request states, as well as to
|
||||
register for events happening on the pins.
|
||||
|
||||
|
||||
Terminal
|
||||
========
|
||||
|
||||
The graphical terminal has been enhanced with support for different built-in
|
||||
font sizes and background-color handling.
|
||||
|
||||
In addition to those functional changes, the implementation has been decomposed
|
||||
into several parts that thereby became reusable. Those parts comprise the
|
||||
handling of key mappings, decoding the VT character stream, and the handling of
|
||||
the character array. These functionalities are now available at
|
||||
'gems/include/terminal'.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
:Allocator optimized for small-object allocations:
|
||||
|
||||
To optimize the performance of workloads that depend on a large number of small
|
||||
dynamic memory allocations, in particular the lwIP TCP/IP stack, we replaced
|
||||
the memory allocator of the libc with a more sophisticated strategy. Until now,
|
||||
the libc used 'Genode::Heap' as allocator. This implementation is an
|
||||
AVL-tree-based best-fit allocator that is optimized for low code complexity
|
||||
rather than performance for small allocations. The observation of the allocator
|
||||
usage pattern of lwIP prompted us to replace the original libc malloc/free with
|
||||
a version that uses slab allocators for small objects and relies on the
|
||||
'Genode::Heap' for large objects only.
|
||||
|
||||
:Symbolic links:
|
||||
|
||||
Because part of our ongoing refinements of the Noux runtime is the provision of
|
||||
symbolic links, support for symbolic links was added in the libc, libc plugins,
|
||||
and file system servers.
|
||||
|
||||
|
||||
lwIP
|
||||
====
|
||||
|
||||
We updated the light-weight IP stack to version STABLE-1.4.1. Additionally,
|
||||
the following optimizations were conducted to improve its performance and
|
||||
robustness.
|
||||
|
||||
We reduced the maximum segment lifetime from one minute to one second to avoid
|
||||
queuing up PCBs in TIME-WAIT state. This is the state, PCBs end up after
|
||||
closing a TCP connection socket at the server side. The number of PCBs in this
|
||||
state is apparently not limited by the value of 'MEMP_NUM_TCP_PCB'. One
|
||||
allocation costs around 160 bytes. If clients connect to the server at a high
|
||||
rate, those allocations accumulate quickly and thereby may exhaust the memory
|
||||
of the server. By reducing the segment lifetime, PCBs in TIME-WAIT state are
|
||||
cleaned up from the 'tcp_tw_pcbs' queue in a more timely fashion (by
|
||||
'tcp_slowtmr()').
|
||||
|
||||
To prevent the TCP/IP stack from artificially throttling TCP throughput,
|
||||
we adjusted lwIP's TCP_SND_BUF size.
|
||||
|
||||
From our work on optimizing the NIC stub-code performance of L4Linux as
|
||||
described [http://genode.org/documentation/articles/pandaboard - here],
|
||||
we learned that the use of a NIC-specific packet allocator for the
|
||||
packet-stream interface is beneficial. At the lwIP back end, we still relied on
|
||||
the original general-purpose allocator. Hence, we improved the lwIP back-end
|
||||
code by using the bitmap-based 'Nic::Packet_allocator' allocator instead.
|
||||
|
||||
|
||||
Standard C++ library
|
||||
====================
|
||||
|
||||
Genode used to rely on the standard C++ library that comes with the tool chain.
|
||||
However, this mechanism was prone to inconsistencies of the types defined in
|
||||
the header files used at compile time of the tool chain and the types provided
|
||||
by our libc. By building the C++ standard library as part of the Genode build
|
||||
process, such inconsistencies cannot happen anymore. The current version of the
|
||||
C++ standard library corresponds to GCC 4.7.2.
|
||||
|
||||
Note that the patch changes the meaning of the 'stdcxx' library for users that
|
||||
happened to rely on 'stdcxx' for hybrid Linux/Genode applications. For such
|
||||
uses, the original mechanism is still available, in the renamed form of
|
||||
'toolchain_stdcxx'.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Open Sound System
|
||||
=================
|
||||
|
||||
Genode tries to re-use existing device drivers as much as possible using an
|
||||
approach called device-driver environment (DDE). A DDE is a library that
|
||||
emulates the environment of the original driver by translating device accesses
|
||||
to the Genode API. There are many success stories of drivers successfully ported
|
||||
to the framework this way. For example, using DDE-Linux, we are able to use the
|
||||
Linux USB stack. Using DDE-ipxe, we are able to use iPXE networking drivers.
|
||||
With Genode 12.11 we extend our arsenal of DDEs with DDE-OSS, which is a
|
||||
device-driver environment for the audio drivers of the Open Sound System (OSS).
|
||||
|
||||
:Website of the Open Sound System:
|
||||
|
||||
[http://http://www.4front-tech.com]
|
||||
|
||||
The new 'dde_oss' contains all the pieces needed to use Intel HDA, AC97, and
|
||||
ES1370 audio cards on Genode. On first use, the 3rd-party code can be
|
||||
downloaded by issuing 'make prepare' from within the 'dde_oss' source-code
|
||||
repository. Also, you need to make sure to add the 'dde_oss' repository to your
|
||||
'REPOSITORIES' variable in 'etc/build.conf'.
|
||||
|
||||
An OSS demo configuration can be found under 'run/oss.run' and can be started
|
||||
via 'make run/oss' from a Genode build directory. Be sure to adjust the
|
||||
'filename' tag of the 'audio0' program. The file has to reside under
|
||||
'<build-dir>/bin/'. The file format is header-less two-channel float-32 at
|
||||
44100 Hz. You may use the 'sox' utility to create these audio files:
|
||||
|
||||
! sox -c 2 -r 44100 foo.mp3 foo.f32
|
||||
|
||||
|
||||
OMAP4 GPIO driver
|
||||
=================
|
||||
|
||||
The new OMAP4 GPIO driver is the first implementation of the just introduced
|
||||
'Gpio::Session' interface. The driver supports two ways of interacting
|
||||
with GPIO pins, by providing a static configuration, or by interacting with a
|
||||
session interface at runtime. An example for a static configuration looks as
|
||||
follows:
|
||||
|
||||
! <config>
|
||||
! <gpio num="121" mode="I"/>
|
||||
! <gpio num="7" mode="O" value="0"/>
|
||||
! <gpio num="8" mode="O" value="0"/>
|
||||
! </config>
|
||||
|
||||
The driver is located at 'os/src/drivers/gpio/omap4'. As reference for using
|
||||
the driver, please refer to the 'os/run/gpio_drv.run' script.
|
||||
|
||||
Thanks to Ivan Loskutov of Ksys-Labs for contributing the session interface
|
||||
and the driver!
|
||||
|
||||
|
||||
iPXE networking drivers
|
||||
=======================
|
||||
|
||||
We updated our device-driver environment for iPXE networking drivers to a
|
||||
recent git revision and enabled support for the x86_64 architecture.
|
||||
Currently, the driver covers Intel gigabit ethernet (e1000, e1000e, igb),
|
||||
Intel eepro100, and Realtek 8139/8169.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Noux
|
||||
====
|
||||
|
||||
The Noux runtime environment has received plenty of love thanks to the
|
||||
aspiration to execute the Genode build system.
|
||||
|
||||
:Time:
|
||||
|
||||
The build system uses GNU make, which depends on time stamps of files. We do
|
||||
not necessarily need a real clock. A monotonic increasing virtual time is
|
||||
enough. To provide such a virtual time, the libc was enhanced with basic
|
||||
support for functions like 'gettimeofday', 'clock_gettime', and 'utimes'. As
|
||||
there is currently no interface to obtain the real-world time in Genode, Noux
|
||||
simulates a pseudo real-time clock using a jiffies-counting thread. This
|
||||
limited degree of support for time is apparently sufficient to trick tools like
|
||||
ping, find, and make into working as desired.
|
||||
|
||||
:Improved networking support:
|
||||
|
||||
The Noux/net version of Noux extends the Noux runtime with the BSD-socket
|
||||
interface by using the lwIP stack. This version of Noux multiplexes the
|
||||
BSD-socket interface of lwIP to multiple Noux programs, each having a different
|
||||
socket-descriptor name space and the principal ability to use blocking calls
|
||||
such as 'select'. The code for multiplexing the lwIP stack among multiple Noux
|
||||
processes has been improved to cover corner cases exposed by sophisticated
|
||||
network clients, i.e., openssh.
|
||||
|
||||
:Directory cache for the TAR file system:
|
||||
|
||||
The original version of the TAR file system required a search in all TAR
|
||||
records for each file lookup. This takes a long time when composing a large
|
||||
directory tree out of multiple TAR archives stacked together. This is the case
|
||||
for the Genode build-system scenario where we have all the files of the GNU
|
||||
tools as well as the Genode source tree. Searching through thousands of records
|
||||
for each call of 'stat' quickly becomes a scalability issue. Therefore, we
|
||||
introduced a TAR indexing mechanism that scans each TAR file only once at the
|
||||
startup of Noux and generates a tree structure representing the directory
|
||||
layout. Looking up files using this index is quick.
|
||||
|
||||
:New packages:
|
||||
|
||||
With Genode-12.11, new 3rd-party packages have become available, namely
|
||||
OpenSSH, the 'which' command, and all tool-chain components in their current
|
||||
version. OpenSSH is still at an experimental stage. The run script at
|
||||
'ports/run/noux_net_openssh_interactive.run' demonstrates how SSH can be used
|
||||
to login into a remote machine.
|
||||
|
||||
:New pseudo file systems:
|
||||
|
||||
The new 'stdio' and 'random' file systems are intended to represent the pseudo
|
||||
devices '/dev/random' and '/dev/tty' on Noux. Both are needed to run OpenSSH.
|
||||
Note that the 'Arc4random' class, on which the random file system is based on,
|
||||
currently _does not collect enough_ random bytes! It should not be used for
|
||||
security-critical applications.
|
||||
|
||||
|
||||
L4Linux
|
||||
=======
|
||||
|
||||
The paravirtualized L4Linux kernel for the Fiasco.OC platform was updated to
|
||||
SVN revision 25, which matches the Fiasco.OC SVN revision 40. We further
|
||||
improved the integration of L4Linux with Genode by optimizing the stub drivers
|
||||
for block devices and networking, and added principal support for running
|
||||
L4Linux on SMP platforms.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
NOVA
|
||||
====
|
||||
|
||||
Genode follows the steady development of the NOVA microhypervisor very closely.
|
||||
The kernel used by the framework corresponds to the current state of the master
|
||||
branch of IntelLabs/NOVA.
|
||||
|
||||
|
||||
:Improvements towards GDB support:
|
||||
|
||||
The NOVA-specific implementation of the CPU session interface has been improved
|
||||
to accommodate the requirements posed by GDB. In particular, the 'pause',
|
||||
'resume', 'state', and 'single_step' functions have been implemented. Those
|
||||
functions can be used to manipulate the execution and register state of
|
||||
threads. Under the hood, NOVA's 'recall' feature is used to implement these
|
||||
mechanisms. By issuing a 'recall' for a given thread, the targeted thread is
|
||||
forced into an exception. In the exception, the current state of the thread can
|
||||
be obtained and its execution can be halted/paused.
|
||||
|
||||
|
||||
:Maximizing contiguous virtual space:
|
||||
|
||||
To enable the Vancouver virtual machine monitor to hand out large amounts of
|
||||
guest memory, we optimized core's virtual address space to retain large and
|
||||
naturally aligned contiguous memory regions. For non-core processes, the
|
||||
thread-context area that contains the stacks of Genode threads has been moved
|
||||
to the end of the available virtual address space.
|
||||
|
||||
|
||||
:Life-time management of kernel resources:
|
||||
|
||||
We improved the life-time management of kernel resources, in particular
|
||||
capabilities, within Genode. Still the management of such kernel resources
|
||||
is not on par with the Fiasco.OC version, partially because of missing
|
||||
kernel functionality. This is an ongoing topic that is being worked on.
|
||||
|
||||
|
||||
:Using the BIOS data area (BDA) to get serial I/O ports on x86:
|
||||
|
||||
If the I/O ports for the comport are non default (default is 0x3f8), we had to
|
||||
specify manually the correct I/O ports in the source code. To avoid the need
|
||||
for source-code modifications when changing test machines, we changed the core
|
||||
console to read the BDA and use the first serial interface that is available.
|
||||
If no serial interface is available, no device configuration will be
|
||||
undertaken. The BDA can be populated via a multi-boot chain loader. Bender is
|
||||
such a chain loader that can detect serial ports accessible via PCI and writes
|
||||
the I/O ports to the Bios Data area (BDA). These values get then picked up by
|
||||
core.
|
||||
|
||||
|
||||
Fiasco.OC
|
||||
=========
|
||||
|
||||
The Fiasco.OC kernel has been updated to the SVN revision 40. The update improves
|
||||
SMP support and comes with various bug fixes. There is no noteworthy change
|
||||
with regard to the kernel interface. We extended the number of supported
|
||||
Fiasco.OC-based platforms for Genode by including the Freescale i.MX53.
|
||||
|
||||
To enable the use of multiple CPUs by Genode processes, the CPU session
|
||||
interface has been enhanced to support configuring the affinity of threads with
|
||||
CPUs. We changed the default kernel configuration for x86 and ARM to
|
||||
enable SMP support and adapted L4Linux to use the new interface.
|
||||
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
The development of our custom platform for executing Genode directly on bare
|
||||
hardware with no kernel underneath went full steam ahead during the release
|
||||
cycle.
|
||||
|
||||
:Pandaboard:
|
||||
|
||||
The in-kernel drivers needed to accommodate the Pandaboard, more specifically
|
||||
the timer and interrupt controller, are now supported. So the Pandaboard can be
|
||||
used with both 'base-hw' and 'base-foc'. Also, the higher-level platform
|
||||
drivers for USB, HDMI, and SD-card that were introduced with the previous
|
||||
release, are equally functional on both platforms.
|
||||
|
||||
:Freescale i.MX31:
|
||||
|
||||
We added principal support for the Freescale i.MX line of SoCs taking the
|
||||
ARMv6-based i.MX31 as starting point. As of now, the degree of support is
|
||||
limited to the devices needed by the kernel to operate. Pure software-based
|
||||
scenarios are able to work, i.e., the nested init run script executes
|
||||
successfully.
|
||||
|
||||
:TrustZone support:
|
||||
|
||||
The new VM session interface of core provides a way to execute software
|
||||
in the normal world of a TrustZone system whereas Genode runs in the secure
|
||||
world. From Genode's point of view, the normal world looks like a virtual
|
||||
machine. Each time, the normal world produces a fault or issues a secure
|
||||
monitor call, control gets transferred to the virtual machine monitor, which is
|
||||
a normal user-level Genode process. The base-hw kernel has been enhanced to
|
||||
perform world switches between the secure and normal world and with the ability
|
||||
to handle fast interrupts (FIQs) in addition to normal interrupts. The latter
|
||||
extension is needed to assign a subset of devices to either of both worlds.
|
||||
|
||||
Currently, the only TrustZone capable platform is the ARM CoreTile Express
|
||||
CA9x4 for the Versatile Express board. For a virtual machine working properly
|
||||
on top, some platform resources must be reserved. Therefore, there exist two
|
||||
flavours of this platform now, one with the 'trustzone' spec-variable enabled
|
||||
and one without. If 'trustzone' is specified, most platform resources (DDR-RAM,
|
||||
and most IRQs) are reserved for the normal world and not available to the
|
||||
secure Genode world.
|
||||
|
||||
:Memory attributes and caching:
|
||||
|
||||
We successively activated various levels of caching and improved the handling
|
||||
of caching attributes propagated into the page tables. These changes resulted
|
||||
in a significant boost in performance on non-emulated platforms.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
The Linux version of Genode was originally meant as a vehicle for rapid
|
||||
development. It allows the framework components including core to be executed
|
||||
as plain Linux processes. But in contrast to normal Linux programs, which
|
||||
use the glibc, Genode's components interact with the kernel directly without
|
||||
any C runtime other than what comes with Genode. We use the Linux version on a
|
||||
regular basis to implement platform-agnostic functionality and protocols. Most
|
||||
of Genode's code (except for device drivers) falls in this category. Because
|
||||
the Linux version was meant as a mere tool, however, we haven't put much
|
||||
thought into the principle way to implementing Genode's security concept on
|
||||
this platform. Threads used to communicate over globally accessible Unix-domain
|
||||
sockets and memory objects were represented as globally accessible files within
|
||||
'/tmp'.
|
||||
|
||||
That said, even though Linux was not meant as a primary platform for Genode in
|
||||
the first place, Genode can bring additional value to Linux. When considering
|
||||
the implementation of a component-based system on Linux, there are several
|
||||
possible approaches to take. For example, components may use DBus to
|
||||
communicate, or components could pick from the manifold Unix mechanisms such as
|
||||
named pipes, files, sysv-shared memory, signals, and others. Unfortunately
|
||||
those mechanisms are not orthogonal and most of them live in the global name
|
||||
space of the virtual file system. Whereas those mechanisms are principally able
|
||||
to let processes communicate, questions about how processes get to know each
|
||||
other, access-control policy, synchronization of the startup of processes are
|
||||
left to the developer.
|
||||
|
||||
Genode, on the other hand, does provide an API for letting components
|
||||
communicate but also answers those tricky questions concerning the composition
|
||||
of components. This makes Genode an interesting option to build component based
|
||||
applications, even on Linux. However, when used in such a context, the
|
||||
limitations of the original Linux support need resolutions. Therefore, the
|
||||
current release comes with a largely revised platform support for the Linux
|
||||
base platform.
|
||||
|
||||
The changes can be summarized as follows:
|
||||
|
||||
:Using file descriptors as communication addresses:
|
||||
|
||||
Genode's synchronous RPC framework was using Unix domain sockets. Each RPC
|
||||
entrypoint was represented by a pair of named files, one for sending and one
|
||||
for receiving messages. In the new version, inter-process communication is
|
||||
performed via file descriptors only.
|
||||
|
||||
:Transfer of communication rights via RPC only:
|
||||
|
||||
Capabilities used to be represented as a pair of the destination thread ID and
|
||||
a global object ID. The thread ID has been replaced by a file descriptor that
|
||||
points to the corresponding RPC entrypoint. When capabilities are transferred
|
||||
as RPC arguments, those file descriptors are transferred via SCM rights
|
||||
messages. This is in line with Genode's way of capability-based delegation of
|
||||
access rights.
|
||||
|
||||
:Core-only creation of communication channels:
|
||||
|
||||
Communication channels used to be created locally by each process. The naming
|
||||
of those channels was a mere convention. In contrast, now, communication
|
||||
channels are created by core only and do not reside on the Linux virtual file
|
||||
system. When creating an RPC entrypoint, core creates a socket pair and hands
|
||||
out both ends to the creator of the entrypoint.
|
||||
|
||||
:Restricted access to memory objects:
|
||||
|
||||
Access to dataspace content was performed by mmap'ing a file. For a given
|
||||
dataspace, the file name could be requested at core via a Linux-specific RPC
|
||||
call. Now, core holds the file descriptors of all dataspaces, which are
|
||||
actually unlinked files. A process that is in possession of a dataspace
|
||||
capability can request the file descriptor for the content from core and mmap
|
||||
the file locally. This way, access to memory objects is subjected to the
|
||||
delegation of dataspace capabilities.
|
||||
|
||||
:Core-local process creation:
|
||||
|
||||
Genode used to create new processes by directly forking from the respective
|
||||
Genode parent using the process library. The forking process created a PD
|
||||
session at core merely for propagating the PID of the new process into core
|
||||
(for later destruction). This traditional mechanism has the following
|
||||
disadvantages:
|
||||
|
||||
First, the PID reported by the creating process to core cannot easily be
|
||||
validated by core. Therefore core has to trust the PD client to not specify a
|
||||
PID of an existing process, which would happen to be killed once the PD session
|
||||
gets destructed. Second, there is no way for a Genode process to detect the
|
||||
failure of any of its grandchildren. The immediate parent of a faulting process
|
||||
could use the SIGCHLD-and-waitpid mechanism to observe its children but this
|
||||
mechanism does not work transitively.
|
||||
|
||||
By performing the process creation exclusively within core, all Genode
|
||||
processes become immediate child processes of core. Hence, core can respond to
|
||||
failures of any of those processes and reflect such conditions via core's
|
||||
session interfaces. Furthermore, the PID associated to a PD session is locally
|
||||
known within core and cannot be forged anymore. In fact, there is actually no
|
||||
need at all to make processes aware of any PIDs of other processes.
|
||||
|
||||
:Handling of chroot, user IDs, and group IDs:
|
||||
|
||||
With the move of the process creation into core, the original chroot trampoline
|
||||
mechanism implemented in 'os/src/app/chroot' does not work anymore. A process
|
||||
could simply escape the chroot environment by spawning a new process via core's
|
||||
PD service. Therefore, chroot support has been integrated into core and the
|
||||
chroot policy becomes a mandatory part of the process creation. For each process
|
||||
created by core, core checks for a 'root' argument of the PD session. If a path
|
||||
is present, core takes the precautions needed to execute the new process in the
|
||||
specified chroot environment.
|
||||
|
||||
This conceptual change implies minor changes with respect to the Genode API and
|
||||
the configuration of the init process. The API changes are the enhancement of
|
||||
the 'Genode::Child' and 'Genode::Process' constructors to take the root path as
|
||||
argument. Init supports the specification of a chroot per process by specifying
|
||||
the new 'root' attribute to the '<start>' node of the process. In line with
|
||||
these changes, the 'Loader::Session::start' function has been enhanced with the
|
||||
additional (optional) PD argument.
|
||||
|
||||
In line with how the chroot path can be propagated into core, core has become
|
||||
able to assign customized UIDs and GIDs to individual Genode processes or whole
|
||||
Genode subsystems. The new 'base-linux/run/lx_uid.run' script contains an
|
||||
example of how to use the feature.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
The current release comes with a new tool chain based on GCC 4.7.2 and binutils
|
||||
2.22. The tool-chain upgrade involved adapting the Genode code base and fixing
|
||||
various issues in 3rd-party software. To obtain the new tool chain, please
|
||||
refer to the tool-chain website:
|
||||
|
||||
:Genode tool chain:
|
||||
|
||||
[http://genode.org/download/tool-chain]
|
||||
@@ -1,941 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 13.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
Traditionally, the February release of Genode is focused on platform support.
|
||||
The version 13.02 follows this tradition by vastly improving Genode for the
|
||||
NOVA base platform and the extending the range of ARM SoCs supported by
|
||||
both our custom kernel platform and the Fiasco.OC kernel.
|
||||
|
||||
The NOVA-specific improvements concern three major topics, namely the added
|
||||
support for running dynamic workloads on this kernel, the use of IOMMUs, and
|
||||
the profound integration of the Vancouver virtual machine monitor with the
|
||||
Genode environment. The latter point is particularly exciting to us because
|
||||
this substantial work is the first contribution by Intel Labs to the Genode
|
||||
code base. Thanks to Udo Steinberg and Markus Partheymüller for making that
|
||||
possible.
|
||||
|
||||
Beyond the x86 architecture, the new version comes with principal support for
|
||||
the ARM Cortex-A15-based Exynos 5250 SoC and the Freescale i.MX53 SoC. The
|
||||
Exynos 5250 SoC has been enabled for our custom kernel as well as for the
|
||||
Fiasco.OC kernel. The most significant functional improvements are a new
|
||||
facility to detect faulting processes and a new mechanism for file-system
|
||||
notifications.
|
||||
|
||||
Besides those added functionalities, the release cycle was taken as an
|
||||
opportunity to revisit several aspects under the hood of the framework. A few
|
||||
examples are the reworked synchronization primitives, the simplified base
|
||||
library structure, the completely redesigned audio-output interface, and a
|
||||
modernized timer interface.
|
||||
|
||||
|
||||
DMA protection via IOMMU
|
||||
########################
|
||||
|
||||
Direct memory access (DMA) of devices is universally considered as the Achilles
|
||||
heel of microkernel-based operating systems. The most compelling argument in
|
||||
favour of using microkernels is that by encapsulating each system component
|
||||
within a dedicated user-level address space, the system as a whole becomes more
|
||||
robust and secure compared to a monolithic operating-system kernel. In the
|
||||
event that one component fails due to a bug or an attack, other components
|
||||
remain unaffected. The prime example for such buggy components are device
|
||||
drivers. By empirical evidence, those remain the most prominent trouble makers
|
||||
in today's operating systems. Unfortunately however, most commodity hardware
|
||||
used to render this nice argumentation moot because it left one giant loophole
|
||||
open, namely bus-master DMA.
|
||||
|
||||
Via bus-master DMA, a device attached to the system bus is able to directly
|
||||
access the RAM without involving the CPU. This mechanism is crucial for all
|
||||
devices that process large amounts of data such as network adapters, disk
|
||||
controllers, or USB controllers. Because those devices can issue bus requests
|
||||
targeting the RAM directly and not involving the CPU altogether, such requests
|
||||
are naturally not subjected by the virtual-memory mechanism implemented in the
|
||||
CPU in the form of an MMU. From the device's point of view there is just
|
||||
physical memory. Hence, if a driver sets up a DMA transaction, let's say a disk
|
||||
driver wants to read a block from the disk, the driver tells the device about
|
||||
the address and size of a physical-memory buffer where the it wants to receive
|
||||
the data. If the driver lives in a user-level process, as is the case for a
|
||||
microkernel-based system, it still needs to know the physical address to
|
||||
program the device correctly. Unfortunately, there is nothing to prevent the
|
||||
driver from specifying any physical address to the device. Consequently, a
|
||||
malicious driver could misuse the device to read and manipulate all parts of
|
||||
the memory, including the kernel.
|
||||
|
||||
[image no_iommu]
|
||||
Traditional machine without IOMMU. Direct memory accesses issued by the
|
||||
disk controller are not subjected to the MMU. The disk controller can
|
||||
access the entity of memory present in the system.
|
||||
|
||||
So - does this loop hole render the micro-kernel approach useless? Of course not.
|
||||
Putting each driver in a dedicated address space is still beneficial in two
|
||||
ways. First, classes of bugs that are unrelated to DMA remain confined in the
|
||||
driver's address space. In practice most driver issues arise from issues like
|
||||
memory leaks, synchronization problems, deadlocks, flawed driver logic, wrong
|
||||
state machines, or incorrect device-initialization sequences. For those classes
|
||||
of problems, the microkernel argument still applies. Second, executing a driver
|
||||
largely isolated from other operating-system code minimizes the attack surface
|
||||
of the driver. If the driver interface is rigidly small and well-defined, it is
|
||||
hard to compromise the driver by exploiting its interface.
|
||||
|
||||
Still the DMA issue remains to be addressed. Fortunately, modern PC hardware
|
||||
has closed the bus-master-DMA loophole by incorporating a so-called IOMMU into
|
||||
the system. As depicted in the following figure, the IOMMU sits between the RAM
|
||||
and the system bus where the devices are attached to. So each DMA request has
|
||||
to pass the IOMMU, which is not only able to arbitrate the access of DMA
|
||||
requests to the RAM but also able to virtualize the address space per device.
|
||||
Similar to how a MMU confines each process running on the CPU within a distinct
|
||||
virtual address space, the IOMMU is able to confine each device within a
|
||||
dedicated virtual address space. To tell the different devices apart, the IOMMU
|
||||
uses the PCI device's bus-device-function triplet as unique identification.
|
||||
|
||||
[image iommu]
|
||||
An IOMMU arbitrates and virtualizes DMA accesses issued by a device to the
|
||||
RAM. Only if a valid IOMMU mapping exists for a given DMA access, the memory
|
||||
access is performed.
|
||||
|
||||
Of the microkernels supported by Genode, NOVA is the first kernel that supports
|
||||
the IOMMU. NOVAs interface to the IOMMU is quite elegant. The kernel simply
|
||||
applies a subset of the (MMU) address space of a process (aka protection domain
|
||||
in NOVA speak) to the (IOMMU) address space of a device. So the device's
|
||||
address space can be managed in the same way as we normally manage the address
|
||||
space of a process. The only missing link is the assignment of device address
|
||||
spaces to process address spaces. This link is provided by the dedicated system
|
||||
call "assign_pci" that takes a process identifier and a device identifier as
|
||||
arguments. Of course, both arguments must be subjected to a security policy.
|
||||
Otherwise, any process could assign any device to any other process. To enforce
|
||||
security, the process identifier is a capability to the respective protection
|
||||
domain and the device identifier is a virtual address where the extended PCI
|
||||
configuration space of the device is mapped in the specified protection domain.
|
||||
Only if a user-level device driver got access to the extended PCI configuration
|
||||
space of the device, it is able to get the assignment in place.
|
||||
|
||||
To make NOVA's IOMMU support available to Genode programs, we enhanced the
|
||||
ACPI/PCI driver with the ability to hand out the extended PCI configuration
|
||||
space of a device and added a NOVA-specific extension to the PD session
|
||||
interface. The new 'assign_pci' function allows the assignment of a PCI device
|
||||
to the protection domain.
|
||||
|
||||
[image iommu_aware]
|
||||
NOVAs management of the IOMMU address spaces facilities the use of
|
||||
driver-local virtual addresses as DMA addresses.
|
||||
|
||||
Even though these mechanisms combined principally
|
||||
suffice to let drivers operate with the IOMMU enabled, in practice, the
|
||||
situation is a bit more complicated. Because NOVA uses the same
|
||||
virtual-to-physical mappings for the device as it uses for the process, the DMA
|
||||
addresses the driver needs to supply to the device must be virtual addresses
|
||||
rather than physical addresses. Consequently, to be able to make a device
|
||||
driver usable on systems without IOMMU as well as on systems with IOMMU, the
|
||||
driver needs to be IOMMU-aware and distinguish both cases. This is an
|
||||
unfortunate consequence of the otherwise elegant mechanism provided by NOVA. To
|
||||
relieve the device drivers from caring about both cases, we came up with a
|
||||
solution that preserves the original device interface, which expects physical
|
||||
addresses. The solution comes in the form of so called device PDs. A device PD
|
||||
represents the address space of a device as a Genode process. Its sole purpose
|
||||
is to hold mappings of DMA buffers that are accessible by the associated
|
||||
device. By using one-to-one physical-to-virtual mappings for those buffers
|
||||
within the device PD, each device PD contains a subset of the physical address
|
||||
space. The ACPI/PCI server performs the assignment of device PDs to PCI
|
||||
devices. If a device driver intends to use DMA, it asks the ACPI/PCI driver for
|
||||
a new DMA buffer. The ACPI/PCI driver allocates a RAM dataspace at core,
|
||||
attaches it to the device PD using the dataspace's physical address as virtual
|
||||
address, and hands out the dataspace capability to the driver. If the driver
|
||||
requests the physical address of the dataspace, the returned address will be a
|
||||
valid virtual address in the associated device PD. From this design follows
|
||||
that a device driver must allocate DMA buffers at the ACPI/PCI server (while
|
||||
specifying the PCI device the buffer is intended for) instead of using core's
|
||||
RAM service to allocate buffers anonymously. The current implementation of the
|
||||
ACPI/PCI server assigns all PCI devices to only one device PD. However, the
|
||||
design devises a natural way to partition devices into different device PDs.
|
||||
|
||||
[image iommu_agnostic]
|
||||
By modelling a device address space as a dedicated process (device PD),
|
||||
the traditional way of programming DMA transactions can be maintained,
|
||||
even with the IOMMU enabled.
|
||||
|
||||
Because the changed way of how DMA buffers are allocated, our existing drivers
|
||||
such as the AHCI disk driver, the OSS sound driver, the iPXE network driver,
|
||||
and the USB driver had to be slightly modified. We also extended DDE Kit with
|
||||
the new 'dde_kit_pci_alloc_dma_buffer' function for allocating DMA buffers.
|
||||
With those changes, the complete Genode user land can be used on systems with
|
||||
IOMMU enabled. Hence, we switched on the IOMMU on NOVA by default.
|
||||
|
||||
|
||||
Full virtualization on NOVA/x86
|
||||
###############################
|
||||
|
||||
Vancouver is a x86 virtual machine monitor that is designed to run as
|
||||
user-level process on top of the NOVA hypervisor. In
|
||||
[http://genode.org/documentation/release-notes/11.11#Faithful_x86_PC_Virtualization_enabled_by_the_Vancouver_VMM - Genode version 11.11],
|
||||
we introduced the preliminary adaptation of Vancouver to Genode. This version
|
||||
was meant as a mere proof of concept, which allowed the bootup of small Guest
|
||||
OSes (such as Fiasco.OC or Pistachio) inside the VMM. However, it did not
|
||||
support any glue code to Genode's session interface, which limited the
|
||||
usefulness of this virtualization solution at that point. We had planned to
|
||||
continue the integration of Vancouver with Genode once we observed public
|
||||
demand.
|
||||
|
||||
The move of NOVA's development to Intel Labs apparently created this demand.
|
||||
It is undeniable that combining the rich user land provided by Genode with the
|
||||
capabilities of the Vancouver VMM poses an attractive work load for NOVA. So
|
||||
the stalled line of the integration work of Vancouver with Genode was picked up
|
||||
within Intel Labs, more specifically by Markus Partheymüller. We are delighted
|
||||
to be able to merge the outcome of this undertaking into the mainline Genode
|
||||
development. Thanks to Intel Labs and Markus in particular for this substantial
|
||||
contribution!
|
||||
|
||||
The features added to the new version of Vancouver for Genode are as follows:
|
||||
|
||||
:VMX support:
|
||||
|
||||
Our initial version supported AMD's SVM technology only because this was
|
||||
readily supported by Qemu. With the added support for Intel VMX, Vancouver
|
||||
has become able to operate on both Intel and AMD processors with hardware
|
||||
virtualization support.
|
||||
|
||||
:Timer support:
|
||||
|
||||
With added support for timer interrupts, the VMM has become able to
|
||||
boot a complete Linux system.
|
||||
|
||||
:Console support:
|
||||
|
||||
With this addition, the guest VM can be provided with a frame buffer and
|
||||
keyboard input.
|
||||
|
||||
For the frame-buffer size in Vancouver, the configuration value in the
|
||||
machine XML node is used. It is possible to map the corresponding memory
|
||||
area directly to the guest regardless if it comes from nitpicker, a virtual
|
||||
frame buffer, or the VESA driver. The guest is provided with two modes (text
|
||||
mode 3 and graphics mode 0x114 (0x314 in Linux).
|
||||
|
||||
Pressing LWIN+END while a VM has focus resets the virtual machine. Also,
|
||||
RESET and DEBUG key presses will not be forwarded to the VM anymore.
|
||||
It is possible to dump a VM's state by pressing LWIN+INS keys.
|
||||
|
||||
The text console is able to detect idle mode, unmaps the buffer from the
|
||||
guest and stops interpreting. Upon the next page fault in this area, it
|
||||
resumes operation again. The code uses a simple checksum mechanism instead
|
||||
of a large buffer and 'memcmp' to detect an idle text console. False
|
||||
positives don't matter very much.
|
||||
|
||||
:Network support:
|
||||
|
||||
The VMM has become able to use the Intel 82576 device model from the NUL
|
||||
user land to give VMs access to the network via Genode's NIC bridge service
|
||||
or a NIC driver.
|
||||
|
||||
:Disk support:
|
||||
|
||||
The VMM can now assign block devices to guests using Genode's block-session
|
||||
interface. The machine has to be configured to use a specified drive, which
|
||||
could be theoretically routed to different partitions or services via policy
|
||||
definitions. Currently the USB driver only supports one device. Genode's AHCI
|
||||
driver is untested.
|
||||
|
||||
:Real-time clock:
|
||||
|
||||
By using the new RTC session interface, Vancouver is able to provide the
|
||||
wall-clock time to guest OSes.
|
||||
|
||||
To explore the new version of the Vancouver VMM, there exists a ready-to-use
|
||||
run script at 'ports/run/vancouver.run'. Only the guest OS binaries such as a
|
||||
Linux kernel image and a RAM disk must be manually supplied in the
|
||||
'<build-dir>/bin' directory. The run script is able to start one or multiple
|
||||
instances of the VMM using the graphical launchpad.
|
||||
|
||||
|
||||
Low-latency audio output
|
||||
########################
|
||||
|
||||
In version 10.05, we introduced an interface for the playback of audio data
|
||||
along with an audio mixer component and ALSA-based sound drivers ported from
|
||||
the Linux kernel. The original 'Audio_out' session interface was based on
|
||||
Genode's packet stream facility, which allows the communication of bulk data
|
||||
across address spaces via a combination of shared memory and signals. Whereas
|
||||
shared memory is used to transfer the payload in an efficient manner without
|
||||
the need to copy data via the kernel, signals are used to manage the data flow
|
||||
between the information source and sink.
|
||||
|
||||
[image packet_stream]
|
||||
|
||||
Figure [packet_stream] displays the life cycle of a packet of information
|
||||
transferred from the source to the sink. The original intent behind the
|
||||
packet-stream facility was the transmission of networking packets and blocks
|
||||
of block devices. At the time when we first introduced the 'Audio_out'
|
||||
interface, the packet stream seemed like a good fit for audio, too. However, in
|
||||
the meanwhile, we came to the conclusion that this is not the case when trying
|
||||
to accommodate streamed audio data and sporadic audio output at the same time.
|
||||
|
||||
For the output of streamed audio data, a codec typically decodes a relatively
|
||||
large portion of an audio stream and submits the sample data to the mixer. The
|
||||
mixer, in turn, mixes the samples of multiple sources and forwards the result
|
||||
to the audio driver. Each of those components the codec, the mixer, and the
|
||||
audio driver live in a separate process. By using large buffer sizes between
|
||||
them, the context-switching overhead is hardly a concern. Also, the driver can
|
||||
submit large buffers of sample data to the sound device without any further
|
||||
intervention needed.
|
||||
|
||||
In contrast, sporadic sounds are used to inform the user about an immediate
|
||||
event. It is ultimately expected that such sounds are played back without much
|
||||
latency. Otherwise the interactive experience (e.g., of games) would suffer.
|
||||
Hence, using large buffers between the audio source, the mixer, and the driver
|
||||
is not an option. By using the packet stream concept, we have to settle on a
|
||||
specific buffer size. A too small buffer increases CPU load caused by many
|
||||
context switches and the driver, which has to feed small chunks of sample data
|
||||
to the sound device. A too large buffer, however, makes sporadic sounds at low
|
||||
latencies impossible. We figured out that the necessity to find a sweet spot
|
||||
for picking a buffer size is a severe drawback. This observation triggered us
|
||||
to replace the packet-stream-based communication mechanism of the 'Audio_out'
|
||||
session interface by a new solution that we specifically designed to
|
||||
accommodate both corner cases of audio output.
|
||||
|
||||
[image audio_out]
|
||||
|
||||
Similarly to the packet-stream mechanism, the new interface is based on a
|
||||
combination of shared memory and signals. However, we dropped the notion of
|
||||
ownership of packets. When using the packet-stream protocol depicted as above,
|
||||
either the source or the sink is in charge of handling a given packet at a
|
||||
given time, not both. At the points 1, 2, and 4, the packet is owned by the
|
||||
source. At the points 3 and 4, the packet is owned by the sink. By putting a
|
||||
packet descriptor in the submit queue or acknowledgement queue, there is a
|
||||
handover of responsibility. The new interface weakens this notion of ownership
|
||||
by letting the source update once submitted audio frames even after submitting
|
||||
them. If there are solely continuous streams of audio arriving at the mixer,
|
||||
the mixer can mix those large batches of audio samples at once and pass the
|
||||
result to the driver.
|
||||
|
||||
[image mixer_streaming]
|
||||
The mixer processes incoming data from multiple streaming sources as batches.
|
||||
|
||||
Now, if a sporadic sound comes in, the mixer checks the
|
||||
current output position reported by the audio driver, and re-mixes those
|
||||
portions that haven't been played back yet by incorporating the sporadic sound.
|
||||
So the buffer consumed by the driver gets updated with new data.
|
||||
|
||||
[image mixer_sporadic]
|
||||
A sporadic occuring sound prompts the mixer to remix packets that are
|
||||
already submitted in the output queue.
|
||||
|
||||
Besides changing the way of how packets are populated with data, the second
|
||||
major change is turning the interface into a time-triggered concept. The
|
||||
driver produces periodic signals that indicate the completeness of a
|
||||
played-back audio packet. This signal triggers the mixer to become active,
|
||||
which in turn serves as a time base for its clients. The current playback
|
||||
position is denoted alongside the sample data as a field in the memory buffer
|
||||
shared between source and sink.
|
||||
|
||||
The new 'Audio_out' interface has the potential to align the requirements of
|
||||
both streamed audio with those of sporadic sounds. As a side benefit, the now
|
||||
domain-specific interface has become simpler than the original packet-stream
|
||||
based solution. This becomes nowhere as evident as in the implementation of the
|
||||
mixer, which has become much simpler (30% less code). The interface change
|
||||
is accompanied with updates of components related to audio output, in
|
||||
particular the OSS sound drivers contained in 'dde_oss', the ALSA audio driver
|
||||
for Linux, the avplay media player, and the libSDL audio back-end.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Signalling API improvements
|
||||
===========================
|
||||
|
||||
The signalling API provided by 'base/signal.h' is fairly low level. For
|
||||
employing the provided mechanism by application software, we used to craft
|
||||
additional glue code that translates incoming signals to C++ method
|
||||
invocations. Because the pattern turned out to be not only useful but a good
|
||||
practice, we added the so called 'Signal_dispatcher' class template to the
|
||||
signalling API.
|
||||
|
||||
In addition to being a 'Signal_context', a 'Signal_dispatcher' associates a
|
||||
member function with the signal context. It is intended to be used as a member
|
||||
variable of the class that handles incoming signals of a certain type. The
|
||||
constructor takes a pointer-to-member to the signal handling function as
|
||||
argument. If a signal is received at the common signal reception code, this
|
||||
function will be invoked by calling 'Signal_dispatcher_base::dispatch'. This
|
||||
pattern can be observed in the implementation of RAM file system
|
||||
('os/src/server/ram_fs').
|
||||
|
||||
Under the hood, the signalling implementation received a major improvement with
|
||||
regard to the life-time management of signal contexts. Based on the observation
|
||||
that 'Signal' objects are often referring to non-trivial objects derived from
|
||||
'Signal_context', it is important to defer the destruction of such objects to a
|
||||
point when no signal referring to the context is in flight anymore. We solved
|
||||
this problem by modelling 'Signal' type as a shared pointer that operates on a
|
||||
reference counter embedded in the corresponding 'Signal_context'. Based on
|
||||
reference counter, the 'Signal_receiver::dissolve()' function does not return
|
||||
as long as the signal context to be dissolved is still referenced by one or
|
||||
more 'Signal' objects.
|
||||
|
||||
|
||||
Trimmed and unified framework API
|
||||
=================================
|
||||
|
||||
A though-provoking
|
||||
[http://sourceforge.net/mailarchive/forum.php?thread_name=CAGQ-%3Dq27%2B_UooBiJmz9RdTE1gDmVcg9v0w-8TNgEH5fzHYiA%2BQ%40mail.gmail.com&forum_name=genode-main - posting]
|
||||
on our mailing list prompted us to explore the idea to make shared libraries
|
||||
and dynamically linked executables binary compatible among different kernels.
|
||||
This sounds a bit crazy at first but it is not downright infeasible.
|
||||
|
||||
As a baby step into this direction, we unified several public headers of the
|
||||
Genode API and tried to make headers private to the framework where possible.
|
||||
The latter is the case for the 'base/platform_env.h' header, which is actually
|
||||
not part of the generic Genode API. Hence, it was moved to the
|
||||
framework-internal 'src/base/env'. Another step was the removal of
|
||||
platform-specific types that are not necessarily platform-dependent. We could
|
||||
remove the 'Native_lock' type without any problems. Also, we were able to unify
|
||||
the IPC API, which was formerly split into the two parts 'base/ipc_generic.h'
|
||||
and 'base/ipc.h' respectively. Whereas 'base/ipc_generic.h' was shared among
|
||||
all platforms, the 'base/ipc.h' header used to contain platform-specific IPC
|
||||
marshalling and unmarshalling code. But by moving this code from the header to
|
||||
the corresponding (platform-specific) IPC library, we were able to discard the
|
||||
content of 'base/ipc.h' altogether. Consequently, the former
|
||||
'base/ipc_generic.h' could be renamed to 'base/ipc.h'. These changes imply no
|
||||
changes at the API level.
|
||||
|
||||
|
||||
Simplified structure of base libraries
|
||||
======================================
|
||||
|
||||
The Genode base API used to come in the form of many small libraries, each
|
||||
covering a dedicated topic. Those libraries were 'allocator_avl', 'avl_tree',
|
||||
'console', 'env', 'cxx', 'elf', 'env', 'heap', 'server', 'signal', 'slab',
|
||||
'thread', 'ipc', and 'lock'. The term "library" for those bits of code was
|
||||
hardly justified as most of the libraries consisted of only a few .cc files.
|
||||
Still the build system had to check for their inter-dependencies on each run of
|
||||
the build process. Furthermore, for Genode developers, specifying the list of
|
||||
base libraries in their 'target.mk' files tended to be an inconvenience. Also,
|
||||
the number of libraries and their roles (core only, non-core only, shared by
|
||||
both core and non-core) were not easy to capture. Hence, we simplified the way
|
||||
of how those base libraries are organized. They have been reduced to the
|
||||
following few libraries:
|
||||
|
||||
* 'cxx.mk' contains the C++ support library
|
||||
* 'startup.mk' contains the startup code for normal Genode processes
|
||||
On some platform, core is able to use the library as well.
|
||||
* 'base-common.mk' contains the parts of the base library that are
|
||||
identical by core and non-core processes.
|
||||
* 'base.mk' contains the complete base API implementation for non-core
|
||||
processes
|
||||
|
||||
Consequently, the 'LIBS' declaration in 'target.mk' files becomes simpler as
|
||||
well. In the normal case, only the 'base' library must be mentioned.
|
||||
|
||||
|
||||
New fault-detection mechanism
|
||||
=============================
|
||||
|
||||
Until now, it was hardly possible for a parent process to respond to crashes of
|
||||
child processes in a meaningful way. If a child process crashed, the parent
|
||||
would normally just not take notice. Even though some special use cases such as
|
||||
GDB monitor could be accommodated by the existing
|
||||
'Cpu_session::exception_handler' facility, this mechanism requires the
|
||||
virtualization of the 'Cpu_session interface' because an exception handler used
|
||||
to refer to an individual thread rather than the whole process. For ordinary
|
||||
parents, this mechanism is too cumbersome to use. However, there are several
|
||||
situations where a parent process would like to actively respond to crashing
|
||||
children. For example, the parent might like to restart a crashed component
|
||||
automatically, or enter a special failsafe mode.
|
||||
|
||||
To ease the implementation of such scenarios, we enhanced the existing
|
||||
'Cpu_session::exception_handler' mechanism with the provision of a
|
||||
default signal handler that is used if no thread-specific handler is installed.
|
||||
The default signal handler can be set by specifying an invalid thread
|
||||
capability and a valid signal-context capability. So for registering a signal
|
||||
handler to all threads of a process, no virtualization of the 'Cpu_session'
|
||||
interface is needed anymore. The new mechanism is best illustrated by the
|
||||
'os/run/failsafe.run' script, which creates a system that repeatedly spawns a
|
||||
crashing child process.
|
||||
|
||||
|
||||
Reworked synchronization primitives
|
||||
===================================
|
||||
|
||||
We reworked the framework-internal lock interface in order to be able to use
|
||||
the 'futex' syscall on the Linux base platform. Previously, the lock
|
||||
implementation on Linux was based on Unix signals. In the contention case, the
|
||||
applicant for a contended lock would issue a blocking system call, which gets
|
||||
canceled by the occurrence of a signal. We used 'nanosleep' for this purpose.
|
||||
Once the current owner of the lock releases the lock, it sends a signal to the
|
||||
next applicant of the lock. Because signals are buffered by the kernel, they
|
||||
are guaranteed to be received by the targeted thread. However, in situations
|
||||
with much lock contention, we observed the case where the signal was delivered
|
||||
just before the to-be-blocked thread could enter the 'nanosleep' syscall. In
|
||||
this case, the signal was not delivered at the next entrance into the kernel
|
||||
(when entering 'nanosleep') but earlier. Even though the signal handler was
|
||||
invoked, we found no elegant way to handle the signal such that the subsequent
|
||||
'nanosleep' call would get skipped. So we decided to leave our signal-based
|
||||
solution behind and went for the mainstream 'futex' mechanism instead.
|
||||
|
||||
Using this mechanism required us to re-design the internal lock API, which was
|
||||
originally designed with the notion of thread IDs. The 'Native_thread_id' type,
|
||||
which was previously used in the lock-internal 'Applicant' class to identify a
|
||||
thread to be woken up, was not suitable anymore for implementing this change.
|
||||
Hence, we replaced it with the 'Thread_base*' type, which also has the positive
|
||||
effect of making the public 'base/cancelable_lock.h' header file
|
||||
platform-independent.
|
||||
|
||||
In addition to reworking the basic locking primitives, we changed the
|
||||
'Object_pool' data structure to become safer to use. The former 'obj_by_*'
|
||||
functions have been replaced by 'lookup_and_lock' that looks up an object and
|
||||
locks it in one atomic operation. Additionally, the case that an object may
|
||||
already be in destruction is handled gracefully. In this case, the lookup will
|
||||
return that the object is not available anymore.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Notification mechanism for the file-system interface
|
||||
====================================================
|
||||
|
||||
To support dynamic system scenarios, we extended Genode's file-system interface
|
||||
with the ability to monitor changes of files or directories, similar to the
|
||||
inotify mechanism on Linux but simpler. The new 'File_system::sigh' function
|
||||
can be used to install a signal handler for an open file node. When a node is
|
||||
closed after a write operation, a prior registered signal handler for this file
|
||||
gets notified. Signal handlers can also be installed for directories. In this
|
||||
case, the signal handler gets informed about changes of immediate nodes hosted
|
||||
in the directory, i.e., the addition, renaming, or removal of nodes.
|
||||
|
||||
The 'ram_fs' server has been enhanced to support the new interface. So any file
|
||||
or directory change can now be observed by 'ram_fs' clients.
|
||||
|
||||
|
||||
New adapter from file-system to ROM session interface
|
||||
=====================================================
|
||||
|
||||
The new 'fs_rom' server translates the 'File_system' session interface to the
|
||||
'ROM' session' interface. Each request for a ROM file is handled by looking
|
||||
up an equally named file on the file system. If no such file can be found,
|
||||
then the server will monitor the file system for the creation of the
|
||||
corresponding file. Furthermore, the server reflects file changes as signals
|
||||
to the ROM session.
|
||||
|
||||
There currently exist two limitations: First, symbolic links are not handled.
|
||||
Second, the server needs to allocate RAM for each requested file. The RAM is
|
||||
always allocated from the RAM session of the server. Thereby, the RAM quota
|
||||
consumed by the server depends on the client requests and the size of the
|
||||
requested files. Therefore, one instance of the server should not be used by
|
||||
untrusted clients and trusted clients at the same time. In such situations,
|
||||
multiple instances of the server could be used.
|
||||
|
||||
The most interesting feature of the 'fs_rom' server is the propagation of
|
||||
file-system changes as ROM module changes. This clears the way to use this
|
||||
service to supply dynamic configurations to Genode programs.
|
||||
|
||||
|
||||
Dynamic re-configuration of the init process
|
||||
============================================
|
||||
|
||||
The init process has become able to respond to configuration changes by
|
||||
restarting the scenario using the new configuration. To make this feature
|
||||
useful in practice, init must not fail under any circumstances. Even on
|
||||
conditions that were considered previously as fatal and led to the abort of
|
||||
init (such as ambiguous names of the children or misconfiguration in general),
|
||||
init must stay alive and responsive to configuration changes.
|
||||
|
||||
With this change, the init process is one of the first use cases of the dynamic
|
||||
configuration feature enabled via the 'fs_rom' service and the new file-system
|
||||
notifications. By supplying the configuration of an init instance via the
|
||||
'fs_rom' and 'ram_fs' services, the configuration of this instance gets fetched
|
||||
from a file of the 'ram_fs' service. Each time, this file is changed, for
|
||||
example via VIM running within a Noux runtime environment, the init process
|
||||
re-evaluates its configuration.
|
||||
|
||||
In addition to the support for dynamic re-configurations, we simplified the use
|
||||
of conditional session routing, namely the '<if-args>' mechanism. When matching
|
||||
the 'label' session argument using '<if-args>' in a routing table, we can omit
|
||||
the child name prefix because it is always the same for all sessions
|
||||
originating from the child anyway. By handling the matching of session labels
|
||||
as a special case, the expression of label-specific routing
|
||||
becomes more intuitive.
|
||||
|
||||
|
||||
Timer interface turned into asynchronous mode of operation
|
||||
==========================================================
|
||||
|
||||
The 'msleep' function of 'Timer::Session' interface is one of the last relics
|
||||
of blocking RPC interfaces present in Genode. As we try to part away from
|
||||
blocking RPC calls inside servers and as a means to unify the timer
|
||||
implementation across the many different platforms supported by Genode, we
|
||||
changed the interface to an asynchronous mode of operation.
|
||||
|
||||
Synchronous blocking RPC interfaces turned out to be constant sources of
|
||||
trouble and code complexity. E.g., a timer client that also wants to respond to
|
||||
non-timer events was forced to be a multi-threaded process. Now, the blocking
|
||||
'msleep' call has been replaced by a mechanism for programming timeouts and
|
||||
receiving wakeup signals in an asynchronous fashion. Thereby signals
|
||||
originating from the timer can be handled, along with signals from other signal
|
||||
sources, by a single thread. Once a timer client has registered a signal
|
||||
handler using the 'Timer::sigh' function, it can program timeouts using the
|
||||
functions 'trigger_once' and 'trigger_periodic', which take an amount of
|
||||
microseconds as argument. For maintaining compatibility and convenience, the
|
||||
interface still contains the virtual 'msleep' function. However, it is not an
|
||||
RPC function anymore but a mere client-side wrapper around the 'sigh' and
|
||||
'trigger_once' functions. For use cases where sleeping at the granularity of
|
||||
milliseconds is too coarse (such as udelay calls by device drivers), we added
|
||||
a new 'usleep' call, which takes a number of microseconds as argument.
|
||||
|
||||
As a nice side effect of the interface changes, the platform-specific
|
||||
implementations could be vastly unified. On NOVA and Fiasco.OC, the need to use
|
||||
one thread per client has vanished. As a further simplification, we changed the
|
||||
timer to use the build system's library-selection mechanism instead of
|
||||
providing many timer targets with different 'REQUIRES' declarations. This
|
||||
reduces the noise of the build system. For all platforms, the target at
|
||||
'os/src/drivers/timer' is built. The target, in turn, depends on a 'timer'
|
||||
library, which is platform-specific. The various library description files are
|
||||
located under 'os/lib/mk/<platform>'. The common bits are contained in
|
||||
'os/lib/mk/timer.inc'.
|
||||
|
||||
Since the 'msleep' call is still available from the client's perspective,
|
||||
the change of the timer interface does not imply an API incompatibility.
|
||||
However, it provides the opportunity to simplify clients in cases that required
|
||||
the maintenance of a separate thread for the sole purpose of
|
||||
periodic signal generation.
|
||||
|
||||
|
||||
Loader
|
||||
======
|
||||
|
||||
The loader is a service that enables its clients to dynamically create Genode
|
||||
subsystems. Leveraging the new fault-detection support described in section
|
||||
[New fault-detection mechanism], we enabled loader clients to respond to
|
||||
failures that occur inside the spawned subsystem. This is useful for scenarios
|
||||
where subsystems should be automatically restarted or in situations where the
|
||||
system should enter a designated failsafe mode once an unexpected fault
|
||||
happens.
|
||||
|
||||
The loader provides this feature by installing an optional client-provided
|
||||
fault handler as default CPU exception handler and a RM fault handler for all
|
||||
CPU and RM sessions of the loaded subsystem. This way, the failure of any
|
||||
process within the subsystem gets reflected to the loader client as a signal.
|
||||
|
||||
The new 'os/run/failsafe.run' test illustrate this mechanism. It covers two
|
||||
cases related to the loader, which are faults produced by the immediate child
|
||||
of the loader and faults produced by indirect children.
|
||||
|
||||
|
||||
Focus events for the nitpicker GUI server
|
||||
=========================================
|
||||
|
||||
To enable a way for applications to provide visual feedback to changed keyboard
|
||||
focus, we added a new 'FOCUS' event type to the 'Input::Event' structure. To
|
||||
encode whether the focus was entered or left, the former 'keycode' member is
|
||||
used (value 0 for leaving, value 1 for entering). Because 'keycode' is
|
||||
misleading in this context, the former 'Input::Event::keycode' function was
|
||||
renamed to 'Input::Event::code'. The nitpicker GUI server has been adapted to
|
||||
deliver focus events to its clients.
|
||||
|
||||
|
||||
NIC bridge with support for static IP configuration
|
||||
===================================================
|
||||
|
||||
NIC bridge is a service that presents one physical network adaptor as many
|
||||
virtual network adaptors to its clients. Up to now, it required each client
|
||||
to obtain an IP address from a DHCP server at the physical network. However,
|
||||
there are situations where the use of static IPs for virtual NICs is useful.
|
||||
For example, when using the NIC bridge to create a virtual network between
|
||||
the lighttpd web server and the Arora web browser, both running as Genode
|
||||
processes without real network connectivity.
|
||||
|
||||
The static IP can be configured per client of the NIC bridge using a '<policy>'
|
||||
node of the configuration. For example, the following policy assigns a static
|
||||
address to a client with the session label "lighttpd".
|
||||
!<start name="nic_bridge">
|
||||
! ...
|
||||
! <config>
|
||||
! <policy label="lighttpd" ip_addr="10.0.2.55"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
Of course, the client needs to configure its TCP/IP stack to use the assigned
|
||||
IP address. This can be done via configuration arguments examined by the
|
||||
'lwip_nic_dhcp' libc plugin. For the given example, the configuration for the
|
||||
lighttpd process would look as follows.
|
||||
!<start name="lighttpd">
|
||||
! <config>
|
||||
! <interface ip_addr="10.0.2.55"
|
||||
! netmask="255.255.255.0"
|
||||
! gateway="10.0.2.1"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New terminal multiplexer
|
||||
========================
|
||||
|
||||
The new 'terminal_mux' server located at 'gems/src/server/terminal_mux' is able
|
||||
to provide multiple terminal sessions over one terminal-client session. The
|
||||
user can switch between the different sessions using a keyboard shortcut, which
|
||||
brings up an ncurses-based menu.
|
||||
|
||||
The terminal sessions provided by terminal_mux implement (a subset of) the
|
||||
Linux terminal capabilities. By implementing those capabilities, the server
|
||||
is interchangeable with the graphical terminal ('gems/src/server/terminal').
|
||||
The terminal session used by the server is expected to by VT102 compliant.
|
||||
This way, terminal_mux can be connected via an UART driver with terminal
|
||||
programs such as minicom, which typically implement VT102 rather than the Linux
|
||||
terminal capabilities.
|
||||
|
||||
When started, terminal_mux displays a menu with a list of currently present
|
||||
terminal sessions. The first line presents status information, in particular
|
||||
the label of the currently visible session. A terminal session can be selected
|
||||
by using the cursor keys and pressing return. Once selected, the user is able
|
||||
to interact with the corresponding terminal session. Returning to the menu is
|
||||
possible at any time by pressing control-x.
|
||||
|
||||
For trying out the new terminal_mux component, the 'gems/run/termina_mux.run'
|
||||
script sets up a system with three terminal sessions, two instances of Noux
|
||||
executing VIM and a terminal_log service that shows the log output of both Noux
|
||||
instances.
|
||||
|
||||
|
||||
New ported 3rd-party libraries
|
||||
==============================
|
||||
|
||||
To support our forthcoming port of Git to the Noux runtime environment, we
|
||||
have made the following libraries available via the libports repository:
|
||||
|
||||
* libssh-0.5.4
|
||||
* curl-7.29.0 (for now the port is x86_* only because it depends on libcrypto,
|
||||
which is currently not tested on ARM)
|
||||
* iconv-1.14
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Besides the changes concerning the use of IOMMUs, the following device driver
|
||||
have received improvements:
|
||||
|
||||
:UART drivers:
|
||||
|
||||
The OMAP4 platform support has been extended by a new UART driver, which
|
||||
enables the use of up to 4 UART interfaces. The new driver is located at
|
||||
'os/src/drivers/uart/omap4'.
|
||||
|
||||
All UART drivers implement the 'Terminal::Session' interface, which
|
||||
provides read/write functionality accompanied by a function to determine
|
||||
the terminal size. The generic UART driver code shared among the various
|
||||
implementations has been enhanced to support the detection of the terminal
|
||||
size using a protocol of escape sequences. This feature can be enabled by
|
||||
including the attribute 'detect_size="yes"' in the policy of a UART client.
|
||||
This is useful for combining UART drivers with the new 'terminal_mux'
|
||||
server.
|
||||
|
||||
:ACPI support for 64-bit machines:
|
||||
|
||||
In addition to IOMMU-related modifications, the ACPI driver has been enhanced
|
||||
to support 64-bit machines and MCFG table parsing has been added.
|
||||
|
||||
:PCI support for IOMMUs:
|
||||
|
||||
With the added support of IOMMUs, the 'Pci::Session' interface has been
|
||||
complemented with a way to obtain the extended PCI configuration space in the
|
||||
form of a 'Genode::Dataspace'. Also, the interface provides a way to allocate
|
||||
DMA buffers for a given PCI device. Device drivers that are meant to be used
|
||||
on system with and without IOMMUs should use this interface rather than
|
||||
core's RAM session interface to allocate DMA buffers.
|
||||
|
||||
:Real-time clock on x86:
|
||||
|
||||
Up to now, the x86 real-time clock driver served as a mere example for
|
||||
accessing I/O ports on x86 machines but the driver did not expose any service
|
||||
interface. With the newly added 'os/include/rtc_session' interface and the
|
||||
added support of this interface in the RTC driver, Genode programs have now
|
||||
become able to read the real-time clock. Currently, the interface is used by
|
||||
the Vancouver VMM.
|
||||
|
||||
:USB driver restructured, support for Arndale board added:
|
||||
|
||||
While adding support for the Exynos-5-based Arndale board, we took the
|
||||
chance to restructure the driver to improve portability to new
|
||||
platforms. The most part of the driver has become a library, which is
|
||||
built in a platform-specific way. The build system automatically selects
|
||||
the library that fits for the platform as set up for the build directory.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
NOVA
|
||||
====
|
||||
|
||||
The NOVA base platform received major improvements that address the kernel
|
||||
as well as Genode's NOVA-specific code. We pursued two goals with this line
|
||||
of work. The first goal was the use of NOVA in highly dynamic settings, which
|
||||
was not possible before, mainly due to lacking kernel features. The second
|
||||
goal was the use of IOMMUs.
|
||||
|
||||
NOVA is ultimately designed for accommodating dynamic workloads on top of the
|
||||
kernel. But we found that the implementation of crucial functionality was
|
||||
missing. In particular, the kernel lacked the ability to destroy all kinds of
|
||||
kernel objects and to reuse memory of kernel objects that had been destroyed.
|
||||
Consequently, when successively creating and destroying kernel objects such as
|
||||
threads and protection domains, the kernel would eventually run out of memory.
|
||||
This issue became a show stopper for running the Genode tool chain on NOVA
|
||||
because this scenario spawns and destroys hundreds of processes. For this
|
||||
reason, we complemented the kernel with the missing functionality. This step
|
||||
involved substantial changes in the kernel code. So our approach of using the
|
||||
upstream kernel and applying a hand full of custom patches started to show its
|
||||
limitations.
|
||||
|
||||
To streamline our work flow and to track the upstream kernel in a structured
|
||||
way, we decided to fork NOVA's Git repository and maintain our patches in our
|
||||
fork. For each upstream kernel revision that involves kernel ABI changes, we
|
||||
create a separate branch called "r<number>". This branch corresponds to the
|
||||
upstream kernel with our series of custom patches applied (actually rebased) on
|
||||
top. This way, our additions to the upstream kernel are well documented. The
|
||||
'make prepare' mechanism in the base-nova repository automates the task of
|
||||
checking out the right branch. So from the Genode user's point of view, this
|
||||
change is transparent.
|
||||
|
||||
The highly dynamic application scenarios executed on NOVA triggered several
|
||||
synchronization issues in Genode's core process that had not been present on
|
||||
other base platforms. The reason for those issues to occur specifically on NOVA
|
||||
lies in the concurrent page fault handling as employed on this base platform.
|
||||
For all classical L4-like kernels and Fiasco.OC, we use one global pager thread
|
||||
to resolve all page faults that occur in the whole Genode system. In contrast,
|
||||
on NOVA we use one pager thread per user thread. Consequently, proper
|
||||
fine-grained synchronization between those pager threads and the other parts of
|
||||
core is mandated. Even though the immediate beneficiary of these changes is the
|
||||
NOVA platform, many of the improvements refer to generic code. This paves the
|
||||
ground for scaling the page-fault handling on other base platforms (such as
|
||||
Fiasco.OC) to multiple threads. With these improvements in place, we are able
|
||||
to successfully execute the 'noux_tool_chain_nova' scenario on the NOVA kernel
|
||||
and build Genode's core on NOVA. That said, however, not all issues are covered
|
||||
yet. So there is still a way left to go to turn base-nova into a base platform
|
||||
that is suitable for highly dynamic scenarios.
|
||||
|
||||
The second goal was the use of NOVA's IOMMU support on Genode. This topic is
|
||||
covered in detail in section [DMA protection via IOMMU].
|
||||
|
||||
To be able to use and debug Genode on NOVA on modern machines that lack legacy
|
||||
comports, we either use UART PCI cards or the Intel's Active Management
|
||||
Technology (AMT) mechanism. In both cases, the I/O ports to access the serial
|
||||
interfaces differ from the legacy comports. To avoid the need for adjusting the
|
||||
I/O port base addresses per platform, we started using the chain-boot-loader
|
||||
called "bender" developed by the Operating Systems Group of TU Dresden,
|
||||
Germany. This boot loader is started prior the kernel, searches the PCI bus for
|
||||
the first suitable device and registers the corresponding I/O port base address
|
||||
at the bios data area (BDA). Genode's core, in turn, picks the I/O port base
|
||||
address up from the BDA and uses the registered i8250 serial controller for its
|
||||
LOG service.
|
||||
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
The base-hw platform enables the use of Genode on ARM-based hardware without
|
||||
the need for a 3rd-party kernel.
|
||||
|
||||
With the new release, the range of supported ARM-based hardware has been
|
||||
extended to cover the following additional platforms. With the previous
|
||||
release, we introduced the support for Freescale i.MX family of SoC, starting
|
||||
with i.MX31. The current release adds support for the i.MX53 SoC and adds
|
||||
a user-level timer driver for this platform. With the Samsung Exynos 5, the
|
||||
first Cortex-A15-based SoC has entered the list of supported SoCs. Thanks to
|
||||
this addition, Genode has become able to run on the
|
||||
[http://www.arndaleboard.org - Howchip Arndale board]. At the current state,
|
||||
core and multiple instances of init can be executed but drivers for peripherals
|
||||
are largely missing. Those will be covered by our ongoing work with this SoC.
|
||||
The added platforms are readily available via the 'create_builddir' tool.
|
||||
|
||||
To make base-hw practically usable on real hardware (i.e., the Pandaboard),
|
||||
support for caches has been implemented. Furthermore, the implementation of the
|
||||
signalling API underwent a redesign, which leverage the opportunities that
|
||||
arise with tailoring a kernel specifically to the Genode API. As a side-benefit
|
||||
of this endeavour, we could unify the 'base/signal.h' header with the generic
|
||||
version and thereby took another step towards the unification of the Genode
|
||||
headers across different kernels.
|
||||
|
||||
|
||||
Microblaze platform removed
|
||||
===========================
|
||||
|
||||
The 'base-mb' platform has been removed because it is no longer maintained.
|
||||
This platform enabled Genode to run directly on the Xilinx Microblaze softcore
|
||||
CPU. For supporting the Microblaze CPU architecture in the future, we might
|
||||
consider integrating support for this architecture into base-hw. Currently
|
||||
though, there does not seem to be any demand for it.
|
||||
|
||||
|
||||
Fiasco.OC forked, support for Exynos 5 SoC added
|
||||
================================================
|
||||
|
||||
In the last release cycle, we went beyond just using the Fiasco.OC kernel and
|
||||
started to engage with the kernel code more intensively. To avoid that the
|
||||
management of a growing number of kernel patches goes out of hand, we forked
|
||||
the Fiasco.OC kernel and conduct our development in our Fiasco.OC Git
|
||||
repository. When using the 'make prepare' mechanism in the 'base-foc'
|
||||
repository, the new Git repository will be used automatically. There exists a
|
||||
dedicated branch for each upstream SVN revision that we use. We started with
|
||||
updating Fiasco.OC to the current revision 47. Hence, the current branch used
|
||||
by Genode is named "r47". The branch contains the unmodified state of the
|
||||
upstream SVN repository with our modifications appearing as individual commits
|
||||
on top. This makes it easy to keep track of the Genode-specific modifications.
|
||||
Please note that the update to Fiasco.OC requires minor adaptations inside
|
||||
the 'ports-foc' repository. So for using L4Linux, "make prepare" must be
|
||||
issued in both repositories 'base-foc' and 'ports-foc'.
|
||||
|
||||
Speaking of engaging with the kernel code, the most profound improvement is
|
||||
the support for the Samsung Exynos-5-based Arndale board that we added to the
|
||||
kernel. This goes hand in hand with the addition of this platform to Genode.
|
||||
For creating a build directory targeting the Arndale board, just specify
|
||||
"foc_arndale" to the 'create_builddir' tool. At the time of the release,
|
||||
several basic scenarios including the timer driver and the USB driver are
|
||||
working. Also, both Cortex-A15 CPUs of the Exynos 5 SoC are operational.
|
||||
However, drivers for most of the peripherals of the Exynos-5 SoC are missing,
|
||||
which limits the current scope of Genode on this platform.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Since the base-linux platform became used for more than a mere development
|
||||
vehicle, we are revisiting several aspects of this base platform. In the last
|
||||
release, we changed the synchronous inter-process-communication mechanism to
|
||||
the use of SCM rights. For the current release, it was time to have a closer
|
||||
look at the memory management within core. The Linux version of core used a
|
||||
part of the BSS to simulate access to physical memory. All dataspaces would
|
||||
refer to a portion of 'some_mem'. So each time when core would access the
|
||||
dataspace contents, it would access its local BSS. For all processes outside of
|
||||
core, dataspaces were represented as files. We have now removed the distinction
|
||||
between core and non-core processes. Now, core uses the same 'Rm_session_mmap'
|
||||
implementation as regular processes. This way, the 'some_mem' could be
|
||||
abandoned. We still use a BSS variable for allocating core-local meta data
|
||||
though. The major benefit of this change is the removal of the artificial
|
||||
quota restriction that was imposed by the predefined size of the 'some_mem'
|
||||
array. Now, the Linux base platform can use as much memory as it likes. Because
|
||||
the Linux kernel implements virtual memory, we are not bound by the physical
|
||||
memory. Hence, the available quota assigned to the init process is almost
|
||||
without bounds.
|
||||
|
||||
To implement the fault-detection mechanism described in section
|
||||
[New fault-detection mechanism] on Linux, we let core catch SIGCHLD signals of
|
||||
all Genode processes. If such a signal occurs, core determines the process that
|
||||
produced the signal by using 'wait_pid', looks up the CPU session that belongs
|
||||
to the process and delivers an exception signal to the registered exception
|
||||
handler. This way, abnormal terminations of Genode processes are reflected to
|
||||
the Genode API in a clean way and Genode processes become able to respond to
|
||||
terminating Genode child processes.
|
||||
|
||||
|
||||
OKL4
|
||||
====
|
||||
|
||||
The audio stub driver has been removed from OKLinux. Because of the changed
|
||||
'Audio_out::Session' interface, we needed to decide on whether to adapt the
|
||||
OKLinux stub driver to the changed interface or to remove the stub driver.
|
||||
Given the fact that OKLinux is not actively used, we decided for the latter.
|
||||
@@ -1,943 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 13.05
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
With Genode 13.05, we have diverged quite a bit from the feature-laden plans
|
||||
laid out in our [http://genode.org/about/road-map road map] as we realized
|
||||
that consolidating and optimizing the current feature set will have a more
|
||||
sustainable effect than functional enhancements at this point. In particular,
|
||||
we addressed the problem that the ever growing diversity of platforms imposes
|
||||
on the quality and coverage of testing. We also desired to extend our
|
||||
systematic testing efforts to real hardware platforms, and to have a mechanism
|
||||
for detecting performance regressions. Section
|
||||
[Automated quality-assurance testing] details how we approached these
|
||||
challenges, and how we went on analyzing Genode's network performance in
|
||||
particular.
|
||||
|
||||
That said, we haven't completely restrained ourself from implementing new
|
||||
features. Closely related to test automation but very useful in other
|
||||
situations, we improved the terminal infrastructure in order to enable the
|
||||
interactive use of dynamic system scenarios in headless situations. Section
|
||||
[Terminal infrastructure] introduces a new command-line interface for managing
|
||||
Genode subsystems.
|
||||
|
||||
With regard to platform support, the current release follows up on the
|
||||
hardware support added in the previous releases. For Samsung Exynos-5-based
|
||||
platforms, drivers for USB-3, fast-ethernet networking, gigabit networking,
|
||||
eMMC, and SATA have been added. For Freescale i.MX53-based devices, new
|
||||
drivers for display, touchscreen, and GPIO have become available. The
|
||||
OMAP4 display driver has been enhanced to cover both LCD displays and HDMI.
|
||||
Our custom base-hw kernel has been enabled on the Raspberry Pi
|
||||
board. Finally, Linux/ARM was added to accompany Linux/x86 as a fully usable
|
||||
Genode base platform.
|
||||
|
||||
|
||||
Automated quality-assurance testing
|
||||
###################################
|
||||
|
||||
One of the greatest challenges of the Genode OS Framework is preventing
|
||||
regressions in the face of the growing number of supported platforms.
|
||||
The challenge stems from the fact that the space of Genode scenarios grow
|
||||
two-dimensional. On one axis, the software stack on top of Genode gets more
|
||||
and more complex, which calls for contiguous testing. On the other axis, there
|
||||
is a growing number of kernel and hardware platforms to support.
|
||||
In principle, there are even more dimensions, for example the diversity
|
||||
of tool chains or the diversity of the OS used on the development machine.
|
||||
Luckily, the problem of tool-chain diversity could be mitigated with the
|
||||
introduction of the Genode tool chain since version 11.11, which was a huge
|
||||
relief. However, the mentioned two dimensions cannot be avoided. Because
|
||||
manual testing of manifold scenarios of component compositions on top of many
|
||||
different kernels became infeasible, we automated the task of building and
|
||||
testing years ago.
|
||||
|
||||
The automated builder checks out the staging branch of Genode, prepares
|
||||
the repositories that integrate 3rd-party code, and builds the software
|
||||
for 12 different kernel/platform combinations. Not all 3rd-party software
|
||||
packages are built for each combination though. But we make sure that each
|
||||
piece of software is exposed to different combinations of CPU architectures
|
||||
and kernels.
|
||||
|
||||
The build test is accompanied with automated runtime tests of various
|
||||
run scripts on Qemu. Each run script listed in 'tool/autopilot.lst' is
|
||||
executed on each kernel using the autopilot tool. The tests range from
|
||||
stimulating low-level mechanisms (such as signal, timer, and ldso) to complex
|
||||
scenarios (such as testing networking with L4Linux, or running Noux).
|
||||
|
||||
Both build and runtime tests are executed daily. If any of the
|
||||
tests fail, the Genode developers receive a notification email.
|
||||
Once all tests are passed, the staging branch can be merged into the master
|
||||
branch. This way, we spare the users of Genode to deal with intermediate
|
||||
problems introduced in the staging branch.
|
||||
|
||||
The build and runtime tests have become a fundamental tool for our
|
||||
development work. With the growing variety of real hardware
|
||||
(as opposed to hardware emulated via Qemu), however, our existing solution
|
||||
was falling short. Even though our tests confirm that Genode is running
|
||||
happily on Qemu, they won't help us to detect regressions in our device
|
||||
drivers for non-Qemu hardware such as Pandaboard, Arndale, or modern PC
|
||||
hardware. Furthermore, we are increasingly focussing on performance
|
||||
considerations. In order to be a viable OS platform, Genode does not only need
|
||||
to be able to do networking, but networking performance must be on par with
|
||||
mainstream OSes. This raises the new challenge to extend our
|
||||
continuous-testing tools to become continuous-benchmarking tools. The ultimate
|
||||
goal is to monitor the performance of Genode on real hardware over long
|
||||
periods of development.
|
||||
|
||||
In this release cycle, we attacked this problem in two steps. First, we
|
||||
enabled Genode's run tool to target not only Qemu but real hardware, with the
|
||||
premise that existing run scripts must not be changed. The second step is the
|
||||
creation of new run scripts that perform benchmarks in an automated fashion.
|
||||
By aggregating the results of this automatically executed benchmarks, we can
|
||||
correlate performance effects with commits in our code repository.
|
||||
|
||||
|
||||
Targeting real hardware via the run tool
|
||||
========================================
|
||||
|
||||
In the following, we briefly describe the procedure to execute run scripts
|
||||
on native hardware, for both Intel-based x86 machines and ARM-based platforms.
|
||||
|
||||
|
||||
TFTP boot x86
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The following description uses NOVA as an example to illustrate the usage.
|
||||
Other base platforms are supported as well and can be configured analogously.
|
||||
|
||||
[http://os.inf.tu-dresden.de/~us15/pulsar/ - Pulsar] is a tiny boot loader
|
||||
that uses PXE to fetch boot images via TFTP over the network. On the x86
|
||||
architecture, Genode supports the automatic generation of Pulsar configuration
|
||||
files, which can be placed directly onto a TFTP server. Genode can be booted
|
||||
via Pulsar using the following steps:
|
||||
|
||||
* On the x86 test machine, enable "PXE boot feature" in the BIOS.
|
||||
* When booting, the machine will look for a DHCP server announcing a TFTP server.
|
||||
So you need to make sure to have both the DHCP server and the TFTP server
|
||||
configured such that the 'pulsar' binary will be loaded as PXE binary.
|
||||
* After the PXE BIOS of the test machine has loaded and started the pulsar
|
||||
binary, Pulsar will look on the TFTP server for a file called
|
||||
'config-XX-XX-XX-XX-XX-XX', where the sequence of 'XX' corresponds to the
|
||||
MAC address of the test machine.
|
||||
For example, if the MAC of the network card is 01:02:03:04:05:06, Pulsar
|
||||
would request a file called 'config-01-02-03-04-05-06'.
|
||||
* Using this configuration file, we direct Pulsar to the configuration
|
||||
generated by the run tool. I.e., it should look as follows
|
||||
! root /tftpboot/nova
|
||||
! config config-00-00-00-00-00-00
|
||||
The lines above tell pulsar to load another config file, which contains the
|
||||
actual configuration. To instruct the run script to actually generate the
|
||||
'config-00-00-00-00-00-00' file, set the following environment variables in
|
||||
your shell prior executing the run script:
|
||||
! export PXE_TFTP_DIR_BASE=/tftpboot
|
||||
! export PXE_TFTP_DIR_OFFSET=/nova
|
||||
|
||||
The two-staged configuration of Pulsar may look overly complicated at first
|
||||
sight but has the benefit that the run tool does not need to know the MAC
|
||||
address of the test machine in order to generate the Pulsar configuration
|
||||
file.
|
||||
|
||||
* Create a symbolic link '/tftpboot/nova' pointing to the corresponding
|
||||
Genode build directory.
|
||||
|
||||
* The next time 'make run/printf' is invoked,
|
||||
the run script will generate the 'config-00-00-00-00-00-00' in
|
||||
'/tftpboot/nova'.
|
||||
|
||||
* When rebooting the test machine, it will load and start the printf test.
|
||||
|
||||
|
||||
TFTP boot using U-Boot
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Configure your U-Boot boot loader to load the images via TFTP.
|
||||
|
||||
The remainder of the procedure is similar to the description for x86 above.
|
||||
On ARM platforms, the run tool automatically generates the uBoot image and
|
||||
creates a symbolic link into the TFTP directory.
|
||||
|
||||
* Pandaboard:
|
||||
|
||||
! export PXE_TFTP_DIR_BASE=/tftpboot
|
||||
! export PXE_TFTP_DIR_OFFSET=/panda
|
||||
! ln -s <genode-build-dir> /tftpboot/panda
|
||||
! RUN_OPT="--target uboot" make run/printf
|
||||
|
||||
* Arndale board:
|
||||
|
||||
! export PXE_TFTP_DIR_BASE=/tftpboot
|
||||
! export PXE_TFTP_DIR_OFFSET=/arndale
|
||||
! ln -s <genode-build-dir> /tftpboot/panda
|
||||
! RUN_OPT="--target uboot" make run/printf
|
||||
|
||||
|
||||
|
||||
Output and reset with Intel's AMT
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Most modern x86-based machines lack a COM port, which is normally used for
|
||||
kernel debug messages as well as LOG messages printed by Genode's core.
|
||||
However, Intel's Advanced Management Technology (AMT) can be used to obtain
|
||||
the serial output of the test machine and to reset the test machine. To use
|
||||
AMT with Genode's run tool, install the 'amtterm' package (version 1.3 is
|
||||
known to work well) and set the following environment variables, specifying
|
||||
the IP address of the test machine and the AMT password.
|
||||
|
||||
! export AMT_TEST_MACHINE_IP=XXX.XXX.XXX.XXX
|
||||
! export AMT_TEST_MACHINE_PWD=XXXXXXXXX
|
||||
|
||||
Via setting the RUN_OPT environment variable, we instruct the run tool to use
|
||||
AMT instead of Qemu. The following command will reset the test machine, the test
|
||||
machine will load the binaries of the printf run script via PXE, and we will be
|
||||
able to see the serial output of the test machine through Intel's AMT Serial
|
||||
Over Line (SOL),
|
||||
|
||||
! RUN_OPT="--target amt" make run/printf
|
||||
|
||||
|
||||
Output via a COM port (UART)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If the x86 test machine, Pandaboard or Arndale test board is connected
|
||||
via UART, the run tool can use a specified command to interact with it.
|
||||
|
||||
For example, if the UART interface of the test machine is connected directly
|
||||
to the host machine at /dev/ttyUSB3, and the picocom tool is available,
|
||||
the following command can be used to establish a connection:
|
||||
|
||||
! RUN_OPT="--target serial --serial-cmd \"picocom -b 115200 /dev/ttyUSB3\"" make run/printf
|
||||
|
||||
Alternatively, if the board is connected to some remote machine, which exports
|
||||
the corresponding serial line via TCP/IP, the socat tool can be used for
|
||||
communicating with the remote test machine:
|
||||
|
||||
! RUN_OPT="--target serial --serial-cmd \"socat - tcp:10.0.0.1:2000\"" make run/printf
|
||||
|
||||
|
||||
Reset via a IP power plug NETIO-230B from Koukaam
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
At Genode Labs, we use a NETIO-230B power plug to automate power-cycling ARM
|
||||
boards. This power plug can be controlled over the network. For example, if
|
||||
the Pandaboard is connected to power port 3, the following command will
|
||||
automatically turn on the board when the run script is started:
|
||||
|
||||
! RUN_OPT="--target uboot --target reset --reset-port 2 --reset-ip 10.0.0.1 --reset-user admin --reset-passwd secret" make run/printf
|
||||
|
||||
The '--target reset' option can be combined with '--target uboot' to
|
||||
instruct the run tool to boot via TFTP (as described above) and take care
|
||||
of power cycling. When the run script has finished, the specified port
|
||||
will be automatically switched off by the run tool.
|
||||
|
||||
Of course, the IP address settings, as well as the actual user name and
|
||||
password, to access the NETIO-230B power plug, have to be adjusted accordingly.
|
||||
|
||||
|
||||
Automated benchmarking
|
||||
======================
|
||||
|
||||
With the '--target' features added to the run tool, the road is paved to
|
||||
obtain benchmark results in an automated fashion. Currently, we are most
|
||||
interested in exploring the network-performance characteristics of Genode.
|
||||
|
||||
Network performance can be explored at different levels. We started with
|
||||
looking at raw driver performance, then looked at the overhead of separating
|
||||
the network application from the device driver (and thereby introducing
|
||||
inter-process communication overhead), and finally explored the effects
|
||||
of the TCP/IP stack.
|
||||
|
||||
For pursuing the packet-level performance measurements, we crafted a library
|
||||
called 'net-stat', which contains the application logic of a low-level
|
||||
benchmark operating at network-packet level. This library has been
|
||||
successively incorporated into the 'dde_ipxe' NIC driver and the 'usb_drv'
|
||||
(NIC driver via ethernet-over-USB) to measure the raw driver performance
|
||||
without any microkernel overhead or TCP/IP protocol overhead.
|
||||
|
||||
To see the influence of the inter-process communication, namely the
|
||||
packet-stream interface employed by Genode's NIC-session interface,
|
||||
we implanted the same net-stat library into a NIC-session client. This
|
||||
experiment enables us to compare the operation of the NIC driver
|
||||
with the operation of a NIC driver separated from the NIC
|
||||
application.
|
||||
|
||||
The raw networking tests can be executed automatically using the set
|
||||
of 'network_test_nic*.run' scripts located at 'os/run'.
|
||||
The scenario sends raw ethernet packets from the host machine to the
|
||||
target machine. Three tests are provided:
|
||||
The 'network_test_nic_raw.run' test measures the net-stat-instrumented driver
|
||||
(of usb_drv and net_drv respectively) to observe the raw receive performance.
|
||||
The 'network_test_nic_raw_client.run' test implements the benchmark in a
|
||||
NIC-session client connected to the NIC driver running as a separate
|
||||
component whereas the NIC driver is not instrumented.
|
||||
The 'network_test_nic_raw_bridge_client.run' test further adds a NIC bridge
|
||||
in-between the driver and the NIC-session client.
|
||||
|
||||
In addition to analyzing the performance on a low level, we investigated
|
||||
the effects of TCP/IP for the application performance. This topic is
|
||||
covered in more detail in Section [TCP/IP performance].
|
||||
|
||||
|
||||
Terminal infrastructure
|
||||
#######################
|
||||
|
||||
Closely related to the quality-assurance measures detailed in the previous
|
||||
section, there is the arising need to interact with increasingly complex system
|
||||
scenarios in headless settings. In particular when executing tests remotely on a
|
||||
development board, manual user-interaction via a GUI
|
||||
becomes impractical. We vastly prefer a low-bandwidth textual interface
|
||||
in such situations. But how should a textual user interface for dynamic
|
||||
systems comprised of many components look like? This is particularly difficult
|
||||
because most development boards are equipped with merely a single UART
|
||||
connector.
|
||||
|
||||
On a normal Genode system, the UART connector is typically used
|
||||
by the kernel debugger to print debugging output, or for the interactive
|
||||
use of a debugger. This leaves no interface for interacting with Genode
|
||||
components. So how can we expose complex scenarios, such as concurrently
|
||||
running several instances of Genode subsystems, to the user?
|
||||
Our solution consists of three parts: A pseudo UART driver for Genode
|
||||
that uses the kernel debugger as back end, a terminal-multiplexing
|
||||
facility running on the reference platform, and a command-line based
|
||||
tool for interacting with Genode. By combining those, the user
|
||||
can interact with the kernel debugger, a Genode command line, and the
|
||||
consoles of executed Linux instances over a single serial connection.
|
||||
|
||||
The pseudo UART driver called kdb_uart_drv is a Genode service that
|
||||
implements the 'Uart::Session' interface. Therefore, it can be combined
|
||||
with all components that use the 'Uart::Session' or the 'Terminal::Session'
|
||||
interfaces, for example the Noux runtime environment, the terminal_log
|
||||
service (for displaying LOG messages via the terminal interface), L4Linux, or
|
||||
programs linked against the 'libc_terminal' plugin. The kdb_uart_drv component
|
||||
is located at 'os/src/drivers/uart/kdb'. It does not access a real UART device
|
||||
but rather uses the user-level bindings of the kernel debugger to indirectly
|
||||
read and write data over the UART interface.
|
||||
|
||||
[image kdb_uart_drv 65%]
|
||||
The kdb_uart_drv driver used for sharing one UART among the kernel
|
||||
debugger, core's LOG service, and a terminal client application
|
||||
running on Genode.
|
||||
|
||||
Figure [kdb_uart_drv] illustrates the relationship between the kernel
|
||||
debugger, core's LOG service, and kdb_uart_drv. Because write operations
|
||||
target the kernel debugger directly, core's LOG service gets bypassed. Output
|
||||
written to the kdb_uart_drv will directly appear at the terminal program of
|
||||
the host system. Because kdb_uart_drv has
|
||||
direct access to the host terminal, it can leverage all facilities of the host
|
||||
terminal, in particular various escape sequences for terminal manipulations.
|
||||
For reading from the kernel debugger, there is no way to block for UART input.
|
||||
Hence, the kdb_uart_drv periodically polls for new input with a period of 20
|
||||
milliseconds. If new input is available, the driver reads as many characters as
|
||||
available at once. So the runtime overhead of polling is negligible. To test
|
||||
kdb_uart_drv as individual component, there is a run script provided at
|
||||
'os/run/kdb_uart_drv.run'.
|
||||
|
||||
Thanks to kdb_uart_drv, both the kernel debugger and Genode can
|
||||
share one single UART connection. So we have a principal way to let the user
|
||||
interact with a Genode component that uses the 'Terminal::Session' interface.
|
||||
However, typical system scenarios should accommodate not just a single program
|
||||
but multiple Linux instances and native Genode applications simultaneously,
|
||||
each requiring a dedicated 'Terminal::Session'. Hence, we need a way to
|
||||
multiplex the 'Terminal::Session' interface between those clients. Our
|
||||
multiplexing solution comes in the form of a component called terminal_mux,
|
||||
which we just introduced in the
|
||||
[http://genode.org/documentation/release-notes/13.02#New_terminal_multiplexer - previous release].
|
||||
It uses a single terminal connection to implement a text-based user interface
|
||||
to multiple virtual terminal consoles.
|
||||
|
||||
[image terminal_mux 40%]
|
||||
Operation of the terminal_mux service.
|
||||
|
||||
Figure [terminal_mux] depicts the basic functioning of this component. For
|
||||
terminal_mux clients, the service implements the Linux terminal capabilities.
|
||||
For doing that, it shares large parts of the implementation of the existing
|
||||
Genode terminal program. For each client, terminal_mux renders the client
|
||||
output into a client-specific text-screen buffer. So any number of clients can
|
||||
perform output on terminal_mux concurrently. According to the selection by
|
||||
the user, terminal_mux periodically translates one client buffer (the
|
||||
foreground buffer) to escape sequences as understood by the host terminal. This
|
||||
translation is performed using the ncurses library. The user can pick the
|
||||
foreground buffer using an interactive menu that can be activated via the
|
||||
keyboard shortcut _Control-x_.
|
||||
|
||||
By combining kdb_uart_drv with terminal_mux, we created a flexible way
|
||||
to let the user interact with many Genode applications. The last part
|
||||
missing for a real dynamic system is a text-based command interface to
|
||||
start and stop Genode subsystems. This functionality is provided by the
|
||||
new cli_monitor component located at 'os/src/app/cli_monitor'.
|
||||
It uses the 'Terminal::Session' interface to present a simple interactive
|
||||
command line with commands for starting and stopping Genode subsystems,
|
||||
entering the kernel debugger, and showing status information. It provides
|
||||
tab completion and inline help to make it easily explorable. The cli_monitor
|
||||
component is integrated in the scenario of the 'terminal_mux.run' script
|
||||
mentioned above. Because cli_command is a 'Terminal::Session' client, it can
|
||||
be interfaced with terminal_mux. This composition is illustrated by Figure
|
||||
[uart_overview].
|
||||
|
||||
[image uart_overview 100%]
|
||||
Overview of the terminal infrastructure as employed in the
|
||||
demonstration scenario.
|
||||
|
||||
Note that in some situations, e.g., when killing subsystems, the kernel, core,
|
||||
or the init process may print LOG messages. Because those messages are
|
||||
naturally not routed through terminal_log, they will interfere with the
|
||||
operation of terminal_mux and thereby result in visible inconsistencies.
|
||||
Pressing _Control-x_ will clear such artifacts. This will bring up the
|
||||
terminal_mux menu, which implicitly triggers the redraw of the entire terminal.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
The current release comes with incremental improvements of the MMIO framework
|
||||
API and a new utility to ease the synchronized accesses to otherwise
|
||||
unsynchronized class interfaces.
|
||||
|
||||
:MMIO framework improvements:
|
||||
|
||||
For native Genode device drivers, we consistently use our
|
||||
[http://genode.org/documentation/release-notes/12.02#MMIO_access_framework - MMIO framework API].
|
||||
These utilities help us to safeguard the access to individual bit fields of
|
||||
memory-mapped device registers and cleanly separate the declaration of device
|
||||
registers from the driver logic. During the increased use of the API, we
|
||||
observe that the 'Genode::Mmio' class template operates mostly on addresses
|
||||
that belong to dataspaces provided by core's IO_MEM service. Those dataspaces
|
||||
are typically obtained via the 'Attached_io_mem_dataspace' convenience class,
|
||||
which requests the dataspace and attaches it to the local address
|
||||
space at once. To further reduce repetitive code, we introduced the new
|
||||
'Attached_mmio' class (located at 'os/attached_mmio.h'), which handles the
|
||||
common case of making the content of a IO_MEM dataspace available through
|
||||
register definitions using the 'Mmio' utility. Furthermore, the MMIO framework
|
||||
API has been enhanced with a variant of the 'Mmio::wait_for()' function that
|
||||
waits for whole register values rather than bits.
|
||||
|
||||
:Synchronized interfaces:
|
||||
|
||||
Most Genode programs are multi-threaded, which makes the proper use of locks
|
||||
inevitable. For most data structures, Genode does not implicitly manage the
|
||||
locking but expects the user of the data structures to know what he is doing.
|
||||
This way, we can avoid the locking overhead if a data structure is known to be
|
||||
accessed by a single thread only. If accessed by multiple threads, we usually
|
||||
wrap such data structures within an accessor interface that takes care of the
|
||||
locking. For example, for the 'Allocator' interface, there exists a
|
||||
corresponding 'Synchronized_allocator' interface wrapper. This technique works
|
||||
well as long as the number of interfaces is low -- as is the case for Genode's
|
||||
base API. However, as the wrapper code is for the most part pretty dumb, we'd
|
||||
like to avoid it. Also, when using the Genode API to implement programs on
|
||||
top, we do not anticipate manually creating such accessor wrappers. To ease
|
||||
the creation of synchronized interfaces, we introduced the new
|
||||
'Synced_interface' class template. It takes a pointer to an existing interface
|
||||
and a lock as arguments. An instance of a 'Synced_interface' provides
|
||||
synchronized access to the wrapped interface functions via the 'operator ()'.
|
||||
Because the 'Synced_interface' does not provide any means to obtain the
|
||||
unsynchronized version of the interface, once wrapped, the interface cannot be
|
||||
misused by subsystems that get handed over a reference to a
|
||||
'Synced_interface'. To see how to employ this utility, please have a look of
|
||||
how we realize the synchronization within the Vancouver VMM (in particular,
|
||||
the access to the motherboard).
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
TCP/IP performance
|
||||
==================
|
||||
|
||||
On the course of the automated benchmarking described in Section
|
||||
[Automated quality-assurance testing], we conducted the following steps
|
||||
to enable benchmarks and to improve performance at the TCP/IP level.
|
||||
|
||||
At application level, we desire to compare our network performance with the
|
||||
performance on GNU/Linux using commodity benchmarks. For this reason, netperf
|
||||
has been ported to run as native Genode using the lwIP stack. This benchmark
|
||||
allows us to systematically compare our results with those achieved by Linux.
|
||||
The port of netperf is available in the ports repository.
|
||||
|
||||
In addition to running a commodity benchmark, we pursue synthetic benchmarks
|
||||
that model the behaviour of typical application scenarios, for example, a
|
||||
web server that receive many small requests. This is where the added
|
||||
'test-ping_client' and 'test-ping_server' tests come into play. The test
|
||||
is located at 'libports/src/test/lwip/pingpong'. It is used by the
|
||||
series of 'network_test_*.run' scripts located at 'libports/run'. The
|
||||
run scripts exercise the test in various scenarios and thereby allow us to
|
||||
systematically explore the impact of the libc and NIC bridge on the
|
||||
application performance.
|
||||
|
||||
# Using raw lwIP without the libc
|
||||
# Like the first test, but with an instance of the NIC bridge in between the
|
||||
test program and the driver.
|
||||
# Using lwIP with the libc socket bindings
|
||||
# Like the third test, but with NIC bridge added
|
||||
|
||||
To keep track of the lwIP development more closely, we switched to the
|
||||
Git version of lwIP instead of using a source snapshot.
|
||||
|
||||
Furthermore, we incorporated "window scaling" support (RFC 1323) into our
|
||||
version of lwIP as we identify the TCP window size as a limiting factor
|
||||
of the TCP throughput achieved via lwIP.
|
||||
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
We added support for "resolv" functionality to the libc_lwip_nic_dhcp plugin.
|
||||
Normally, a file called 'resolv.conf' is expected to be located at '/etc'.
|
||||
On Genode, however, we don't have a global file system, which makes this
|
||||
way of configuration cumbersome. To ease the provision of a simple default
|
||||
'resolv.conf' configuration, the plugin hands out the file as a virtual file.
|
||||
The configuration automatically provides the DNS server address acquired by
|
||||
lwIP via DHCP. If, for some reason, this policy is not desired, the feature
|
||||
can be disabled via:
|
||||
|
||||
! <libc resolv="no" />
|
||||
|
||||
*Note that the configuration of the C runtime has changed*
|
||||
|
||||
To foster consistency of the libc configuration, we moved the static
|
||||
network "interface" attributes into the 'libc' XML node. A new configuration
|
||||
of static networking would look as follows:
|
||||
|
||||
! <libc ip_addr="..." netmask="..." gateway="..." />
|
||||
|
||||
|
||||
Terminal
|
||||
========
|
||||
|
||||
Genode's custom terminal implementation has been improved to better handle
|
||||
widely used escape sequences.
|
||||
The new version is able to handle two-argument SGR commands with
|
||||
attribute/color arguments in any order, and supports the ED, EL0, and
|
||||
CUB commands.
|
||||
|
||||
Because the terminal classes do not rely on any 3rd-party code, they
|
||||
have been moved to the os repository at 'os/include/terminal'. This way,
|
||||
we can use those classes by other components of the os repository such
|
||||
as the new CLI monitor.
|
||||
|
||||
|
||||
FS-LOG service
|
||||
==============
|
||||
|
||||
Using the new FS-LOG service residing at 'libports/os/src/server/fs_log', log
|
||||
messages of different processes can be redirected to files on a file-system
|
||||
service. The assignment of processes to files can be expressed in the
|
||||
configuration as follows:
|
||||
|
||||
! <start name="fs_log">
|
||||
! <resource name="RAM" quantum="2M"/>
|
||||
! <provides><service name="LOG"/></provides>
|
||||
! <config>
|
||||
! <policy label="noux" file="/noux.log" />
|
||||
! <policy label="noux ->" file="/noux_process.log" />
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
In this example, all messages originating from the noux process are directed
|
||||
to the file '/noux.log'. All messages originating from children of the noux
|
||||
process end up in the file '/noux_process.log'.
|
||||
|
||||
|
||||
Liquid FB
|
||||
=========
|
||||
|
||||
Liquid FB is a virtual framebuffer service that uses the nitpicker GUI
|
||||
server as back end. The virtual framebuffer is presented as a movable
|
||||
window with a title bar. Until now, we used it primarily for demonstration
|
||||
purposes, i.e., it is part of Genode's default demo scenario.
|
||||
|
||||
Thanks to our forthcoming adaptation of Qt5 to Genode, which requires a
|
||||
very similar solution to interface Qt5's platform-abstraction layer (QPA) to
|
||||
Genode, liquid FB got in the spotlight of this release.
|
||||
|
||||
First, we took the chance to update its configuration parameters to
|
||||
become more consistent with similar services such as nit_fb. As liquid_fb was
|
||||
originally conceived at a time when Genode's XML parser did not support
|
||||
XML attributes, its configuration syntax used to be a bit arcane. This
|
||||
has changed now. Apart from this cosmetic refinement, there are two prominent
|
||||
new features: Support for resizing the framebuffer window with the
|
||||
mouse and support for dynamic reconfiguration of the virtual framebuffer
|
||||
via Genode's configuration mechanism.
|
||||
|
||||
When the liquid FB window gets resized by the user, the virtual framebuffer
|
||||
emits a mode-changed signal to its client, which, in turn can handle the
|
||||
event by re-acquiring the frame-buffer dataspace.
|
||||
|
||||
The added support for dynamic reconfiguration allows for changing the
|
||||
properties of a liquid FB instance via Genode's configuration mechanism.
|
||||
For example, the window position and size can be manipulated this way.
|
||||
|
||||
Furthermore, two new configuration options have been added. The
|
||||
'resize_handle' option shows or hides the resize handle widget at the
|
||||
lower-right window corner (by default, it is hidden). The 'decoration' option
|
||||
defines whether window decorations should be visible (default is yes). Both
|
||||
options can have the values "on" or "off".
|
||||
|
||||
|
||||
3rd-party libraries
|
||||
###################
|
||||
|
||||
The following 3rd-party libraries have been added or updated:
|
||||
|
||||
* To complement libSDL, we have added ports of SDL_ttf, SDL_image,
|
||||
SDL_image, SDL_mixer, and SDL_loadso. Those additions to libSDL
|
||||
are used by popular libSDL-based applications such as Tuxpaint.
|
||||
They are now available at the libports repository.
|
||||
|
||||
* GNU FriBidi 0.19.5 added to the libports repository
|
||||
|
||||
* Qt4 updated to version 4.8.4
|
||||
|
||||
* zlib updated to version 1.2.8
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Unified driver names
|
||||
====================
|
||||
|
||||
The growing diversity of supported hardware platforms calls for improved
|
||||
conventions of how to name device drivers. Otherwise, run scripts that are
|
||||
meant to support a wide range of platforms will eventually become more
|
||||
and more complicated due to platform-dependent conditional configuration
|
||||
snippets. For example, the default framebuffer drivers of the respective
|
||||
platforms used to be called "vesa_drv" (for x86), "omap4_fb_drv", or "pl11x_drv".
|
||||
In order to support the different platforms, run scripts that were otherwise
|
||||
platform-agnostic had to explicitly deal with those differences.
|
||||
|
||||
To solve this issue, we introduced a generic SPEC values for device types, for
|
||||
which a default driver is expected to exist. If a platform features a
|
||||
framebuffer driver, it includes the SPEC value "framebuffer". On each
|
||||
platform, the default driver for the respective device has the same name. So
|
||||
each of "vesa_drv", "pl11x_drv", and "omap4_fb_drv" had been renamed to
|
||||
"fb_drv". This is possible because the use of those drivers is mutually
|
||||
exclusive.
|
||||
|
||||
The same convention has been applied to GPIO drivers as well. The
|
||||
corresponding SPEC value is called "gpio". The driver binaries are called
|
||||
"gpio_drv".
|
||||
|
||||
|
||||
ATAPI
|
||||
=====
|
||||
|
||||
LBA48 support has been added to the ATAPI driver. Thanks to Ivan Loskutov!
|
||||
|
||||
|
||||
KDB UART driver for L4/Fiasco and Fiasco.OC
|
||||
===========================================
|
||||
|
||||
The new KDB UART driver at 'os/src/drivera/uart/kdb' uses the kernel debugger
|
||||
console as backend for input and output. This is useful in the case that only
|
||||
one UART is available as described in Section [Terminal infrastructure].
|
||||
Examples for using the kdb_uart_drv are available in the form of the run scripts
|
||||
'ports-foc/run/l4linux.run' and 'os/run/kdb_uart_drv.run'.
|
||||
|
||||
|
||||
Revised GPIO session interface
|
||||
==============================
|
||||
|
||||
The original design of the GPIO session interface enabled the client of a
|
||||
single session to interact with any number GPIO pins. Each function of the
|
||||
interface took a GPIO number as first argument, which addressed the GPIO pin.
|
||||
|
||||
To simplify the interface and to enable fine-grained GPIO-assignment policies,
|
||||
the interface has been changed to provide access to a single GPIO pin per
|
||||
session only. At session creation time, the client specifies a single GPIO
|
||||
pin, to which the session refers. This information can be evaluated for the
|
||||
session routing. So access-control policies can be easily implemented per GPIO
|
||||
pin. The server stores the pin as part of the session context and implicitly
|
||||
uses the pin for operations on the session interface.
|
||||
|
||||
Furthermore, a generic driver interface for GPIO-class-device drivers
|
||||
has been introduced. The new interface at 'os/include/gpio' alleviates the
|
||||
need to implement the boilerplate code to interface the driver with Genode.
|
||||
The existing GPIO drivers for OMAP4 and i.MX53 are the first beneficiaries of
|
||||
these changes.
|
||||
|
||||
|
||||
Exynos 5 SoC
|
||||
============
|
||||
|
||||
After principally enabling the Exynos 5 SoC platform in the previous
|
||||
release, we moved on with extending the device-driver coverage of this SoC. In
|
||||
particular, we addressed USB networking, XHCI (USB-3), Gigabit networking over
|
||||
USB-3, eMMC, and SATA.
|
||||
|
||||
The development of those device drivers follows our rationale that guided our
|
||||
[http://genode.org/documentation/articles/pandaboard - previous work on the OMAP4 platform].
|
||||
For the USB driver, we employed the device-driver-environment (DDE) approach
|
||||
for reusing the Linux USB stack and the host controller drivers. In contrast,
|
||||
the eMMC and SATA drivers are built as genuine Genode drivers with no
|
||||
3rd-party code used.
|
||||
|
||||
Technically, the addition of Exynos-5 support to our USB driver was
|
||||
an evolutionary step. It required us to add the corresponding EHCI
|
||||
controller and to supply a few additions to the device-driver
|
||||
environment. To simplify the driver, we decided to let the driver
|
||||
rely on the platform initialization as performed by the U-Boot boot
|
||||
loader. Since the initialization is performed during the boot process
|
||||
already, there is no need to do this work twice. Because the platforms
|
||||
supported by the USB driver become more and more diverse, we re-organized the
|
||||
internal structure of the 'dde_linux' repository to keep those platforms well
|
||||
separated. Furthermore, we reworked the memory management of the USB driver to
|
||||
improve the utilization of the available RAM. The new solution employs Genode's
|
||||
concept of managed dataspaces to manage a part of the local address-space
|
||||
layout manually. This helps us to implement a fast translation of driver-local
|
||||
virtual addresses to physical addresses as needed for issuing DMA requests.
|
||||
|
||||
The eMMC driver builds upon our protocol implementation for the SD-card
|
||||
protocol, which was originally developed for the OMAP4 SD-card driver.
|
||||
Because we kept the SD-card protocol implementation well separated
|
||||
from the host-controller driver, it was possible to leverage parts of our
|
||||
existing work for the eMMC driver. Because the eMMC protocol is an extension
|
||||
of the SD-card protocol, however, we needed to enhance the protocol
|
||||
implementation accordingly. The extension comprises support for the
|
||||
MMC_SEND_EXT_CSD, MMC_SEND_OP_COND, and STOP_TRANSMISSION commands as well as
|
||||
the MMC detection. The host controller driver was implemented from scratch
|
||||
with the help of I/O access traces gathered from instrumenting the U-Boot boot
|
||||
loader and the Linux kernel. The driver operates the eMMC in high-speed, 8-bit
|
||||
mode at 52 MHz using DMA. The implementation can be found at
|
||||
'os/src/drivers/sd_card/exynos5'.
|
||||
|
||||
The initial version of our new SATA driver for Exynos 5 has been implemented
|
||||
from the ground up. Even though it is at an early stage, it has been
|
||||
successfully tested with a UDMA-133 disk, e.g., our generic block test
|
||||
is passed and the disk can be attached as a block device to an instance of
|
||||
L4Linux.
|
||||
|
||||
|
||||
Freescale i.MX SoC
|
||||
==================
|
||||
|
||||
The support for the Freescale i.MX53 SoC has been extended by a number of
|
||||
devices. All drivers reside in the os repository under the 'os/src/drivers'
|
||||
subdirectory.
|
||||
|
||||
The general-purpose I/O (GPIO) driver located at 'gpio/imx53' implements the
|
||||
revised GPIO-session interface.
|
||||
|
||||
The i.MX53 input driver provides support for the input devices featured on the
|
||||
i.MX53 SABRE tablet. The tablet uses an Egalaxy touchscreen and Freescale's
|
||||
MPR121 capacitative touch buttons. Both are supported by the new driver. The
|
||||
driver is located at 'input/imx53'.
|
||||
|
||||
The new framebuffer driver for the i.MX53 quick-start board (QSB) as well as
|
||||
the SABRE tablet comes with special support for using the
|
||||
hardware overlay feature provided by the i.MX53 image processing unit (IPU)
|
||||
Access to the overlay is implemented via an IPU-specific extension
|
||||
of the framebuffer-session interface. To combine the driver well with
|
||||
nitpicker using alpha-channels, optional support for double-buffering
|
||||
is provided. The driver is located at 'framebuffer/imx53'.
|
||||
|
||||
As an abstraction of platform features that need to be accessed by
|
||||
multiple drivers, a so-called platform driver has been introduced.
|
||||
The platform driver safeguards the access to global resources such
|
||||
as clocks and system-configuration bits. It can be found at 'platform/imx53'.
|
||||
|
||||
|
||||
OMAP4 SoC
|
||||
=========
|
||||
|
||||
The OMAP4 framebuffer driver used to support HDMI only, which was used
|
||||
for connecting a display to the Pandaboard. To make the driver usable on
|
||||
phones and tablets, the driver has been enhanced to support LCD output. Thanks
|
||||
to Alexander Tarasikov for the patch and the insightful story about
|
||||
[http://allsoftwaresucks.blogspot.com/2013/05/porting-genode-to-commercial-hardware.html - porting Genode to the B&N Nook HD+ tablet]!
|
||||
|
||||
|
||||
USB
|
||||
===
|
||||
|
||||
The USB driver of the 'dde_linux' repository has received substantial
|
||||
improvements both feature-wise and under the hood.
|
||||
|
||||
First and foremost, the Linux device-driver environment, on which the
|
||||
driver is based on, has been updated from kernel version 3.2 to version
|
||||
3.9 as the latter version includes drivers for recent host controllers
|
||||
such as DWC3 out of the box.
|
||||
|
||||
DWC3 is the host controller employed on the Exynos-5-based
|
||||
Arndale platform for USB 3. We added the support needed to operate this
|
||||
controller in XHCI mode and added support for Gigabit networking through
|
||||
the ASIX AX88179 Gigabit-Ethernet Adapter as well as USB storage support.
|
||||
|
||||
Apart from extending the device-driver coverage, we revised the driver
|
||||
internally. The back-end allocators for DMA buffers and normal memory have been
|
||||
rewritten to allocate RAM more sparingly. Furthermore, we enabled the USB
|
||||
driver for 64-bit x86 machines and improved the support for HID keyboards,
|
||||
including the application of quirks to cherry keyboards.
|
||||
|
||||
*Note the change of the USB configuration*
|
||||
|
||||
With the addition of XHCI, the USB driver supports a growing number
|
||||
of host controllers. In some situations, it is desirable to constrain the
|
||||
driver to a subset of controllers only. For example, on the Arndale platform,
|
||||
we desire to use a dedicated USB stack for XHCI, which operates completely
|
||||
independent from the USB stack accessing USB-2. This way, gigabit networking
|
||||
over USB-3 won't interfere with the operation of USB-2. To make this
|
||||
possible, we added new configuration options to the USB driver.
|
||||
With the new scheme, host controllers must be explicitly enabled in the
|
||||
configuration. Supported config attributes are: 'uhci', 'ehci', and 'xhci'.
|
||||
For example, a configuration snippet to enable UHCI and EHCI looks as
|
||||
follows:
|
||||
! <config uhci="yes" ehci="yes">
|
||||
|
||||
|
||||
Updated iPXE device-driver environment
|
||||
======================================
|
||||
|
||||
The iPXE device-driver environment was update to the most recent
|
||||
iPXE upstream Git version in order to benefit from upstream improvements
|
||||
of the Intel E1000 NIC driver.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Vancouver VMM on NOVA
|
||||
=====================
|
||||
|
||||
Vancouver is the user-level virtual-machine monitor that accompanies the
|
||||
NOVA hypervisor for hosting unmodified guest operating systems.
|
||||
|
||||
The most active line of development is led by Julian Stecklina at TU Dresden
|
||||
via a fork called Seoul. In contrast to the original version of Vancouver,
|
||||
this fork is open for outside contributions. Hence, it represents an ideal
|
||||
platform for those parties with a stake in Vancouver to collaborate, i.e.,
|
||||
the NUL userland, the NOVA runtime environment of TUD, and Genode.
|
||||
|
||||
In the current state of the transition, the Hip structure from Genode
|
||||
is reused. String functions, which were formerly taken from NUL are now
|
||||
provided by a stripped-down version of the C library called
|
||||
'seoul_libc_support'. The nul/config.h is replaced by just using a constant
|
||||
value in the one place where the file was needed.
|
||||
|
||||
The Genode-specific back ends of Vancouver, as largely introduced with the
|
||||
previous Genode release, have been improved in several respects:
|
||||
|
||||
* CPUID 0x40000000: This instruction is issued by Linux when the KVM
|
||||
guest support is compiled in. We have to return deterministic values to let
|
||||
the Linux kernel survive.
|
||||
|
||||
* Replaced busy thread startup synchronization by proper locking.
|
||||
|
||||
* New locking scheme: We replaced the error-prone manual locking with the
|
||||
use of the freshly introduced 'Synced_interface' for the motherboard and the
|
||||
VCPU dispatcher. Also, all globally visible locks have been removed. They are
|
||||
explicitly passed to subsystems only when needed.
|
||||
|
||||
* Improved PS/2 mouse back-end:
|
||||
The previous version of the PS/2 mouse back end managed mouse-motion
|
||||
events in a strange way, effectively throwing away most information
|
||||
about the motion vector. Furthermore, the tracking of the mouse-button
|
||||
states were missing. So drag-and-drop in a guest OS won't work. The new
|
||||
version fixes those issues. For the transformation of input events to
|
||||
PS/2 packets, the 'Genode::Register' facility is used, which greatly
|
||||
simplifies the code.
|
||||
|
||||
|
||||
L4Linux on Fiasco.OC
|
||||
====================
|
||||
|
||||
We improved the memory management of L4Linux on Genode in two ways.
|
||||
The first improvement is concerned about the upper limit of memory per Linux
|
||||
instance. The corresponding discussion can be found at
|
||||
[https://github.com/genodelabs/genode/issues/414 - issue #414].
|
||||
We changed our L4Re emulation library to match the semantics of the original
|
||||
L4Re more closely. Furthermore, we removed a heuristic in the L4Linux kernel,
|
||||
which assumed that all kernel-local addresses above 0x8000000 refer to device
|
||||
resources. In our version of L4Linux, there exist no MMIO resources. In
|
||||
contrary, the virtual addresses above this addresses are used for normal
|
||||
memory. By removing this artificial restriction with regard to the virtual
|
||||
memory layout of the L4Linux kernel, we can host a larger kernel memory area.
|
||||
|
||||
The second improvement is concerned with the allocation of L4Linux
|
||||
memory at Genode's core. Until now, L4Linux used to allocate its memory
|
||||
as one contiguous RAM dataspace at core's RAM service. Core tries to
|
||||
naturally align the allocation to improve the likelihood for large-page
|
||||
mappings. So a dataspace is likely to be physically located at a
|
||||
power-of-two boundary larger or equal than the dataspace size. For example,
|
||||
the allocation of a 100 MiB RAM dataspace for a Linux instance will
|
||||
be located at a 128 MiB boundary. If multiple of such allocations happen
|
||||
sub-sequentially, this allocation strategy results in 28 MiB gaps between
|
||||
100 MiB dataspaces. This memory cannot be used for large contiguous
|
||||
allocations anymore. So even if the available memory capacity is far
|
||||
larger than 100 MiB, an allocation of a 100 MiB block may fail.
|
||||
To relieve this problem, we weakened the requirement for contiguous memory
|
||||
by assembling L4Linux memory from multiple chunks of small dataspaces.
|
||||
For example, by using a chunk size of 16 MiB, core's best-fit allocator
|
||||
will have a better chance to find a more suited position for allocation
|
||||
when aligning the block to a 16 MiB boundary compared to the allocation
|
||||
of a larger block. Furthermore, slack memory can be used more efficiently
|
||||
because smaller gaps (such as a 20 MiB gap) remain to be usable for L4Linux.
|
||||
The discussion of this topic and the individual patch can be found at
|
||||
[https://github.com/genodelabs/genode/issues/695 - issue #695].
|
||||
|
||||
Furthermore, the L4Linux block driver has been improved to support large
|
||||
partitions.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Raspberry Pi
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Principal support for the Raspberry Pi platform has been added to the base-hw
|
||||
kernel. The popular Raspberry Pi board is based on an ARMv6 Broadcom BCM2835
|
||||
SoC. The current scope of the platform support comprises:
|
||||
|
||||
* IRQ controller driver: Because the interrupt controller uses a cascade of
|
||||
registers, we settled on the following IRQ enumeration scheme.
|
||||
IRQ numbers 0..7 refer to the basic IRQs.
|
||||
IRQ numbers 8..39 refer to GPU IRQs 0..31.
|
||||
IRQ numbers 40..71 refer to GPU IRQs 32..63.
|
||||
|
||||
* The kernel employs the so-called system timer for the preemptive scheduling.
|
||||
|
||||
* Core's LOG messages are printed over the PL011-based UART.
|
||||
|
||||
* The user-level timer driver uses the so-called ARM timer, which is a
|
||||
slightly modified SP804 timer device.
|
||||
|
||||
Up to this point, a few device driver are missing to use Genode on the
|
||||
Raspberry Pi in practice, most notably USB.
|
||||
|
||||
To build and run Genode on the Raspberry Pi, create a new build directory
|
||||
via the 'create_builddir' tool, specifying 'hw_rpi' as platform.
|
||||
|
||||
|
||||
User-level timer driver for Arndale platform
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By adding our new Exynos 5250 PWM timer driver, the base-hw kernel can now
|
||||
be used for executing meaningful scenarios on the Arndale board including
|
||||
the USB stack and networking.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Until now, Genode on Linux supported x86-based platforms only.
|
||||
The newly added 'linux_arm' platform clears the way to run Genode directly on
|
||||
Linux-based ARM platforms. Genode's entire software stack is supported,
|
||||
including the dynamic linker, graphical applications, and Qt4.
|
||||
|
||||
As a known limitations, the libc 'setjmp()'/'longjmp()' doesn't currently
|
||||
save/restore floating point registers.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
The run tool has been enhanced as detailed in Section
|
||||
[Automated quality-assurance testing].
|
||||
|
||||
@@ -1,995 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 13.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The release of version 13.08 marks the 5th anniversary of the Genode OS
|
||||
framework. We celebrate this anniversary with the addition of three major
|
||||
features that we have much longed for, namely the port of Qt5 to Genode,
|
||||
profound multi-processor support, and a light-weight event tracing
|
||||
framework. Additionally, the new version comes with new device drivers for
|
||||
SATA 3.0 and power management for the Exynos-5 SoC, improved virtualization
|
||||
support on NOVA on x86, updated kernels, and integrity checks for
|
||||
downloaded 3rd-party source code.
|
||||
|
||||
Over the course of the past five years, Genode's development was primarily
|
||||
motivated by adding and cultivating features to make the framework fit for as
|
||||
many application areas as possible. Now that we have a critical mass of
|
||||
features, the focus on mere functionality does not suffice anymore. The
|
||||
question of what Genode can do ultimately turns into the question of how well
|
||||
Genode can do something: How stable is a certain workload? How does networking
|
||||
perform? How does it scale to multi-processor systems? Because we are lacking
|
||||
concise answers to these kind of questions, we have to investigate.
|
||||
|
||||
When talking about stability, our recently introduced automated testing
|
||||
infrastructure makes us more confident than ever. Each night, over 200
|
||||
automated tests are performed, covering various kernels and several hardware
|
||||
platforms. All those tests are publicly available in the form of so-called run
|
||||
scripts and are under continues development.
|
||||
|
||||
Regarding performance investigations, recently we have begun to benchmark
|
||||
application performance focusing on network throughput. Interestingly, our
|
||||
measurements reveal significant differences between the used kernels, but
|
||||
also shortcomings in our software stack. For example, currently we see that
|
||||
our version of lwIP performs poorly with gigabit networking. To thoroughly
|
||||
investigate such performance issues, the current version adds support
|
||||
for tracing the behaviour of Genode components. This will allow us to get a
|
||||
profound understanding of all inter-component interaction that are on the
|
||||
critical path for the performance of complex application-level workloads.
|
||||
Thanks to the Genode architecture, we could come up with a strikingly simple,
|
||||
yet powerful design for a tracing facility. Section
|
||||
[Light-weight event tracing] explains how it works.
|
||||
|
||||
When it comes to multi-processor scalability, we used to shy away from such
|
||||
inquiries because, honestly, we haven't paid much consideration to it. This
|
||||
view has changed by now. With the current release, we implemented the
|
||||
management of CPU affinities right into the heart of the framework, i.e.,
|
||||
Genode's session concept. Additionally, we cracked a damn hard nut by enabling
|
||||
Genode to use multiple CPUs on the NOVA hypervisor. This kernel is by far the
|
||||
most advanced Open-Source microkernel for the x86 architecture. However,
|
||||
NOVA's MP model seemed to inherently contradict with the API design of Genode.
|
||||
Fortunately, we found a fairly elegant way to go forward and we're able to
|
||||
tame the beast. Section [Enhanced multi-processor support] goes into more
|
||||
detail.
|
||||
|
||||
Functionality-wise, we always considered the availability of Qt on Genode as a
|
||||
big asset. With the current release, we are happy to announce that we finally
|
||||
made the switch from Qt4 to Qt5. Section [Qt5 available on all kernels] gives
|
||||
insights into the challenges that we faced during porting work.
|
||||
|
||||
In addition to those highlights, the new version comes with improvements all
|
||||
over the place. To name a few, there are improved support for POSIX threads,
|
||||
updated device drivers, an updated version of the Fiasco.OC kernel and
|
||||
L4Linux, and new device drivers for Exynos-5. Finally, the problem of
|
||||
verifying the integrity of downloaded 3rd-party source codes has been
|
||||
addressed.
|
||||
|
||||
|
||||
Qt5 available on all kernels
|
||||
############################
|
||||
|
||||
Since its integration with Genode version 9.02, Qt4 is regarded as
|
||||
one of the most prominent features of the framework. For users, combining Qt
|
||||
with Genode makes the world of sophisticated GUI-based end-user applications
|
||||
available on various microkernels. For Genode developers, Qt represents by far
|
||||
the most complex work load natively executed on top of the framework API,
|
||||
thereby stressing the underlying system in any way imaginable. We have been
|
||||
keeping an eye on Qt version 5 for a while and highly anticipate the direction
|
||||
where Qt is heading. We think that the time is right to leave Qt4 behind to
|
||||
embrace Qt5 for Genode.
|
||||
|
||||
For the time being, both Qt4 and Qt5 are available for Genode, but Qt4 is
|
||||
declared as deprecated and will be removed with the upcoming version 13.11.
|
||||
Since Qt5 is almost API compatible to Qt4, the migration path is relatively
|
||||
smooth. So we recommend to move your applications over to Qt5 during the
|
||||
next release cycle.
|
||||
|
||||
In the following, we briefly describe the challenges we faced while adding Qt5
|
||||
support to Genode, point you to the place where to find Qt5 in the source
|
||||
tree, and give quick-start instructions for getting a Qt5 application
|
||||
scenario running.
|
||||
|
||||
We found that the biggest architectural difference between version 4 and
|
||||
version 5 is the use of the so-called Qt Platform Abstraction (QPA) interface,
|
||||
which replaces the former Qt Window System (QWS).
|
||||
|
||||
|
||||
Moving from QWS to QPA
|
||||
======================
|
||||
|
||||
With Qt4, we relied on QWS
|
||||
to perform the window handling. A Qt4 application used to create a session to
|
||||
Genode's GUI server (called nitpicker) and applied its graphical output onto a
|
||||
virtual framebuffer. The virtual framebuffer was not visible per se. To make
|
||||
portions of the virtual framebuffer visible on screen, the application had to
|
||||
create so-called nitpicker views. A view is a rectangular area of the physical
|
||||
screen that displays a (portion of) the virtual framebuffer. The position,
|
||||
size, and stacking order of views is managed by the application. For each Qt
|
||||
window, the application would simply create a corresponding nitpicker view and
|
||||
maintain the consistency of the view with the geometry of the Qt window. Even
|
||||
though each Qt application seemingly operated as a full-screen application
|
||||
with the windows managed by the application-local QWS, the use of nitpicker
|
||||
views still allowed the integration of any number of Qt applications into one
|
||||
windowed environment.
|
||||
|
||||
With the advent of compositing window managers, the typical way of how an
|
||||
application interacts with the window system of the OS changed. Whereas
|
||||
old-generation GUIs relied on a tight interplay of the application with the
|
||||
window server in order to re-generate newly exposed window regions whenever
|
||||
needed (e.g., revealing the window content previously covered by another
|
||||
window), the modern model of a GUI server keeps all pixels of all windows in
|
||||
memory regardless of whether the window is visible or covered by other
|
||||
windows. The use of one pixel buffer per window seems wasteful with respect to
|
||||
memory usage when many large windows are overlapping each other. On the other
|
||||
hand, this technique largely simplifies GUI servers and makes the
|
||||
implementation of fancy effects, like translucent windows, straight forward.
|
||||
Since memory is cheap, the Qt developers abandoned the old method and fully
|
||||
embraced the buffer-per-window approach by the means of QPA.
|
||||
|
||||
For Genode, we faced the challenge that we don't have a window server
|
||||
in the usual sense. With nitpicker, we have a GUI server, but with a more
|
||||
radical design. In particular, nitpicker leaves the management of window
|
||||
geometries and stacking to the client. In contrast, QPA expects the window
|
||||
system to provide both means for a user to interactively change the window
|
||||
layout and a way for an application to define the properties (such as the
|
||||
geometry, title, and visibility) of its windows.
|
||||
The obviously missing piece was the software component that deals with window
|
||||
controls. Fortunately, we already have a bunch of native nitpicker applications
|
||||
that come with client-side window controls, in particular the so-called liquid
|
||||
framebuffer (liquid_fb). This nitpicker client presents a virtual framebuffer
|
||||
in form of a proper window on screen and, in turn, provides a framebuffer and
|
||||
input service. These services can be used by other Genode processes, for
|
||||
example, another nested instance of nitpicker.
|
||||
This way, liquid_fb lends itself to be the interface between the nitpicker
|
||||
GUI server and QPA.
|
||||
|
||||
For each QPA window, the application creates a new liquid_fb instance as a
|
||||
child process. The liquid_fb instance will request a dedicated nitpicker
|
||||
session, which gets routed through the application towards the parent of the
|
||||
application, which eventually routes the request to the nitpicker GUI server.
|
||||
Finally, the liquid_fb instance announces its input and framebuffer services
|
||||
to its parent, which happens to be the application. Now, the application is
|
||||
able to use those services in order to access the window. Because the
|
||||
liquid_fb instances are children of the application, the application can
|
||||
impose control over those. In particular, it can update the liquid_fb
|
||||
configuration including the window geometry and title at any time. Thanks to
|
||||
Genode's dynamic reconfiguration mechanism, the liquid_fb instances are able
|
||||
to promptly respond to such reconfigurations.
|
||||
|
||||
Combined, those mechanisms give the application a way to receive user input
|
||||
(via the input services provided by the liquid_fb instances), perform
|
||||
graphical output (via the virtual framebuffers provided by the liquid_fb
|
||||
instances), and define window properties (by dynamically changing the
|
||||
respective liquid_fb configurations). At the same time, the user can use
|
||||
liquid_fb's window controls to move, stack, and resize application windows as
|
||||
expected.
|
||||
|
||||
[image qt5_screenshot]
|
||||
|
||||
|
||||
Steps of porting Qt5
|
||||
====================
|
||||
|
||||
Besides the switch to QPA, the second major change was related to the build
|
||||
system. For the porting work, we use a Linux host system to obtain the
|
||||
starting point for the build rules. The Qt4 build system would initially
|
||||
generate all Makefiles, which could be inspected and processed at once. In
|
||||
contrast, Qt5 generates Makefiles during the build process whenever needed.
|
||||
When having configured Qt for Genode, however, the build on Linux will
|
||||
ultimately fail. So the much-desired intermediate Makefiles won't be created.
|
||||
The solution was to have 'configure' invoke 'qmake -r' instead of 'qmake'.
|
||||
This way, qmake project files will be processed recursively. A few additional
|
||||
tweaks were needed to avoid qmake from backing out because of missing
|
||||
dependencies (qt5_configuration.patch). To enable the build of the Qt tools
|
||||
out of tree, qmake-specific files had to be slightly adapted
|
||||
(qt5_tools.patch). Furthermore, qtwebkit turned out to use code-generation
|
||||
tools quite extensively during the build process. On Genode, we perform this
|
||||
step during the 'make prepare' phase when downloading and integrating the Qt
|
||||
source code with the Genode source tree.
|
||||
|
||||
For building Qt5 on Genode, we hit two problems. First, qtwebkit depends on
|
||||
the ICU (International Components for Unicode) library, which was promptly
|
||||
ported and can be found in the libports repository. Second, qtwebkit
|
||||
apparently dropped the support of the 'QThread' API in favor of
|
||||
POSIX-thread support only. For this reason, we had to extend the coverage
|
||||
of Genode's pthread library to fulfill the needs of qtwebkit.
|
||||
|
||||
Once built, we entered the territory of debugging problems at runtime.
|
||||
* We hit a memory-corruption problem caused by an assumption of 'QArrayData'
|
||||
with regard to the alignment of memory allocated via malloc. As a
|
||||
work-around, we weakened the assumptions to 4-byte alignment
|
||||
(qt5_qarraydata.patch).
|
||||
* Page faults in QWidgetAnimator caused by
|
||||
use-after-free problems. Those could be alleviated by adding pointer
|
||||
checks (qt5_qwidgetanimator.patch).
|
||||
* Page faults caused by the slot function 'QWidgetWindow::updateObjectName()'
|
||||
with a 'this' pointer of an incompatible type 'QDesktopWidget*'.
|
||||
As a workaround, we avoid this condition by delegating the
|
||||
'QWidgetWindow::event()' that happened to trigger the slot method to
|
||||
'QWindow' (base class of 'QWidgetWindow') rather than to a
|
||||
'QDesktopWidget' member (qt5_qwidgetwindow.patch).
|
||||
* We observed that Arora presented web sites incomplete, or including HTTP
|
||||
headers. During the evaluation of HTTP data, a signal was sent to another
|
||||
thread, which activated a "user provided download buffer" for optimization
|
||||
purposes. On Linux, the receiving thread was immediately scheduled and
|
||||
everything went fine. However, on some kernels used by Genode, scheduling
|
||||
is different, so that the original thread continued to execute a bit longer,
|
||||
ultimately triggering a race condition. As a workaround, we disabled the
|
||||
"user provided download buffer" optimization.
|
||||
* Page faults in the JavaScript engine of Webkit. The JavaScript
|
||||
'RegExp.exec()' function returned invalid string objects. We worked around
|
||||
this issue by deactivating the JIT compiler for the processing of
|
||||
regular expressions (ENABLE_YARR_JIT).
|
||||
|
||||
The current state of the Qt5 port is fairly complete. It covers the core, gui,
|
||||
jscore, network, script, scriptclassic, sql, ui, webcore, webkit, widgets,
|
||||
wtf, and xml modules. That said, there are a few known limitations and
|
||||
differences compared to Qt4. First, the use of one liquid_fb instance per
|
||||
window consumes more memory compared to the use of QWS in Qt4. Furthermore,
|
||||
external window movements are not recognized by our QPA implementation yet.
|
||||
This can cause popup menus to appear at unexpected positions. Key repeat is
|
||||
not yet handled. The 'QNitpickerViewWidget' is not yet adapted to Qt5. For this
|
||||
reason, qt_avplay is not working yet.
|
||||
|
||||
|
||||
Test drive
|
||||
==========
|
||||
|
||||
Unlike Qt4, which was hosted in the dedicated 'qt4' repository, Qt5 is
|
||||
integrated in the libports repository. It can be downloaded and integrated
|
||||
into the Genode build system by issuing 'make prepare' from within the
|
||||
libports repository. The Qt5 versions of the known Qt examples are located at
|
||||
libports/src/app/qt5. Ready-to-use run scripts for those examples are available
|
||||
at libports/run.
|
||||
|
||||
|
||||
Migration away from Qt4 to Qt5
|
||||
==============================
|
||||
|
||||
The support for Qt4 for Genode has been declared as deprecated. By default,
|
||||
it's use is inhibited to avoid name aliasing problems between both versions.
|
||||
Any attempt to build a qt4-based target will result in a message:
|
||||
!Skip target app/qt_launchpad because it requires qt4_deprecated
|
||||
To re-enable the use of Qt4, the SPEC value qt4_deprecated must be defined
|
||||
manually for the build directory:
|
||||
!echo "SPECS += qt4_deprecated" >> etc/specs.conf
|
||||
|
||||
We will keep the qt4 repository in the source tree during the current
|
||||
release cycle. It will be removed with version 13.11.
|
||||
|
||||
|
||||
Light-weight event tracing
|
||||
##########################
|
||||
|
||||
With Genode application scenarios getting increasingly sophisticated,
|
||||
the need for thorough performance analysis has come into spotlight.
|
||||
Such scenarios entail the interaction of many components.
|
||||
For example, with our recent work on optimizing network performance, we
|
||||
have to consider several possible attack points:
|
||||
|
||||
* Device driver: Is the device operating in the proper mode? Are there
|
||||
CPU-intensive operations such as allocations within the critical path?
|
||||
* Interface to the device driver: How frequent are context switches between
|
||||
client and device driver? Is the interface designed appropriately for
|
||||
the access patterns?
|
||||
* TCP/IP stack: How does the data flow from the raw packet level to the
|
||||
socket level? How dominant are synchronization costs between the involved
|
||||
threads? Are there costly in-band operations performed, e.g., dynamic
|
||||
memory allocations per packet?
|
||||
* C runtime: How does integration of the TCP/IP stack with the C runtime
|
||||
work, for example how does the socket API interfere with timeout
|
||||
handling during 'select' calls?
|
||||
* Networking application
|
||||
* Timer server: How often is the timer consulted by the involved components?
|
||||
What is the granularity of timeouts and thereby the associated costs for
|
||||
handling them?
|
||||
* Interaction with core: What is the profile of the component's interaction
|
||||
with core's low-level services?
|
||||
|
||||
This example is just an illustration. Most real-world performance-critical
|
||||
scenarios have a similar or even larger scope. With our traditional
|
||||
tools, it is hardly possible to gather a holistic view of the scenario. Hence,
|
||||
finding performance bottlenecks tends to be a series of hit-and-miss
|
||||
experiments, which is a tiresome and costly endeavour.
|
||||
|
||||
To overcome this situation, we need the ability to gather traces of component
|
||||
interactions. Therefore, we started investigating the design of a tracing
|
||||
facility for Genode one year ago while posing the following requirements:
|
||||
|
||||
* Negligible impact on the performance, no side effects:
|
||||
For example, performing a system call per traced event
|
||||
is out of question because this would severely influence the flow of
|
||||
control (as the system call may trigger the kernel to take a scheduling
|
||||
decision) and the execution time of the traced code, not to speak of
|
||||
the TLB and cache footprint.
|
||||
|
||||
* Kernel independence: We want to use the same tracing facility across
|
||||
all supported base platforms.
|
||||
|
||||
* Accountability of resources: It must be clearly defined where the
|
||||
resources for trace buffers come from. Ideally, the tracing tool should be
|
||||
able to dimension the buffers according to its needs and, in turn, pay for
|
||||
the buffers.
|
||||
|
||||
* Suitable level of abstraction: Only if the trace contains information at
|
||||
the right level of abstraction, it can be interpreted for large scenarios.
|
||||
A counter example is the in-kernel trace buffer of the Fiasco.OC kernel,
|
||||
which logs kernel-internal object names and a few message words when tracing
|
||||
IPC messages, but makes it almost impossible to map this low-level
|
||||
information to the abstraction of the control flow of RPC calls. In
|
||||
contrast, we'd like to capture the names of invoked RPC calls (which is an
|
||||
abstraction level the kernel is not aware of). This requirement implies the
|
||||
need to have useful trace points generated automatically. Ideally those
|
||||
trace points should cover all interactions of a component with the outside
|
||||
world.
|
||||
|
||||
* (Re-)definition of tracing policies at runtime: The
|
||||
question of which information to gather when a trace point is passed
|
||||
should not be solely defined at compile time. Instead of changing static
|
||||
instrumentations in the code, we'd prefer to have a way to configure
|
||||
the level of detail and possible conditions for capturing events at runtime,
|
||||
similar to dtrace. This way, a series of different hypotheses could be
|
||||
tested by just changing the tracing policy instead of re-building and
|
||||
rebooting the entire scenario.
|
||||
|
||||
* Straight-forward implementation: We found that most existing tracing
|
||||
solutions are complicated. For example, dtrace comes with a virtual
|
||||
machine for the sandboxed interpretation of policy code. Another typical
|
||||
source of complexity is the synchronization of trace-buffer accesses.
|
||||
Because for Genode, low TCB complexity is of utmost importance, the
|
||||
simplicity of the implementation is the prerequisite to make it an
|
||||
integral part of the base system.
|
||||
|
||||
* Support for both online and offline analysis of traces.
|
||||
|
||||
We are happy to report to have come up with a design that meets all those
|
||||
requirements thanks to the architecture of Genode. In the following, we
|
||||
present the key aspects of the design.
|
||||
|
||||
The tracing facility comes in the form of a new TRACE service implemented
|
||||
in core. Using this service, a TRACE client can gather information about
|
||||
available tracing subjects (existing or no-longer existing threads),
|
||||
define trace buffers and policies and assign those to tracing subjects,
|
||||
obtain access to trace-buffer contents, and control the tracing state
|
||||
of tracing subjects. When a new thread is created via a CPU session, the
|
||||
thread gets registered at a global registry of potential tracing sources. Each
|
||||
TRACE service manages a session-local registry of so-called trace subjects.
|
||||
When requested by the TRACE client, it queries new tracing sources from the
|
||||
source registry and obtains references to the corresponding threads. This way,
|
||||
the TRACE session becomes able to control the thread's tracing state.
|
||||
|
||||
To keep the tracing overhead as low as possible, we assign a separate trace
|
||||
buffer to each individually traced thread. The trace buffer is a shared memory
|
||||
block mapped to the virtual address space of the thread's process. Capturing
|
||||
an event comes down to a write operation into the thread-local buffer. Because
|
||||
of the use of shared memory for the trace buffer, no system call is needed and
|
||||
because the buffer is local to the traced thread, there is no need for
|
||||
synchronizing the access to the buffer. When no tracing is active, a thread
|
||||
has no trace buffer. The buffer gets installed only when tracing is started.
|
||||
The buffer is not installed magically from the outside of the traced process
|
||||
but from the traced thread itself when passing a trace point. To detect
|
||||
whether to install a new trace buffer, there exists a so-called trace-control
|
||||
dataspace shared between the traced process and its CPU service. This
|
||||
dataspace contains control bits for each thread created via the CPU session.
|
||||
The control bits are evaluated each time a trace point is passed by the
|
||||
thread. When the thread detects a change of the tracing state, it actively
|
||||
requests the new trace buffer from the CPU session and installs it into its
|
||||
address space. The same technique is used for loading the code for tracing
|
||||
policies into the traced process. The traced thread actively checks for
|
||||
policy-version updates by evaluating the trace-control bits. If an update is
|
||||
detected, the new policy code is requested from the CPU session. The policy
|
||||
code comes in the form of position-independent code, which gets mapped into
|
||||
the traced thread's address space by the traced thread itself. Once mapped,
|
||||
a trace point will call the policy code. When called, the policy
|
||||
module code returns the data to be captured into the trace buffer. The
|
||||
relationship between the trace monitor (the client of TRACE service), core's
|
||||
TRACE service, core's CPU service, and the traced process is depicted in
|
||||
Figure [trace_control].
|
||||
|
||||
[image trace_control]
|
||||
|
||||
There is one trace-control dataspace per CPU session, which gets accounted
|
||||
to the CPU session's quota. The resources needed for the
|
||||
trace-buffer dataspaces and the policy dataspaces are paid-for by the
|
||||
TRACE client. On session creation, the TRACE client can specify the amount
|
||||
of its own RAM quota to be donated to the TRACE service in core. This
|
||||
enables the TRACE client to define trace buffers and policies of arbitrary
|
||||
sizes, limited only by its own RAM quota.
|
||||
|
||||
In Genode, the interaction of a process with its outside world is
|
||||
characterized by its use of inter-process communication, namely synchronous
|
||||
RPC, signals, and access to shared memory. For the former two types of
|
||||
inter-process communication, Genode generates trace points automatically. RPC
|
||||
clients generate trace points when an RPC call is issued and when a call
|
||||
returned. RPC servers generate trace points in the RPC dispatcher, capturing
|
||||
incoming RPC requests as well as RPC replies. Thanks to Genode's RPC
|
||||
framework, we are able to capture the names of the RPC functions in the RPC
|
||||
trace points. This information is obtained from the declarations of the RPC
|
||||
interfaces. For signals, trace points are generated for submitting and
|
||||
receiving signals. Those trace points form a useful base line for gathering
|
||||
tracing data. In addition, manual trace points can be inserted into the code.
|
||||
|
||||
|
||||
State of the implementation
|
||||
===========================
|
||||
|
||||
The implementation of Genode's tracing facility is surprisingly low complex.
|
||||
The addition to the base system (core as well as the base library) are
|
||||
merely 1500 lines of code. The mechanism works across all base platforms.
|
||||
|
||||
Because the TRACE client provides the policy code and trace buffer to the
|
||||
traced thread, the TRACE client imposes ultimate control over the traced
|
||||
thread. In contrast to dtrace, which sandboxes the trace policy, we express
|
||||
the policy module in the form of code executed in the context of the traced
|
||||
thread. However, in contrast to dtrace, such code is never loaded into a large
|
||||
monolithic kernel, but solely into the individually traced processes. So the
|
||||
risk of a misbehaving policy is constrained to the traced process.
|
||||
|
||||
In the current form, the TRACE service of core should be considered as a
|
||||
privileged service because the trace-subject namespace of each session
|
||||
contains all threads of the system. Therefore, TRACE sessions should be routed
|
||||
only for trusted processes. In the future, we plan to constrain the
|
||||
namespaces for tracing subjects per TRACE session.
|
||||
|
||||
The TRACE session interface is located at base/include/trace_session/.
|
||||
A simple example for using the service is available at os/src/test/trace/
|
||||
and is accompanied with the run script os/run/trace.run. The test
|
||||
demonstrates the TRACE session interface by gathering a trace of a thread
|
||||
running locally in its address space.
|
||||
|
||||
|
||||
Enhanced multi-processor support
|
||||
################################
|
||||
|
||||
Multi-processor (MP) support is one of those features that most users take for
|
||||
granted. MP systems are so ubiquitous, even on mobile platforms, that a
|
||||
limitation to utilizing a single CPU only is almost a fallacy.
|
||||
That said, MP support in operating systems is hard to get right. For this
|
||||
reason, we successively deferred the topic on the agenda of Genode's
|
||||
road map.
|
||||
|
||||
For some base platforms such as the Linux or Codezero kernels, Genode
|
||||
always used to support SMP because the kernel would manage the affinity
|
||||
of threads to CPU cores transparently to the user-level process. So on
|
||||
these kernels, there was no need to add special support into the framework.
|
||||
|
||||
However, on most microkernels, the situation is vastly different. The
|
||||
developers of such kernels try hard to avoid complexity in the kernel and
|
||||
rightfully argue that in-kernel affinity management would contribute to kernel
|
||||
complexity. Another argument is that, in contrast to monolithic kernels that
|
||||
have a global view on the system and an "understanding" of the concerns of the
|
||||
user processes, a microkernel is pretty clueless when it comes to the roles
|
||||
and behaviours of individual user-level threads. Not knowing whether a thread
|
||||
works as a device driver, an interactive program, or a batch process, the
|
||||
microkernel is not in the position to form a reasonably useful model of the
|
||||
world, onto which it could intelligently apply scheduling and affinity
|
||||
heuristics. In fact, from the perspective of a microkernel, each thread does
|
||||
nothing else than sending and receiving messages, and causing page faults.
|
||||
|
||||
For these reasons, microkernel developers tend to provide the bootstrapping
|
||||
procedure for the physical CPUs and a basic mechanism to assign
|
||||
threads to CPUs but push the rest of the problem to the user space, i.e.,
|
||||
Genode. The most straight-forward way would make all physical CPUs visible
|
||||
to all processes and require the user or system integrator to assign
|
||||
physical CPUs when a thread is created. However, on the recursively
|
||||
structured Genode system, we virtualize resources at each level, which
|
||||
calls for a different approach. Section [Management of CPU affinities]
|
||||
explains our solution.
|
||||
|
||||
When it comes to inter-process communication on MP systems, there is a
|
||||
certain diversity among the kernel designs. Some kernels allow the user land
|
||||
to use synchronous IPC between arbitrary threads, regardless of whether both
|
||||
communication partners reside on the same CPU or on two different CPUs. This
|
||||
convenient model is provided by Fiasco.OC. However, other kernels do not offer
|
||||
any synchronous IPC mechanism across CPU cores at all, NOVA being a poster
|
||||
child of this school of thought. If a user land is specifically designed for
|
||||
a particular kernel, those peculiarities can be just delegated to the
|
||||
application developers. For example, the NOVA user land called NUL is designed
|
||||
such that a recipient of IPC messages spawns a dedicated thread on each
|
||||
physical CPU. In contrast, Genode is meant to provide a unified API that
|
||||
works well across various different kernels. To go forward, we had four
|
||||
options:
|
||||
|
||||
# Not fully supporting the entity of API semantics across all base platforms.
|
||||
For example, we could stick with the RPC API for synchronous communication
|
||||
between threads. Programs just would happen to fail on some base platforms
|
||||
when the called server resides on a different CPU. This would effectively
|
||||
push the problem to the system integrator. The downside would be the
|
||||
sacrifice of Genode's nice feature that a program developed
|
||||
on one kernel usually works well on other kernels without any changes.
|
||||
|
||||
# Impose the semantics provided by the most restrictive kernel onto all
|
||||
users of the Genode API. Whereas this approach would facilitate that
|
||||
programs behave consistently across all base platforms, the restrictions
|
||||
would be artificially imposed onto all Genode users, in particular the
|
||||
users of kernels with less restrictions. Of course, we don't change
|
||||
the Genode API lightheartedly, which attributes to our hesitance to go
|
||||
into this direction.
|
||||
|
||||
# Hiding kernel restrictions behind the Genode API. This approach could come
|
||||
in many different shapes. For example, Genode could transparently spawn a
|
||||
thread on each CPU when a single RPC entrypoint gets created, following
|
||||
the model of NUL. Or Genode could emulate synchronous IPC using the core
|
||||
process as a proxy.
|
||||
|
||||
# Adapting the kernel to the requirements of Genode. That is, persuading
|
||||
kernel developers to implement the features we find convenient, i.e., adding
|
||||
a cross-CPU IPC feature to NOVA. History shows that our track record in
|
||||
doing that is not stellar.
|
||||
|
||||
Because each of those options is like opening a different can of worms, we
|
||||
used to defer the solution of the problem. Fortunately, however, we finally
|
||||
kicked off a series of practical experiments, which led to a fairly elegant
|
||||
solution, which is detailed in Section
|
||||
[Adding multi-processor support to Genode on NOVA].
|
||||
|
||||
|
||||
Management of CPU affinities
|
||||
============================
|
||||
|
||||
In line with our experience of supporting
|
||||
[http://www.genode.org/documentation/release-notes/10.02#Real-time_priorities - real-time priorities]
|
||||
in version 10.02, we were seeking a way to express CPU affinities such that
|
||||
Genode's recursive nature gets preserved and facilitated. Dealing with
|
||||
physical CPU numbers would contradict with this mission. Our solution
|
||||
is based on the observation that most MP systems have topologies that can
|
||||
be represented on a two-dimensional coordinate system. CPU nodes close
|
||||
to each other are expected to have closer relationship than distant nodes.
|
||||
In a large-scale MP system, it is natural to assign clusters of closely
|
||||
related nodes to a given workload. Genode's architecture is based on the
|
||||
idea to recursively virtualize resources and thereby lends itself to the
|
||||
idea to apply this successive virtualization to the problem of clustering
|
||||
CPU nodes.
|
||||
|
||||
In our solution, each process has a process-local view on a so-called affinity
|
||||
space, which is a two-dimensional coordinate space. If the process creates a
|
||||
new subsystem, it can assign a portion of its own affinity space to the new
|
||||
subsystem by imposing a rectangular affinity location to the subsystem's CPU
|
||||
session. Figure [affinity_space] illustrates the idea.
|
||||
|
||||
[image affinity_space]
|
||||
|
||||
Following from the expression of affinities as a rectangular location within a
|
||||
process-local affinity space, the assignment of subsystems to CPU nodes
|
||||
consists of two parts, the definition of the affinity space dimensions as used
|
||||
for the process and the association of sub systems with affinity locations
|
||||
(relative to the affinity space). For the init process, the affinity space is
|
||||
configured as a sub node of the config node. For example, the following
|
||||
declaration describes an affinity space of 4x2:
|
||||
|
||||
! <config>
|
||||
! ...
|
||||
! <affinity-space width="4" height="2" />
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
Subsystems can be constrained to parts of the affinity space using the
|
||||
'<affinity>' sub node of a '<start>' entry:
|
||||
|
||||
! <config>
|
||||
! ...
|
||||
! <start name="loader">
|
||||
! <affinity xpos="0" ypos="1" width="2" height="1" />
|
||||
! ...
|
||||
! </start>
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
As illustrated by this example, the numbers used in the declarations for this
|
||||
instance of the init process are not directly related to physical CPUs. If
|
||||
the machine has just two cores, init's affinity space would be mapped
|
||||
to the range [0,1] of physical CPUs. However, in a machine
|
||||
with 16x16 CPUs, the loader would obtain 8x8 CPUs with the upper-left
|
||||
CPU at position (4,0). Once a CPU session got created, the CPU client can
|
||||
request the physical affinity space that was assigned to the CPU session
|
||||
via the 'Cpu_session::affinity()' function. Threads of this CPU session
|
||||
can be assigned to those physical CPUs via the 'Cpu_session::affinity()'
|
||||
function, specifying a location relative to the CPU-session's affinity space.
|
||||
|
||||
|
||||
Adding multi-processor support to Genode on NOVA
|
||||
================================================
|
||||
|
||||
The NOVA kernel has been supporting MP systems for a long time. However
|
||||
Genode did not leverage this capability until now. The main reason was that
|
||||
the kernel does not provide - intentionally by the kernel developer - the
|
||||
possibility to perform synchronous IPC between threads residing on different
|
||||
CPUs.
|
||||
|
||||
To cope with this situation, Genode servers and clients would need to make
|
||||
sure to have at least one thread on a common CPU in order to communicate.
|
||||
Additionally, shared memory and semaphores could be used to communicate across
|
||||
CPU cores. Both options would require rather fundamental changes to the Genode
|
||||
base framework and the API. An exploration of this direction should in any
|
||||
case be pursued in evolutionary steps rather than as one big change, also
|
||||
taking into account that other kernels do not impose such hard requirements on
|
||||
inter-CPU communication. To tackle the challenge, we conducted a series of
|
||||
experiments to add some kind of cross-CPU IPC support to Genode/NOVA.
|
||||
|
||||
As a general implication of the missing inter-CPU IPC, messages between
|
||||
communication partners that use disjoint CPUs must take an indirection through
|
||||
a proxy process that has threads running on both CPUs involved. The sender
|
||||
would send the message to a proxy thread on its local CPU, the proxy process
|
||||
would transfer the message locally to the CPU of the receiver by using
|
||||
process-local communication, and the proxy thread on the receiving CPU would
|
||||
deliver the message to the actual destination. We came up with three options
|
||||
to implement this idea prototypically:
|
||||
|
||||
# Core plays the role of the proxy because it naturally has access to all
|
||||
CPUs and emulates cross-CPU IPC using the thread abstractions of the
|
||||
Genode API.
|
||||
# Core plays the role of the proxy but uses NOVA system calls directly
|
||||
rather than Genode's thread abstraction.
|
||||
# The NOVA kernel acts as the proxy and emulates cross-CPU IPC directly
|
||||
in the kernel.
|
||||
|
||||
After having implemented the first prototypes, we reached the following
|
||||
conclusions.
|
||||
|
||||
For options 1 and 2 where core provides this service: If a client can not
|
||||
issue a local CPU IPC, it asks core - actually the pager of the client
|
||||
thread - to perform the IPC request. Core then spawns or reuses a proxy thread
|
||||
on the target CPU and performs the actual IPC on behalf of the client. Option
|
||||
1 and 2 only differ in respect to code size and the question to whom to
|
||||
account the required resources - since a proxy thread needs a stack and some
|
||||
capability selectors.
|
||||
|
||||
As one big issue for option 1 and 2, we found that in order to delegate
|
||||
capabilities during the cross-CPU IPC, core has to receive capability mappings
|
||||
to delegate them to the target thread. However, core has no means to know
|
||||
whether the capabilities must be maintained in core or not. If a capability is
|
||||
already present in the target process, the kernel would just translate the
|
||||
capability to the target's capability name space. So core wouldn't need to
|
||||
keep it. In the other case where the target receives a prior unknown
|
||||
capability, the kernel creates a new mapping. Because the mapping gets
|
||||
established by the proxy in core, core must not free the capability.
|
||||
Otherwise, the mapping would disappear in the target process. This means that
|
||||
the use of core as a proxy ultimately leads to leaking kernel resources
|
||||
because core needs to keep all transferred capabilities, just for the case a
|
||||
new mapping got established.
|
||||
|
||||
For option 3, the same general functionality as for option 1 and 2 is
|
||||
implemented in the kernel instead of core. If a local CPU IPC call
|
||||
fails because of a BAD_CPU kernel error code, the cross-CPU IPC extension
|
||||
will be used. The kernel extension creates - similar as to option 1 and 2 - a
|
||||
semaphore (SM), a thread (EC), and a scheduling context (SC) on the remote
|
||||
CPU and lets it run on behalf of the caller thread. The caller thread
|
||||
gets suspended by blocking on the created semaphore until the remote EC has
|
||||
finished the IPC. The remote proxy EC reuses the UTCB of the suspended caller
|
||||
thread as is and issues the IPC call. When the proxy EC returns, it wakes up
|
||||
the caller via the semaphore. Finally, the proxy EC and SC de-schedule
|
||||
themselves and the resources get to be destroyed later on by the kernel's RCU
|
||||
mechanism. Finally, when the caller thread got woken up, it takes care to
|
||||
initiate the deconstruction of the semaphore.
|
||||
|
||||
The main advantage of option 3 compared to options 1 and 2 is that we don't
|
||||
have to keep and track the capability delegations during a cross-CPU IPC.
|
||||
Furthermore, we do not have potentially up to two additional address space
|
||||
switches per cross-CPU IPC (from client to core and core to the server).
|
||||
Additionally, the UTCB of the caller is reused by the proxy EC and does not
|
||||
need to be allocated separately as for option 1 and 2.
|
||||
|
||||
For these reasons, we decided to go for the third option. From Genode's API
|
||||
point of view, the use of cross-CPU IPC is completely transparent. Combined
|
||||
with the affinity management described in the previous section, Genode/NOVA
|
||||
just works on MP systems.
|
||||
As a simple example for using Genode on MP systems, there is a ready-to-use
|
||||
run script available at base/run/affinity.run.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Affinity propagation in parent, root, and RPC entrypoint interfaces
|
||||
===================================================================
|
||||
|
||||
To support the propagation of CPU affinities with session requests, the
|
||||
parent and root interfaces had to be changed. The 'Parent::Session'
|
||||
and 'Root::Session' take the affinity of the session as a new argument.
|
||||
The affinity argument contains both the dimensions of the affinity space
|
||||
used by the session and the session's designated affinity location within
|
||||
the space. The corresponding type definitions can be found at
|
||||
base/affinity.h.
|
||||
|
||||
Normally, the 'Parent::Session' function is not used directly but indirectly
|
||||
through the construction of a so-called connection object, which represents an
|
||||
open session. For each session type there is a corresponding connection type,
|
||||
which takes care of assembling the session-argument string by using the
|
||||
'Connection::session()' convenience function. To maintain API compatibility,
|
||||
we kept the signature of the existing 'Connection::session()' function using a
|
||||
default affinity and added a new overload that takes the affinity as
|
||||
additional argument. Currently, this overload is used in
|
||||
cpu_session/connection.h.
|
||||
|
||||
For expressing the affinities of RPC entrypoints to CPUs within the affinity
|
||||
space of the server process, the 'Rpc_entrypoint' takes the desired affinity
|
||||
location of the entrypoint as additional argument. For upholding API
|
||||
compatibility, the affinity argument is optional.
|
||||
|
||||
|
||||
CPU session interface
|
||||
=====================
|
||||
|
||||
The CPU session interface underwent changes to accommodate the new event
|
||||
tracing infrastructure and the CPU affinity management.
|
||||
|
||||
Originally the 'Cpu_session::num_cpus()' function could be used to
|
||||
determine the number of CPUs available to the session. This function
|
||||
has been replaced by the new 'affinity_space' function, which returns the
|
||||
bounds of the CPU session's physical affinity space. In the simplest case of
|
||||
an SMP machine, the affinity space is one-dimensional where the width
|
||||
corresponds to the number of CPUs. The 'affinity' function, which is used to
|
||||
bind a thread to a specified CPU, has been changed to take an affinity
|
||||
location as argument. This way, the caller can principally express the
|
||||
affiliation of the thread with multiple CPUs to guide load-balancing in a CPU
|
||||
service.
|
||||
|
||||
|
||||
New TRACE session interface
|
||||
===========================
|
||||
|
||||
The new event tracing mechanism as described in Section
|
||||
[Light-weight event tracing] is exposed to Genode processes in the form
|
||||
of the TRACE service provided by core. The new session interface
|
||||
is located under base/include/trace_session/. In addition to the new session
|
||||
interface, the CPU session interface has been extended with functions for
|
||||
obtaining the trace-control dataspace for the session as well as the trace
|
||||
buffer and trace policy for a given thread.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Event-driven operation of NIC bridge
|
||||
====================================
|
||||
|
||||
The NIC bridge component multiplexes one physical network device among
|
||||
multiple clients. It enables us to multiplex networking on the network-packet
|
||||
level rather than the socket level and thereby take TCP/IP out of the
|
||||
critical software stack for isolating network applications. As it
|
||||
represents an indirection in the flow of all networking packets, its
|
||||
performance is important.
|
||||
|
||||
The original version of NIC bridge was heavily multi-threaded. In addition to
|
||||
the main thread, a timer thread, and a thread for interacting with the NIC
|
||||
driver, it employed one dedicated thread per client. By merging those flows of
|
||||
control into a single thread, we were able to significantly reduce the number
|
||||
of context switches and improve data locality. These changes reduced the
|
||||
impact of the NIC bridge on the packet throughput from 25% to 10%.
|
||||
|
||||
|
||||
Improved POSIX thread support
|
||||
=============================
|
||||
|
||||
To accommodate qtwebkit, we had to extend Genode's pthread library with
|
||||
working implementations of condition variables, mutexes, and thread-local
|
||||
storage. The implemented functions are attr_init, attr_destroy, attr_getstack,
|
||||
attr_get_np, equal, mutex_attr, mutexattr_init, mutexattr_destroy,
|
||||
mutexattr_settype, mutex_init, mutex_destroy, mutex_lock, mutex_unlock,
|
||||
cond_init, cond_timedwait, cond_wait, cond_signal, cond_broadcast, key_create,
|
||||
setspecific, and getspecific.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
SATA 3.0 on Exynos 5
|
||||
====================
|
||||
|
||||
The previous release featured the initial version of our SATA 3.0 driver for
|
||||
the Exynos 5 platform. This driver located at os/src/drivers/ahci/exynos5 has
|
||||
reached a fully functional state by now. It supports UDMA-133 with up to
|
||||
6 GBit/s.
|
||||
|
||||
For driver development, we set the goal to reach a performance equal to
|
||||
the Linux kernel. To achieve that goal, we had to make sure to
|
||||
operate the controller and the disks in the same ways as Linux does.
|
||||
For this reason, we modeled our driver closely after the behaviour of the
|
||||
Linux driver. That is, we gathered traces of I/O transactions to determine the
|
||||
initialization steps and the request patterns that Linux performs to access
|
||||
the device, and used those behavioral traces as a guide for our
|
||||
implementation. Through step-by-step analysis of the traces, we not only
|
||||
succeeded to operate the device in the proper modes, but we also found
|
||||
opportunities for further optimization, in particular regarding the error
|
||||
recovery implementation.
|
||||
|
||||
This approach turned out to be successful. We measured that our driver
|
||||
generally operates as fast (and in some cases even significantly faster)
|
||||
than the Linux driver on solid-state disks as well as on hard disks.
|
||||
|
||||
|
||||
Dynamic CPU frequency scaling for Exynos 5
|
||||
==========================================
|
||||
|
||||
As the Samsung Exynos-5 SoC is primarily targeted at mobile platforms,
|
||||
power management is an inherent concern. Until now, Genode did not pay
|
||||
much attention to power management though. For example, we completely
|
||||
left out the topic from the scope of the OMAP4 support. With the current
|
||||
release, we took the first steps towards proper power management on ARM-based
|
||||
platforms in general, and the Exynos-5-based Arndale platform in particular.
|
||||
|
||||
First, we introduced a general interface to regulate clocks and voltages.
|
||||
Priorly, each driver did its own part of configuring clock and power control
|
||||
registers. The more device drivers were developed, the higher were the chances
|
||||
that they interfere when accessing those clock, or power units.
|
||||
The newly introduced "Regulator" interface provides the possibility to enable
|
||||
or disable, and to set or get the level of a regulator. A regulator might be
|
||||
a clock for a specific device (such as a CPU) or a voltage regulator.
|
||||
For the Arndale board, an exemplary implementation of the regulator interface
|
||||
exists in the form of the platform driver. It can be found at
|
||||
os/src/drivers/platform/arndale. Currently, the driver implements
|
||||
clock regulators for the CPU, the USB 2.0 and USB 3.0 host controller, the
|
||||
eMMC controller, and the SATA controller. Moreover, it provides power
|
||||
regulators for SATA, USB 2.0, and USB 3.0 host controllers. The selection of
|
||||
regulators is dependent on the availability of drivers for the platform.
|
||||
Otherwise it wouldn't be possible to test that clock and power state doesn't
|
||||
affect the device.
|
||||
|
||||
Apart from providing regulators needed by certain device drivers, we
|
||||
implemented a clock regulator for the CPU that allows changing the CPU
|
||||
frequency dynamically and thereby giving the opportunity to scale down
|
||||
voltage and power consumption. The possible values range from 200 MHz to
|
||||
1.7 GHz whereby the last value isn't recommended and might provoke system
|
||||
crashes due to overheating. When using Genode's platform driver for Arndale
|
||||
it sets CPU clock speed to 1.6 GHz by default. When reducing
|
||||
the clock speed to the lowest level, we observed a power consumption
|
||||
reduction of approximately 3 Watt. Besides reducing dynamic power consumption
|
||||
by regulating the CPU clock frequency, we also explored the gating of the clock
|
||||
management and power management to further reduce power consumption.
|
||||
|
||||
With the CPU frequency scaling in place, we started to close all clock gates
|
||||
not currently in use. When the platform driver for the Arndale board gets
|
||||
initialized, it closes everything. If a device driver enables its clock
|
||||
regulator, all necessary clock gates for the device's clock are opened. This
|
||||
action saves about 0.7 Watt. The initial closing of all unnecessary power
|
||||
gates was much more effective. Again, everything not essential for the working
|
||||
of the kernel is disabled on startup. When a driver enables its power
|
||||
regulator, all necessary power gates for the device are opened. Closing all
|
||||
power gates saves about 2.6 Watt.
|
||||
|
||||
If we consider all measures taken to save power, we were able to reduce power
|
||||
consumption to about 59% without performance degradation. When measuring power
|
||||
consumption after boot up, setting the CPU clock to 1.6 GHz, and fully load
|
||||
both CPU cores without the described changes, we measured about 8 Watt. With
|
||||
the described power saving provisions enabled, we measured about 4.7 Watt.
|
||||
When further reducing the CPU clock frequency to 200 MHz, only 1.7 Watt were
|
||||
measured.
|
||||
|
||||
|
||||
VESA driver moved to libports
|
||||
=============================
|
||||
|
||||
The VESA framebuffer driver executes the initialization code located
|
||||
in VESA BIOS of the graphics card. As the BIOS code is for real mode,
|
||||
the driver uses the x86emu library from X11 as emulation environment.
|
||||
We updated x86emu to version 1.20 and moved the driver from the 'os'
|
||||
repository to the 'libports' repository as the library is third-party
|
||||
code. Therefore, if you want to use the driver, the 'libports'
|
||||
repository has to be prepared
|
||||
('make -C <genode-dir>/libports prepare PKG=x86emu') and enabled in
|
||||
your 'etc/build.conf'.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Seoul (aka Vancouver) VMM on NOVA
|
||||
=================================
|
||||
|
||||
Since we repeatedly received requests for using the Seoul respectively
|
||||
Vancouver VMM on NOVA, we improved the support for this virtualization
|
||||
solution on Genode. Seoul now supports booting from raw hard disk images
|
||||
provided via Genode's block session interface. Whether this image is actually
|
||||
a file located in memory, or it is coming directly from the hard disk, or just
|
||||
from a partition of the hard disk using Genode's part_blk service, is
|
||||
completely transparent thanks to Genode's architecture.
|
||||
|
||||
Additionally, we split up the one large Vancouver run script into several
|
||||
smaller Seoul run scripts for easier usage - e.g. one for disk, one for
|
||||
network testing, one for automated testing, and one we call "fancy". The
|
||||
latter resembles the former vancouver.run script using Genode's GUI to let the
|
||||
user start VMs interactively. The run scripts prefixed with 'seoul-' can be
|
||||
found at ports/run. For the fancy and network scripts, ready-to-use VM images
|
||||
are provided. Those images are downloaded automatically when executing the run
|
||||
script for the first time.
|
||||
|
||||
|
||||
L4Linux on Fiasco.OC
|
||||
====================
|
||||
|
||||
L4Linux has been updated from version 3.5.0 to Linux kernel version 3.9.0 thus
|
||||
providing support for contemporary user lands running on top of L4Linux on both
|
||||
x86 (32bit) and ARM platforms.
|
||||
|
||||
|
||||
Noux runtime for Unix software
|
||||
==============================
|
||||
|
||||
Noux is our way to use the GNU software stack natively on Genode. To improve
|
||||
its performance, we revisited the address-space management of the runtime to
|
||||
avoid redundant revocations of memory mappings when Noux processes are cleaned
|
||||
up.
|
||||
|
||||
Furthermore, we complemented the support for the Genode tool chain to
|
||||
cover GNU sed and GNU grep as well. Both packages are available at the ports
|
||||
repository.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Fiasco.OC updated to revision r56
|
||||
=================================
|
||||
|
||||
Fiasco.OC and the required L4RE parts have been updated to the current SVN
|
||||
revision (r56). For us, the major new feature is the support of Exynos SOCs in
|
||||
the mainline version of Fiasco.OC (www.tudos.org). Therefore Genode's
|
||||
implementation of the Exynos5250 platform could be abandoned leading to less
|
||||
maintenance overhead of Genode on Fiasco.OC.
|
||||
|
||||
Furthermore, Genode's multi-processor support for this kernel has been
|
||||
improved so that Fiasco.OC users benefit from the additions described in
|
||||
Section [Enhanced multi-processor support].
|
||||
|
||||
|
||||
NOVA updated
|
||||
============
|
||||
|
||||
In the process of our work on the multi-processor support on NOVA, we updated
|
||||
the kernel to the current upstream version. Additionally, our customized branch
|
||||
(called r3) comes with the added cross-CPU IPC system call and improvements
|
||||
regarding the release of kernel resources.
|
||||
|
||||
|
||||
Integrity checks for downloaded 3rd-party software
|
||||
##################################################
|
||||
|
||||
Even though Genode supports a large variety of 3rd-party software, its
|
||||
source-code repository contains hardly any 3rd-party source code. Whenever
|
||||
3rd-party source code is needed, Genode provides automated tools for
|
||||
downloading the code and integrating it with the Genode environment. As of
|
||||
now, there exists support for circa 70 software packages, including the
|
||||
tool chain, various kernels, libraries, drivers, and a few applications. Of
|
||||
those packages, the code for 13 packages comes directly from their respective
|
||||
Git repositories. The remaining 57 packages are downloaded in the form of tar
|
||||
archives from public servers via HTTP or FTP. Whereas we are confident with
|
||||
the integrity of the code that comes from Git repositories, we are less so
|
||||
about the archives downloaded from HTTP or FTP servers.
|
||||
|
||||
Fortunately, most Open-Source projects provide signature files that allow
|
||||
the user to verify the origin of the archive. For example, archives of
|
||||
GNU software are signed with the private key of the GNU project. So the
|
||||
integrity of the archive can be tested with the corresponding public key.
|
||||
We used to ignore the signature files for many years but
|
||||
this has changed now. If there is a signature file available for a package,
|
||||
the package gets verified right after downloading. If only a hash-sum file
|
||||
is provided, we check it against a known-good hash sum.
|
||||
|
||||
The solution required three steps, the creation of tools for validating
|
||||
signatures and hashes, the integration of those tools into Genode's
|
||||
infrastructure for downloading the 3rd-party code, and the definition of
|
||||
verification rules for the individual packages.
|
||||
|
||||
First, new tools for downloading and validating hash sums and signatures were
|
||||
added in the form of the shell scripts download_hashver (verify hash sum) and
|
||||
download_sigver (verify signature) found at the tool/ directory. Under the
|
||||
hood, download_sigver uses GNU GPG, and download_hashver uses the tools
|
||||
md5sum, sha1sum, and sha256sum provided by coreutils.
|
||||
|
||||
Second, hooks for invoking the verification tools were added to the
|
||||
tool-chain build script as well as the ports and the libports repositories.
|
||||
|
||||
The third and the most elaborative step, was going through all the packages,
|
||||
looking for publicly available signature files, and adding corresponding
|
||||
package rules. As of now, this manual process has been carried out for 30
|
||||
packages, thereby covering the half of the archives.
|
||||
|
||||
Thanks to Stephan Mueller for pushing us into the right direction, kicking off
|
||||
the work on this valuable feature, and for the manual labour of revisiting all
|
||||
the 3rd-party packages!
|
||||
|
||||
@@ -1,791 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 14.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
During the release cycle of version 14.02, our development has been focused on
|
||||
storage and virtualization. It goes without saying that proper support for
|
||||
block-device access and file systems is fundamental for the use of
|
||||
Genode as general-purpose OS. Virtualization is relevant as well because
|
||||
it bridges the gap between the functionality we need and the features
|
||||
natively available on Genode today.
|
||||
|
||||
Our work on the storage topic involved changes of the block-driver APIs to an
|
||||
asynchronous mode of operation, overhauling most of the existing block-level
|
||||
components, as well as the creation of new block services, most importantly a
|
||||
block cache. At file-system level, we continued our line of work on FUSE-based
|
||||
file systems, adding support for NTFS-3g. A new highlight, however, is a new
|
||||
file-system service that makes the file systems of the NetBSD kernel available
|
||||
to Genode. This is made possible by using rump kernels as described in Section
|
||||
[NetBSD file systems using rump kernels].
|
||||
|
||||
Virtualization on Genode has a long history, starting with the original
|
||||
support of OKLinux on the OKL4 kernel (OKLinux is no longer supported), over
|
||||
the support of L4Linux on top of the Fiasco.OC kernel, to the support of the
|
||||
Vancouver VMM on top of NOVA. However, whereas each of those variants has
|
||||
different technical merits, all of them were developed in the context of
|
||||
university research projects and were never exposed to real-world scenarios.
|
||||
We were longing for a solution that meets the general expectations from a
|
||||
virtualization product, namely the support for a wide range of guest OSes,
|
||||
guest-host integration features, ease of use, and an active development.
|
||||
VirtualBox is one of the most popular commodity virtualization products as of
|
||||
today. With the current release, we are happy to announce the availability of
|
||||
VirtualBox on top of Genode/NOVA. Section
|
||||
[VirtualBox on top of the NOVA microhypervisor] gives insights into the
|
||||
background of this development, the technical challenges we had to overcome,
|
||||
and the current state of the implementation.
|
||||
|
||||
In addition to addressing storage and virtualization, the current release
|
||||
comes with a new pseudo file system called trace_fs that allows the
|
||||
interactive use of Genode's tracing facilities via Unix commands,
|
||||
a profound unification of the various graphics back ends used throughout
|
||||
the framework, a new facility for propagating status reports, and
|
||||
improvements of the Noux runtime for executing Unix software on Genode.
|
||||
|
||||
|
||||
VirtualBox on top of the NOVA microhypervisor
|
||||
#############################################
|
||||
|
||||
Virtualization is an important topic for Genode for two distinct reasons.
|
||||
It is repeatedly requested by users of the framework who consider
|
||||
Genode as a microkernel-based hosting platform for virtual machines,
|
||||
and it provides a smooth migration path from using Linux-based systems
|
||||
towards using Genode as day-to-day OS.
|
||||
|
||||
Why do people consider Genode as a hosting platform for virtual machines
|
||||
if there is an abundance of mature virtualization solutions on the market?
|
||||
What all existing popular solutions have in common is the staggering complexity
|
||||
of their respective trusted-computing base (TCB). The user of a virtual
|
||||
machine on a commodity hosting platform has to trust millions of lines of
|
||||
code. For example, with Xen, the TCB comprises the hypervisor and the Linux
|
||||
system running as DOM0. For security-sensitive application areas, it is
|
||||
almost painful to trust such a complex foundation. In contrast, the TCB of a
|
||||
hosting platform based on Genode/NOVA is two orders of magnitude less complex.
|
||||
Lowering the complexity reduces the likelihood for vulnerabilities and thereby
|
||||
mitigates the attack surface of the system. It also enables the assessment of
|
||||
security properties by thorough evaluation or even formal verification. In the
|
||||
light of the large-scale privacy issues of today, the desire for systems that
|
||||
are resilient against malware and zero-day exploits has never been higher.
|
||||
Microkernel-based operating systems promise a solution. Virtualization enables
|
||||
compatibility to existing software. Combining both seems natural. This is what
|
||||
Genode/NOVA stands for.
|
||||
|
||||
From the perspective of us Genode developers who are in the process of
|
||||
migrating from Linux-based OSes to Genode as day-to-day OS, we consider
|
||||
virtualization as a stop-gap solution for all those applications that
|
||||
do not exist natively on Genode, yet. Virtualization makes our transition
|
||||
an evolutionary process.
|
||||
|
||||
Until now, NOVA was typically accompanied with a co-developed virtual machine
|
||||
monitor called Seoul (formerly called Vancouver), which is executed as a
|
||||
regular user-level process on top of NOVA. In contrast to conventional wisdom
|
||||
about the performance of microkernel-based systems, the Seoul VMM on top of
|
||||
NOVA is extremely fast, actually faster then most (if not all) commonly used
|
||||
virtualization solutions. However, originating from a research project, Seoul
|
||||
is quite challenging to use and not as mature as commodity VMMs that were
|
||||
developed as real-world products. For example, there is a good chance that an
|
||||
attempt to boot an arbitrary version of a modern Linux distribution might just
|
||||
fail. In our experience, it takes a few days to investigate the issues, modify
|
||||
the guest OS configuration, and tweak the VMM here and there, to run the OS
|
||||
inside the Seoul VMM. That is certainly not a show stopper in appliance-like
|
||||
scenarios, but it rules out Seoul as a general solution. Running Windows
|
||||
OS as guest is not supported at all, which further reduces the application
|
||||
areas of Seoul. With this in mind, it is unrealistic to propose the use
|
||||
of Genode/NOVA as an alternative for popular VM hosting solutions.
|
||||
|
||||
Out of this realization, the idea was born to combine NOVA's virtualization
|
||||
interface with a time-tested and fully-featured commodity VMM. Out of the
|
||||
available Open-Source virtualization solutions, we decided to take a closer
|
||||
look at VirtualBox, which attracted us for several reasons: First, it is
|
||||
portable, supporting various host OSes such as Solaris, Windows OS, Linux,
|
||||
and Mac OS X. Second, it has all the guest-integration features we could
|
||||
wish for. There are extensive so-called guest additions for popular guest
|
||||
OSes that vastly improve the guest-OS performance and allow a tight
|
||||
integration with the host OS using shared folders or a shared clipboard.
|
||||
Third, it comes with sophisticated device models that support all
|
||||
important popular guest OSes. And finally, it is actively developed and
|
||||
commercially supported.
|
||||
|
||||
However, moving VirtualBox over to NOVA presented us with a number of
|
||||
problems. As a precondition, we needed to gain a profound understanding
|
||||
of the VirtualBox architecture and the code base. To illustrate the challenge,
|
||||
the source-code distribution of VirtualBox comprises 2.8 million lines of
|
||||
code. This code contains build tools, the VMM, management tools, several
|
||||
3rd-party libraries, middleware, the guest additions, and tests. The pieces
|
||||
that are relevant for the actual VMM amount to 700 thousand lines. By
|
||||
reviewing the architecture, we found that the part of VirtualBox that
|
||||
implements the hypervisor functionality (the world switch) runs in the
|
||||
kernel of the host OS (it is loaded on demand by the user-level VM process
|
||||
through the _/dev/vboxdrv_ interface into the host OS kernel). It is
|
||||
appropriately named VMMR0. Once installed into the host OS kernel, it
|
||||
takes over the control over the machine. To put it blatantly simple, it runs
|
||||
"underneath" the host OS. The VMMR0 code is kernel agnostic, which explains
|
||||
the good portability of VirtualBox across various host OSes. Porting
|
||||
VirtualBox to a new host OS comes down to finding a hook for installing the
|
||||
VMMR0 code into the host OS kernel and adapting the VirtualBox runtime API
|
||||
to the new host OS.
|
||||
|
||||
In the context of microkernel-based systems, however, it becomes clear that
|
||||
this classical approach of porting VirtualBox would subvert the microkernel
|
||||
architecture. Not only would we need to punch a hole into NOVA for loading
|
||||
additional kernel code, but also the VMMR0 code would inflate the amount of
|
||||
code executed in privileged mode by more than factor 20. Both implications
|
||||
are gross violations of the microkernel principle. Consequently, we needed to
|
||||
find a different way to marry NOVA with VirtualBox.
|
||||
|
||||
Our solution was the creation of a drop-in replacement of the VMMR0 code that
|
||||
runs solely at user level and interacts with NOVA's virtualization
|
||||
interface. Our VMMR0 emulation code is co-located with the VirtualBox
|
||||
VM process. Architecturally, the resulting solution is identical to the
|
||||
use of Seoul on top of NOVA. There is one VM process per virtual machine,
|
||||
and each VM process is isolated from others by the NOVA kernel. In
|
||||
addition to creating the VMMR0 emulation code, we needed to replace some parts
|
||||
of the VirtualBox VMMR3 code with custom implementations because they
|
||||
overlapped with functionality provided by NOVA's virtualization interface,
|
||||
in particular the provisioning of guest-physical memory. Finally, we needed
|
||||
to interface the VM process with Genode's API to let the VM process
|
||||
interact with Genode's input, file-system, and framebuffer services.
|
||||
|
||||
The result of this undertaking is available at the _ports_ repository.
|
||||
VirtualBox can be downloaded and integrated with Genode via the following
|
||||
command issued from within the repository:
|
||||
! make prepare PKG=virtualbox
|
||||
|
||||
To illustrate the integration of VirtualBox into a Genode system, there
|
||||
is run script located at _ports/run/virtualbox.run_. It expects a
|
||||
bootable ISO image containing a guest OS at _<build-dir>/bin/test.iso_.
|
||||
The configuration of the VirtualBox process is as simple as
|
||||
! <config>
|
||||
! <image type="iso" file="/iso/test.iso" />
|
||||
! </config>
|
||||
|
||||
VirtualBox will try to obtain the specified ISO file via a file-system
|
||||
session. Furthermore, it will open a framebuffer session and an input session.
|
||||
The memory assigned to the guest OS depends on the RAM quota assigned to the
|
||||
VirtualBox process. Booting a guest OS stored in a VDI file is supported. The
|
||||
image type must be changed to "vdi" accordingly.
|
||||
|
||||
Please note that this first version of VirtualBox is far from being complete
|
||||
as it lacks many features (SMP, guest-addition support, networking), is not
|
||||
optimized, and must be considered as experimental. However, we could
|
||||
successfully run GNU/Linux, Android, Windows XP, Windows 7, HelenOS, Minix-3,
|
||||
GNU Hurd, and of course Genode inside VirtualBox.
|
||||
|
||||
One point we are pretty excited about is that the porting effort to
|
||||
Genode/NOVA did not require any change of Genode. From Genode's point of
|
||||
view, VirtualBox is just an ordinary leaf node of the process tree, which
|
||||
can happily co-exist with other processes - even if it is the Seoul VMM.
|
||||
|
||||
[image seoul-vbox-win7-tinycore]
|
||||
|
||||
In the screenshot above, VirtualBox is running besides the Seoul VMM on top of
|
||||
Genode/NOVA. Seoul executes Tinycore Linux as guest OS. VirtualBox executes MS
|
||||
Windows 7. Both VMMs are using hardware virtualization (VT-x) but are plain
|
||||
user-level programs with no special privileges.
|
||||
|
||||
|
||||
NetBSD file systems using rump kernels
|
||||
######################################
|
||||
|
||||
In the previous release, we made FUSE-based file systems available to Genode
|
||||
via a custom implementation of the FUSE API. Even though this step made
|
||||
several popular file systems available, we found that the file systems most
|
||||
important to us (such as ext) are actually not well supported by FUSE. For
|
||||
example, write support on ext2 is declared as an experimental feature. In
|
||||
hindsight it is clear why: FUSE is primarily being used for accessing file
|
||||
systems not found in the Linux kernel. So it shines with supporting NTFS
|
||||
but less so with file systems that are well supported by the Linux kernel.
|
||||
Coincidentally, when we came to this realization, we stumbled upon the
|
||||
wonderful work of Antti Kantee on so-called rump kernels:
|
||||
|
||||
:[http://wiki.netbsd.org/rumpkernel/]:
|
||||
Rump kernel Wiki
|
||||
|
||||
The motivation behind the rump kernels was the development of
|
||||
NetBSD kernel subsystems (referred to as "drivers") in the NetBSD user land.
|
||||
Such subsystems like file systems, device drivers, or the TCP/IP stack are
|
||||
linked against a stripped-down version of the NetBSD kernel that can be
|
||||
executed in user mode and uses a fairly small "hypercall" interface to
|
||||
interact with the outside world. A rump kernel contains everything needed to
|
||||
execute NetBSD kernel subsystems but hardly anything else. In particular, it
|
||||
does not support the execution of programs on top. From our perspective,
|
||||
having crafted device-driver environments (DDEs) for Linux, iPXE, and OSS over
|
||||
the years, a rump kernel sounded pretty much like a DDE for NetBSD. So we
|
||||
started exploring rump kernels with the immediate goal of making time-tested
|
||||
NetBSD file systems available to Genode.
|
||||
|
||||
To our delight, the integration of rump kernels into the Genode system went
|
||||
fairly smooth. The most difficult part was the integration of the NetBSD build
|
||||
infrastructure with Genode's build system. The glue between rump kernels and
|
||||
Genode is less than 3,000 lines of code. This code enables us to reuse all
|
||||
NetBSD file systems on Genode. A rump kernel instance that contains several
|
||||
file systems such as ext2, iso9660, msdos, and ffs takes about 8 MiB of memory
|
||||
when executed on Genode.
|
||||
|
||||
The support for rump kernels comes in the form of the dedicated _dde_rump_
|
||||
repository. For downloading and integrating the required NetBSD source code,
|
||||
the repository contains a Makefile providing the usual 'make prepare'
|
||||
mechanism. To build the file-system server, make sure to add the _dde_rump_
|
||||
repository to the 'REPOSITORIES' declaration of your _etc/build.conf_ file
|
||||
within your build directory. The server then can be built via
|
||||
! make server/rump_fs
|
||||
|
||||
There is a run script located at _dde_rump/run/rump_ext2.run_ to execute
|
||||
a simple test scenario:
|
||||
! make run/rump_ext2
|
||||
|
||||
The server can be configured as follows:
|
||||
!<start name="rump_fs">
|
||||
! <resource name="RAM" quantum="8M" />
|
||||
! <provides><service name="File_system"/></provides>
|
||||
! <config fs="ext2fs"><policy label="" root="/" writeable="yes"/></config>
|
||||
!</start>
|
||||
|
||||
On startup, it requests a service that provides a block session. If
|
||||
there is more than one block session in the system, the block session must be
|
||||
routed to the right block-session server. The value of the _fs_ attribute of
|
||||
the '<config>' node can be one of the following: _ext2fs_ for EXT2, _cd9660_ for
|
||||
ISO-9660, or _msdos_ for FAT file-system support. _root_ defines the directory
|
||||
of the file system as seen as root directory by the client. The server hands
|
||||
most of its RAM quota to the rump kernel. This means the larger the quota is,
|
||||
the larger the internal block caches of the rump kernel will be.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
The base API has not underwent major changes apart from the addition of
|
||||
a few new utilities and minor refinements. Under the hood, however, the inner
|
||||
workings of the framework received much attention, including an extensive
|
||||
unification of the startup code and stack management.
|
||||
|
||||
|
||||
New 'construct_at' utility
|
||||
==========================
|
||||
|
||||
A new utility located at 'base/include/util/construct_at.h' allows for the
|
||||
manual placement of objects without the need to have a global placement new
|
||||
operation nor the need for type-specific new operators.
|
||||
|
||||
|
||||
New utility for managing volatile objects
|
||||
=========================================
|
||||
|
||||
Throughout Genode, we maintain a programming style that largely avoids dynamic
|
||||
memory allocations. For the most part, higher-level objects aggregate
|
||||
lower-level objects as class members. For example, the nitpicker GUI server
|
||||
is actually a compound of such aggregations (see
|
||||
[https://github.com/genodelabs/genode/blob/master/os/src/server/nitpicker/main.cc#L803 - Nitpicker::Main]).
|
||||
This functional programming style leads to robust programs but it poses a
|
||||
problem for programs that are expected to adopt their behaviour at runtime.
|
||||
For the example of nitpicker, the graphics back end of the GUI server takes
|
||||
the size of the screen as constructor argument. If the screen size changes,
|
||||
the once constructed graphics back end becomes inconsistent with the new
|
||||
screen size. We desire a way to selectively replace an aggregated object by a
|
||||
new version with updated constructor arguments. The new utilities found in
|
||||
'os/include/util/volatile_object.h' solve this problem. A so-called
|
||||
'Volatile_object' wraps an object of the type specified as template argument.
|
||||
In contrast of a regular object, a 'Volatile_object' can be re-constructed any
|
||||
number of times by calling 'construct' with the constructor arguments. It is
|
||||
accompanied with a so-called 'Lazy_volatile_object', which remains
|
||||
unconstructed until 'construct' is called the first time.
|
||||
|
||||
|
||||
Changed interface of 'Signal_rpc_member'
|
||||
========================================
|
||||
|
||||
We unified the 'Signal_rpc_member' interface to be more consistent with the
|
||||
'Signal_rpc_dispatcher'. The new version takes an entrypoint as argument and
|
||||
cares for dissolving itself from the entrypoint when destructed.
|
||||
|
||||
|
||||
Filename as default label for ROM connections
|
||||
=============================================
|
||||
|
||||
Since the first version of Genode, ROM services used to rely on a "filename"
|
||||
provided as session argument. In the meanwhile, we established the use of the
|
||||
session label to select routing policies as well as server-side policies.
|
||||
Strictly speaking, the name of a ROM module is used as a key to a server-side
|
||||
policy of ROM services. So why not to use the session label to express the
|
||||
key as we do with other services? By assigning the file name as label for ROM
|
||||
sessions, we may become able to remove the filename argument in the future by
|
||||
just interpreting the last part of the label as filename. By keeping only the
|
||||
label, we won't need to consider conditional routing (via '<if-arg>') based on
|
||||
session arguments other than the label anymore, which would simplify Genode
|
||||
configurations in the long run. This change is transparent at API level but
|
||||
may be taken into consideration when configuring Genode systems.
|
||||
|
||||
|
||||
New 'Genode::Deallocator' interface
|
||||
===================================
|
||||
|
||||
By splitting the new 'Genode::Deallocator' interface from the former
|
||||
'Genode::Allocator' interface, we become able to restrict the accessible
|
||||
operations for code that is only supposed to release memory, but not
|
||||
perform any allocations.
|
||||
|
||||
Closely related to the allocator interface, we introduced variants of the
|
||||
'new' operator that take a reference (as opposed to a pointer) to a
|
||||
'Genode::Allocator' as argument.
|
||||
|
||||
|
||||
Unified main-stack management and startup code among all platforms
|
||||
==================================================================
|
||||
|
||||
In contrast to the stacks of regular threads, which are located within a
|
||||
dedicated virtual-address region called thread-context area, the stack of
|
||||
the main thread of a Genode program used to be located within the BSS
|
||||
segment. If the stack of a normal thread overflows, the program produces
|
||||
an unresolvable page fault, which can be easily debugged. However,
|
||||
an overflowing main stack would silently corrupt the BSS segment. With
|
||||
the current release, we finally resolved this long-standing problem by
|
||||
moving the main stack to the context area, too. The tricky part was that
|
||||
the context area is created by the main thread. So we hit a hen-and-egg
|
||||
problem. We overcame this problem by splitting the process startup
|
||||
into two stages, both called from the crt0 assembly code. The first
|
||||
stage runs on a small stack within the BSS and has the sole purpose
|
||||
of creating the context area and a thread object for the main thread.
|
||||
This code path (and thereby the stack usage) is the same for all programs.
|
||||
So we can safely dimension the stage-1 stack. Once the first stage
|
||||
returns to the crt0 assembly code, the stack pointer is loaded with the
|
||||
stack that is now located within the context area. Equipped with the
|
||||
new stack, the actual startup code ('_main') including the global
|
||||
constructors of the program is executed.
|
||||
|
||||
This change paved the ground for several further code unifications and
|
||||
simplifications, in particular related to the dynamic linker.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Revised block-driver framework
|
||||
==============================
|
||||
|
||||
Whereas Genode's block-session interface was designed to work asynchronously
|
||||
and supports the out-of-order processing of requests, those capabilities
|
||||
remained unused by the existing block services as those services used to
|
||||
operate synchronously to keep their implementation simple. However, this
|
||||
simplicity came at the prize of two disadvantages: First, it prevented us
|
||||
to fully utilize native command queuing of modern disk controllers. Second,
|
||||
when chaining components such as a block driver, the part_blk server, and
|
||||
a file system, latencies accumulated along the chain of services. This
|
||||
hurts the performance of random access patterns.
|
||||
|
||||
To overcome this limitation, we changed the block-component framework to work
|
||||
asynchronously and to facilitate the recently introduced server API.
|
||||
Consequently, all users of the API underwent an update. The affected
|
||||
components are rom_loopdev, atapi_drv, fb_block_adapter, http_block, usb_drv,
|
||||
and part_blk. For some components, in particular part_blk, this step led to a
|
||||
complete redesign.
|
||||
|
||||
Besides the change of the block-component framework, the block-session
|
||||
interface got extended to support logical block addresses greater than
|
||||
32bit (LBA48). Thereby, the block component framework can now support
|
||||
devices that exceed 2 TiB in size.
|
||||
|
||||
|
||||
Block cache
|
||||
===========
|
||||
|
||||
The provisioning of a block cache was one of the primary motivations behind the
|
||||
[http://www.genode.org/documentation/release-notes/13.11#Dynamic_resource_balancing - dynamic resource balancing]
|
||||
concept that was introduced in Genode 13.11. We are now introducing the first
|
||||
version of such a cache.
|
||||
|
||||
The new block cache component located at _os/src/server/blk_cache/_ is both
|
||||
a block-session client as well as a block-session server serving a single
|
||||
client. It is meant to sit between a block-device driver and a file-system
|
||||
server. When accessing the block device, it issues requests at a granularity
|
||||
of 4K and thereby implicitly reads ahead whenever a client requests a smaller
|
||||
amount of blocks. Blocks obtained from the device or written by the client
|
||||
are kept in memory. If memory becomes scarce, the block cache first tries
|
||||
to request further memory resources from its parent. If the request
|
||||
gets denied, the cache evicts blocks from memory to the block device following
|
||||
a least-recently-used replacement strategy. As of now, the block cache supports
|
||||
dynamic resource requests to grow on demand but support for handling yield
|
||||
requests is not yet implemented. So memory once handed out to the block cache
|
||||
cannot be regained. Adding support for yielding memory on demand will be
|
||||
complemented in the next version.
|
||||
|
||||
To see how to integrate the block cache in a Genode scenario, there is a
|
||||
ready-to-use run script available at _os/run/blk_cache.run_.
|
||||
|
||||
|
||||
|
||||
File-system infrastructure
|
||||
==========================
|
||||
|
||||
In addition to the integration of NetBSD's file systems, there are
|
||||
file-system-related improvements all over the place.
|
||||
|
||||
First, the 'File_system::Session' interface has been extended with a 'sync'
|
||||
RPC function. This function allows the client of a file system to force
|
||||
the file system to write back its internal caches.
|
||||
|
||||
Second, we extended the FUSE implementation introduced with the previous
|
||||
release.
|
||||
Since file systems tend to have a built-in caching mechanism, we need to
|
||||
sync these caches at the end of a session when using the fuse_fs server.
|
||||
Therefore, each FUSE file system port has to implement a 'Fuse::sync_fs()'
|
||||
function that executes the necessary actions if requested. Further
|
||||
improvements are related to the handling of symbolic links and error
|
||||
handling. Finally, we added a libc plugin for accessing NTFS file systems
|
||||
via the ntfs-3g library.
|
||||
|
||||
Third, we complemented the family of FUSE-based libc plugins with a family of
|
||||
FUSE-based file-system servers. To utilize a FUSE file system, there is a
|
||||
dedicated binary (e.g., _os/src/server/fuse_fs/ext2_) for each FUSE
|
||||
file-system server.
|
||||
Note that write support is possible but considered to be experimental at this
|
||||
point. For now, using it is not recommended.
|
||||
To use the ext2_fuse_fs server in Noux, the following configuration snippet
|
||||
may be used:
|
||||
|
||||
! <start name="ext2_fuse_fs">
|
||||
! <resource name="RAM" quantum="8M"/>
|
||||
! <provides> <service name="File_system"/> </provides>
|
||||
! <config>
|
||||
! <policy label="noux -> fuse" root="/" writeable="no" />
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
Finally, the libc file-system plugin has been extended to support 'unlink'.
|
||||
|
||||
|
||||
Trace file system
|
||||
=================
|
||||
|
||||
The new _trace_fs_ server provides access to a trace session by providing a
|
||||
file-system session as front end. Combined with Noux, it allows for the
|
||||
interactive exploration and tracing of Genode's process tree using
|
||||
traditional Unix tools.
|
||||
|
||||
Each trace subject is represented by a directory ('thread_name.subject') that
|
||||
contains specific files, which are used to control the tracing process of the
|
||||
thread as well as storing the content of its trace buffer:
|
||||
|
||||
:'enable': The tracing of a thread is activated if there is a valid policy
|
||||
installed and the intend to trace the subject was made clear by writing '1'
|
||||
to the 'enable' file. The tracing of a thread may be deactivated by writing a
|
||||
'0' to this file.
|
||||
|
||||
:'policy': A policy may be changed by overwriting the currently used one in the
|
||||
'policy' file. In this case, the old policy is replaced by the new one and
|
||||
automatically used by the framework.
|
||||
|
||||
:'buffer_size': Writing a value to the 'buffer_size' file changes the size of
|
||||
the trace buffer. This value is evaluated only when reactivating the tracing
|
||||
of the thread.
|
||||
|
||||
:'events': The trace-buffer contents may be accessed by reading from the
|
||||
'events' file. New trace events are appended to this file.
|
||||
|
||||
:'active': Reading the file will return whether the tracing is active (1) or
|
||||
not (0).
|
||||
|
||||
:'cleanup': Nodes of untraced subjects are kept as long as they do not change
|
||||
their tracing state to dead. Dead untraced nodes are automatically removed
|
||||
from the file system. Subjects that were traced before and are now untraced
|
||||
can be removed by writing '1' to the 'cleanup' file.
|
||||
|
||||
To use the trace_fs, a configuration similar to the following may be used:
|
||||
|
||||
! <start name="trace_fs">
|
||||
! <resource name="RAM" quantum="128M"/>
|
||||
! <provides><service name="File_system"/></provides>
|
||||
! <config>
|
||||
! <policy label="noux -> trace"
|
||||
! interval="1000"
|
||||
! subject_limit="512"
|
||||
! trace_quota="64M" />
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
:'interval': sets the period the Trace_session is polled. The
|
||||
time is given in milliseconds.
|
||||
|
||||
:'subject_limit': specifies how many trace subjects should by acquired at
|
||||
max when the Trace_session is polled.
|
||||
|
||||
:'trace_quota': is the amount of quota the trace_fs should use for the
|
||||
Trace_session connection. The remaining amount of RAM quota will be used
|
||||
for the actual nodes of the file system and the 'policy' as well as the
|
||||
'events' files.
|
||||
|
||||
In addition, there are 'buffer_size' and 'buffer_size_limit' that define
|
||||
the initial and the upper limit of the size of a trace buffer.
|
||||
|
||||
A ready-to-use run script can by found in 'ports/run/noux_trace_fs.run'.
|
||||
|
||||
|
||||
Unified interfaces for graphics
|
||||
===============================
|
||||
|
||||
Genode comes with several programs that perform software-based graphics
|
||||
operations. A few noteworthy examples are the nitpicker GUI server,
|
||||
the launchpad, the scout tutorial browser, or the terminal. Most of those
|
||||
programs were equipped with their custom graphics back end. In some
|
||||
cases such as the terminal, nitpicker's graphics back end was re-used.
|
||||
But this back end is severely limited because its sole purpose is the
|
||||
accommodation of the minimalistic (almost invisible) nitpicker GUI server.
|
||||
|
||||
The ongoing work on Genode's new user interface involves the creation of
|
||||
new components that rely on a graphics back end. Instead of further
|
||||
diversifying the zoo of graphics back ends, we took the intermediate step
|
||||
to consolidate the existing back ends into one unified concept such that
|
||||
application-specific graphics back ends can be created and extended using
|
||||
modular building blocks. The new versions of nitpicker, scout, launchpad,
|
||||
liquid_fb, nitlog, and terminal have been changed to use the new common
|
||||
interfaces:
|
||||
|
||||
:os/include/util/geometry.h: Basic data structures and operations needed
|
||||
for 2D graphics.
|
||||
|
||||
:os/include/util/color.h: Common color representation and utilities.
|
||||
|
||||
:os/include/os/pixel_rgba.h: Class template for representing a pixel.
|
||||
|
||||
:os/include/os/pixel_rgb565.h: Template specializations for RGB565 pixels.
|
||||
|
||||
:os/include/os/surface.h: Target surface, onto which graphics operations
|
||||
can be applied.
|
||||
|
||||
:os/include/os/texture.h: Source texture for graphics operations that
|
||||
transfer 2D pixel data to a surface.
|
||||
|
||||
The former _os/include/nitpicker_gfx/_ directory is almost deserted. The only
|
||||
remainders are functors for the few graphics operations actually required by
|
||||
nitpicker. For the scout widgets, the corresponding functors have become
|
||||
available at the public headers at _demo/include/scout_gfx/_.
|
||||
|
||||
Because the scout widget set is used by at least three programs and will
|
||||
most certainly play a role in new GUI components, we undertook a major
|
||||
cleanup of the parts worth reusing. The result can be found at
|
||||
_demo/include/scout/_.
|
||||
|
||||
|
||||
New session interface for status reporting
|
||||
==========================================
|
||||
|
||||
Genode has a uniform way of how configuration information is passed from
|
||||
parents to children within the process tree by the means of "config" ROM
|
||||
modules. Using this mechanism, a parent is able to steer the behaviour of
|
||||
its children, not just at their start time but also during runtime.
|
||||
Until now, however, there was no counterpart to the config mechanism, which
|
||||
would allow a child to propagate runtime information to its parent. There
|
||||
are many use cases for such a mechanism. For example, a bus-controller driver
|
||||
might want to propagate a list of devices attached to the bus. When a new
|
||||
device gets plugged in, this list should be updated to let the parent
|
||||
take the new device resource into consideration. Another use case would be the
|
||||
propagation of status information such as the feature set of a plugin.
|
||||
Taken to the extreme, a process might expose its entire internal state to its
|
||||
parent in order to allow the parent to kill and restart the process, and
|
||||
feed the saved state back to the new process instance.
|
||||
|
||||
To cover these use cases, we introduced the new report-session interface. When
|
||||
a client opens a report session, it transfers a part of its RAM quota to the
|
||||
report server. In return, the report server hands out a dataspace dimensioned
|
||||
according to the donated quota. Upon reception of the dataspace, the client
|
||||
can write its status reports into the dataspace and inform the server about
|
||||
the update via the 'submit' function. In addition to the mere reporting of
|
||||
status information, the report-session interface is designed to allow the
|
||||
server to respond to reports. For example, if the report mechanism is used to
|
||||
implement a desktop notification facility, the user may interactively respond
|
||||
to an incoming notification. This response can be reflected to the originator
|
||||
of the notification via the 'response_sigh' and 'obtain_response' functions.
|
||||
|
||||
The new _report_rom_ component is both a report service and a ROM service. It
|
||||
reflects incoming reports as ROM modules. The ROM modules are named
|
||||
after the label of the corresponding report session.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The report-ROM server hands out ROM modules only if explicitly permitted by a
|
||||
configured policy. For example:
|
||||
|
||||
! <config>
|
||||
! <rom>
|
||||
! <policy label="decorator -> pointer" report="nitpicker -> pointer"/>
|
||||
! <policy ... />
|
||||
! ...
|
||||
! </rom>
|
||||
! </config>
|
||||
|
||||
The label of an incoming ROM session is matched against the 'label' attribute
|
||||
of all '<policy>' nodes. If the session label matches a policy label, the
|
||||
client obtains the data from the report client with the label specified in the
|
||||
'report' attribute. In the example above, the nitpicker GUI server sends
|
||||
reports about the pointer position to the report-ROM service. Those reports
|
||||
are handed out to a window decorator (labeled "decorator") as ROM module.
|
||||
|
||||
|
||||
XML generator utility
|
||||
=====================
|
||||
|
||||
With the new report-session interface in place, comes the increased
|
||||
need to produce XML data. The new XML generator utility located at
|
||||
_os/include/util/xml_generator.h_ makes this extremely easy, thanks to
|
||||
C++11 language features. For an example application, refer to
|
||||
_os/src/test/xml_generator/_ and the corresponding run script at
|
||||
_os/run/xml_generator.run_.
|
||||
|
||||
|
||||
Dynamic ROM service for automated testing
|
||||
=========================================
|
||||
|
||||
The new _dynamic_rom_ service provides ROM modules that change during the
|
||||
lifetime of a ROM session according to a timeline. The main purpose of this
|
||||
service is the automated testing of programs that are able to respond to ROM
|
||||
module changes, for example configuration changes.
|
||||
|
||||
The configuration of the dynamic ROM server contains a '<rom>' sub node per
|
||||
ROM module provided by the service. Each '<rom>' node hosts a 'name' attribute
|
||||
and contains a sequence of sub nodes that define the timeline of the ROM
|
||||
module. The possible sub nodes are:
|
||||
|
||||
:'<inline>': The content of the '<inline>' node is assigned to the content
|
||||
of the ROM module.
|
||||
|
||||
:'<sleep>': Sleeps a number of milliseconds as specified via the 'milliseconds'
|
||||
attribute.
|
||||
|
||||
:'<empty>': Removes the ROM module.
|
||||
|
||||
At the end of the timeline, it re-starts at the beginning.
|
||||
|
||||
|
||||
Nitpicker GUI server
|
||||
====================
|
||||
|
||||
The nitpicker GUI server has been enhanced to support dynamic screen
|
||||
resizing. This is needed to let nitpicker respond to screen-resolution
|
||||
changes, or when using a nested version of nitpicker within a resizable
|
||||
virtual framebuffer window.
|
||||
|
||||
To accommodate Genode's upcoming user-interface concept, we introduced the
|
||||
notion of a parent-child relationship between nitpicker views. If an existing
|
||||
view is specified as parent at construction time of a new view, the parent
|
||||
view's position is taken as the origin of the child view's coordinate space.
|
||||
This allows for the grouping of views, which can be atomically repositioned by
|
||||
moving their common parent view. Another use case is the handling of popup
|
||||
menus in Qt5, which can now be positioned relative to their corresponding
|
||||
top-level window. The relative position is maintained transparently to Qt when
|
||||
the top-level window gets repositioned.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Noux runtime for executing Unix software
|
||||
========================================
|
||||
|
||||
Noux plays an increasingly important role for Genode as it allows the use
|
||||
of the GNU software stack. Even though it already supported a variety of
|
||||
packages including bash, gcc, binutils, coreutils, make, and vim, some
|
||||
programs were still limited by Noux' not fully complete POSIX semantics,
|
||||
in particular with regard to signal handling. For example, it was not
|
||||
possible to cancel the execution of a long-running process via Control-C.
|
||||
|
||||
To overcome those limitations, we enhanced Noux by adding the _kill_ syscall,
|
||||
reworking the _wait_ and _execve_ syscalls, as well as adding
|
||||
signal-dispatching code to the Noux libc. Special attention had to be paid to
|
||||
the preservation of pending signals during the process creation via _fork_ and
|
||||
_execve_.
|
||||
|
||||
The current implementation delivers signals each time a Noux syscall
|
||||
returns. Signal handlers are executed as part of the normal control flow. This
|
||||
is in contrast to traditional Unix implementations, which allow the
|
||||
asynchronous invocation of signal handlers out of band with the regular
|
||||
program flow. The obvious downside of our solution is that a program that got
|
||||
stuck in a busy loop (and thereby not issuing any system calls) won't respond
|
||||
to signals. However, as we regard the Unix interface just as a runtime and not
|
||||
as the glue that holds the system together, we think that this compromise is
|
||||
justified to keep the implementation simple and kernel-agnostic. In the worst
|
||||
case, if a Noux process gets stuck because of such a bug, we certainly can
|
||||
live with the inconvenience of restarting the corresponding Noux subsystem.
|
||||
|
||||
To complement our current activities on the block and file-system levels,
|
||||
the e2fsprogs-v1.42.9 package as been ported to Noux. To allow the
|
||||
block-device utilities to operate on Genode's block sessions, we added a new
|
||||
"block" file system to Noux. Such a block file system can be mounted using a
|
||||
'<block>' node within the '<fstab>'. By specifying a label attribute, each
|
||||
block session request can be routed to the proper block session provider:
|
||||
|
||||
! <fstab>
|
||||
! ...
|
||||
! <dir name="dev">
|
||||
! <block name="blkdev0" label="block_session_0" />
|
||||
! </dir>
|
||||
! ...
|
||||
! </fstab>
|
||||
|
||||
In addition to this file system, support for the DIOCGMEDIASIZE ioctl
|
||||
request was added. This request is used by FreeBSD and therefore by our
|
||||
libc to query the size of the block device in bytes.
|
||||
|
||||
|
||||
Qt5 refinements
|
||||
===============
|
||||
|
||||
Our port of Qt5 used to rely on custom versions of synchronization
|
||||
primitives such as 'QWaitCondition' and 'QMutex'. However, since most of the
|
||||
usual pthread synchronization functions as relied on by Qt5's regular POSIX
|
||||
back end have been added to Genode's pthread library by now, we could replace
|
||||
our custom implementations by Qt5's POSIX version.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
The development of our base-hw kernel platform during this release cycle was
|
||||
primarily geared towards adding multi-processor support. However, as we
|
||||
haven't exposed the code to thorough testing yet, we deferred the integration
|
||||
of this feature for the current release.
|
||||
|
||||
We increased the number of usable ARM platforms by adding basic support for
|
||||
the ODROID XU board.
|
||||
|
||||
|
||||
NOVA microhypervisor
|
||||
====================
|
||||
|
||||
The port of VirtualBox to Genode prompted us to improve the NOVA platform in
|
||||
the following respects.
|
||||
|
||||
NOVA used to omit the propagation of the FPU state of the guest OS to the
|
||||
virtual machine monitor (VMM) during the world switch between the guest OS and
|
||||
the VMM. With the Vancouver VMM, which is traditionally used on NOVA, this
|
||||
omission did not pose any problem because Vancouver would never touch the FPU
|
||||
state of the guest. So the FPU context of the guest was always preserved
|
||||
throughout the handling of virtualization events. However, in contrast to the
|
||||
Vancouver VMM, VirtualBox relies on the propagation of the FPU state between
|
||||
the guest running in VT-X non-root mode and the guest running within the
|
||||
VirtualBox recompiler. Without properly propagating the FPU state between both
|
||||
virtualization back ends, both the guest OS in non-root mode and VirtualBox's
|
||||
recompiler would corrupt each other's FPU state. After first implementing an
|
||||
interim solution in our custom version of the kernel, the missing FPU context
|
||||
propagation had been implemented in the upstream version of NOVA as well.
|
||||
|
||||
In contrast to most kernels, NOVA did not allow a thread to yield its current
|
||||
time slice to another thread. The only way to yield CPU time was to block on
|
||||
a semaphore or to perform an RPC call. Unfortunately both of those instruments
|
||||
require the time-receiving threads to explicitly unblock the yielding thread
|
||||
(by releasing the semaphore or replying to the RPC call). However, there are
|
||||
situations where the progress of a thread may depend on an external
|
||||
condition or a side effect produced by another (unknown) thread. One
|
||||
particular example is the spin lock used to protect (an extremely short)
|
||||
critical section of Genode's lock metadata. Apparently VirtualBox presented
|
||||
us with several more use cases for thread-yield semantics. Therefore, we
|
||||
decided to extend NOVA's kernel interface with a new 'YIELD' opcode to the
|
||||
'ec_control' system call.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,899 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 15.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
Genode's [http://genode.org/about/road-map - roadmap] for this year puts a
|
||||
strong emphasis on the consolidation and cultivation of the existing feature
|
||||
set. With the first release of the year, version 15.02 pays tribute to this
|
||||
mission by stepping up to extensive and systematic automated testing. As
|
||||
a precondition for scaling up Genode's test infrastructure, the release
|
||||
features a highly modular tool kit for exercising system scenarios on a growing zoo
|
||||
of test machines. Section [Modular tool kit for automated testing] explains
|
||||
the new tools in detail. In the spirit of improving the existing feature
|
||||
set, Genode 15.02 vastly improves the performance and stability of our version of
|
||||
VirtualBox running on the NOVA microhypervisor, solves long-standing shortcomings
|
||||
of memory management on machines with a lot of RAM, addresses NOVA-related
|
||||
scalability limitations, stabilizes our Rump-kernel-based file-system server,
|
||||
and refines the configuration interface of the Intel wireless driver.
|
||||
|
||||
As the most significant new feature, the new version introduces virtualization
|
||||
support for ARM to our custom base-hw kernel. Section [Virtualization on ARM]
|
||||
outlines the design and implementation of this feature, which was greatly
|
||||
inspired by NOVA's virtualization architecture and has been developed over the
|
||||
time span of more than a year.
|
||||
|
||||
With respect to platform support, we are happy to accommodate the upcoming
|
||||
USB-Armory board, which is a computer in the form factor of a USB
|
||||
stick especially geared towards security applications. Section
|
||||
[Support for the USB-Armory board] covers the background and the current
|
||||
state of this line of work.
|
||||
|
||||
|
||||
Virtualization on ARM
|
||||
#####################
|
||||
|
||||
The ARMv7 architecture of recent processors like Cortex-A7, Cortex-A15, or
|
||||
Cortex-A17 CPUs support hardware extensions to facilitate virtualization of
|
||||
guest operating systems. With the current release, we enable the use of these
|
||||
virtualization extensions in our custom base-hw kernel when running on the
|
||||
Cortex-A15-based Arndale board.
|
||||
|
||||
While integrating ARM's virtualization extension, we aimed to strictly follow
|
||||
microkernel-construction principles. The primary design is inspired by the
|
||||
[http://hypervisor.org/ - NOVA OS Virtualization Architecture]. It is based on a
|
||||
microhypervisor that provides essential microkernel mechanisms along with
|
||||
basic primitives to switch between virtual machines (VMs). On top of the
|
||||
microhypervisor, classical OS services are implemented as
|
||||
ordinary, unprivileged user-level components. Those services can be used by other
|
||||
applications. Services may be shared between applications or instantiated
|
||||
separately, according to security and safety needs. Correspondingly,
|
||||
following the NOVA principles, each VM has its own associated virtual-machine
|
||||
monitor (VMM) that runs as an unprivileged user-level component. VMM implementations
|
||||
can range from simple ones that just emulate primary device requirements to highly
|
||||
complex monitors including sophisticated device models, like VirtualBox. The
|
||||
NOVA approach allows to decouple the TCB complexity of one VM with respect to
|
||||
another, as well as with respect to all components not related to
|
||||
virtualization at all.
|
||||
|
||||
Along those lines, we extended the base-hw kernel/core conglomerate with API
|
||||
extensions that enable user-level VMM components to create and control virtual
|
||||
machines.
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
The ARM virtualization extensions are based on the so-called security
|
||||
extensions, commonly known as
|
||||
[http://genode.org/documentation/articles/trustzone - TrustZone].
|
||||
The ARM designers did not follow the
|
||||
Intel approach to split the CPU into a "root" and a "guest" world while having all prior
|
||||
existing CPU modes available in both worlds. Instead, ARM added a new privilege level
|
||||
to the non-secure side of TrustZone that sits underneath the ordinary kernel
|
||||
and userland privilege levels. It is subjected to a hypervisor-like kernel. All
|
||||
instructions used to prepare a VM's environment have to be executed in this so
|
||||
called "hyp" mode. In hyp mode, some instructions
|
||||
differ from their regular behaviour on the kernel-privilege level.
|
||||
For this reason, prior-existing kernel code cannot simply be reused in
|
||||
hyp mode without modifications.
|
||||
|
||||
The base-hw kernel is meant to execute Genode's core component on bare hardware.
|
||||
Core, which is an ordinary user-level component, is
|
||||
linked together with a slim kernel library that is executed in privileged kernel
|
||||
mode. To enable ARM hardware virtualization, we pushed this approach
|
||||
even further by executing core in three different privilege levels. Thereby,
|
||||
core shares the same view on hardware resources and virtual memory across all
|
||||
levels. A code path is executed on a higher privilege level only if the code
|
||||
would fail to execute on a lower privilege level.
|
||||
Following this approach, we were able to keep most of the existing kernel code
|
||||
with no modifications.
|
||||
|
||||
[image avirt_overview]
|
||||
Genode's ARM kernel (core) runs across all privilege levels
|
||||
|
||||
The hypervisor part of core is solely responsible to switch between VMs and the
|
||||
host system. Therefore, it needs to load/store additional CPU state that
|
||||
normally remains untouched during context switches of ordinary tasks. It also needs to
|
||||
configure the VM's guest-physical to host-physical memory translations. Moreover, the
|
||||
virtualization extensions of the ARMv7 architecture are not related to the CPU
|
||||
cores only. The interrupt controller and the CPU-local timers are also
|
||||
virtualization-aware. Therefore, the hypervisor has to load/store state specific
|
||||
to those devices, too. Nevertheless, the hypervisor merely reloads those
|
||||
devices. It does not interpret their state.
|
||||
|
||||
In contrast to the low-complexity hypervisor, a user-level VMM can be complex
|
||||
without putting the system's security at risk. It contains potentially complex
|
||||
device-emulation code and assigns hardware resources such as memory and
|
||||
interrupts to the VM. The VMM is an ordinary user-level component running
|
||||
unprivileged. Of course, as a plain user-level component, it is not able to
|
||||
directly access hardware resources. Hence an interface between VMMs and the
|
||||
kernel is needed to share the state of a virtual machine. In the past, we faced a similar
|
||||
problem when building a VMM for our former TrustZone experiments. It was natural
|
||||
to build upon the available solution and to extend it where necessary. Core
|
||||
provides a so-called VM service. Each VM corresponds to a session of this
|
||||
service. The session provides the following extended interface:
|
||||
|
||||
:CPU state:
|
||||
The CPU-state function returns a dataspace containing the virtual machine's
|
||||
state. The state is initialized by the VMM before bootstrapping the VM, gets updated
|
||||
by the hypervisor whenever it switches away from the VM, and can be used by
|
||||
the VMM to interpret the behavior of the guest OS. Moreover, the CPU state can be
|
||||
updated after the virtual machine monitor emulated instructions
|
||||
for the VM.
|
||||
|
||||
:Exception handler:
|
||||
The second function is used to register a signal handler that gets informed
|
||||
whenever the VM produces a virtualization fault.
|
||||
|
||||
:Run:
|
||||
The run function starts or resumes the execution of the VM.
|
||||
|
||||
:Pause:
|
||||
The pause function removes the VM from the kernel's scheduler.
|
||||
|
||||
:Attach:
|
||||
This function attaches a given RAM dataspace to a designated area of the
|
||||
guest-physical address space.
|
||||
|
||||
:Detach:
|
||||
The detach function invalidates a designated area of the guest-physical
|
||||
address space.
|
||||
|
||||
:Attach_pic: Tells the hypervisor to attach the CPU's virtual interface of the
|
||||
virtualization-aware interrupt controller to a designated area of the
|
||||
guest-physical address space.
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
By strictly following the micro-kernel construction principles when integrating the
|
||||
hypervisor into the base-hw kernel, we reached a minimally invasive solution. In
|
||||
doing so, we took the time to separate TrustZone-specific code that was formerly
|
||||
an inherent part of the kernel on ARMv7 platforms. Now, TrustZone- and
|
||||
virtualization-specific aspects are incorporated into the kernel only if
|
||||
actually used. The change in complexity of the whole core component expressed in
|
||||
lines of code is shown in the table below. As can be seen, the additional code in
|
||||
the root of the trusted computing base when using virtualization is about 700-800
|
||||
LOC.
|
||||
|
||||
Platform | with TrustZone, no VT | TrustZone/VT optional
|
||||
-----------------------------------------------------------------
|
||||
hw_arndale | 17970 LOC | 18730 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_imx53_qsb | 17900 LOC | 17760 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_imx53_qsb_tz | 18260 LOC | 18320 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_rpi | 17500 LOC | 17430 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_panda | 18040 LOC | 17880 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_odroid_xu | 17980 LOC | 18050 LOC
|
||||
|
||||
Besides the VM world switch, we enabled support for the so-called "large
|
||||
physical address extension" (LPAE), which is obligatory when using
|
||||
virtualization. It allows for addressing a 40-bit instead of only 32-bit physical
|
||||
address space. Moreover, to execute in hypervisor mode, the bootstrap code of
|
||||
the kernel had to be set up properly. Hence, when booting on the Arndale board,
|
||||
the kernel now prepares the non-secure TrustZone world first, and finally leaves the
|
||||
secure world forever.
|
||||
|
||||
To test and showcase the ARM virtualization features integrated in base-hw, we
|
||||
implemented a minimal, exemplary VMM. It can be found in
|
||||
_repos/os/src/server/vmm_. The VMM emulates a simplified variant of ARM's
|
||||
Versatile Express Cortex-A15 development platform. Currently, it only comprises
|
||||
support for the CPU, the timer, the interrupt controller, and a UART device. It is
|
||||
written in 1100 lines of C++ in addition to the base Genode libraries. The VMM
|
||||
is able to boot a vanilla Linux kernel compiled with a slightly modified
|
||||
standard configuration (no-SMP), and a device tree description stripped down to
|
||||
the devices provided by the VMM. This release includes an automated run test that
|
||||
executes the Linux kernel on top of the VMM on Genode. It can be started via:
|
||||
|
||||
! make run/vmm
|
||||
|
||||
[image avirt_screen]
|
||||
Three Linux serial consoles running in parallel on top of Genode
|
||||
|
||||
|
||||
Modular tool kit for automated testing
|
||||
######################################
|
||||
|
||||
In
|
||||
[http://genode.org/documentation/release-notes/13.05#Automated_quality-assurance_testing - Genode version 13.05],
|
||||
we already introduced comprehensive support for the automated testing of
|
||||
Genode scenarios. Since then, Genode Labs has significantly widened the scope
|
||||
of its internal test infrastructure, both in terms of the coverage of the test
|
||||
scenarios as well as the variety of the used hardware platforms.
|
||||
|
||||
The centerpiece of our test infrastructure is the so-called run tool. Steered
|
||||
by a script (run script), it performs all the steps necessary to test drive
|
||||
a Genode system scenario. Those steps are:
|
||||
|
||||
# *Building* the components of a scenario
|
||||
# *Configuration* of the init component
|
||||
# Assembly of the *boot directory*
|
||||
# Creation of the *boot image*
|
||||
# *Powering-on* the test machine
|
||||
# *Loading* of the boot image
|
||||
# Capturing the *LOG output*
|
||||
# *Validation* of the scenario behavior
|
||||
# *Powering-off* the test machine
|
||||
|
||||
Each of those steps depends on various parameters such as the
|
||||
used kernel, the hardware platform used to run the scenario, the
|
||||
way the test hardware is connected to the test infrastructure
|
||||
(e.g., UART, AMT, JTAG, network), the way the test hardware is powered or
|
||||
reseted, or the way of how the scenario is loaded into the test hardware.
|
||||
Naturally, to accommodate the growing variety of combinations of those
|
||||
parameters, the complexity of the run tool increased over time.
|
||||
This growth of complexity prompted us to eventually turn the run tool into a
|
||||
highly modular and extensible tool kit.
|
||||
|
||||
Originally, the run tool consisted of built-in rules that could be
|
||||
extended and tweaked by a kernel-specific supplement called run environment.
|
||||
The execution of a run script used to depend on the policies built into
|
||||
the run tool, the used run environment, and optional configuration
|
||||
parameters (run opts).
|
||||
|
||||
The new run tool kit replaces most of the formerly built-in policies by the
|
||||
ability to select and configure different modules for the various steps.
|
||||
The selection and configuration of the modules is expressed in the run-tool
|
||||
configuration. There exist the following types of modules:
|
||||
|
||||
:boot-dir modules:
|
||||
These modules contain the functionality to populate the boot directory
|
||||
and are specific to each kernel. It is mandatory to always include the
|
||||
module corresponding to the used kernel.
|
||||
|
||||
_(the available modules are: linux, hw, okl4, fiasco, pistachio, nova,_
|
||||
_codezero, foc)_
|
||||
|
||||
:image modules:
|
||||
These modules are used to wrap up all components used by the run script
|
||||
in a specific format and thereby prepare them for execution.
|
||||
Depending on the used kernel, different formats can be used. With these
|
||||
modules, the creation of ISO and disk images is also handled.
|
||||
|
||||
_(the available modules are: uboot, disk, iso)_
|
||||
|
||||
:load modules:
|
||||
These modules handle the way the components are transfered to the
|
||||
target system. Depending on the used kernel there are various options
|
||||
to pass on the components. For example, loading from TFTP or via JTAG is handled
|
||||
by the modules of this category.
|
||||
|
||||
_(the available modules are: tftp, jtag, fastboot)_
|
||||
|
||||
:log modules:
|
||||
These modules handle how the output of a currently executed run script
|
||||
is captured.
|
||||
|
||||
_(the available modules are: qemu, linux, serial, amt)_
|
||||
|
||||
:power_on modules:
|
||||
These modules are used for bringing the target system into a defined
|
||||
state, e.g., by starting or rebooting the system.
|
||||
|
||||
_(the available modules are: qemu, linux, softreset, powerplug, amt)_
|
||||
|
||||
:power_off modules:
|
||||
These modules are used for turning the target system off after the
|
||||
execution of a run script.
|
||||
|
||||
_(the available modules are: powerplug)_
|
||||
|
||||
When executing a run script, only one module of each category must be used.
|
||||
|
||||
Each module has the form of a script snippet located under the
|
||||
_tool/run/<step>/_
|
||||
directory where _<step>_ is a subdirectory named after the module type.
|
||||
Further instructions about the use of each module (e.g., additional
|
||||
configuration arguments) can be found in the form of comments inside the
|
||||
respective script snippets.
|
||||
Thanks to this modular structure,
|
||||
the extension of the tool kit comes down to adding a file at the corresponding
|
||||
module-type subdirectory. This way, custom work flows (such as tunneling JTAG
|
||||
over SSH) can be accommodated fairly easily.
|
||||
|
||||
|
||||
Usage examples
|
||||
==============
|
||||
|
||||
To execute a run script, a combination of modules may be used. The combination
|
||||
is controlled via the RUN_OPT variable used by the build framework. Here are a
|
||||
few common exemplary combinations:
|
||||
|
||||
Executing NOVA in Qemu:
|
||||
|
||||
!RUN_OPT = --include boot_dir/nova \
|
||||
! --include power_on/qemu --include log/qemu --include image/iso
|
||||
|
||||
Executing NOVA on a real x86 machine using AMT for resetting the target system
|
||||
and for capturing the serial output while loading the files via TFTP:
|
||||
|
||||
!RUN_OPT = --include boot_dir/nova \
|
||||
! --include power_on/amt --power-on-amt-host 10.23.42.13 \
|
||||
! --power-on-amt-password 'foo!' \
|
||||
! --include load/tftp --load-tftp-base-dir /var/lib/tftpboot \
|
||||
! --load-tftp-offset-dir /x86 \
|
||||
! --include log/amt --log-amt-host 10.23.42.13 \
|
||||
! --log-amt-password 'foo!'
|
||||
|
||||
Executing Fiasco.OC on a real x86 machine using AMT for resetting, USB serial
|
||||
for output while loading the files via TFTP:
|
||||
|
||||
!RUN_OPT = --include boot_dir/foc \
|
||||
! --include power_on/amt --amt-host 10.23.42.13 --amt-password 'foo!' \
|
||||
! --include load/tftp --tftp-base-dir /var/lib/tftpboot \
|
||||
! --tftp-offset-dir /x86 \
|
||||
! --include log/serial --log-serial-cmd 'picocom -b 115200 /dev/ttyUSB0'
|
||||
|
||||
Executing base-hw on a Raspberry Pi using powerplug to reset the hardware,
|
||||
JTAG to load the image and USB serial to capture the output:
|
||||
|
||||
!RUN_OPT = --include boot_dir/hw \
|
||||
! --include power_on/powerplug --power-on-powerplug-ip 10.23.42.5 \
|
||||
! --power-on-powerplug-user admin \
|
||||
! --power-on-powerplug-password secret \
|
||||
! --power-on-powerplug-port 1
|
||||
! --include power_off/powerplug --power-off-powerplug-ip 10.23.42.5 \
|
||||
! --power-off-powerplug-user admin \
|
||||
! --power-off-powerplug-password secret \
|
||||
! --power-off-powerplug-port 1
|
||||
! --include load/jtag \
|
||||
! --load-jtag-debugger /usr/share/openocd/scripts/interface/flyswatter2.cfg \
|
||||
! --load-jtag-board /usr/share/openocd/scripts/interface/raspberrypi.cfg \
|
||||
! --include log/serial --log-serial-cmd 'picocom -b 115200 /dev/ttyUSB0'
|
||||
|
||||
After the run script was executed successfully, the run tool will print the
|
||||
string 'Run script execution successful.". This message can be used to check
|
||||
for the successful completion of the run script when doing automated testing.
|
||||
|
||||
|
||||
Meaningful default behaviour
|
||||
============================
|
||||
|
||||
To maintain the ease of use of creating and using a build directory, the
|
||||
'create_builddir' tool equips a freshly created build directory with a meaningful
|
||||
default configuration that depends on the selected platform. For example, if
|
||||
creating a build directory for the Linux base platform, RUN_OPT
|
||||
is initially defined as
|
||||
|
||||
! RUN_OPT = --include boot_dir/linux \
|
||||
! --include power_on/linux --include log/linux
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Improved management of physical memory
|
||||
======================================
|
||||
|
||||
On machines with a lot of memory, there exist constraints with regard to
|
||||
the physical address ranges of memory:
|
||||
|
||||
* On platforms with a non-uniform memory architecture, subsystems should
|
||||
preferably use memory that is local to the CPU cores the subsystem is using.
|
||||
Otherwise the performance is impeded by costly memory accesses to
|
||||
the memory of remote computing nodes.
|
||||
|
||||
* Unless an IOMMU is used, device drivers program physical addresses
|
||||
into device registers to perform DMA operations. Legacy devices such as
|
||||
USB UHCI controllers expect a 32-bit address. Consequently, the memory
|
||||
used as DMA buffers for those devices must not be allocated above 4 GiB.
|
||||
|
||||
* When using an IOMMU on NOVA, Genode represents the address space
|
||||
accessible by devices (by the means of DMA) using a so-called device PD
|
||||
([http://genode.org/documentation/release-notes/13.02#DMA_protection_via_IOMMU]).
|
||||
DMA transactions originating from PCI devices are subjected to the virtual
|
||||
address space of the device PD.
|
||||
All DMA buffers are identity-mapped with their physical addresses within
|
||||
the device PD. On 32-bit systems with more than 3 GiB of memory, this
|
||||
creates a problem. Because the device PD is a regular user-level component, the
|
||||
upper 1 GiB of its virtual address space is preserved for the kernel. Since
|
||||
no user-level memory objects can be attached to this
|
||||
area, the physical address range to be used for DMA buffers is limited
|
||||
to the lower 3 GiB.
|
||||
|
||||
Up to now, Genode components had no way to influence the allocation of
|
||||
memory with respect to physical address ranges. To solve the problems outlined
|
||||
above, we extended core's RAM services to take allocation constraints
|
||||
as session arguments when a RAM session is created. All dataspaces created
|
||||
from such a session are subjected to the specified constraints. In particular,
|
||||
this change enables the AHCI/PCI driver to allocate DMA buffers at suitable
|
||||
physical address ranges.
|
||||
|
||||
This innocent looking feature to constrain RAM allocations raises a problem
|
||||
though: If any component is able to constrain RAM allocations in
|
||||
arbitrary ways, it would become able to scan the physical address space for
|
||||
allocated memory by successively opening RAM sessions with the constraints set
|
||||
to an individual page and observe whether an allocation succeeds or not. Two
|
||||
conspiring components could use this information to construct a covert storage
|
||||
channel.
|
||||
|
||||
To prevent such an abuse, the init component filters out allocations
|
||||
constrains from RAM-session requests unless explicitly permitted. The
|
||||
permission is granted by supplementing the RAM resource assignment of
|
||||
a component with a new 'constrain_phys' attribute. For example:
|
||||
|
||||
! <resource name="RAM" quantum="3M" constrain_phys="yes"/>
|
||||
|
||||
|
||||
Init component
|
||||
==============
|
||||
|
||||
Most of Genode's example scenarios in the form of run scripts support
|
||||
different platforms. However, as the platform details vary, the run scripts
|
||||
have to tweak the configuration of the init component according to the
|
||||
features of the platform.
|
||||
For example, when declaring an explicit route to a framebuffer driver named
|
||||
"fb_drv", the run script won't work on Linux because on this platform, the
|
||||
framebuffer driver is called "fb_sdl".
|
||||
Another example is the role of the USB driver. Depending on the platform, the
|
||||
USB driver is an input driver, a block driver, a networking driver, or a
|
||||
combination of those.
|
||||
Consequently, run scripts with support
|
||||
for a great variety of platforms tend to become convoluted with
|
||||
platform-specific conditionals.
|
||||
|
||||
To counter this problem, we enhanced init to support aliases for component
|
||||
names. By defining the following aliases in the init configuration
|
||||
! <alias name="nic_drv" child="usb_drv"/>
|
||||
! <alias name="input_drv" child="usb_drv"/>
|
||||
! <alias name="block_drv" child="usb_drv"/>
|
||||
the USB driver becomes reachable for session requests routed to either "usb_drv",
|
||||
"nic_drv", "input_drv", and "block_drv". Consequently, the routing
|
||||
configuration of components that use either of those drivers does no longer
|
||||
depend on any platform-intrinsic knowledge.
|
||||
|
||||
|
||||
RTC session interface
|
||||
=====================
|
||||
|
||||
Until now, the RTC session interface used an integer to return the current
|
||||
time. Although this is preferable when performing time-related
|
||||
calculations, a structured representation is more convenient to use, i.e., if
|
||||
the whole purpose is showing the current time. This interface change is only
|
||||
visible to components that use the RTC session directly.
|
||||
|
||||
Since the current OS API of Genode lacks time-related functions, most users
|
||||
end up using the libc, which already converts the structured time stamp
|
||||
internally, or provide their own time related functions.
|
||||
|
||||
|
||||
Update of rump-kernel-based file systems
|
||||
========================================
|
||||
|
||||
We updated the rump-kernel support to a newer rump-kernel version (as of mid of
|
||||
January 2015). This way, Genode is able to benefit from upstream stability
|
||||
improvements related to the memory management. Furthermore, we revised the
|
||||
Genode backend to allow the rump_fs server to cope well with a large amount of
|
||||
memory assigned to it. The latter is useful to utilize the block cache of the
|
||||
NetBSD kernel.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
As a stepping stone in the
|
||||
[https://github.com/genodelabs/genode/issues/1399 - forthcoming community effort]
|
||||
to bring the Nix package manager to Genode, ports of libbz2 and sqlite have
|
||||
been added to the _repos/libports/_ repository.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
VirtualBox on NOVA
|
||||
==================
|
||||
|
||||
Whereas our previous efforts to run VirtualBox on Genode/NOVA were mostly
|
||||
concerned with enabling principal functionality and with the addition of
|
||||
features, we took the release cycle of Genode 15.02 as a chance to focus
|
||||
on performance and stability improvements.
|
||||
|
||||
|
||||
:Performance:
|
||||
|
||||
Our goal with VirtualBox on NOVA is to achieve a user experience
|
||||
comparable to running VirtualBox on Linux. Our initial port of VirtualBox used
|
||||
to cut a lot of corners with regards to performance and timing accuracy
|
||||
because we had to concentrate on more fundamental issues of the porting
|
||||
work first. Now, with the feature set settled, it was time to revisit
|
||||
and solidify our interim solutions.
|
||||
|
||||
The first category of performance improvements is the handling of timing,
|
||||
and virtual guest time in particular. In our original version,
|
||||
we could observe a substantial drift of the guest time compared to the host time.
|
||||
The drift is not merely inconvenient but may even irritate the guest OS
|
||||
because it violates its assumptions about the behaviour of certain virtual devices.
|
||||
The drift was caused by basing the timing on a simple jiffies counter
|
||||
that was incremented by a thread after sleeping for a fixed period. Even
|
||||
though the thread almost never executes, there is still a chance that it gets
|
||||
preempted by the kernel and resumed only after the time slices of
|
||||
concurrently running threads have elapsed. This can take tens of milliseconds.
|
||||
During this time, the jiffies counter remains unchanged. We could
|
||||
significantly reduce the drift by basing the timing on absolute time values
|
||||
requested from the timer driver. Depending on the used guest OS, however,
|
||||
there is still a residual inaccuracy left, which is subject to ongoing
|
||||
investigations.
|
||||
|
||||
The second type of improvements is related to the handling of virtual
|
||||
interrupts. In its original habitat, VirtualBox relies on so-called
|
||||
external-interrupt virtualization events. If a host interrupt occurs while the
|
||||
virtual machine is active, the virtualization event is forwarded by the
|
||||
VirtualBox hypervisor to the virtual machine monitor (VMM).
|
||||
On NOVA, however, the kernel does not propagate this
|
||||
condition to the user-level VMM because the occurrence of host interrupts should
|
||||
be of no matter to the VMM. In the event of a host interrupt, NOVA takes
|
||||
a normal scheduling decision (eventually activating the user-level device driver
|
||||
the interrupt belongs to) and leaves the virtual CPU (vCPU) in a runnable
|
||||
state - to be rescheduled later. Once the interrupt is handled, the vCPU gets
|
||||
resumed. The VMM remains out of the loop. Because the update of the VirtualBox
|
||||
device models ultimately relies on the delivery of external-interrupt
|
||||
virtualization events, the lack of this kind of event introduced huge delays
|
||||
with respect to the update of device models and the injection of virtual
|
||||
interrupts. We solved this problem by exploiting a VirtualBox-internal
|
||||
mechanism called POKE. By setting the so-called POKE flag, an I/O thread is
|
||||
able to express its wish to force the virtual machine into the VMM. We only
|
||||
needed to find the right spots to set the POKE flag.
|
||||
|
||||
Another performance-related optimization is the caching of RTC time
|
||||
information inside VirtualBox. The original version of the gettimeofday
|
||||
function used by VirtualBox contacted the RTC server for obtaining the
|
||||
wall-clock time on each call. After the update to VirtualBox 4.3, the rate of those
|
||||
calls increased significantly. To reduce the costs of these calls, our
|
||||
new version of gettimeofday combines infrequent calls to the RTC driver
|
||||
with a component-local time source based on the jiffies mechanism mentioned above.
|
||||
|
||||
With these optimizations in place,
|
||||
simple benchmarks like measuring the boot time of Window 7 or the time of
|
||||
compiling Genode within a Debian VM suggest that our version of VirtualBox
|
||||
has reached a performance that is roughly on par with the Linux version.
|
||||
|
||||
|
||||
:Stability:
|
||||
|
||||
Since the upgrade to VirtualBox 4.3.16 in release 14.11, we fixed several
|
||||
regression issues caused by the upgrade. Beside that, we completed the
|
||||
support to route serial output of guests to Genode, lifted the restriction
|
||||
to use just one fixed VESA mode, and enabled support for 32-bit Windows 8
|
||||
guests on 64-bit Genode/NOVA. The 64-bit host restriction stems from
|
||||
the fact that Windows 8 requires support for the non-executable bit (NX)
|
||||
feature of page tables. The 32-bit version of the NOVA kernel does not leverage
|
||||
the physical address extension (PAE) feature, which is a pre-requisite for
|
||||
using NX on 32-bit.
|
||||
|
||||
In the course of the adaptation, our port of VirtualBox now evaluates the
|
||||
PAE and HardwareVirtExUX XML tags of .vbox files:
|
||||
|
||||
!<VirtualBox xmlns=...>
|
||||
! <Machine uuid=...>
|
||||
! <Hardware ..>
|
||||
! <CPU ...>
|
||||
! <HardwareVirtExUX enabled="true"/>
|
||||
! <PAE enabled="true"/>
|
||||
! ...
|
||||
|
||||
The PAE tag specifies whether to report PAE capabilities to the guest
|
||||
or not. The HardwareVirtExUx tag is used by our port to decide whether to stay
|
||||
for non-paged x86 modes in Virtualbox's recompiler (REM) or not. Until now, we used REM
|
||||
to emulate execution when the guest was running in real mode and protected mode
|
||||
with paging disabled. However, newer Intel machines support the unrestricted guest
|
||||
feature, which makes the usage of REM in non-paged modes not strictly
|
||||
necessary anymore. Setting the HardwareVirtExUx tag to false accommodates
|
||||
older machines with no support for the unrestricted-guest feature.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
iPXE-based network drivers
|
||||
==========================
|
||||
|
||||
We enabled and tested the driver with Intel I218-LM and I218-V PCI devices.
|
||||
|
||||
|
||||
Intel wireless stack
|
||||
====================
|
||||
|
||||
In this release, several small issues regarding the wireless stack are fixed.
|
||||
From now on, the driver only probes devices on the PCI bus that correspond to
|
||||
the PCI_CLASS_NETWORK_OTHER device class. Prior to that, the driver probed all
|
||||
devices attached to the bus resulting in problems with other devices, e.g.
|
||||
the GPU, when accessing their extended PCI config space.
|
||||
Since the driver uses cooperative scheduling internally, it must never block
|
||||
or, in case it blocks, must schedule another task. Various sleep functions
|
||||
lacked this scheduling call and are now fixed. Furthermore, a bug in the timer
|
||||
implementation has been corrected, which caused the scheduling of wrong timeouts.
|
||||
In addition to these fixes, patches for enabling the support for
|
||||
Intel 7260 cards were incorporated.
|
||||
|
||||
Up to now, the configuration of the wireless driver was rather inconvenient because
|
||||
it did not export any information to the system. The driver now creates two
|
||||
distinct reports to communicate its state and information about the wireless
|
||||
infrastructure to other components. The first one is a list of all available
|
||||
access points. The following exemplary report shows its structure:
|
||||
|
||||
!<wlan_accesspoints>
|
||||
! <accesspoint ssid="skynet" bssid="00:01:02:03:04:05" quality="40"/>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70" protection="WPA-PSK"/>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:07" quality="10" protection="WPA-PSK"/>
|
||||
!</wlan_accesspoints>
|
||||
|
||||
Each '<accesspoint>' node has attributes that contain the SSID and the BSSID
|
||||
of the access point as well as the link quality (signal strength). These
|
||||
attributes are mandatory. If the network is protected, the node will also
|
||||
have an attribute describing the type of protection in addition.
|
||||
|
||||
The second report provides information about the state of the connection
|
||||
with the currently associated access point:
|
||||
|
||||
!<wlan_state>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70"
|
||||
! protection="WPA-PSK" state="connected"/>
|
||||
!</wlan_state>
|
||||
|
||||
Valid state values are 'connected', 'disconnected', 'connecting' and
|
||||
'disconnecting'.
|
||||
|
||||
The driver obtains its configuration via a ROM module. This ROM
|
||||
module contains the selected access point and can be updated during runtime.
|
||||
To connect to an access point, a configuration like the following is used:
|
||||
|
||||
!<selected_accesspoint ssid="foobar" bssid="01:02:03:04:05:06"
|
||||
! protection="WPA-PSK" psk="foobar123!"/>
|
||||
|
||||
To disconnect from an access point, an empty configuration can be set:
|
||||
|
||||
!<selected_accesspoint/>
|
||||
|
||||
For now, the prevalent WPA/WPA2 protection using a pre-shared key is supported.
|
||||
|
||||
|
||||
Improved UART driver for Exynos5
|
||||
================================
|
||||
|
||||
The UART driver for the Exynos5 SoC has been enhanced by enabling the RX
|
||||
channel. This improvement was motivated by automated tests, where a run script
|
||||
needs to interact with some component via a terminal connection.
|
||||
|
||||
|
||||
Touchscreen support
|
||||
===================
|
||||
|
||||
We enabled support of Wacom USB touchscreen devices via dde_linux - a port of
|
||||
Linux USB driver to Genode. In order to make touchscreen coordinates
|
||||
usable by Genode's input services, they must be calibrated
|
||||
to screen-absolute coordinates. The screen resolution is not determined
|
||||
automatically by the USB driver. It can, however, be configured as a sub
|
||||
node of the '<hid>' XML tag of the USB driver's configuration:
|
||||
|
||||
!<start name="usb_drv">
|
||||
! ...
|
||||
! <config uhci=... ohci=... xhci=...>
|
||||
! <hid>
|
||||
! <screen width="1024" height="768"/>
|
||||
! </hid>
|
||||
! ...
|
||||
|
||||
|
||||
USB session interface
|
||||
=====================
|
||||
|
||||
We enhanced our USB driver with the support of remote USB sessions. This
|
||||
feature makes it possible to implement USB-device drivers outside the USB
|
||||
server using a native Genode API. The new USB session can be found under
|
||||
_repos/os/include/usb_session_ and can be used to communicate with the USB
|
||||
server, which merely acts as a host controller and HUB driver in this scenario.
|
||||
Under _repos/os/include/usb_, there are a number of convenience
|
||||
and wrapper functions that operate directly on top of a USB session. These
|
||||
functions are meant to ease the task of USB-device-driver programming by hiding
|
||||
most of the USB session management, like packet-stream handling.
|
||||
|
||||
We also added a USB terminal server, which exposes a Genode terminal session to
|
||||
its clients and drives the popular PL2303 USB to UART adapters using the new
|
||||
USB-session interface.
|
||||
A practical use case for this component is the transmission of logging data on
|
||||
systems where neither UART, AMT, nor JTAG are available. A run script
|
||||
showcasing this feature can be found at _repos/dde_linux/run/usb_terminal.run_.
|
||||
|
||||
|
||||
RTC proxy driver for Linux
|
||||
==========================
|
||||
|
||||
There are a handful of run scripts that depend on the RTC service. So far,
|
||||
it was not possible to run these tests on Linux due to the lack of an RTC
|
||||
driver on this platform. To address this problem, we created a proxy driver
|
||||
that uses the time() system call to provide a
|
||||
reasonable base period on Linux.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Support for the USB-Armory board
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
With [https://www.crowdsupply.com/inverse-path/usb-armory - USB Armory],
|
||||
there is an intriguing hardware platform for Genode on the horizon.
|
||||
In short, USB Armory is a computer in the form factor of a USB
|
||||
stick. It is meant for security applications such as VPNs,
|
||||
authentication tokens, and encrypted storage. It is based on the
|
||||
FreeScale i.MX53 SoC, which is well supported by Genode, i.e.,
|
||||
Genode can be used as secure-world OS besides Linux running in the
|
||||
normal world.
|
||||
Apart from introducing a novel form factor, this project is
|
||||
interesting because it strives to be an 100% open platform, which
|
||||
includes hardware, software, and firmware. This motivated us to
|
||||
bring Genode to this platform.
|
||||
|
||||
The underlying idea is to facilitate
|
||||
[http://genode.org/documentation/articles/trustzone - ARM TrustZone] to
|
||||
use Genode as a companion to a Linux-based OS on the platform.
|
||||
Whereas Linux would run in the normal world of TrustZone, Genode runs
|
||||
in the secure world. With Linux, the normal world will control the
|
||||
communication over USB and provide a familiar environment to implement
|
||||
USB-Armory applications. However, security-critical functions and data like
|
||||
cryptographic keys will reside exclusively in the secure world. Even in
|
||||
the event that Linux gets compromised, the credentials of the user
|
||||
will stay protected.
|
||||
|
||||
The support of the USB Armory platform was added in two steps:
|
||||
First, we enabled our base-hw kernel to run as TrustZone monitor with
|
||||
Genode on the "secure side". Since the USB Armory is based on the
|
||||
FreeScale i.MX53 SoC, which Genode already supported, this step went
|
||||
relatively straight-forward.
|
||||
|
||||
Second, we enabled a recent version of the Linux kernel (3.18) to run in the
|
||||
normal world. The normal world is supervised by a user-level Genode component
|
||||
called tz_vmm (TrustZone Virtual Machine Monitor). The tz_vmm is, among
|
||||
others, responsible for providing startup and hardware information to the
|
||||
non-secure guest. The Linux kernel version we used previously as TrustZone
|
||||
guest on i.MX53 boards expected this information to be communicated via
|
||||
so-called ATAGs. The new version, however, expects this to be done via a
|
||||
device tree blob. As a consequence, the tz_vmm had to be adapted to properly
|
||||
load this blob into the non-secure RAM. The original USB-Armory device tree
|
||||
was modified to blind out the RAM regions that get protected by the TrustZone
|
||||
hardware. This way, Linux won't attempt to access them. Furthermore,
|
||||
to keep basic user interaction simple, our device tree tells Linux to use the
|
||||
same non-secure UART as Genode for console I/O.
|
||||
|
||||
The kernel itself received some modifications, for two reasons. First,
|
||||
we don't want Linux to rely on resources that are protected to keep
|
||||
the secure world secure. This is why the driver for the interrupt controller
|
||||
that originally made use of the TrustZone interrupt configuration, had to be
|
||||
adapted. Second, to prevent Linux from disturbing Genode activities, we
|
||||
disabled most of the dynamic clock and power management as it may sporadically
|
||||
gear down or even disable hardware that Genode relies on. Furthermore, we
|
||||
disabled the Linux drivers for I2C interfaces and the GPIO configuration as
|
||||
these are reserved for Genode.
|
||||
|
||||
|
||||
IPC helping
|
||||
~~~~~~~~~~~
|
||||
|
||||
In traditional L4 microkernels, scheduling parameters (like time-slice
|
||||
length and priority) used to be bound to threads. Usually, those parameters
|
||||
are defined at thread creation time. The initial version
|
||||
of base-hw followed this traditional approach. However, it has a few problems:
|
||||
|
||||
* For most threads, the proper *choice of scheduling parameters* is very
|
||||
difficult if not impossible. For example, the CPU-time demands of a
|
||||
server thread may depend on the usage patterns of its clients. Most
|
||||
theoretical work in the domain of scheduling presumes the knowledge of
|
||||
job lengths in advance of computing a schedule. But in practice and in
|
||||
particular in general-purpose computing, job lengths are hardly known a priori.
|
||||
As a consequence, in most scenarios, scheduling parameters are
|
||||
set to default values.
|
||||
|
||||
* With each thread being represented as an independent schedulable entity,
|
||||
the kernel has to take a scheduling decision each time a thread performs an
|
||||
IPC call because the calling thread gets blocked and the called thread
|
||||
may get unblocked. In a microkernel-based system, those events occur at a
|
||||
much higher rate than the duration of typical time slices, which puts the
|
||||
scheduler in a *performance-critical* position.
|
||||
|
||||
* Regarding IPC calls, a synchronous flow of control along IPC call chains is
|
||||
desired. Ideally, an IPC call should have the same characteristics as
|
||||
a function call with respect to scheduling. When a client thread performs an
|
||||
IPC call, it expects the server to immediately become active to
|
||||
handle the request. But if the kernel treats each thread independently,
|
||||
it may pick any other thread and thereby introduce *high latencies* into
|
||||
IPC operations.
|
||||
|
||||
To counter those problems, the NOVA microhypervisor introduced a new approach
|
||||
that decouples scheduling parameters from threads. Instead of selecting
|
||||
threads for execution, the scheduler selects so-called scheduling contexts.
|
||||
For a selected scheduling context, the kernel dynamically determines a
|
||||
thread to execute by taking IPC relationships into account. When a thread
|
||||
performs an IPC, the thread's scheduling context will be used to execute
|
||||
the called server. In principle, a server does not need CPU time on its own
|
||||
but always works with CPU resources provided by clients.
|
||||
|
||||
The new version of the base-hw kernel adapts NOVA's approach with slight
|
||||
modifications. Each thread owns exactly one scheduling context for its entire
|
||||
lifetime. However, by the means of "helping" during an IPC call, the caller
|
||||
lends its scheduling context to the callee. Even if the callee is still busy
|
||||
and cannot handle the IPC request right away, the caller helps because it
|
||||
wants the callee to become available for its request as soon as
|
||||
possible. Consequently, a thread has potentially many scheduling contexts at
|
||||
its disposal, its own scheduling context plus all scheduling contexts
|
||||
provisioned by helpers. This works transitively.
|
||||
|
||||
|
||||
Purged outdated platforms
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We removed the support for two stale platforms that remained unused for
|
||||
more than a year, namely FreeScale i.MX31 and the TrustZone variant
|
||||
of the Coretile Versatile Express board.
|
||||
|
||||
|
||||
NOVA
|
||||
====
|
||||
|
||||
On Genode/NOVA, we used to employ one pager thread in core for each thread
|
||||
in the system. We were forced to do so because not every page
|
||||
fault can be resolved immediately. In some situations, core asynchronously
|
||||
propagates the fault to an external component for the resolution.
|
||||
In the meantime, the
|
||||
pager thread leaves the page fault unanswered. Unfortunately, the kernel
|
||||
provides no mechanism to support this scenario besides just blocking the
|
||||
pager thread using a semaphore. This, in turn, means that the pager thread is not
|
||||
available for other page-fault requests. Ultimately, we had to setup a
|
||||
dedicated pager per thread.
|
||||
|
||||
This implementation has the downside of "wasting" memory for a lot of
|
||||
pager threads. Moreover, it becomes a denial-of-service vector as soon as more
|
||||
threads get created than core can accommodate. The number of threads is
|
||||
limited per address space - also for core - by the size of Genode's context
|
||||
area, which typically means 256 threads.
|
||||
|
||||
To avoid the downsides mentioned, we extended the NOVA IPC reply syscall to
|
||||
specify an optional semaphore capability. The NOVA kernel validates the
|
||||
capability and blocks the faulting thread in the semaphore. The faulted thread
|
||||
remains blocked even after the pager has replied to the fault message. But
|
||||
the pager immediately becomes available for other
|
||||
page-fault requests. With this change, it suffices to maintain only one pager
|
||||
thread per CPU for all client threads.
|
||||
|
||||
The benefits are manifold. First, the base-nova implementation converges more
|
||||
closely to other Genode base platforms. Second, core can not run out of threads
|
||||
anymore as the number of threads in core is fixed for a given setup. And the
|
||||
third benefit is that the helping mechanism of NOVA can be leveraged for
|
||||
concurrently faulting threads.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
Tools for convenient handling of port contrib directories
|
||||
=========================================================
|
||||
|
||||
We supplemented our tools for the ports mechanism with two convenient
|
||||
scripts:
|
||||
|
||||
:_tool/ports/shortcut_:
|
||||
|
||||
Creates a symbolic link from _contrib/<port-name>-<hash>_ to
|
||||
_contrib/<port-name>_. This is useful when working on the third-party
|
||||
code contained in the _contrib_ directory.
|
||||
|
||||
:_tool/ports/current_:
|
||||
|
||||
Prints the current contrib directory of a port. When switching
|
||||
branches back and forth, the hash of the used port might change.
|
||||
The script provides a shortcut to looking up the hash file for a
|
||||
specific port within the repositories and printing its content.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,791 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 15.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The version 15.08 marks the beginning of Genode as day-to-day OS as one of the
|
||||
project's core developers switched to using Genode/NOVA on his machine,
|
||||
stressing the OS infrastructure we created over the course of the last seven
|
||||
years. Thanks to components like VirtualBox, the Noux runtime for GNU software,
|
||||
the Linux wireless stack and Rump-kernel-based file systems, the transition
|
||||
went actually much smoother than expected. So other members of the team plan
|
||||
to follow soon. Section [Genode as day-to-day operating system] gives an
|
||||
overview of the taken approach. Genode's use as general-purpose OS provided
|
||||
the incentive for most of the improvements featured by the current release,
|
||||
starting with the addressing of the long-standing kernel-memory management
|
||||
deficiencies of the NOVA kernel (Section [NOVA kernel-resource management]),
|
||||
over enhancements of Genode's tracing and file-system facilities, to vast
|
||||
improvements of the guest-host integration of VirtualBox when running on
|
||||
Genode.
|
||||
|
||||
The release is accompanied with a second line of work led by our friends
|
||||
at Codelabs: Enabling Genode to run on top of their Muen separation
|
||||
kernel as described in Section [Genode on top of the Muen Separation Kernel].
|
||||
Muen is a low-complexity kernel for the 64-bit x86 architecture that
|
||||
statically partitions the machine into multiple domains. In contrast to
|
||||
microkernels like the ones already supported by Genode, the assignment
|
||||
of physical resources (such as memory, CPU time, and devices) happens at
|
||||
system-integration time. Since an isolation kernel does not have to deal
|
||||
with dynamic resource management at runtime, it is less complex than
|
||||
a general-purpose microkernel. This makes it relatively easy to reason about
|
||||
its strong isolation properties, which, in turn, makes it attractive for
|
||||
high-assurance computing. With Genode being able to run within a Muen
|
||||
domain, the rich component infrastructure of Genode can be combined with
|
||||
the strong isolation guarantees of Muen.
|
||||
|
||||
|
||||
Genode on top of the Muen Separation Kernel
|
||||
###########################################
|
||||
|
||||
_This section was written by Adrian-Ken Rueegsegger and Reto Buerki who_
|
||||
_conducted the described line of work independent from Genode Labs._
|
||||
|
||||
After completing our x86_64 port of the Genode base-hw kernel, which was
|
||||
featured in the
|
||||
[http://genode.org/documentation/release-notes/15.05#Principal_support_for_the_64-bit_x86_architecture - previous release (15.05)],
|
||||
we immediately started working on our main goal: running a Genode system as
|
||||
guest on the Muen Separation Kernel (SK). This would enable the Muen platform
|
||||
to benefit from the rich ecosystem of Genode.
|
||||
|
||||
For those who have not read the 15.05 Genode release notes, [http://muen.sk - Muen]
|
||||
is an Open-Source microkernel, which uses the [http://spark-2014.org/ - SPARK]
|
||||
programming language to enable light-weight formal methods for high assurance.
|
||||
The 64-bit x86 kernel, currently consisting of a little over 5'000 LOC, makes
|
||||
extensive use of the latest Intel virtualization features and has been formally
|
||||
proven to contain no runtime errors at the source-code level.
|
||||
|
||||
The new 'hw_x86_64_muen' platform, as the name implies, extends the 'hw_x86_64'
|
||||
base-hw kernel by replacing the PIC and timer drivers with paravirtualized
|
||||
variants.
|
||||
|
||||
In contrast to other kernels supported by Genode, the architecture with Muen is
|
||||
different in the sense that the entire 'hw_x86_64_muen' Genode system runs as
|
||||
guest VM in VMX non-root mode on the SK. From the perspective of Muen, Genode
|
||||
is executed on top of the kernel like any other guest OS without special
|
||||
privileges.
|
||||
|
||||
[image muen_system_overview]
|
||||
Genode running on top of the Muen Separation Kernel alongside other subjects
|
||||
|
||||
This loose coupling of Muen and Genode base-hw enables the robust combination
|
||||
of a static, low-complexity SK with a feature-rich and extensive OS framework.
|
||||
The result is a flexible platform for the construction of component-based
|
||||
high-assurance systems.
|
||||
|
||||
People interested in giving the 'hw_x86_64_muen' platform a spin can find a
|
||||
small tutorial at _repos/base-hw/doc/x86_64_muen.txt_.
|
||||
|
||||
|
||||
NOVA kernel-resource management
|
||||
###############################
|
||||
|
||||
For several years, the NOVA kernel has served as Genode's primary base
|
||||
platform on x86. The main reasons for this choice are: the kernel provides -
|
||||
among the supported x86 kernels - the richest feature set like the support of
|
||||
IOMMUs, virtualization, and SMP. It also offers a clean design and a stable
|
||||
kernel interface. The available kernel-interface specification and the
|
||||
readable and modern source base are a pleasure to work with. Hence, Genode
|
||||
Labs is able to fully commit to the maintenance and further evolution of this
|
||||
kernel.
|
||||
|
||||
Nevertheless, since the beginning, the vanilla kernel lacks one essential
|
||||
feature to reliably host Genode as user-land, namely the proper management of
|
||||
the memory used by the kernel itself (in short kernel-memory management). In
|
||||
the past, we already extended the kernel to free up kernel resources when
|
||||
destroying kernel objects, e.g., protection domains and page-tables, threads,
|
||||
semaphores, and portals. Still, on Genode/NOVA, a component may trigger
|
||||
arbitrary kernel-memory consumption during RPC by delegating memory,
|
||||
capabilities, or by creating other components via Genode's core component. If
|
||||
the kernel memory gets depleted, the kernel panics with an "Out of memory"
|
||||
message and the entire Genode scenario stops.
|
||||
|
||||
In principal, the consumption of kernel memory can be deliberately provoked by
|
||||
a misbehaving (greedy) component. But also during the regular day-to-day usage
|
||||
of Genode, can such a situation occur when the system is used in a highly
|
||||
dynamic fashion. For example, compiling and linking source code within the
|
||||
noux environment constantly creates and destroys protection domains, threads,
|
||||
and memory mappings. Our nightly test of compiling Genode within noux triggers
|
||||
this condition every once in a while.
|
||||
|
||||
The main issue here is that the consumption of kernel memory is not accounted
|
||||
by Genode. The kernel interface does not support such a feature. Kernels like
|
||||
seL4 as well as Genode's custom base-hw kernel show how this problem can be
|
||||
solved.
|
||||
|
||||
To improve the current situation - where the overall kernel memory is a fixed
|
||||
amount - we extended NOVA in the following ways: First, the NOVA kernel
|
||||
accounts any kernel memory consumption per protection domain. Second, each
|
||||
process has a limited amount of kernel-memory quota it can use. Last, the
|
||||
kernel detects when the quota limit of a protection domain is reached.
|
||||
|
||||
If the third condition occurs, the kernel stops the offending thread and
|
||||
(optionally) notifies a handler thread. This so called out-of-memory (OOM)
|
||||
handler thread receives information about the current situation and may
|
||||
respond to it in the following ways:
|
||||
|
||||
* Stop the thread of the depleted protection domain, or
|
||||
* Transfer kernel-memory quota between protection domains (upgrading the limit
|
||||
if desired), or
|
||||
* Free up kernel memory if possible, e.g., revoke memory delegations, which
|
||||
can be re-created.
|
||||
|
||||
We implemented the steps above inside the NOVA kernel and extended Genode's
|
||||
core component to handle such OOM situations. All system calls beside the IPC
|
||||
call/reply may now return an error code upon depletion of the quota. Most of
|
||||
these system calls can solely be performed by core and are handled inside
|
||||
core's NOVA-specific platform code.
|
||||
|
||||
In the case of IPC call/reply operations, we desired to handle OOM cases
|
||||
transparently to Genode user-level components. Therefore, each thread in
|
||||
Genode/NOVA now gets constructed with an OOM IPC portal attached. This portal
|
||||
is served by the pager thread in core and is traversed on OOM occurrences
|
||||
during IPC operations. If a pager thread receives such an OOM IPC, it decodes
|
||||
the involved IPC sender and IPC receiver and locates the appropriate
|
||||
core-internal paging objects. The currently implemented out-of-memory policy
|
||||
tries to upgrade the quota. If this is not possible, an attempt to revoke
|
||||
memory mappings from the OOM-causing protection domain is made. This
|
||||
implicitly frees-up some kernel memory (e.g., mapping nodes). If none of the
|
||||
responses suffices, the handler stops the OOM-causing thread and writes a
|
||||
message to the system log.
|
||||
|
||||
The current policy implementation constitutes a rather rough heuristic, which
|
||||
may not suffice under all circumstances. In the future, we would like to
|
||||
specify a distinct policy per component, e.g. depending on prior known memory
|
||||
usage patterns. For example, some components follow well-known usage patterns
|
||||
and therefore a fixed upper quota limit can be specified. Other components are
|
||||
highly dynamic and desire quota upgrades on demand. There are many more
|
||||
combinations imaginable.
|
||||
|
||||
Our current plan is to collect more experience over the next months with this
|
||||
new kernel mechanism. Based on our observations, we may externalize such
|
||||
policy decisions and possibly make them configurable per component.
|
||||
|
||||
The current implementation however, already avoids the situation that the
|
||||
kernel goes out of service if a single component misbehaves
|
||||
kernel-memory-wise.
|
||||
|
||||
|
||||
Genode as day-to-day operating system
|
||||
#####################################
|
||||
|
||||
At the beginning of June, Genode reached the probably most symbolic milestone
|
||||
in the project's history: Norman - one of the core developers - replaced his
|
||||
Linux-based working environment with a Genode-based system. This system is
|
||||
composed of the following ingredients:
|
||||
|
||||
[image turmvilla_scenario]
|
||||
|
||||
The machine used is a Lenovo Thinkpad X201. We settled on this five-year-old
|
||||
machine for several reasons. First, it is a very solid platform with a nice
|
||||
form factor. Second, it features Intel's AMT (Active Management Technology),
|
||||
which is handy to obtain low-level system logs in the case something goes
|
||||
wrong. Third, refurbished machines of this type can be obtained for as little
|
||||
as 200 EUR. Finally, an older machine reinforces the need for good performance
|
||||
of the operating system. So it creates a natural incentive for Norman to find
|
||||
and address performance bottlenecks.
|
||||
|
||||
Our modified version of the NOVA microhypervisor is the used kernel.
|
||||
|
||||
The user interface is based on our custom GUI stack including the nitpicker
|
||||
GUI server as well as the window manager and its companion components
|
||||
(decorator, layouter, pointer) we introduced in
|
||||
[http://genode.org/documentation/release-notes/14.08#New_GUI_architecture - version 14.08].
|
||||
The display is driven by the VESA driver. User input is handled by the PS/2
|
||||
driver for handling the laptop keyboard and trackpoint, and the USB driver for
|
||||
handling an externally connected keyboard and mouse.
|
||||
|
||||
Network connectivity is provided by our port of the Intel Wireless stack that
|
||||
we introduced with the version
|
||||
[http://genode.org/documentation/release-notes/14.11#Intel_wireless_stack - 14.11].
|
||||
|
||||
Our custom AHCI driver provides access to the physical hard disk. File-system
|
||||
access is provided by our
|
||||
[http://genode.org/documentation/release-notes/14.02#NetBSD_file_systems_using_rump_kernels - Rump-kernel-based file-system server].
|
||||
|
||||
A simple Genode shell called CLI monitor allows the user to start and kill
|
||||
subsystems dynamically. Initially, the two most important subsystems are
|
||||
VirtualBox and Noux.
|
||||
|
||||
VirtualBox executes a GNU/Linux-based guest OS that we refer to as "rich OS".
|
||||
The rich OS serves as a migration path from GNU/Linux to Genode. It is used
|
||||
for all tasks that cannot be accomplished directly on Genode yet. At the
|
||||
beginning of the transition, the daily routine still very much depends on the
|
||||
rich OS. By moving more and more functionality over to the Genode world, we
|
||||
will eventually be able to make the rich OS obsolete step by step. Thanks to
|
||||
VirtualBox' excellent host-guest-integration features, the VirtualBox window
|
||||
can be dynamically resized and the guest mouse cursor integrates seamlessly
|
||||
with Genode's pointer. VirtualBox is directly connected to the wireless
|
||||
network driver. So common applications like Firefox can be used.
|
||||
|
||||
The noux runtime allows us to use command-line-based GNU software directly on
|
||||
Genode. Coreutils and Bash are used for managing files. Vim is used for
|
||||
editing files. Unlike the rich OS, the noux environment has access to the
|
||||
Genode partition of the hard disk. In particular, it can be used to update the
|
||||
Genode system. It has access to a number of pseudo files that contain status
|
||||
information of the underlying components, e.g., the list of wireless access
|
||||
points. Furthermore, it has limited access to the configuration interfaces of
|
||||
the base components. For example, it can point the wireless driver to the
|
||||
access point to use, or change the configuration of the nitpicker GUI server
|
||||
at runtime.
|
||||
|
||||
As a bridge between the rich OS and the Genode world, we combine VirtualBox'
|
||||
shared-folder mechanism with Genode's VFS infrastructure. The shared folder is
|
||||
represented by a dedicated instance of a RAM file system, which is mounted in
|
||||
both the VFS of VirtualBox and the VFS of noux.
|
||||
|
||||
As evidenced by Norman's use since June, the described system setup is
|
||||
sufficient to be productive. So other members of the Genode team plan to
|
||||
follow in his footsteps soon. At the same time, the continued use of the
|
||||
system from day to day revealed a number of shortcomings, performance
|
||||
limitations, and rough edges, which we eventually eliminated. It goes without
|
||||
saying that this is an ongoing effort. Eating our own dog food forces us to
|
||||
address the right issues to make the daily life more comfortable.
|
||||
|
||||
Feature-wise the switch to Genode motivated three developments, namely the
|
||||
enhancement of Genode's CLI monitor, the improvement of the window manager,
|
||||
and the creation of a CPU-load monitoring tool.
|
||||
|
||||
|
||||
Interactive management of subsystem configurations
|
||||
==================================================
|
||||
|
||||
The original version of CLI monitor obtained the configuration data of its
|
||||
subsystems at start time via the Genode::config mechanism. But for managing
|
||||
complex scenarios, the config node becomes very complex. Hence, it is
|
||||
preferable to have a distinct file for each subsystem configuration.
|
||||
|
||||
The new version of CLI monitor scans the directory '/subsystems' for files
|
||||
ending with ".subsystem". Each file has the same syntax as the formerly used
|
||||
subsystem nodes. This change has the welcome implication that subsystem
|
||||
configurations can be changed during the runtime of the CLI monitor, e.g., by
|
||||
using a concurrently running instance of noux with access to the _subsystems/_
|
||||
directory. This procedure has become an essential part of the daily work flow
|
||||
as it enables the interactive evolution of the Genode system.
|
||||
|
||||
|
||||
Window-management improvements
|
||||
==============================
|
||||
|
||||
To make the window manager more flexible while reducing its complexity at the
|
||||
same time, we removed the formerly built-in policy hosting the decorator and
|
||||
layout components as children of the window manager. Those components are no
|
||||
longer child components but siblings. The relationship of the components is
|
||||
now solely expressed by the configuration of their common parent, i.e., init.
|
||||
This change clears the way to dynamically replace those components during
|
||||
runtime (e.g., switching between different decorators).
|
||||
|
||||
To improve the usability of the windowed GUI, we enabled the layouter to
|
||||
raise windows on click and to let the keyboard focus follow the pointer.
|
||||
Furthermore, the window manager, the decorator, and the floating window
|
||||
layouter became able to propagate the usage of an alpha channel from the
|
||||
client application to the decorator. This way, the decorator can paint the
|
||||
decoration elements behind the affected windows, which would otherwise be
|
||||
skipped. Consequently, partially transparent windows can be properly displayed.
|
||||
|
||||
|
||||
CPU-load monitoring
|
||||
===================
|
||||
|
||||
During daily system use, we started to wish to know in detail where the CPU
|
||||
cycles are spent. For example, the access of a file by the rich OS involves
|
||||
several components, including the guest OS itself, VirtualBox, rump_fs (file
|
||||
system), part_blk (partition access), ahci_drv (SATA device access), core, and
|
||||
NOVA. Investigating performance issues requires a holistic view of all those
|
||||
components. For this reason, we enhanced our existing tracing infrastructure
|
||||
(Section [Enhanced tracing facilities]) to allow the creation of CPU-load
|
||||
monitoring tools. The first tool in this category is the graphical CPU-load
|
||||
monitor located at _gems/app/cpu_load_display/_, which displays a timeline of
|
||||
the CPU load where each thread is depicted with a different color. Thanks to
|
||||
this tool, we have become able to explore performance issues in an interactive
|
||||
way. In particular, it helped us to identify and resolve a long-standing
|
||||
inaccuracy problem in our low-level timer service.
|
||||
|
||||
|
||||
Base framework and low-level OS infrastructure
|
||||
##############################################
|
||||
|
||||
Improved audio support
|
||||
======================
|
||||
|
||||
In the previous release, we replaced our old audio driver with a new one that
|
||||
provided the same audio-out session interface. Complementing the audio-out
|
||||
session, we are now introducing a new audio-in session interface that can be
|
||||
used to record audio frames. It is modeled after the audio-out interface in
|
||||
the way how it handles the communication between the client and the server. It
|
||||
uses shared memory in the form of the Audio_in::Stream to transport the frames
|
||||
between the components. A server component captures frames and puts them into
|
||||
a packet queue, which is embedded in the Audio_in::Stream. The server
|
||||
allocates packets from this queue to store the recorded audio frames. If the
|
||||
queue is already full, the server will override already allocated packets and
|
||||
will notify the client by submitting an 'overrun' signal. The client has to
|
||||
cope with this situation, e.g., by consuming packets more frequently. A client
|
||||
can install a signal handler to respond to a progress signal, which is sent by
|
||||
the server when a new Audio_in::Packet has been submitted to the packet queue.
|
||||
For now, all audio-in server components only support one channel (left)
|
||||
although the audio-in session interface principally supports multiple
|
||||
channels.
|
||||
|
||||
The _dde_bsd_ audio_drv is the first and currently only audio driver component
|
||||
that was extended to provide the audio-in session. To express this fact, the
|
||||
driver was renamed from _audio_out_drv_ to _audio_drv_. In contrast to its
|
||||
playback functionality, which is enabled by default, recording has to be
|
||||
enabled explicitly by setting the configuration attribute 'recording' to
|
||||
'yes'. If the need arises, playback may be disabled by setting 'playback' to
|
||||
'no'. In addition, it is now possible to configure the driver by adjusting the
|
||||
mixer in the driver's configuration node. For the time being, the interface as
|
||||
employed by the original OpenBSD mixer utility is used.
|
||||
|
||||
The following snippet shows how to enable and configure recording on a
|
||||
Thinkpad X220 where the headset instead of the internal microphone is used as
|
||||
source:
|
||||
|
||||
! <start name="audio_drv">
|
||||
! <resource name="RAM" quantum="8M"/>
|
||||
! <provides>
|
||||
! <service name="Audio_out"/>
|
||||
! <service name="Audio_in"/>
|
||||
! </provides>
|
||||
! <config recording="yes">
|
||||
! <mixer field="outputs.master" value="255"/>
|
||||
! <mixer field="record.adc-0:1_source" value="sel2"/>
|
||||
! <mixer field="record.adc-0:1" value="255"/>
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
In addition to selecting the recording source, the playback as well as the
|
||||
recording volume are raised to the maximum. Information about all available
|
||||
mixers and settings in general may be obtained by specifying the 'verbose'
|
||||
attribute in the config node.
|
||||
|
||||
The enriched driver is accompanied by a simple monitor application, which
|
||||
directly plays back all recorded audio frames and shows how to use the
|
||||
audio-in session. It can be tested by executing the
|
||||
_repos/dde_bsd/run/audio_in.run_ run script.
|
||||
|
||||
There are also changes to the audio-out session itself. The length of a period
|
||||
was reduced from 2048 to 512 samples to accommodate for a lower latency when
|
||||
mixing audio-out packets. A method for invalidating all packets in the queue
|
||||
was also added.
|
||||
|
||||
|
||||
File-system infrastructure
|
||||
==========================
|
||||
|
||||
Unlike traditional operating systems that rely on a global name space for
|
||||
files, each Genode component has a distinct view on files. Many low-level
|
||||
components do not even have the notion of files. Whereas traditional operating
|
||||
systems rely on a virtual file system (VFS) implemented in the OS kernel,
|
||||
Genode's VFS has the form of a library that can optionally be linked to a
|
||||
component. The implementation of this library originated from the noux runtime
|
||||
introduced in version
|
||||
[http://genode.org/documentation/release-notes/11.02#Noux_-_an_execution_environment_for_the_GNU_userland - 11.02],
|
||||
and was later integrated into our C runtime in version
|
||||
[http://genode.org/documentation/release-notes/14.05#Per-process_virtual_file_systems - 14.05].
|
||||
With the current release, we take the VFS a step further by making it
|
||||
available to components without a C runtime. Thereby, low-complexity
|
||||
security-sensitive components such as CLI monitor become able to benefit from
|
||||
the powerful VFS infrastructure.
|
||||
|
||||
The VFS itself received a welcome improvement in the form of private RAM file
|
||||
systems. A need for process-local storage motivated a conversion of the
|
||||
existing ram_fs server component to an embeddable VFS file system. This
|
||||
addition to the set of VFS plugins enables components to use temporary file
|
||||
systems without relying on the resources of an external component.
|
||||
|
||||
|
||||
Unified networking components
|
||||
=============================
|
||||
|
||||
Having had a good experience with our Block::Driver implementation, which
|
||||
wraps the block-session interface and takes care of the packet-stream
|
||||
handling, thus easing the implementation of driver and other block components,
|
||||
we observed that this approach did not provide enough flexibility for
|
||||
NIC-session servers. For example, NIC servers are bi-directional and when a
|
||||
network packet arrives the server has to make sure that there are enough
|
||||
resources available to dispatch the network packet to the client. This has to
|
||||
be done because the server must never block, e.g., by waiting for allocations
|
||||
to succeed or for an empty spot in the packet queue of a client. Therefore,
|
||||
such a non-blocking NIC server needs to validate all preconditions for
|
||||
dispatching the packet in advance and, if they cannot be met, drop the network
|
||||
packet.
|
||||
|
||||
In order to implement this kind of behavior, NIC-session servers must have
|
||||
direct access to the actual NIC session. For this reason, we removed the
|
||||
Nic::Driver interface from Genode and added a Nic::Session_component that
|
||||
offers common basic packet-stream-signal dispatch functionality. Servers may
|
||||
now inherit from this component and implement their own policy.
|
||||
|
||||
We adjusted all servers that implement NIC sessions to the new interface
|
||||
(dde_ipxe, wifi, usb, nic_bridge, OpenVPN, ...), and thereby unified all
|
||||
networking components within Genode.
|
||||
|
||||
|
||||
Enhanced tracing facilities
|
||||
===========================
|
||||
|
||||
Recent Genode-based system scenarios like the one described in Section
|
||||
[Genode as day-to-day operating system] consist of dozens of components that
|
||||
interact with each other. For reasoning about the behaviour of such scenarios
|
||||
and identifying effective optimization vectors, tools for gathering a holistic
|
||||
view of the system are highly desired.
|
||||
|
||||
With the introduction of our light-weight
|
||||
[http://genode.org/documentation/release-notes/13.08#Light-weight_event_tracing - event-tracing facility]
|
||||
in version 13.08, we laid the foundation for such tools. The current release
|
||||
extends core's TRACE service with the ability to obtain statistics about CPU
|
||||
utilization. More specifically, it enables clients of core's TRACE service to
|
||||
obtain the execution times of trace subjects (i.e., threads). The execution
|
||||
time is delivered as part of the 'Subject_info' structure. In addition to the
|
||||
execution time, the structure delivers the information about the affinity of
|
||||
the subject with a physical CPU.
|
||||
|
||||
At the current stage, the feature is available solely on NOVA since this is
|
||||
our kernel of choice for using Genode as our day-to-day OS. On all other base
|
||||
platforms, the returned execution times are 0. To give a complete picture of
|
||||
the system's threads, the kernel's idle threads (one per CPU) are featured as
|
||||
trace subjects as well. Of course, idle threads cannot be traced but their
|
||||
corresponding trace subjects allow TRACE clients to obtain the idle time of
|
||||
each CPU.
|
||||
|
||||
By obtaining the trace-subject information in periodic intervals, a TRACE
|
||||
client is able to gather statistics about the CPU utilization attributed to
|
||||
the individual threads present (or no longer present) in the system. One
|
||||
instance of such a tool is the new trace-subject reporter located at
|
||||
_os/src/app/trace_subject_reporter_. It acts as a TRACE client, which delivers
|
||||
the gathered trace-subject information in the form of XML-formatted data to a
|
||||
report session. This information, in turn, can be consumed by a separate
|
||||
component that analyses the data. In contrast to the low-complexity
|
||||
trace-subject reporter, which requires access to the privileged TRACE services
|
||||
of core, the (potentially complex) analysing component does not require access
|
||||
to core's TRACE service. So it isn't as critical as the trace-subject monitor.
|
||||
The first representative of a consumer of trace-subject reports is the
|
||||
CPU-load display mentioned in Section [CPU-load monitoring] and depicted in
|
||||
Figure [nano3d].
|
||||
|
||||
In addition to the CPU-monitoring additions, the tracing facilities received
|
||||
minor refinements. Up to now, it was not possible to trace threads that use a
|
||||
CPU session other than the component's initial one. A specific example is
|
||||
VirtualBox, which employs several CPU sessions, one for each priority. This
|
||||
problem has been solved by associating the event logger of each thread with
|
||||
its actual CPU session. Consequently, the tracing mechanism has become able to
|
||||
trace VirtualBox, which is pivotal for our further optimizations.
|
||||
|
||||
|
||||
Low-complexity software rendering functions
|
||||
===========================================
|
||||
|
||||
Our ambition to use Genode as our day-to-day OS raises the need for custom
|
||||
graphical applications. Granted, it is principally possible to base such
|
||||
applications on Qt5, which is readily available to native Genode components.
|
||||
However, for certain applications like status displays, we prefer to avoid the
|
||||
dependency on an overly complex GUI tool kit. To accommodate such
|
||||
applications, Genode hosts a small collection of low-complexity graphics
|
||||
functions called painters. All of Genode's low-complexity graphical components
|
||||
such as nitpicker, launchpad, window decorator, or the terminal are based on
|
||||
this infrastructure.
|
||||
|
||||
With the current release, we extend the collection with two new painters
|
||||
located at _gems/include/polygon_gfx_. Both draw convex polygons with an
|
||||
arbitrary number of points. The shaded-polygon painter interpolates the color
|
||||
and alpha values whereas the textured-polygon painter applies a texture to the
|
||||
polygon. The painters are accompanied by simplistic 3D routines located at
|
||||
_gems/include/nano3d/_ and a corresponding example (_gems/run/nano3d.run_).
|
||||
|
||||
[image nano3d]
|
||||
|
||||
With the nano3d demo and our new CPU load display, the screenshot above shows
|
||||
two applications that make use of the new graphics operations.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Completing the transition to the new platform driver
|
||||
====================================================
|
||||
|
||||
Until now, the platform driver on x86-based machines was formed by the ACPI
|
||||
and PCI drivers. The ACPI driver originally executed the PCI driver as a slave
|
||||
(child) service. The ACPI driver parsed the ACPI tables and provided the
|
||||
relevant information as configuration during the PCI-driver startup. We
|
||||
changed this close coupling to the more modern and commonly used
|
||||
[http://genode.org/documentation/release-notes/14.02#New_session_interface_for_status_reporting - report_rom mechanism].
|
||||
|
||||
When the new ACPI driver finishes the ACPI table parsing, it provides the
|
||||
information via a report to any interested and registered components. The
|
||||
report contains among other the IRQ re-routing information. The PCI driver is
|
||||
a component, which - according to its session routing configuration - plays
|
||||
the role of a consumer of the ACPI report.
|
||||
|
||||
With this change of interaction of ACPI and PCI driver, the policy for devices
|
||||
must be configured solely at the PCI driver and not at the ACPI driver. The
|
||||
syntax, however, stayed the same as introduced with release 15.05.
|
||||
|
||||
Finally, the PCI driver 'pci_drv' got renamed to 'platform_drv' as already
|
||||
used on most ARM platforms. All files and session interfaces containing
|
||||
PCI/pci in the names were renamed to Platform/platform. The x86 platform
|
||||
interfaces moved to _repos/os/include/platform/x86/_ and the implementation of
|
||||
the platform driver to _repos/os/src/drivers/platform/x86/_.
|
||||
|
||||
An example x86 platform configuration snippet looks like this:
|
||||
|
||||
!<start name="acpi_drv" >
|
||||
! <resource .../>
|
||||
! <route>
|
||||
! ...
|
||||
! <service name="Report"> <child name="acpi_report_rom"/> </service>
|
||||
! </route>
|
||||
!</start>
|
||||
!
|
||||
!<start name="acpi_report_rom" >
|
||||
! <binary name="report_rom"/>
|
||||
! <resource .../>
|
||||
! <provides> <service name="ROM" /> <service name="Report" /> </provides>
|
||||
! <config>
|
||||
! <rom> <policy label="platform_drv -> acpi" report="acpi_drv -> acpi"/> </rom>
|
||||
! </config>
|
||||
! <route> ... </route>
|
||||
!</start>
|
||||
!
|
||||
!<start name="platform_drv" >
|
||||
! <resource name="RAM" quantum="3M" constrain_phys="yes"/>
|
||||
! <provides> <service name="Platform"/> </provides>
|
||||
! <route>
|
||||
! <service name="ROM">
|
||||
! <if-arg key="label" value="acpi"/> <child name="acpi_report_rom"/>
|
||||
! </service>
|
||||
! ...
|
||||
! </route>
|
||||
! <config>
|
||||
! <policy label="ps2_drv"> <device name="PS2"/> </policy>
|
||||
! <policy label="nic_drv"> <pci class="ETHERNET"/> </policy>
|
||||
! <policy label="fb_drv"> <pci class="VGA"/> </policy>
|
||||
! <policy label="wifi_drv"> <pci class="WIFI"/> </policy>
|
||||
! <policy label="usb_drv"> <pci class="USB"/> </policy>
|
||||
! <policy label="ahci_drv"> <pci class="AHCI"/> </policy>
|
||||
! <policy label="audio_drv"> <pci class="AUDIO"/> <pci class="HDAUDIO"/> </policy>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
In order to unify and simplify the writing of run scripts, we added the
|
||||
commonly used platform configuration to the file
|
||||
_repos/base/run/platform_drv.inc_. This file may be included by any test run
|
||||
script in order to setup a default platform driver configuration.
|
||||
|
||||
In addition, the snippet provides the following functions:
|
||||
'append_platform_drv_build_components', 'append_platform_drv_config' and
|
||||
'append_platform_drv_boot_modules'. The functions add necessary information to
|
||||
the 'build_components', 'config' and 'boot_modules' run variables. The
|
||||
_platform_drv.inc_ also contains the distinction between various ARM/x86
|
||||
platforms and includes the necessary pieces. Hence, run scripts are largely
|
||||
relieved from platform-specific peculiarities.
|
||||
|
||||
The body of an example run script looks like this:
|
||||
|
||||
! set build_components { ... }
|
||||
!
|
||||
! source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
! append_platform_drv_build_components
|
||||
!
|
||||
! build $build_components
|
||||
!
|
||||
! create_boot_directory
|
||||
!
|
||||
! set config { ... }
|
||||
!
|
||||
! append_platform_drv_config
|
||||
!
|
||||
! append config { ... }
|
||||
!
|
||||
! install_config $config
|
||||
!
|
||||
! append_platform_drv_boot_modules
|
||||
!
|
||||
! build_boot_image $boot_modules
|
||||
!
|
||||
! run_genode_until ...
|
||||
|
||||
|
||||
BCM57cxx network cards
|
||||
======================
|
||||
|
||||
During Hack'n Hike 2015, we had access to a server that featured a Broadcom
|
||||
network card. Therefore Guido Witmond performed the first steps to enable
|
||||
Broadcom's BCM 57cxx cards. With this preliminary work in place, we were
|
||||
quickly able to perform the additional steps required to add BCM 57cxx support
|
||||
to Genode.
|
||||
|
||||
|
||||
VESA driver refinements
|
||||
=======================
|
||||
|
||||
The VESA driver now reports the frame buffer's line width instead of the
|
||||
visible width to the client. This fixes a possible distortion if these widths
|
||||
differ, at the cost that content in the right-most area might be invisible in
|
||||
such cases.
|
||||
|
||||
|
||||
VirtualBox
|
||||
##########
|
||||
|
||||
Policy-based mouse pointer
|
||||
==========================
|
||||
|
||||
In the previous release, we implemented support for the transparent
|
||||
integration of the guest mouse pointer with nitpicker via the VirtualBox guest
|
||||
additions and the vbox_pointer component, which is capable of rendering
|
||||
guest-provided mouse-pointer shapes. Now, we extended vbox_pointer by a
|
||||
policy-based configuration that allows the selection of ROMs containing the
|
||||
actual mouse shape based on the nitpicker session label or domain. With this
|
||||
feature in place, it is possible to integrate several VirtualBox instances as
|
||||
well as dedicated pointer shapes for specific components. To see the improved
|
||||
vbox_pointer in action give _run/vbox_pointer_ a shot.
|
||||
|
||||
|
||||
Dynamic adaptation to screen size changes
|
||||
=========================================
|
||||
|
||||
VirtualBox now notifies the guest operating system about screen-size changes
|
||||
(for example if the user resizes a window, which shows the guest frame
|
||||
buffer). The VirtualBox guest additions can use this information to adapt the
|
||||
guest frame buffer to the new size.
|
||||
|
||||
|
||||
SMP support
|
||||
===========
|
||||
|
||||
Guest operating systems can now use multiple virtual CPUs, which are mapped to
|
||||
multiple host CPUs. The number of virtual CPUs can be configured in the
|
||||
'.vbox' file.
|
||||
|
||||
|
||||
Preliminary audio support
|
||||
=========================
|
||||
|
||||
At some point, the use of VirtualBox as a stop-gap solution for using Genode
|
||||
as everyday OS raises the need to handle audio. With this release, we address
|
||||
this matter by enabling preliminary audio support in our VirtualBox port. A
|
||||
back end that uses the audio-out and audio-in sessions to playback and record
|
||||
sound samples has been added. It disguises itself as the OSS back end that is
|
||||
already used by vanilla VirtualBox. Since Genode pretends to be FreeBSD in the
|
||||
eyes of VirtualBox (because Genode's libc is based on FreeBSD's libc), the
|
||||
provisioning of an implementation of the OSS back end as used on FreeBSD host
|
||||
systems is the most natural approach. The audio support is complemented by
|
||||
adding the necessary device models for the virtual HDA as well as the AC97
|
||||
devices to our VirtualBox port.
|
||||
|
||||
For now, it is vital to have the guest OS configure the virtual device in a
|
||||
way that considers the current implementation. For example, we cannot
|
||||
guarantee distortion-free playback or recording if the guest OS uses a period
|
||||
that is too short, typically 10ms or less. There are also remaining issues
|
||||
with the mixing/filtering code in VirtualBox. Therefore, we bypass it to
|
||||
achieve better audio quality. As a consequence, the device model of the VM has
|
||||
to use the same sample rate as is used by the audio-out and audio-in sessions
|
||||
(44.1kHz).
|
||||
|
||||
Enabling audio support is done be adding
|
||||
! <AudioAdapter controller="HDA" driver="OSS" enabled="true"/>
|
||||
to the .vbox file manually or configuring the VM accordingly by using the GUI.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Bender chain loader on base-hw x86_64
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On Intel platforms, we use the Bender chain loader from the
|
||||
[https://github.com/alex-ab/morbo - Morbo multiboot suite] to detect available
|
||||
COM ports of PCI plug-in cards, the AMT SOL device, or as fall back the
|
||||
default comport 1. The loader stores the I/O port information of the detected
|
||||
cards into the BIOS data area (BDA), from where it is retrieved by core on
|
||||
boot and subsequently used for logging. With this release, we added the BDA
|
||||
parsing to base-hw on x86-64 and enabled the feature in the run tool. As a
|
||||
prerequisite, we had to fix an issue in bender triggered by the loading of
|
||||
only one (large) multi-boot kernel. Consequently, its binary in
|
||||
_tool/boot/bender_ was updated.
|
||||
|
||||
|
||||
Revised page-table handling
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
One of the main advantages of the base-hw platform is that the memory trading
|
||||
concept of Genode is universally applied even with regard to kernel objects.
|
||||
For instance, whenever a component wants to create a thread, it pays for the
|
||||
thread's stack, UTCB, and for the corresponding kernel object. The same
|
||||
applies to objects needed to manage the virtual address space of a component
|
||||
with the single exception of page tables.
|
||||
|
||||
Normally, when the quota, which was donated by a component to a specific
|
||||
service, runs out, the component receives an exception the next time it tries
|
||||
to invoke the service. The component can respond by upgrading the respective
|
||||
session quota. However, in the context of page-fault resolution, this is
|
||||
particularly difficult to do. The allocation and thereby the shortage of
|
||||
memory becomes evident only when the client produces a page fault. Therefore,
|
||||
there is no way to inform the component to upgrade its session quota before
|
||||
resolving the fault.
|
||||
|
||||
Instead of designing a sophisticated protocol between core and the other
|
||||
components to solve this problem, we decided to simplify the current
|
||||
page-fault resolution by using a static set of page-tables per component.
|
||||
Formerly, page tables were dynamically allocated from core's memory allocator.
|
||||
Now, an array of page tables gets allocated during construction of a
|
||||
protection domain. When a component runs out of page tables, all of its
|
||||
mappings get flushed, and the page tables are populated from scratch. This
|
||||
change greatly simplifies the page-table handling inside of base-hw.
|
||||
|
||||
|
||||
Dynamic interrupt mode setting on x86_64
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On x86-based hardware, user-level device drivers have become able to specify
|
||||
the trigger mode and polarity of the interrupts when requesting an IRQ
|
||||
session. On ARM, those session parameters are ignored. This change enables the
|
||||
x86_64 platform to support devices, which use arbitrary trigger modes and
|
||||
polarity settings, e.g., AHCI on QEMU and real hardware.
|
||||
|
||||
|
||||
Fiasco.OC
|
||||
=========
|
||||
|
||||
Genode's device-driver support when using the Fiasco.OC kernel as base
|
||||
platform received an upgrade.
|
||||
|
||||
First, principle support for the Raspberry Pi was added. To make this platform
|
||||
useful in practice, a working USB driver is important. I.e., the network
|
||||
interface is connected via USB. Hence the USB driver got enabled for
|
||||
Fiasco.OC, too. As a result, Genode's software stack can now be used on the
|
||||
Raspberry Pi by using either our custom base-hw kernel or Fiasco.OC.
|
||||
|
||||
Second, support for the Odroid-X2 platform using the Exynos4412 SoC was added,
|
||||
which includes the drivers for clock management (CMU), power management
|
||||
(PMU) as well as USB.
|
||||
|
||||
Thanks to Reinier Millo Sánchez and Alexy Gallardo Segura for having
|
||||
contributed this line of work.
|
||||
|
||||
|
||||
Removal of deprecated features
|
||||
##############################
|
||||
|
||||
We dropped the support for the *ARM Versatile Express* board from the Genode
|
||||
source tree to relieve our automated testing infrastructure from supporting a
|
||||
platform that remained unused for more than two years.
|
||||
|
||||
The device driver environment kit (DDE Kit) was originally intended as a
|
||||
common API among the execution environments of ported user-level device
|
||||
drivers. However, over the course of the past years, we found that this
|
||||
approach could not fulfill its promise while introducing a number of new
|
||||
problems. We reported our experiences in the release notes of versions
|
||||
[http://genode.org/documentation/release-notes/12.05#Re-approaching_the_Linux_device-driver_environment - 12.05] and
|
||||
[http://genode.org/documentation/release-notes/14.11#Roundup - 14.11].
|
||||
To be able to remove the DDE-Kit API, we reworked the USB driver, our port of
|
||||
the Linux TCP/IP stack, and the wireless driver accordingly.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,652 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 16.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
With version 16.02, we add RISC-V to Genode's supported CPU architectures,
|
||||
enable the secure pass-through of individual USB devices to virtual machines,
|
||||
and update the support for the Muen and seL4 kernels.
|
||||
|
||||
Trustworthy hardware becomes an increasingly pressing problem. With each new
|
||||
generation of today's commodity hardware comes a dramatic increase of
|
||||
complexity, the addition of proprietary companion processors, and opaque
|
||||
firmware blobs. Even with a perfectly secure operating system, the user's
|
||||
privacy and security remains at risk as there is no way to assess the
|
||||
trustworthiness of our underlying hardware. RISC-V is a new hardware
|
||||
architecture that tries to overcome this problem by the means of open source
|
||||
and transparency. It is designed to scale from micro controllers to
|
||||
general-purpose computers, and to be both synthesizable as FPGA softcores and
|
||||
implementable in ASICs. The prospect of a scalable and trustworthy open-source
|
||||
hardware platform motivated us to add RISC-V to Genode's supported CPU
|
||||
architectures. Section [New support for the RISC-V CPU architecture] gives a
|
||||
brief overview of this line of work.
|
||||
|
||||
Thanks to the growing number of our regular developers using Genode as day to
|
||||
day OS, we create a natural incentive to address typical desktop-OS work
|
||||
flows. In particular, the new version comes with the ability to assign
|
||||
individual USB devices to VirtualBox instances. Conceptually, this looks like
|
||||
a relatively straight-forward feature. But as discussed in Section
|
||||
[Assignment of USB devices to virtual machines], we had to overcome a number of
|
||||
challenging problems caused by the inherently dynamic nature of USB-device
|
||||
hot-plugging. Also on the account of day-to-day computing, the GUI stack
|
||||
received welcomed usability improvements like keyboard shortcuts for certain
|
||||
window-management operations.
|
||||
|
||||
With respect to Genode's underlying base platforms, we are happy to announce
|
||||
the updates of the Muen and seL4 kernels. The Muen separation kernel received
|
||||
an update to version 0.7, which accommodates Genode's regular work flows (via
|
||||
run scripts) much better than the previous version. As described in Section
|
||||
[Muen separation kernel], this change clears the way to subject Muen to
|
||||
Genode's regular automated tests. The seL4 kernel represents an exciting
|
||||
playground as a future base platform for Genode. We have updated the kernel to
|
||||
version 2.1, which prompted us to fundamentally revisit the low-level resource
|
||||
management of Genode on this kernel. A summary of this undertaking is presented
|
||||
in Section [seL4 version 2.1].
|
||||
|
||||
According to the [http:/about/road-map - road map], we originally planned to
|
||||
revise the framework API in this release. Even though this topic is
|
||||
[https://github.com/genodelabs/genode/issues/1832 - very actively pursued], we
|
||||
decided to not rush it. We find it important to provide a smooth migration path
|
||||
from the old API to the new one. Determining the best path is actually trickier
|
||||
than revising the API, though. To let our decisions settle a bit, we postpone
|
||||
the transition to the upcoming release.
|
||||
|
||||
|
||||
Assignment of USB devices to virtual machines
|
||||
#############################################
|
||||
|
||||
As a migration strategy for running Genode on a daily basis, using VirtualBox
|
||||
to execute a feature-rich OS is vital. In release
|
||||
[http://genode.org/documentation/release-notes/15.05#USB-device_pass-through_support - 15.05],
|
||||
we added USB pass-through support to VirtualBox by enabling its integrated USB
|
||||
proxy service. Since we use the open-source edition of VirtualBox, we were
|
||||
merely able to use the OHCI device model and were therefore limited to using
|
||||
USB 1.x devices in low and full speed mode only. To make matters worse, when
|
||||
using the OHCI controller model, it is difficult if not impossible to access
|
||||
USB mass-storage devices. Usually, VirtualBox facilitates the EHCI or xHCI
|
||||
device models for the pass-through of storage devices. Unfortunately, those
|
||||
models are only available as a proprietary extension, which cannot be used by
|
||||
our VirtualBox port.
|
||||
|
||||
Having support for the pass-through of high-speed and super-speed USB devices
|
||||
is a must in such controller models. Therefore, we either have to implement
|
||||
these models ourselves or port existing ones from another VMM or emulator to
|
||||
fill the gap. We went for porting existing models first because device-model
|
||||
development from scratch could end up being time consuming if we want to
|
||||
guarantee them to work with a variety of different OS drivers.
|
||||
|
||||
|
||||
QEMU xHCI device model
|
||||
----------------------
|
||||
|
||||
QEMU features a NEC xHCI (UPD720200) device model that works well with Windows
|
||||
guests. For this reason, we decided to give porting this device model a shot.
|
||||
We applied the DDE approach and started by creating a QEMU emulation
|
||||
environment so that only the bare minimum amount of source code needed to be
|
||||
taken from the QEMU sources. It came down to a handful of source files, mainly
|
||||
the USB core and the xHCI device model files. We iteratively extended the
|
||||
emulation environment until the QEMU sources compiled and linked fine. One
|
||||
particular cumbersome issue we had to overcome was the emulation of the QEMU
|
||||
Object Model. Since QEMU is written in C, it uses its own object model to
|
||||
implement inheritance. This object model is used throughout QEMU. We took the
|
||||
easy way out and just used a C++ wrapper class that contains all QEMU objects
|
||||
that are used in the USB subsystem.
|
||||
|
||||
The next step was to develop a USB host device model. This model connects a
|
||||
USB device attached to Genode's USB host-controller driver to the xHCI device
|
||||
model. Lucky for us, QEMU already contains a USB host device model that uses
|
||||
libusb, which we could use as blueprint. We implemented a USB host device that
|
||||
leverages Genode's custom USB session interface. This host device reacts to a
|
||||
USB device report coming from another component such as the host-controller
|
||||
driver. It tries to claim all devices it finds in that report and then creates
|
||||
a QEMU USB device for each of them that is attached to the xHCI device model.
|
||||
|
||||
The xHCI device model needs infrastructure that normally is provided by QEMU
|
||||
itself such as a timer queue and PCI device handling. We introduced a QEMU
|
||||
USB controller interface _repos/libports/include/qemu/usb.h_ whose back-end
|
||||
library interface has to be implemented by a component, i.e. the VMM, that
|
||||
wants to use the library.
|
||||
|
||||
In the end, this work resulted in a small library that contains the xHCI
|
||||
device model and works in a standalone way. All required resources have to be
|
||||
provided by the component using the library. This makes it easy to integrate
|
||||
the library in different VMMs because the user of the library is not forced to
|
||||
employ the library in a certain way but free to use it any way he chooses.
|
||||
|
||||
|
||||
xHCI device model wrapper in VirtualBox
|
||||
---------------------------------------
|
||||
|
||||
We implemented an xHCI device model _repos/port/src/virtualbox/devxhci.cc_ in
|
||||
VirtualBox that merely wraps the QEMU USB library and provides the back-end
|
||||
functionality required by the library to glue QEMU's xHCI device model to
|
||||
VirtualBox. For now, this device is always part of a VM because there is
|
||||
currently no way to disable it from within the VirtualBox configuration
|
||||
front end. Therefore, it is necessary to always give VirtualBox access to a
|
||||
_usb_devices_ ROM module.
|
||||
|
||||
We removed the afore mentioned USB proxy service from our VirtualBox port
|
||||
because it became redundant with the advent of our xHCI device model.
|
||||
|
||||
|
||||
USB device report filter
|
||||
------------------------
|
||||
|
||||
With the xHCI support in VirtualBox in place, we had to come up with a
|
||||
mechanism to select, which USB devices it may access. Since USB devices are
|
||||
usually hot-plugged by the user of the system, we need to be able to configure
|
||||
the access permissions dynamically at run-time. On this account, we created a
|
||||
component that intercepts the report from the USB host-controller driver. On
|
||||
the one hand, this USB device report-filter component screens the device
|
||||
report coming from the USB host-controller driver by checking each reported
|
||||
device against a given white list of devices. Only approved devices are
|
||||
reported to a consumer of the report, i.e. VirtualBox. On the other hand, this
|
||||
component generates a new configuration for the USB host-controller driver.
|
||||
The configuration has to be changed each time the filter component finds a
|
||||
suitable device because the driver will hand out access to a given device to a
|
||||
client only if there is a valid policy. As we do not know in advance, which
|
||||
devices might be plugged in, this policy must be maintained dynamically. The
|
||||
report filter will send the device report only if the host-controller driver
|
||||
has changed its configuration. This ensures that a matching policy will be in
|
||||
effect at the time when the client component tries to access the device.
|
||||
|
||||
The configuration of the report-filter component can also be changed at run
|
||||
time.
|
||||
|
||||
See _repos/os/src/app/usb_report_filter/README_ for more details on how the
|
||||
USB device report filter may be configured.
|
||||
|
||||
|
||||
Example configuration
|
||||
---------------------
|
||||
|
||||
The following figure illustrates the interplay and configuration of the
|
||||
involved components:
|
||||
|
||||
[image qemu_xhci]
|
||||
|
||||
When the user plugs in a USB device, the USB host-controller driver generates
|
||||
a device report that is consumed by the USB device report-filter component
|
||||
(1). The filter component then examines the report and checks if it contains a
|
||||
device it should report to its report consumer. It then reconfigures the
|
||||
host-controller driver (2). Afterwards it sends a report to its consumer (3).
|
||||
The consumer, in this case a VMM, then accesses the USB device (4).
|
||||
|
||||
|
||||
New support for the RISC-V CPU architecture
|
||||
###########################################
|
||||
|
||||
We became aware of [http://riscv.org - RISC-V] when attending several talks
|
||||
about the project at [https://fosdem.org - FOSDEM] in 2015. RISC-V aims to be
|
||||
an open-source hardware architecture and is now complemented by many projects
|
||||
that target the release of real hardware or ASICs (for example,
|
||||
[http://lowrisc.org - the LowRISC project]). We have experience with various
|
||||
major CPU architectures and many systems on a chip and, therefore, embrace a
|
||||
sharp eye on certain platform properties. Intel's ME and ARM's Trustzone
|
||||
practically lock out operating systems of certain hardware and firmware
|
||||
features. The true nature of these mechanisms becomes increasingly dubious,
|
||||
especially when trying to build a secure open-source operating system. Intel's
|
||||
AMT technology for instance comes with a complete TCP/IP stack that intercepts
|
||||
packets from the integrated NIC and a VNC server that can magically expose a
|
||||
mouse and a keyboard at the USB controller. If you are interested in more
|
||||
details about this topic
|
||||
[http://blog.invisiblethings.org/papers/2015/x86_harmful.pdf - Intel x86 considered harmful]
|
||||
by Joanna Rutkowska is a very good read. We decided to have a deeper look at
|
||||
the RISC-V architecture as an alternative open hardware platform. Especially,
|
||||
since the LowRISC project promises a completely open system on chip, including
|
||||
the peripherals.
|
||||
|
||||
RISC-V comes with a lot of optional features, so it can cover a large field of
|
||||
applications reaching from simple I/O processors to general-purpose computing.
|
||||
For example, there are 64 and 32 bit ISA (instruction set architecture)
|
||||
versions, three page table formats with the option to omit paging at all, up
|
||||
to four privilege modes, and a minimal integer core ISA (I). Everything else,
|
||||
like multiplication and division (M), atomic instructions (A), and floating
|
||||
point support (F) are subject to ISA extensions and are completely optional
|
||||
for a specific hardware implementation.
|
||||
|
||||
For Genode, we chose to add the RISC-V support to our custom _base-hw_ kernel.
|
||||
Since Genode may be used as a general purpose OS, we implemented the kernel
|
||||
using the 64 bit RISC-V version, the Sv39 three-level page table format, and
|
||||
the so-called general-purpose extension (G), which is the abbreviation for the
|
||||
IAMF extensions. The current implementation provides the kernel and the
|
||||
necessary adaptations of the user level part of core.
|
||||
|
||||
For testing, we used the RISC-V instruction emulator called
|
||||
[https://github.com/riscv/riscv-isa-sim - Spike]. There also exists a RISC-V
|
||||
implementation for various Zynq FPGAs. Genode's Zynq board support has kindly
|
||||
been added and contributed by Mark Vels.
|
||||
|
||||
In the current state, basic Genode applications including core, init, and
|
||||
components that use shared libraries can be executed on top of our RISC-V
|
||||
port. We did not enable the libc and postponed further activity as the
|
||||
platform currently does not specify the interaction with peripherals.
|
||||
|
||||
|
||||
Steps to test Genode on RISC-V
|
||||
------------------------------
|
||||
|
||||
# Building the instruction emulator
|
||||
|
||||
! # download the front end server
|
||||
! git clone https://github.com/ssumpf/riscv-fesvr.git
|
||||
!
|
||||
! # build the front end server
|
||||
! cd riscv-fesvr
|
||||
! mkdir build
|
||||
! cd build
|
||||
! export RISCV=<installation path>
|
||||
! ../configure --prefix=$RISCV
|
||||
! (sudo) make install
|
||||
!
|
||||
! # download the instruction emulator
|
||||
! cd ../../
|
||||
! git clone https://github.com/ssumpf/riscv-isa-sim.git
|
||||
! cd riscv-isa-sim
|
||||
!
|
||||
! # build the emulator
|
||||
! mkdir build
|
||||
! cd build
|
||||
! ../configure --prefix=$RISCV --with-fesvr=$RISCV
|
||||
! (sudo) make install
|
||||
!
|
||||
! # add $RISCV/bin to path
|
||||
! export PATH=$RISCV/bin:$PATH
|
||||
|
||||
# Building Genode and running a test scenario
|
||||
|
||||
! # download Genode
|
||||
! cd ../../
|
||||
! git clone https://github.com/genodelabs/genode.git
|
||||
!
|
||||
! # build the Genode tool chain
|
||||
! cd genode
|
||||
! ./tool/tool_chain riscv
|
||||
!
|
||||
! # create RISC-V build directory
|
||||
! ./tool/create_builddir hw_riscv
|
||||
! cd build/hw_riscv
|
||||
!
|
||||
! # build and execute the printf run script
|
||||
! make run/printf
|
||||
|
||||
|
||||
GUI stack usability improvements
|
||||
################################
|
||||
|
||||
Motivated by the daily use of Genode as desktop OS by an increasingly number
|
||||
of developers, the window-layouter component of the
|
||||
[http://genode.org/documentation/release-notes/15.11#GUI_stack - GUI stack]
|
||||
received welcomed usability improvements.
|
||||
|
||||
|
||||
Configurable window placement
|
||||
-----------------------------
|
||||
|
||||
The policy of the window layouter can be adjusted via its configuration. For
|
||||
a given window label, the window's initial position and its maximized state
|
||||
can be defined as follows:
|
||||
|
||||
! <config>
|
||||
! <policy label="mupdf" maximized="yes"/>
|
||||
! <policy label="nit_fb" xpos="50" ypos="50"/>
|
||||
! </config>
|
||||
|
||||
|
||||
Keyboard shortcuts
|
||||
------------------
|
||||
|
||||
The window layouter has become able to respond to key sequences. However,
|
||||
normally, the layouter is not a regular nitpicker client but receives only
|
||||
those input events that refer to the window decorations. It never owns the
|
||||
keyboard focus. In order to propagate global key sequences to the layouter,
|
||||
nitpicker must be explicitly configured to direct key sequences initiated with
|
||||
certain keys to the decorator. For example, the following nitpicker
|
||||
configuration routes key sequences starting with the left windows key to the
|
||||
decorator. The window manager, in turn, forwards those events to the layouter.
|
||||
|
||||
! <start name="nitpicker">
|
||||
! ...
|
||||
! <config>
|
||||
! ...
|
||||
! <global-key name="KEY_LEFTMETA" label="wm -> decorator" />
|
||||
! ...
|
||||
! </config>
|
||||
! ...
|
||||
! </start>
|
||||
|
||||
The response of the window layouter to key sequences can be expressed in the
|
||||
layouter configuration as follows:
|
||||
|
||||
! <config>
|
||||
! <press key="KEY_LEFTMETA">
|
||||
! <press key="KEY_TAB" action="next_window">
|
||||
! <release key="KEY_TAB">
|
||||
! <release key="KEY_LEFTMETA" action="raise_window"/>
|
||||
! </release>
|
||||
! </press>
|
||||
! <press key="KEY_LEFTSHIFT">
|
||||
! <press key="KEY_TAB" action="prev_window">
|
||||
! <release key="KEY_TAB">
|
||||
! <release key="KEY_LEFTMETA" action="raise_window"/>
|
||||
! </release>
|
||||
! </press>
|
||||
! </press>
|
||||
! <press key="KEY_ENTER" action="toggle_fullscreen"/>
|
||||
! </press>
|
||||
! </config>
|
||||
|
||||
Each '<press>' node defines the policy when the specified 'key' is pressed.
|
||||
It can be equipped with an 'action' attribute that triggers a window action.
|
||||
The supported window actions are:
|
||||
|
||||
:next_window: Focus the next window in the focus history.
|
||||
:prev_window: Focus the previous window in the focus history.
|
||||
:raise_window: Bring the focused window to the front.
|
||||
:toggle_fullscreen: Maximize/unmaximize the focused window.
|
||||
|
||||
By nesting '<press>' nodes, actions can be tied to key sequences. In the
|
||||
example above, the 'next_window' action is executed only if TAB is pressed
|
||||
while the left windows-key is kept pressed. Furthermore, key sequences can
|
||||
contain specific release events. In the example above, the release of the left
|
||||
windows key brings the focused window to front, but only if TAB was pressed
|
||||
before.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
USB host-controller driver enhancements
|
||||
=======================================
|
||||
|
||||
The _usb_drv_ component now solely uses a policy to grant other components
|
||||
access to USB devices exposed by its raw interface (USB session). On the basis
|
||||
of the 'label' attribute, it will choose a pre-configured device that is
|
||||
identified by either the 'bus' and 'dev' or the 'vendor' and 'product'
|
||||
attribute tuple. To accommodate policy decisions made at run time, the USB
|
||||
driver is now able to reload its configuration on demand. The USB device
|
||||
report now contains a 'bus' and a 'dev' attribute as well in order to identify
|
||||
a USB device more precisely. In addition to that, there is also a generated
|
||||
'label' attribute in form of 'usb-<bus>-<dev>' that may be used to form
|
||||
policies while configuring the system dynamically, e.g., when using the
|
||||
_usb_report_filter_ component.
|
||||
|
||||
|
||||
USB mass-storage driver
|
||||
=======================
|
||||
|
||||
Up to now, access to USB storage devices was provided by the USB
|
||||
host-controller driver only. However, its ability to do so is limited. E.g.,
|
||||
it only supports one storage device and the storage device cannot be changed
|
||||
at run-time. With this release we add a USB mass-storage driver that supports
|
||||
UMS bulk-only devices that use the SCSI Block Commands set (direct-access).
|
||||
This is still most common for USB sticks. Devices using different command
|
||||
sets, e.g SD/HC devices or some external disc drives, will not work properly
|
||||
if at all. The driver uses the USB session interface to access the USB device
|
||||
and provides its service as block session to its client.
|
||||
|
||||
This component is part of the first step providing the ability to mount and
|
||||
use USB sticks dynamically when using Genode as a general purpose OS. In the
|
||||
future, the _usb_drv_ component should solely be the host-controller driver
|
||||
while other tasks are handled by dedicated USB driver components such as this
|
||||
one.
|
||||
|
||||
|
||||
Audio output on Linux
|
||||
=====================
|
||||
|
||||
The audio-out driver for Linux was modernized by replacing its multi-threaded
|
||||
architecture by an event-driven architecture using Genode's server API. In
|
||||
addition, the playback is now driven by a timer. For now it is a periodic
|
||||
timer that triggers every 11 ms which is roughly the current audio-out period.
|
||||
|
||||
The driver now also behaves like the other BSD-based audio-out driver, i.e.,
|
||||
it always advances the play pointer. That is vital for the audio-out stack
|
||||
above the driver to work properly (e.g., the mixer).
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New Genode-world repository
|
||||
===========================
|
||||
|
||||
With a growing number of users and contributors comes the desire to bring more
|
||||
and more existing software to Genode. Most of such libraries and applications,
|
||||
however, are outside of the scope of Genode as an OS framework. In contrast to
|
||||
device drivers, protocol stacks, and low-level OS services, which we subject
|
||||
to our regular automated tests, most 3rd-party software is pretty independent
|
||||
from Genode. The attempt to integrate the growing pool of such diverse
|
||||
software into the main repository does not scale.
|
||||
|
||||
For this reason, we introduce the new
|
||||
[https://github.com/genodelabs/genode-world - Genode World] repository, which
|
||||
is the designated place for hosting ported applications, libraries, and games.
|
||||
|
||||
To use it, you first need to obtain a clone of Genode:
|
||||
|
||||
! git clone https://github.com/genodelabs/genode.git genode
|
||||
|
||||
Now, clone the _genode-world.git_ repository to _genode/repos/world:_
|
||||
|
||||
! git clone https://github.com/genodelabs/genode-world.git genode/repos/world
|
||||
|
||||
By placing the _world_ repository under the _repos/_ directory, Genode's tools
|
||||
will automatically incorporate the ports provided by the _world_ repository.
|
||||
|
||||
For building software of the _world_ repository, the build-directory
|
||||
configuration _etc/build.conf_ must be extended with the following line:
|
||||
|
||||
! REPOSITORIES += $(GENODE_DIR)/repos/world
|
||||
|
||||
*Word of caution*
|
||||
|
||||
In contrast to the components found in the mainline Genode repository, the
|
||||
components within the _world_ repository are not subjected to the regular
|
||||
quality-assurance measures of Genode Labs. Hence, problems are to be expected.
|
||||
If you encounter bugs, build problems, or stability issues, please report them
|
||||
to the [https://github.com/genodelabs/genode-world/issues - issue tracker] or
|
||||
the [http://genode.org/community/mailing-lists - mailing list].
|
||||
|
||||
|
||||
Updated 3rd-party software
|
||||
==========================
|
||||
|
||||
The following 3rd-party code packages of the _ports_ and _libports_
|
||||
repositories have been ported or updated:
|
||||
|
||||
* Lynx 2.8.8rel.2 (noux package)
|
||||
* OpenSSH 7.1p1 (noux package)
|
||||
* tar-1.27 (noux package)
|
||||
* libssh 0.7.2
|
||||
* Lighttpd 1.4.38
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Within the last months, the initialization code of our custom kernel got
|
||||
re-arranged to simplify the addition of new architectures, e.g., the RISC-V
|
||||
port (Section [New support for the RISC-V CPU architecture]) while also making
|
||||
its implementation leaner. A positive side effect of this work was the
|
||||
generalization of multi-processor and L2-cache support for ARM's Cortex-A9
|
||||
CPUs. For instance, the Wandboard (Freescale i.MX6 SoC) is now driven with all
|
||||
four cores, and its memory can be accessed with full speed.
|
||||
|
||||
Besides those feature additions, we fixed an extremely rare and tricky race
|
||||
condition in the implementation of the kernel-protected capabilities,
|
||||
introduced in release 15.05. A capability's lifetime within a component is
|
||||
tracked by a reference-counting like mechanism that is under control of the
|
||||
component itself. When the kernel transfered a capability to a component, and
|
||||
the very same capability was deleted within the component simultaneously, the
|
||||
received capability was marked as invalid, which led to diverse, sporadic
|
||||
faults. This deficit in the capabilities reference-counting is solved with the
|
||||
current release.
|
||||
|
||||
|
||||
Muen separation kernel
|
||||
======================
|
||||
|
||||
Build integration
|
||||
-----------------
|
||||
|
||||
Building Genode scenarios running on top of the
|
||||
[http://muen.sk - Muen separation kernel] has been greatly simplified by
|
||||
properly integrating the Muen system build process into the Genode build system.
|
||||
As described in the
|
||||
[http://genode.org/documentation/release-notes/15.08#Genode_on_top_of_the_Muen_Separation_Kernel - 15.08 release notes],
|
||||
the architecture with Muen is different since the entire hw_x86_64_muen Genode
|
||||
system runs as a guest VM on top of the separation kernel. This means that the
|
||||
Genode base-hw image must itself be packaged into the final Muen system image
|
||||
as an additional step after the Genode system build.
|
||||
|
||||
The packaging process of a Muen system image is performed by the new
|
||||
_image/muen_ run-tool plugin, which processes the following RUN_OPT parameters.
|
||||
|
||||
:--image-muen-external-build:
|
||||
Muen system is built automatically or externally
|
||||
|
||||
:--image-muen-system:
|
||||
Muen system policy
|
||||
|
||||
:--image-muen-components:
|
||||
Muen system components required for the given system policy
|
||||
|
||||
:--image-muen-hardware:
|
||||
Muen target hardware platform
|
||||
|
||||
:--image-muen-gnat-path:
|
||||
Path to GNAT toolchain
|
||||
|
||||
:--image-muen-spark-path:
|
||||
Path to SPARK toolchain
|
||||
|
||||
The options are automatically added to the _etc/build.conf_ file for the
|
||||
hw_x86_64_muen base-hw platform. The
|
||||
[http://genode.org/documentation/platforms/muen - documentation] has been
|
||||
updated to reflect the new, simplified build process.
|
||||
|
||||
A port file was added to facilitate the download of the Muen sources v0.7 and
|
||||
to check the required dependencies.
|
||||
|
||||
Using the new _image/muen_ script in combination with iPXE allows to run the
|
||||
Genode test suite via the autopilot tool.
|
||||
|
||||
|
||||
MSI support
|
||||
-----------
|
||||
|
||||
Muen employs Intel VT-d interrupt remapping (IR) besides DMA remapping for
|
||||
secure device assignment. As a consequence, PCI devices using Message Signaled
|
||||
Interrupts (MSI) must be programmed to trigger requests in remappable format
|
||||
(see Intel VT-d specification, Section 5.1.2.2 for further details).
|
||||
|
||||
To enable the use of MSIs with the base-hw kernel, a platform-specific
|
||||
function has been introduced that returns the necessary MSI parameters for a
|
||||
given PCI device. If either the platform or the specific device does not
|
||||
support MSI, the function returns false.
|
||||
|
||||
On hw_x86_64_muen, the function consults the Muen subject info page to supply
|
||||
the appropriate information to the IRQ session. This allows Genode device
|
||||
drivers to transparently use MSIs for passed-through PCI devices.
|
||||
|
||||
|
||||
seL4 version 2.1
|
||||
================
|
||||
|
||||
By the end of 2015, the [http://sel4.systems/ - seL4 kernel] version 2.0 was
|
||||
published. With the current release, we update Genode's preliminary support
|
||||
for this kernel from the experimental branch of one year ago to the master
|
||||
branch of version 2.1. Note that this line of work is still considered as an
|
||||
exploration. As of now, there is still a way to go until we can leverage seL4
|
||||
as a fully featured base platform. Under the hood of Genode, the transition to
|
||||
the version 2.1 master branch had the following implications.
|
||||
|
||||
In contrast to the experimental branch, the seL4 master branch has no way to
|
||||
manually define the allocation of kernel objects within untyped memory ranges.
|
||||
Instead, the kernel maintains a built-in allocation policy. This policy rules
|
||||
out the deallocation of once-used parts of untyped memory. The only way to
|
||||
reuse memory is to revoke the entire untyped memory range. Consequently, we
|
||||
cannot share a large untyped memory range for kernel objects of different
|
||||
protection domains. In order to reuse memory at a reasonably fine granularity,
|
||||
we need to split the initial untyped memory ranges into small chunks that can
|
||||
be individually revoked. Those chunks are called "untyped pages". An untyped
|
||||
page is a 4 KiB untyped memory region.
|
||||
|
||||
The bootstrapping of core has to employ a two-stage allocation approach now.
|
||||
For creating the initial kernel objects for core, which remain static during
|
||||
the entire lifetime of the system, kernel objects are created directly out of
|
||||
the initial untyped memory regions as reported by the kernel. The so-called
|
||||
"initial untyped pool" keeps track of the consumption of those untyped memory
|
||||
ranges by mimicking the kernel's internal allocation policy. Kernel objects
|
||||
created this way can be of any size. For example the CNode, which is used to
|
||||
store page-frame capabilities is 16 MiB in size. Also, core's CSpace uses a
|
||||
relatively large CNode.
|
||||
|
||||
After the initial setup phase, all remaining untyped memory is turned into
|
||||
untyped pages. From this point on, newly created kernel objects cannot exceed
|
||||
4 KiB in size because one kernel object cannot span multiple untyped memory
|
||||
regions. The capability selectors for untyped pages are organized similarly to
|
||||
those of page-frame capabilities. There is a new 2nd-level CNode
|
||||
(UNTYPED_CORE_CNODE) that is dimensioned according to the maximum amount of
|
||||
physical memory (1M entries, each entry representing 4 KiB). The CNode is
|
||||
organized such that an index into the CNode directly corresponds to the
|
||||
physical frame number of the underlying memory. This way, we can easily
|
||||
determine an untyped page selector for any physical addresses, i.e., for
|
||||
revoking the kernel objects allocated at a specific physical page. The
|
||||
downside is the need for another 16 MiB chunk of meta data. Also, we need to
|
||||
keep in mind that this approach won't scale to 64-bit systems. We will
|
||||
eventually need to replace the PHYS_CORE_CNODE and UNTYPED_CORE_CNODE by CNode
|
||||
hierarchies to model a sparsely populated CNode. The following figure
|
||||
illustrates the layout of core's capability space.
|
||||
|
||||
[image sel4_core_cspace_master]
|
||||
Organization of core's capability space on seL4
|
||||
|
||||
For each protection domain, core maintains a so-called VM CSpace that holds
|
||||
capability selectors for page frames and page tables. The size constraint of
|
||||
kernel objects has the immediate implication that the VM CSpaces of protection
|
||||
domains must be organized via several levels of CNodes. I.e., as the top-level
|
||||
CNode of core has a size of 2^12, the remaining 20 PD-specific CSpace address
|
||||
bits are organized as a 2nd-level 2^4 padding CNode, a 3rd-level 2^8 CNode,
|
||||
and several 4th-level 2^8 leaf CNodes. The latter contain the actual selectors
|
||||
for the page tables and page-table entries of the respective PD.
|
||||
|
||||
As another slight difference from the experimental branch, the master branch
|
||||
requires the explicit assignment of page directories to an ASID pool.
|
||||
|
||||
Functionality-wise the update to version 2.1 brings no changes. The
|
||||
preliminary support is still limited to Genode's most fundamental mechanisms
|
||||
like the bootstrapping, the creation of protection domains, the execution of
|
||||
threads, and inter-component communication. User-level device drivers are not
|
||||
supported yet. Such functional improvements are scheduled for Genode 16.08.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
We started to experience crashes of our dynamic linker (ldso) when using
|
||||
Genode's _base-linux_ platform on recent Linux kernels. Ldso is primarily a
|
||||
shared object, which is linked to dynamic binaries. But ldso is also an
|
||||
executable, which, once started loads the dynamically-linked binary along with
|
||||
all shared libraries required by the binary. Up to now, ldso had to be loaded
|
||||
at a link address defined at compilation time, which we enforced through
|
||||
linker-script magic. Unfortunately, this does not work any longer on recent
|
||||
Linux versions. The kernel notices that ldso is a shared object and loads it
|
||||
at an arbitrary (randomized) address, which ultimately results in a
|
||||
segmentation fault during ldso initialization. We found a fix for this issue
|
||||
by marking ldso as an executable in the ELF header. But since ldso is linked
|
||||
to all dynamic binaries (it contains Genode's base libraries) the GNU linker
|
||||
then refused to link because ldso was not marked as a shared object.
|
||||
Therefore, we decided to implement true self relocation within ldso. This
|
||||
feature only works on Genode's base-linux platform as it requires some
|
||||
symbol-address magic.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,729 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 16.11
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
In contrast to most parts of the framework, the fundamental low-level
|
||||
protocols, which define the interaction between parent and child components
|
||||
have remained unchanged since the very first Genode version. From this
|
||||
interplay, the entire architecture follows. That said, certain initial design
|
||||
choices were not perfect. They partially resulted from limitations of the
|
||||
kernels we used during Genode's early years and from our pre-occupation with a
|
||||
certain style of programming. Over the years, the drawbacks inherent in our
|
||||
original design became more and more clear and we drafted rough plans to
|
||||
overcome them. However, reworking the fundamental protocols of a system that
|
||||
already accommodates hundreds of component implementations cannot be taken
|
||||
lightly. Because of this discomfort, we repeatedly deferred the topic -
|
||||
until now. With the rapidly growing workloads carried by Genode, we
|
||||
deliberately decided to address long-standing deficiencies rather than adding
|
||||
the features we originally planned according to the
|
||||
[https://genode.org/about/road-map - road map].
|
||||
|
||||
Section [Asynchronous parent-child interactions] presents the reworking of
|
||||
Genode's component interplay at the lowest level. With this change in place,
|
||||
we feel much more comfortable to scale up our workloads in the upcoming
|
||||
releases.
|
||||
|
||||
Functionality-wise, the most prominent topic of the current release is the
|
||||
vastly improved NIC-routing component. Since we introduced the first version
|
||||
of the NIC router in the previous release, we took an iterative approach to
|
||||
shape the component according to its most prominent use cases. Section
|
||||
[Further improved virtual networking] summarizes the changes and the
|
||||
motivation behind them.
|
||||
|
||||
Even though we added support for seL4 in the previous release, the NOVA
|
||||
hypervisor is still our go-to kernel for x86-based hardware because of its
|
||||
feature set. For this reason, we continuously improve this kernel and the
|
||||
NOVA-specific components like VirtualBox. Section [NOVA hypervisor] covers
|
||||
the introduction of an asynchronous map operation to NOVA.
|
||||
|
||||
Further topics of the current release range from added smart-card support,
|
||||
over a new timeout API, to a VFS-based time-based password generator. With
|
||||
respect to the road map, we postponed most topics originally planned. In
|
||||
particular, we intended to enable the use of Genode on top of Xen by following
|
||||
the footsteps of the existing Muen support - using our custom
|
||||
base-hw kernel within a Xen DomU domain. However, before proceeding this
|
||||
route, we decided to modernize the kernel design, in particular with respect
|
||||
to bootstrapping and address-space management. Some parts of this line of work
|
||||
are already present in the current release, for example the unification of the
|
||||
boot-module handling as explained in Section
|
||||
[Unified handling of boot modules].
|
||||
|
||||
|
||||
Asynchronous parent-child interactions
|
||||
######################################
|
||||
|
||||
When Genode was born in 2006, the L4 microkernels of the time universally
|
||||
lacked an asynchronous inter-process-communication (IPC) mechanism.
|
||||
Consequently, we designed the first version of Genode with the presumption
|
||||
that components had to interact solely synchronously. To us, this seemed to be
|
||||
the "right" way because the synchronous low-footprint IPC was presumably the
|
||||
key for L4's good performance. It felt natural to leverage this benefit to the
|
||||
maximum extent possible.
|
||||
|
||||
To illustrate the implications of this line of thinking for Genode, let's take
|
||||
a look at a simple scenario where a parent component hosts two children and one
|
||||
child provides a service to the other child.
|
||||
|
||||
[image simple_scenario]
|
||||
|
||||
During the creation of a session, the kernel's IPC mechanism serves three
|
||||
purposes. First, it is used to communicate information between different
|
||||
protection domains, in this case the parent, the client, and the server.
|
||||
Second, it implicitly dictates the flow of control between the involved
|
||||
parties because the caller blocks until the callee replies to the IPC call.
|
||||
Third, the IPC is the mechanism to delegate authority (like the authority to
|
||||
access the server's session object) between protection domains. The latter is
|
||||
realized with the kernel's ability to carry capabilities as IPC message
|
||||
payload. If this sounds a bit too abstract, please consider reviewing Section
|
||||
3.1. "Capability-based security" of the
|
||||
[https://genode.org/documentation/genode-foundations-16-05.pdf - Genode Foundations].
|
||||
Using solely a synchronous IPC mechanism, the sequence of establishing a
|
||||
session in the given scenario is as follows. In the context of Genode,
|
||||
we usually refer to synchronous IPC as RPC (remote procedure call).
|
||||
|
||||
[image sync_session_seq]
|
||||
|
||||
The sequence looks straightforward:
|
||||
|
||||
# The client issues an RPC call to its parent, requesting a session for a
|
||||
service of the given type while also passing a number of session-construction
|
||||
arguments along with the request.
|
||||
# Given the service name as provided with the session request, the parent
|
||||
determines the server to ask for a new session. It requests a session
|
||||
on behalf of the client by performing an RPC call to the server's prior
|
||||
registered "root" capability. This capability refers to an interface for
|
||||
creating and closing sessions.
|
||||
# The server responds to the invocation of its root interface by creating
|
||||
a new session object along with a session capability.
|
||||
Whereas the session object is local to the server, the corresponding
|
||||
session capability can be passed (delegated) to other components.
|
||||
Each component in possession of the session capability is able to interact
|
||||
with the server's corresponding session object via RPC calls.
|
||||
The server returns the session capability to the parent as the result of the
|
||||
parent's RPC call.
|
||||
# The parent forwards the session capability to the client as the result of
|
||||
the client's original RPC call.
|
||||
|
||||
Even though the simplicity of this protocol seems nice, it has inherent
|
||||
limitations:
|
||||
|
||||
First, as the parent performs a synchronous RPC call to the server on behalf
|
||||
of the client, it must trust the server to eventually respond to the RPC call.
|
||||
If the server doesn't, the parent may block forever. In contrast to the client
|
||||
that actually uses the service and thereby relies on the liveliness of the
|
||||
server, the parent should not need to trust the server to be responsive. To
|
||||
deal with the risk of an unresponsive server, Genode's existing runtime
|
||||
environments (like the init component), maintain a dedicated thread for each
|
||||
child. The session requests originating from a child are handled by the
|
||||
corresponding parent-local child thread. In the worst case - if the server
|
||||
fails to respond - only a single child thread stays blocked but the other
|
||||
parts of the runtime environment remain unaffected. Consequently, runtime
|
||||
environments have to be multi-threaded components. This, in turn, comes at the
|
||||
cost of added complexity, in particular the need for error-prone inter-thread
|
||||
synchronization.
|
||||
|
||||
Second, the approach keeps the parent's state implicitly stored in the stacks
|
||||
of the parent's threads. This becomes a problem in dynamic runtime
|
||||
environments that need to kill subsystems at arbitrary times. E.g., imagine
|
||||
the situation where the client component is to be destroyed while the parent's
|
||||
call to the server's root interface is still pending. The safe destruction of
|
||||
the child - including its associated parent-local child thread - requires the
|
||||
parent to abort the RPC call, which is a complex and - again - error-prone
|
||||
operation.
|
||||
|
||||
Third, even though not inherent to synchronous RPC, Genode's original design
|
||||
facilitated the use of a session capability as argument for requesting the
|
||||
parent to close a specific session. However, the use of capabilities as
|
||||
re-identifiable tokens is not well supported by most kernels, including seL4
|
||||
([http://sel4.systems/pipermail/devel/2014-November/000114.html - discussion]
|
||||
on the seL4 mailing list).
|
||||
|
||||
|
||||
Asynchronous communication throughout Genode
|
||||
--------------------------------------------
|
||||
|
||||
In 2008, we acknowledged the sole reliance on synchronous RPC as too limiting
|
||||
and introduced an
|
||||
[https://genode.org/documentation/release-notes/8.11#Asynchronous_notifications - API for asynchronous notifications].
|
||||
On the traditional L4 kernels, we implemented the API by using Genode's
|
||||
core component as a proxy for signal delivery. The use of asynchronous
|
||||
notifications soon became natural and wide-spread throughout Genode. Today,
|
||||
most session interfaces combine three forms of inter-component communication,
|
||||
namely synchronous RPC calls, asynchronous notifications, and shared memory.
|
||||
The new Genode API introduced in
|
||||
[https://genode.org/documentation/release-notes/16.05#The_great_API_renovation - version 16.05]
|
||||
further cultivated the modeling of Genode components as single-threaded state
|
||||
machines instead of multi-threaded programs.
|
||||
|
||||
Still, until now, the most fundamental mechanism of Genode - the protocol
|
||||
between parent and child components - has remained synchronous. The reasons
|
||||
are twofold. First, our workaround for realizing runtime environments in a
|
||||
multi-threaded way worked too well. So we were not constantly bothered by this
|
||||
design problem. Second and more importantly, redesigning the fundamental
|
||||
mechanism of the framework while not breaking the more than 300 existing
|
||||
components is quite scary. But in anticipation of the rapidly scaling
|
||||
workloads imposed on Genode, we had to take on the problem sooner or later.
|
||||
We figured that now - with the modernized framework API in place - it's the
|
||||
right time. From redesigning the interplay of parent and child components, we
|
||||
will become able to create single-threaded runtime environments that behave
|
||||
completely deterministically while consuming less resources than
|
||||
multi-threaded programs. By the explicit enumeration of possible states, we
|
||||
greatly ease the validation/evaluation of such crucial components.
|
||||
|
||||
|
||||
New session-creation procedure
|
||||
------------------------------
|
||||
|
||||
Following the asynchronous approach, the sequence of creating a session now
|
||||
looks as follows:
|
||||
|
||||
[image async_session_seq]
|
||||
|
||||
The dotted lines are asynchronous notifications, which have fire-and-forget
|
||||
semantics. A component that triggers a signal does not block.
|
||||
|
||||
The following points are worth noting:
|
||||
|
||||
* Sessions are identified via IDs, which are plain numbers as opposed to
|
||||
capabilities. The IDs as seen by the client and server belong to different
|
||||
ID name spaces.
|
||||
IDs of sessions requested by the client are allocated by the client. IDs
|
||||
of sessions requested at the server are allocated by the parent.
|
||||
* The parent does no longer need to perform RPC calls to any of its children.
|
||||
Hence, the need for multiple threads in runtime environments disappears.
|
||||
* Each activation of the parent merely applies a state change of the session's
|
||||
meta data structures maintained at the parent, which capture the entire
|
||||
state of session requests. There is no hidden state stored on the parent's
|
||||
stack.
|
||||
* The information about pending session requests is communicated from the
|
||||
parent to the server via a ROM session. At startup, the server requests
|
||||
a ROM session for the ROM module "session_requests" from its parent. The
|
||||
parent implements this ROM session locally. Since ROM sessions support
|
||||
versions, the parent can post version updates of the "session_requests"
|
||||
ROM with the regular mechanisms already present in Genode.
|
||||
* The involved parties can potentially run in parallel.
|
||||
|
||||
|
||||
Outcome and current state
|
||||
-------------------------
|
||||
|
||||
Intuitively, the sequence of steps required to establish a session has
|
||||
become more complicated. However, for the users of the framework, the entire
|
||||
procedure is completely transparent. With a few tricks, we were actually able
|
||||
to implement this fundamental change while keeping almost all existing
|
||||
components untouched. One trick is the introduction of a server-local proxy
|
||||
mechanism, which translates the requests obtained from the "session_requests"
|
||||
ROM to component-local RPC calls on the server's root interface. So from the
|
||||
perspective of an existing server component, a session request still looks
|
||||
like a synchronous RPC request from the outside. Of course, the proxy is meant
|
||||
as an intermediate solution until we have crafted a convenient front-end API
|
||||
for the asynchronous mode of operation.
|
||||
|
||||
Even though the biggest share of components remains unaffected by the change,
|
||||
this is not true for all components. In particular, runtime environments had
|
||||
to be reworked, in some cases quite fundamentally. These include core, init,
|
||||
noux, the loader, GDB monitor, launcher, CLI monitor, and the platform driver.
|
||||
The change does not only affect the interplay between components but also
|
||||
required a reconsideration of the child-creation procedure.
|
||||
|
||||
Besides the architectural improvement, this line of work had two welcome
|
||||
effects.
|
||||
|
||||
First, in contrast to the original design, which relied on capabilities as
|
||||
re-identifiable tokens, the new version greatly alleviates the need for
|
||||
re-identifying capabilities on seL4. So we are able to eliminate a
|
||||
long-standing problem with Genode on this kernel.
|
||||
|
||||
Second, the work called for new data structures for the safe interaction with
|
||||
ID spaces (_base/id_space.h_) and object registries (_base/registry.h_). Those
|
||||
data structures will possibly be useful in a lot of places that currently use
|
||||
plain (and fairly unsafe) AVL trees or lists.
|
||||
|
||||
At the API level, the change is almost transparent to regular components,
|
||||
except for two details. The upgrading of session quota is no longer
|
||||
possible by a mere RPC call to the parent. Instead, 'Connection' objects
|
||||
received a new 'upgrade_ram' method that must be used instead. Speaking
|
||||
of 'Connection' objects, we had to remove the (fairly obscure) 'KEEP_OPEN'
|
||||
feature, which is conceptually incompatible with the new design.
|
||||
|
||||
|
||||
Further improved virtual networking
|
||||
###################################
|
||||
|
||||
The
|
||||
[https://genode.org/documentation/release-notes/16.08#Virtual_networking_and_support_for_TOR - previous release]
|
||||
introduced the NIC router - a component that individually routes IP
|
||||
packets between multiple NIC sessions, translates between different IP
|
||||
subnets, and also supports port forwarding and NAT. For the first version of
|
||||
the NIC router, we focused on the technical realization. Now, besides
|
||||
some optimization and restructuring, we took the chance to polish the
|
||||
configuration interface of the component. The goal was to make the interface
|
||||
more intuitive and reduce pitfalls to a minimum. Roughly speaking, the
|
||||
handling of the NIC router became more tailored to its/our typical use cases.
|
||||
|
||||
Let's create a practical setup to explain the changes in detail. Assume that
|
||||
there are two virtual subnets 192.168.1.0/24 and 192.168.2.0/24 within our
|
||||
Genode system. They connect as Virtnet A and B to the router. The standard
|
||||
gateway of the virtual networks is the NIC router with IP 192.168.*.1 . The
|
||||
router's uplink, on the other hand, is connected to the NIC driver. It
|
||||
interfaces the machine with our real-world home network 10.0.2.0/24. The home
|
||||
network is connected to the internet through its standard gateway 10.0.2.1.
|
||||
|
||||
[image nic_router_basic]
|
||||
|
||||
The basic router configuration for this setup without any routing rules would
|
||||
be as follows:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" />
|
||||
|
||||
The first thing to notice is the changed usage of the policy tag. Previously,
|
||||
the policy label - normally solely designated to correlate sessions with
|
||||
configuration domains - was misused also as unique peer identifier in the
|
||||
routing rules. This approach disregarded advanced label-matching techniques
|
||||
such as the 'label_prefix' used above. Now, the whole NIC-router-specific
|
||||
enhancement of the policy tag moved to the new '<domain>' tag, leaving the
|
||||
policy tag only with its original purpose to select policies. Note that even
|
||||
if this modification gives the impression, the router is not yet capable of
|
||||
handling multiple NIC sessions at one domain at a time.
|
||||
|
||||
In the domain tag, the 'interface' attribute replaces the old policy attribute
|
||||
named 'src'. That means, it tells the router which IP identity to use when
|
||||
talking as itself to the domain. But in addition to that, the 'interface'
|
||||
attribute also defines which subnet this identity and the domain belong to.
|
||||
This reflects a basic decision we made during the reworking process: The new
|
||||
NIC router is aware of subnets. Sessions of the same subnet have the same
|
||||
configuration domain. We came to this conclusion as it solves some fundamental
|
||||
problems with the old version. First, the equivalence of domain and subnet
|
||||
enables us to link a default gateway to a subnet by adding the 'gateway'
|
||||
attribute to the domain tag. In our example, this is done in the uplink
|
||||
domain. The 'gateway' attribute is optional for a domain and replaces the
|
||||
former 'via' attributes of the different routing rules. It is more efficient
|
||||
and natural to have this value set only once at the corresponding subnet than
|
||||
having it scattered all over the routing rules of the remote domains as done
|
||||
before. If a domain has no default gateway, it drops all packets with a
|
||||
foreign recipient.
|
||||
|
||||
The second advantage of a domain being equivalent to a subnet is that handling
|
||||
ARP broadcasts becomes easy. It can be excluded that such ARP broadcasts
|
||||
concern sessions outside the source domain anymore. And as sessions in the
|
||||
same domain are not distinguishable to the routing, the broadcast can be sent
|
||||
to all of them without breaking any rules.
|
||||
|
||||
Now, let's enhance our example by some routing rules. One pretty complicated
|
||||
thing to do with the old NIC router was port forwarding. You had to combine
|
||||
different routing rules, explicitly enable the back routing at the remote
|
||||
side, and take care that NAT was applied - a lot of opportunities for
|
||||
mistakes. With the new version, it became easier. Let's assume we have an HTTP
|
||||
server in Virtnet A and an NTP server in Virtnet B. We want the NIC router to
|
||||
act as proxy for their services in our home network.
|
||||
|
||||
[image nic_router_servers]
|
||||
|
||||
In order to achieve this, the uplink domain must be enhanced by two rules:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <tcp-forward port="443" domain="virtnet_a" to="192.168.1.2" />
|
||||
! <udp-forward port="123" domain="virtnet_b" to="192.168.2.2" />
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" />
|
||||
|
||||
The TCP forwarding rule for port 443 (HTTP+TLS/SSL) redirects to IP address
|
||||
192.168.1.2 in Virtnet A and the UDP forwarding rule for port 123 (NTP)
|
||||
redirects to IP address 192.168.2.2 in Virtnet B. The Virtnet domains remain
|
||||
empty as the router keeps track of the redirected transfers and routes back
|
||||
reply packets automatically. Also automatically, the router applies NAT for the
|
||||
server as it is in the nature of port forwarding.
|
||||
|
||||
Next, we add some clients to Virtnet B that like to talk to our home network
|
||||
and the internet. We want them to be hidden via NAT when they do so. For
|
||||
internet communication, they shall furthermore be limited to HTTP+TLS/SSL and
|
||||
IMAP+TLS/SSL.
|
||||
|
||||
[image nic_router_client]
|
||||
|
||||
This is what the router configuration looks now:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <tcp-forward port="443" domain="virtnet_a" to="192.168.1.2" />
|
||||
! <udp-forward port="123" domain="virtnet_b" to="192.168.2.2" />
|
||||
! <nat domain="virtnet_b" tcp-ports="1000" udp-ports="1000">
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" >
|
||||
! <tcp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </tcp>
|
||||
! <udp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </udp>
|
||||
! <tcp dst="0.0.0.0/0">
|
||||
! <permit port="443" domain="uplink" />
|
||||
! <permit port="993" domain="uplink" />
|
||||
! </tcp>
|
||||
! </domain>
|
||||
|
||||
There are several new tag types. One of them is the NAT configuration for
|
||||
Virtnet B in the uplink domain. In contrast to the former NIC-router version
|
||||
where NAT settings were part of the source domain, NAT is now configured in
|
||||
the target domain with a sub-tag for each source. This has the advantage
|
||||
of supporting heterogeneous NAT configurations for a packet source depending
|
||||
on which domain it talks to. Besides, it is more intuitive to read. Apart from
|
||||
that, the NAT settings haven't changed.
|
||||
|
||||
Furthermore, there are the new TCP and UDP tags in the Virtnet-B domain. The
|
||||
first two of them have a 'permit-any' sub-tag. With this combination, we open
|
||||
all ports to IP addresses of the 10.0.2.0/24 subnet, our home network, and
|
||||
route them to the uplink domain. TCP packets that don't match these first two
|
||||
rules may fall back to the third. This TCP rule doesn't have all ports opened
|
||||
but only 443 (HTTP+TLS/SSL) and 993 (IMAP+TLS/SSL). Both ports are again bound
|
||||
to the uplink domain. As the IP filter 0.0.0.0/0 of the surrounding rule isn't
|
||||
restrictive, we now also route packets to a foreign destination. The NIC
|
||||
router redirects such packets to the default gateway of our home network.
|
||||
|
||||
Compared to the old router version where IP and UDP/TCP routing had to be
|
||||
combined for this purpose, the new TCP and UDP rules with their
|
||||
port-permission sub-rules have some notable advantages. Like port-forwarding
|
||||
rules, TCP and UDP rules always imply link-state tracking in order to route
|
||||
back reply packets automatically. This can be seen also in our example as no
|
||||
further routing rules had to be added to the uplink domain. This aspect is
|
||||
clear from the outermost rule and not dependent on sub-rules anymore.
|
||||
Furthermore, the strict separation of UDP and TCP routing prevents
|
||||
configuration faults and increases readability. Last but not least, the
|
||||
'permit-any' rule allows something new. Opening all ports for an address range
|
||||
was previously only possible without link-state tracking as it could be
|
||||
expressed only on the IP level.
|
||||
|
||||
At this point, we have thoroughly discussed the layer-3 routing abilities of
|
||||
the new NIC router and our focus has indeed moved more into this direction.
|
||||
Even though IP routing is still available, we found that it should be more
|
||||
clearly separated from the rest. To illustrate this feature, we enhance our
|
||||
example again. We want the Virtnets to be allowed to communicate to each other
|
||||
without any restrictions. For that purpose, we add two more rules to the
|
||||
router configuration:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <tcp-forward port="443" domain="virtnet_a" to="192.168.1.2" />
|
||||
! <udp-forward port="123" domain="virtnet_b" to="192.168.2.2" />
|
||||
! <nat domain="virtnet_b" tcp-ports="1000" udp-ports="1000">
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <ip dst="192.168.2.0/24" domain="virtnet_b"/>
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" >
|
||||
! <tcp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </tcp>
|
||||
! <udp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </udp>
|
||||
! <tcp dst="0.0.0.0/0">
|
||||
! <permit port="443" domain="uplink" />
|
||||
! <permit port="993" domain="uplink" />
|
||||
! </tcp>
|
||||
! <ip dst="192.168.1.0/24" domain="virtnet_a"/>
|
||||
! </domain>
|
||||
|
||||
As you can see, each of the new IP rules in the Virtnet domains match the
|
||||
addresses of the opposite subnet and route to the corresponding domain. As
|
||||
mentioned, the new IP rules and UDP/TCP rules are not combined anymore to
|
||||
clearly distinguish IP routing from layer-3 routing because this decision has
|
||||
far-reaching effects. First, in contrast to UDP and TCP routing, IP routing is
|
||||
stateless. Thus, for each IP routing rule one has to be sure to have a
|
||||
back-routing rule at the remote domain or else bidirectional communication
|
||||
won't happen. And second, NAT does not apply to IP-routed packets. So, if
|
||||
you're not aware of such packets, you may unintentionally reveal information
|
||||
about a private network.
|
||||
|
||||
For more details on the new NIC router, you may refer to the comprehensive
|
||||
documentation in the _repos/os/src/server/nic_router/README_ file and the
|
||||
basic NIC-router test at _libports/run/nic_router.run_ .
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Improved RPC mechanism
|
||||
======================
|
||||
|
||||
Since we introduced Genode's current API for synchronous RPCs in
|
||||
[https://genode.org/documentation/release-notes/11.05#New_API_for_type-safe_inter-process_communication - version 11.05],
|
||||
inter-component communication within Genode has become almost a child's play.
|
||||
The RPC framework leverages the C++ type system and templates to a great
|
||||
effect. In contrast to the traditional use of IDL compilers, the interaction
|
||||
with RPC objects provided by other components is robust and natural because
|
||||
no language boundaries need to be crossed.
|
||||
|
||||
Still, a few differences between RPC calls and regular function calls remain.
|
||||
In particular, there exist a few restrictions with regard to the types of
|
||||
RPC function arguments. Those types did not just need to be POD (plain old
|
||||
data) types but they had to be default-constructible, too. Whereas the former
|
||||
restriction still applies (non-POD objects that include references or
|
||||
vtables cannot be used as arguments), the latter limitation has been lifted
|
||||
now. Generally, non-default-constructible types are a way to attain
|
||||
simpler code because the special case of an "invalid" object does not need
|
||||
to be considered. I.e., values of such types can be kept as constants as
|
||||
opposed to variables. If an object exists (as equivalent to successful
|
||||
instantiation), it is valid. With the improved RPC mechanism, the RPC
|
||||
framework does no longer stay in the way in this respect.
|
||||
|
||||
Thanks to Edgard Schmidt for this welcome contribution!
|
||||
|
||||
|
||||
Unification and tightening of session labels
|
||||
============================================
|
||||
|
||||
In Genode, each session requested by a client component is labeled according
|
||||
to the components that intermediate the session request. The client can
|
||||
optionally specify a label of choice along with the session request. Its
|
||||
parent prefixes the client-provided label by a label of its own. If the
|
||||
session request is further passed to the parent's parent, the grandparent
|
||||
prepends its own label. This works recursively. Consequently, the final label
|
||||
as seen by the server is the product of the labeling policies of all
|
||||
components on the route of the session request.
|
||||
|
||||
The label is used for two purposes. First, the server uses the label as
|
||||
a key for a server-side policy selection. E.g., depending on the session label
|
||||
received by the disk-partition server, the server decides which partition to
|
||||
hand out to the client. Second, the label is used by intermediate components
|
||||
to take session-routing decisions. E.g., based on the label of a file-system
|
||||
session request, a parent component may route the request to one of several
|
||||
file-system servers.
|
||||
|
||||
Originally, Genode did not impose a specific way of how labels are formed.
|
||||
It was up to each intermediate component to filter the label of a session
|
||||
request in any way desired. However, in practice, this freedom remained unused
|
||||
and the very simple successive prefixing of labels prevails in all our use
|
||||
cases. Each intermediate node concatenates its own label in front of the label
|
||||
supplied by the originator of the session request. The different parts of the
|
||||
label are separated with the character sequence '" -> "'. Some corner cases
|
||||
were handles specially for aesthetic reasons. For example, if a client
|
||||
provided no label, the parent would skip the pending separator. That said,
|
||||
since each intermediate component had to provide the labeling policy, not all
|
||||
components were consistent in these respects. Since we found no use for
|
||||
arbitrary labeling policies, we decided to make the only prominent way of
|
||||
session labeling mandatory for all intermediate components. We thereby removed
|
||||
the aesthetically motivated corner cases and possible ambiguities. I.e., with
|
||||
the original policy, it was not possible to distinguish a unlabeled session
|
||||
requested by a client from a labeled session requested by the client's parent.
|
||||
|
||||
As a consequence, the stricter labeling must now be considered wherever
|
||||
a precise label was specified as a key for a session route or a server-side
|
||||
policy selection. The simplest way to adapt those cases is to use a
|
||||
'label_prefix' instead of the 'label' attribute. Alternatively, the
|
||||
'label' attribute may used by appending '" -> "' (note the whitespace).
|
||||
|
||||
|
||||
Transition to new framework API
|
||||
===============================
|
||||
|
||||
Since we fundamentally revised Genode's API in
|
||||
[http://genode.org/documentation/release-notes/16.05#The_great_API_renovation - version 16.05],
|
||||
we gradually adapt our existing components. Given that Genode comes with
|
||||
over 300 components, this is no small feat. But with 30 percent of the
|
||||
components converted, we already made substantial progress.
|
||||
|
||||
In some respects, the conversion is actually nearly complete. In particular,
|
||||
the move away from format-string-based text output to our new type-safe output
|
||||
facility has been applied to almost all components now. The former 'PDBG'
|
||||
macro that is quite useful for temporary debug messages has been replaced with
|
||||
a new version that must be manually included via the _base/debug.h_ header
|
||||
file. Like the regular log functions, the new PDBG facility uses the type-safe
|
||||
text-output facility.
|
||||
|
||||
|
||||
Minor API adjustments
|
||||
---------------------
|
||||
|
||||
While applying Genode's new API, we refined the API in the following respects:
|
||||
|
||||
We added a dedicated 'String' constructor overload to better accommodate
|
||||
string literals. This overload covers the common case for initializing a
|
||||
string from a literal without employing the 'Output' mechanism. This way, such
|
||||
strings can by constructed without calling virtual functions, which in turn
|
||||
makes the 'String' usable during the self-relocation phase of the dynamic
|
||||
linker.
|
||||
|
||||
Up till now, several Genode components still rely on the use of 'snprintf'
|
||||
whenever strings must be assembled out of smaller pieces. As we like to shun
|
||||
format strings from Genode altogether, we needed an alternative mechanism.
|
||||
Since we introduced the new type-safe text-output facilities in Genode 16.05,
|
||||
there is an obvious solution: Let the 'String' constructor accept an arbitrary
|
||||
list of arguments, which are turned into their respective textual
|
||||
representation and appear concatenated in the resulting string. Consequently,
|
||||
strings can be assembled with the same flexibility as log output. For the
|
||||
construction of 'String' objects from character buffers of a known size, the
|
||||
'Cstring' utility can be used, which takes a 'char const *' and an optional
|
||||
length as arguments.
|
||||
|
||||
Several low-level types received support for the new output facilities, e.g.,
|
||||
'Xml_node' or the network-related headers in _os/net/_.
|
||||
|
||||
In anticipation of the forthcoming package-management infrastructure, we try
|
||||
to unify Genode's executable binaries across kernels and architectures
|
||||
wherever reasonable. Of course, the latter is not possible with respect to the
|
||||
used instructions. But unifying symbol information is deemed worthwhile. For
|
||||
this reason, we changed the 'Genode::size_t' type to be always defined as an
|
||||
'unsigned' 'long'. This is in contrast to GCC's built-in '__SIZE_TYPE__',
|
||||
which is defined as 'unsigned int' on 32-bit architectures but 'unsigned long'
|
||||
on 64-bit architectures.
|
||||
|
||||
|
||||
OS-level infrastructure and device drivers
|
||||
##########################################
|
||||
|
||||
New timeout-handing API
|
||||
=======================
|
||||
|
||||
The new timeout API offers tools for easily multiplexing a single time
|
||||
source among different timeouts. In general, the time source can be
|
||||
implemented individually but we expect that the most prominent use case will
|
||||
be the multiplexing of timer sessions. Thus, the timeout library also provides
|
||||
a convenience tool for this use case. A library-usage example can be found
|
||||
under _os/src/test/timeout_. If you're interested in implementing
|
||||
your own time source, you can find an example at _os/include/os/timer.h_ .
|
||||
|
||||
|
||||
Support for smart cards
|
||||
=======================
|
||||
|
||||
We ported the [http://pcsclite.alioth.debian.org/pcsclite.html - PC/SC Lite]
|
||||
library to Genode, which provides a commonly used API for communicating with
|
||||
smart cards. It supports USB smart card readers, using the
|
||||
[http://pcsclite.alioth.debian.org/ccid.html - CCID] library as driver.
|
||||
The CCID driver itself requires [http://libusb.info - libusb] to access the
|
||||
USB device.
|
||||
|
||||
Vanilla PC/SC Lite is structured as a client-server architecture, consisting
|
||||
of the 'pcscd' daemon, which runs on a privileged user account and manages all
|
||||
card reader devices, and one or more non-privileged client applications, which
|
||||
communicate with pcscd to access the card readers. On Genode, pcscd's role as
|
||||
privileged device manager is not really needed, since the devices can also be
|
||||
managed using Genode's configuration mechanisms. For this reason, we merged
|
||||
the part of pcscd which implements the API with the pcsc-lite client library.
|
||||
|
||||
In the current state, a Genode application using PC/SC Lite can access a single
|
||||
card reader device, which is selected using its USB product ID and vendor ID in
|
||||
the application's configuration and in the policy of the USB driver.
|
||||
|
||||
More configuration details can be found in the README files of the PC/SC Lite,
|
||||
CCID, and libusb libraries in the libports repository and in the accompanying
|
||||
_smartcard.run_ script.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Time-based password generation
|
||||
==============================
|
||||
|
||||
A time-based one-time password authentication client that adheres to the
|
||||
Google Authenticator standard has been introduced into the
|
||||
[https://github.com/genodelabs/genode-world - world repository].
|
||||
|
||||
Single use, time-based passwords are commonly used as an additional
|
||||
authentication step for web-based services. In this scheme, a user generates
|
||||
and presents a six digit passcode to a service generated using a shared secret
|
||||
and a timestamp. This short passcode length makes manual entry convenient so
|
||||
that the shared secret may be stored on a separate device than the service
|
||||
client, such as a smartphone, layering the security properties of both
|
||||
devices.
|
||||
|
||||
The 'gtotp' VFS plugin provides these passcodes by embedding the generator as
|
||||
a special file in the file-system layer of a component. This approach provides
|
||||
readily available passcodes for programmatic and manual use without enlarging
|
||||
the code base to encompass a GUI, command-line, or networked interface.
|
||||
|
||||
At the time of this release, the common use case is to manually retrieve codes
|
||||
for clients running in VirtualBox by reading special files with an isolated
|
||||
instance of the Noux runtime. Storing the shared secret on the same device
|
||||
contradicts the recommendations of the standard but the trade-off is that the
|
||||
software stack required to host the shared secret is significantly smaller
|
||||
than that found on a mobile device.
|
||||
|
||||
|
||||
Random number generator testing
|
||||
===============================
|
||||
|
||||
No random number generator can be proved to be good, but empirical statistical
|
||||
tests can prove that some are bad. A port of the TestU01 RNG test suite is
|
||||
provided in the world repository. The TestU01 batteries give independent
|
||||
assurance of the fitness of Genode's CPU jitter based RNG and are available
|
||||
for testing future physical and non-phyical RNGs.
|
||||
|
||||
|
||||
VirtualBox on top on the NOVA hypervisor
|
||||
########################################
|
||||
|
||||
Both VirtualBox-based virtual machine monitors on Genode got updated to the
|
||||
latest revision as provided by Oracle, namely 4.3.40 and 5.1.10 - mainly to
|
||||
stay close to the upstream versions.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Unified handling of boot modules
|
||||
================================
|
||||
|
||||
Until now, the way of passing boot modules from the boot procedure to the core
|
||||
component, which core provides as ROM modules, varied from platform to
|
||||
platform. Either we used a multiboot-compliant bootloader that accepts
|
||||
multiple modules, or the platform provided some specific way of linking binary
|
||||
modules together with the kernel, e.g., the Elfweaver tool of OKL4.
|
||||
By unifying the boot-module handover, we further reduce platform specific core
|
||||
code. Thereby, maintenance costs are decreased, and code analysis becomes
|
||||
easier. With this new solution, when issuing to build the core component:
|
||||
|
||||
! make core
|
||||
|
||||
within the build system, only a core library gets built. Not until all
|
||||
binaries needed by a run-script are available, a final image is linked
|
||||
together using the core library and all additional binaries. The core
|
||||
component now can access its ROM modules directly via addresses contained in
|
||||
its binary. As a side effect of this change, there is no core binary in the
|
||||
'bin' or 'core' directory of the corresponding build directory available
|
||||
anymore. Instead, you will find the core binary with no ROM modules, but
|
||||
including debug information under 'var/run/*.core' within your build
|
||||
directory. The concrete name depends on the name of the run-script.
|
||||
|
||||
The new approach is used on all platforms except Linux where the ROM modules
|
||||
still need to be accessed via the file-system.
|
||||
|
||||
|
||||
NOVA hypervisor
|
||||
===============
|
||||
|
||||
We extended the kernel to support the asynchronous delegation of kernel
|
||||
resources. Up to now, resources could only be delegated during RPC or during
|
||||
the initial protection-domain construction. With this extension, the
|
||||
construction and setup of new protection domains, threads, and especially
|
||||
virtual CPUs for the VirtualBox VMM became more straightforward and several
|
||||
quirks inside the 'core' component could be dropped. The added kernel syscall
|
||||
expects the NOVA-kernel capabilities of the source and target protection
|
||||
domains, which effectively renders the operation solely available to 'core' -
|
||||
as only holder of the NOVA protection domain capabilities.
|
||||
|
||||
Additionally, we changed the CPU ID enumeration in Genode/NOVA to a
|
||||
predictable order. The lower CPU IDs used via the Genode 'Cpu_session'
|
||||
interface now correspond to the first hyper-thread of all physical CPU cores.
|
||||
For example, on a quad-core machine with hyper-threading enabled Genode's CPU
|
||||
IDs 0-3 refer to the first hyper-threads of all physical cores and IDs 4-7 to
|
||||
the second hyper-threads.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,651 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 17.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The flagship feature of Genode 17.08 has been in the works for more than a
|
||||
year: The support for hardware-accelerated graphics on Intel Gen-8 GPUs. This
|
||||
is an especially challenging topic because it is riddled with terminology,
|
||||
involves highly complex software stacks, carries a twisted history with it,
|
||||
and remains to be a moving target. It took up a lot of patience to build up a
|
||||
profound understanding of the existing driver architectures and the mechanisms
|
||||
offered by modern graphics hardware. On the other hand, with the proliferation
|
||||
of hardware-based sandboxing features like virtual GPU memory and hardware
|
||||
contexts, we found that now is the perfect time for a clean-slate design of a
|
||||
microkernelized GPU driver.
|
||||
Section [Hardware-accelerated graphics for Intel Gen-8 GPUs] introduces this
|
||||
work, which includes our new GPU multiplexer as well as the integration with
|
||||
the client-side Mesa protocol stack.
|
||||
|
||||
The second focus of the current release is the extension of Genode's supported
|
||||
base platforms. Most prominently, we upgrade the seL4 kernel to version 6.0
|
||||
while extending the architecture support from 32-bit x86 to ARM and 64-bit
|
||||
x86 (Section [The seL4 kernel on ARM and 64-bit x86 hardware]). To bring
|
||||
Genode closer to cloud-computing scenarios, we added basic support for
|
||||
executing Genode scenarios as Xen DomU domains (Section [Genode as Xen DomU]).
|
||||
Furthermore, the Muen separation kernel has been updated to a current version.
|
||||
As a cross-kernel effort, there is work under way to boot Genode-based
|
||||
systems via UEFI, currently addressing the NOVA, base-hw, and seL4 kernels.
|
||||
|
||||
Among the many other functional additions are a new VFS plugin for accessing
|
||||
FAT file systems, new components like _sequence_ and _fs_report_ that aid new
|
||||
system compositions, and our evolving custom package-management
|
||||
infrastructure.
|
||||
|
||||
|
||||
Hardware-accelerated graphics for Intel Gen-8 GPUs
|
||||
##################################################
|
||||
|
||||
The ability to leverage hardware-accelerated graphics is generally taken for
|
||||
granted in modern commodity operating systems. The user experience of
|
||||
modern desktop environments, web-browser performance, and obviously games
|
||||
depend on it. On the other hand, the benefit of hardware-accelerated graphics
|
||||
comes at the expense of tremendous added complexity in the lower software
|
||||
stack, in particular in system components that need to be ultimately trusted.
|
||||
For example, with circa 100 thousand lines of code, the Intel GPU driver in
|
||||
the Linux kernel is an order of magnitude more complex than a complete modern
|
||||
microkernel. In a monolithic-kernel-based system, this complexity is
|
||||
generally neglected because the kernel is complex anyway. But in
|
||||
microkernel-based scenarios optimized for a trusted computing base in the
|
||||
order of a few ten thousand lines of code, it becomes unacceptable.
|
||||
Fortunately, recent generations of graphics hardware provide a number of
|
||||
hardware features that promise to solve this conflict, which prompted us to
|
||||
investigate the use of these features for Genode.
|
||||
|
||||
During this year's Hack'n'Hike event, we ported the ioquake3 engine to Genode.
|
||||
As preliminary requirement, we had to resurrect OpenGL support in our aging
|
||||
graphics stack and enable support for current Intel HD Graphics devices (IGD).
|
||||
We started by updating Mesa from the old 7.8.x to a more recent 11.2.2 release.
|
||||
Since we focused mainly on supporting Intel devices, we dropped support for the
|
||||
Gallium back end as Intel still uses the old DRI infrastructure. This decision,
|
||||
however, also influenced the choice of the software rendering back end. Rather
|
||||
than retaining the softpipe implementation, we now use swrast. In addition, we
|
||||
changed the available OpenGL implementation from OpenGL ES 2.x to the fully
|
||||
fledged OpenGL 4.5 profile, including the corresponding shader language
|
||||
version. As with the previous Mesa port, EGL serves as front end API for
|
||||
system integration and loads a DRI back-end driver (i965 or swrast). EGL
|
||||
always requests the back-end driver 'egl_drv.lib.so' in form of a shared
|
||||
object. Genode's relabeling features are used to select the proper back end
|
||||
via a route configuration. The following snippet illustrates such a
|
||||
configuration for software rendering:
|
||||
|
||||
! <start name="gears" caps="200">
|
||||
! <resource name="RAM" quantum="32M"/>"
|
||||
! <route>
|
||||
! <service name="ROM" label="egl_drv.lib.so">
|
||||
! <parent label="egl_swrast.lib.so"/>
|
||||
! </service>
|
||||
! <any-service> <parent/> <any-child/> </any-service>
|
||||
! </route>
|
||||
! </start>
|
||||
|
||||
With the graphics-stack front end in place, it was time to take care of the
|
||||
GPU driver. In our case this meant implementing the DRM interface in our
|
||||
ported version of the Intel i915 DRM driver. Up to now, this driver was solely
|
||||
used for mode setting while we completely omitted supporting the render
|
||||
engine.
|
||||
|
||||
[image mesa_genode]
|
||||
|
||||
With this new and adapted software stack, we successfully could play ioquake3
|
||||
on top of Genode with a reasonable performance in 1080p on a Thinkpad X250.
|
||||
|
||||
During this work, we gathered valuable insights into the architecture of a
|
||||
modern 3D-graphics software stack as well as into recent Intel HD Graphics
|
||||
hardware. We found that the Intel-specific Mesa driver itself is far more
|
||||
complex than its kernel counter part. The DRM driver is mainly concerned with
|
||||
resource and execution management whereas the Mesa driver programs the GPU.
|
||||
For example, amongst others, Mesa compiles the OpenGL shaders into a
|
||||
GPU-specific machine code that is passed on to the kernel for execution.
|
||||
|
||||
While inspecting the DRM driver, it became obvious that one of the reasons for
|
||||
its complexity is the need to support a variety of different HD Graphics
|
||||
generations as well as different features driven by software-usage patterns.
|
||||
For our security related use cases, it is important to offer a clear isolation
|
||||
and separation mechanism per client. Hardware features provided by modern
|
||||
Intel GPUs like per-process graphics translation tables (PPGTT) and hardware
|
||||
contexts that are unique for each client make it possible to fulfill these
|
||||
requirements.
|
||||
|
||||
By focusing on this particular feature set and thus limiting the supported
|
||||
hardware generations, the development of a maintainable GPU multiplexer for
|
||||
Genode became feasible. After all, we strive to keep all Genode components as
|
||||
low complex as possible, especially resource multiplexers like such a GPU
|
||||
multiplexer.
|
||||
|
||||
[image intel_gpu_drv]
|
||||
This image shows multiple GPU-session clients and the resources they are
|
||||
using. The fence registers as well as the aperture is partitioned between
|
||||
them, the PPGTT is backed by the system memory, and the contexts are located
|
||||
in disjoint GGTT regions.
|
||||
|
||||
Within four months, we implemented an experimental GPU multiplexer for Intel
|
||||
HD Graphics Gen8 (Broadwell class) devices. We started out defining a GPU
|
||||
session interface that is sufficient to implement the API used by the DRM
|
||||
library. For each session, the driver creates a context consisting of a
|
||||
hardware context, a set of page tables (PPGTT), and a part of the aperture.
|
||||
The client may use the session to allocate and map memory buffers used by the
|
||||
GPU. Each buffer is always eagerly mapped 1:1 into the PPGTT by using the
|
||||
local virtual address of the client. Special memory buffers like an image
|
||||
buffer are additionally mapped through the aperture to make use of the
|
||||
hardware-provided de-tiling mechanism. As is essential in Genode components,
|
||||
the client must donate all resources that the driver might need to fulfill the
|
||||
request, i.e., quota for memory and capability allocations. Clients may
|
||||
request the execution of their workload by submitting an execution buffer. The
|
||||
GPU multiplexer will then enqueue the request and schedule all pending
|
||||
requests sequentially. Once the request is completed, the client is notified
|
||||
via a completion signal.
|
||||
|
||||
[image multi_gl]
|
||||
Example scenario of multiple OpenGL programs that use the new GPU multiplexer
|
||||
for hardware-accelerated rendering.
|
||||
|
||||
We consider this first version of the GPU driver as experimental. As of now,
|
||||
it only manages the render engine of the GPU. Mode-setting or rather display
|
||||
handling must be performed by another component. Currently, the VESA driver is
|
||||
used for this purpose. It also lacks any power-management functionality and
|
||||
permanently keeps the GPU awake. Both limitations will be addressed in future
|
||||
releases and support for Gen9+ (Skylake) and newer devices might be added.
|
||||
|
||||
In its current incarnation, the GPU multiplexer component consists of about
|
||||
4,200 lines of code whereas the Mesa DRI i965 driver complements the driver at
|
||||
the client side with about 78,000 lines of code.
|
||||
|
||||
|
||||
The seL4 kernel on ARM and 64-bit x86 hardware
|
||||
##############################################
|
||||
|
||||
With the 16.08 release, we brought the seL4 support to a level to be
|
||||
considered being on par with the other supported kernels. At the time,
|
||||
Genode's use of seL4 was limited to 32-bit x86 platforms.
|
||||
|
||||
In the current release, we extend the platform support to ARM and 64-bit x86.
|
||||
We started this line of work with an incremental kernel upgrade from version
|
||||
3.2.0 to 5.2.0 and finally to seL4 6.0. Through these upgrades, we were able
|
||||
to drop several Genode-specific seL4 patches, which were required in the 16.08
|
||||
release. One major improvement of version 6.0 compared to earlier versions is
|
||||
the handling of device-memory announcements by the kernel to Genode's roottask
|
||||
_core_.
|
||||
|
||||
With the kernel update in place, we inspected the x86-specific part thoroughly
|
||||
while splitting and separating it properly into architecture-agnostic and
|
||||
architecture-dependent parts. Upon this work, we added the
|
||||
architecture-specific counterparts for x86_64 and ARM. One major work item was
|
||||
to make the page-table handling in Genode's core aware and generic enough to
|
||||
handle the different page-table sizes of the three architectures.
|
||||
|
||||
For the ARM support, we decided to enable the i.MX6 FreeScale based SoC,
|
||||
namely the Wandboard Quad board. Since the seL4 kernel interface provides no
|
||||
timeout support, we revived a user-level timer driver that we originally
|
||||
developed for our custom base-hw kernel: The so-called EPIT timer, which is
|
||||
part of most i.MX SoCs.
|
||||
|
||||
We finished the essential work for the mentioned three platforms in
|
||||
less time than expected and, thereby, had spare time to address additional
|
||||
features.
|
||||
|
||||
First, we enabled multiprocessor support for Genode/seL4 on x86 and
|
||||
thread-priority support for all seL4 platforms. Additionally, we were able to
|
||||
utilize the seL4 benchmark interface for Genode's trace infrastructure in
|
||||
order to obtain utilization information about threads and CPUs. The Genode
|
||||
components _top_ (text-based) and _cpu_load_monitor_ (graphical) are now
|
||||
usable on Genode/seL4.
|
||||
Finally, as we are currently exploring the support for booting various kernels
|
||||
via UEFI on x86, we took the chance to investigate the steps needed to boot
|
||||
seL4 via UEFI. UEFI firmware does not always provide a compatibility support
|
||||
module (CSM) for legacy BIOS boot support. Hence, we extended the seL4 kernel
|
||||
for Genode according to the Multiboot2 specification, which enables us to
|
||||
start Genode/seL4 together with GRUB2 - as an UEFI capable bootloader - on
|
||||
machines missing CSM support.
|
||||
|
||||
|
||||
Base framework and OS-level infrastructure
|
||||
##########################################
|
||||
|
||||
Simplified IOMMU handling
|
||||
=========================
|
||||
|
||||
When IOMMUs are used on x86, all host memory targeted via direct memory
|
||||
accesses (DMA) by devices must eagerly be registered in the respective I/O
|
||||
page table of the device. Up to now, Genode supports IOMMUs on NOVA only. On
|
||||
this kernel, a device protection domain is represented as a regular protection
|
||||
domain with its virtual memory layout being used for both the CPU's MMU and
|
||||
the device. Traditionally, mappings into such virtual memory spaces are
|
||||
inserted on demand as responses to page faults. However, as there are no page
|
||||
faults for DMA transactions, DMA buffers must always be eagerly mapped. The
|
||||
so-called device PD hid this gap for NOVA. In anticipation of adding IOMMU
|
||||
support for more kernels, we desired to generalize the device-PD mechanism by
|
||||
introducing an explicit way to trigger the insertion of DMA memory into the
|
||||
proper page tables.
|
||||
|
||||
We extended the PD-session interface by a 'map' function, which takes a
|
||||
virtual memory region of the PD's virtual address space as argument. The page
|
||||
frames of the previously attached dataspaces are added eagerly by core to the
|
||||
IOMMU page-tables. With this explicit 'map' support, we were able to replace
|
||||
the Genode/NOVA-specific device-PD implementation with a generic one, which
|
||||
will easily accommodate other kernels in the future.
|
||||
|
||||
|
||||
New report server for capturing reports to files
|
||||
================================================
|
||||
|
||||
The report session is a simple mechanism for components to publish structured
|
||||
data without the complexity of a file-system layer. In the simplest case, a
|
||||
client component will produce a report and communicate it directly to a
|
||||
component acting as a server. The disadvantage is that the report client
|
||||
becomes reliant on the liveliness and presence of the consumer component. So
|
||||
in the more robust case, the _report_rom_ component acts as the server hosting
|
||||
the report service as well as a ROM service for components consuming reports.
|
||||
|
||||
The _report_rom_ server permits ROM access only to clients matching an
|
||||
explicit configuration policy. This is good for security but opaque to a user.
|
||||
Reports can only be read where an explicit policy is in place and only a
|
||||
single report session can report to an active ROM session.
|
||||
|
||||
The new _fs_report_ component is a friendlier and more flexible report server.
|
||||
Reports are written to a file system using a file and directory hierarchy that
|
||||
expresses session routing. This allows for intuitive report inspection and
|
||||
injection via a file system. When used with the _ram_fs_ and _fs_rom_ servers,
|
||||
it can also replicate the functionality of _report_rom_.
|
||||
|
||||
|
||||
New runtime environment for starting components sequentially
|
||||
============================================================
|
||||
|
||||
The _init_ component is a prime example of software with an emphasis on
|
||||
function over features. It is the fundamental building block for combining
|
||||
components yet its behavior is simple and without heuristics. Like other
|
||||
contemporary init managers, it starts components in parallel, but to a more
|
||||
extreme degree in that it has no concept of "runlevels" or "targets", all
|
||||
components are started as soon as possible. The concrete sequence of execution
|
||||
is instead determined by when server components make service announcements and
|
||||
how quickly they respond to client requests.
|
||||
|
||||
In some cases, the execution of one component must not occur until the
|
||||
execution of another component ends, be it that the first produces output that
|
||||
is consumed by the second, or that the two contend for a service that cannot
|
||||
be multiplexed. Init contains no provisions to enforce ordering. But we are
|
||||
free to define new behaviors in other management components.
|
||||
|
||||
The solution to the problem of ordering is the _sequence_ component. Sequence
|
||||
walks a list of children and executes them in order, one at a time. With only
|
||||
one child active, there is no need for any local resource or routing
|
||||
management. By applying the same session label transformations as init,
|
||||
external routing and policy handling are unchanged.
|
||||
|
||||
An example of ordering a producer and consumer within an init configuration
|
||||
follows:
|
||||
! <start name="sequence">
|
||||
! <resource name="RAM" quantum="128M"/>
|
||||
! <config>
|
||||
! <start name="producer">
|
||||
! <config .. />
|
||||
! </start>
|
||||
! <start name="consumer">
|
||||
! <config .. />
|
||||
! </start>
|
||||
! </config>
|
||||
! <route>
|
||||
! <service name="LOG" label_prefix="producer">
|
||||
! <child name="log_a"/> </service>
|
||||
! <service name="LOG" label_prefix="consumer">
|
||||
! <child name="log_b"/> </service>
|
||||
! <any-service> <parent/> <any-child/> </any-service>
|
||||
! </route>
|
||||
! </start>
|
||||
|
||||
|
||||
Support for boot-time initialized frame buffer
|
||||
==============================================
|
||||
|
||||
UEFI-based systems do not carry along legacy BIOS infrastructure, on which
|
||||
our generic VESA driver depends. Hence, when booting via UEFI, one has to use
|
||||
either a hardware-specific driver like our Intel-FB driver or - alternatively -
|
||||
facilitate generic UEFI mechanisms.
|
||||
|
||||
Instead of booting in VGA text mode and leaving the switch to a graphics mode
|
||||
(via real-mode SVGA BIOS subroutines) to the booted OS, UEFI employs the
|
||||
so-called graphics output protocol as a means to setup a reasonable default
|
||||
graphics mode prior booting the operating system. In order to produce
|
||||
graphical output, the operating system merely has to know the physical address
|
||||
and layout of the frame buffer. Genode's core exposes this information as the
|
||||
_platform_info_ ROM module. The new _fb_boot_drv_ driver picks up this
|
||||
information to provide a Genode framebuffer session interface. Hence, on
|
||||
UEFI-based systems, it can be used as a drop-in replacement for the VESA
|
||||
driver. In contrast to the VESA driver, however, it is not able to switch
|
||||
graphics modes at runtime.
|
||||
|
||||
The new component is located at _os/src/drivers/framebuffer/boot/_. Thanks
|
||||
to Johannes Kliemann for this contribution.
|
||||
|
||||
|
||||
Extended non-blocking operation of the VFS
|
||||
==========================================
|
||||
|
||||
In
|
||||
[https://genode.org/documentation/release-notes/17.02#VFS_support_for_asynchronous_I_O_and_reconfiguration - version 17.02],
|
||||
we added support for non-blocking reads from the VFS in the form of the
|
||||
'read_ready()', 'queue_read()', and 'complete_read()' functions. Since then,
|
||||
it has become obvious that blocking within the VFS is not only problematic in
|
||||
the VFS server itself when multiple clients are connected, but also when the
|
||||
VFS is deployed in a multi-threaded environment and a VFS plugin needs to
|
||||
reliably wait for I/O-completion signals.
|
||||
|
||||
For this reason, we reworked the interface of the VFS even more towards
|
||||
non-blocking operation and adapted the existing users of the VFS accordingly.
|
||||
|
||||
The most important changes are:
|
||||
|
||||
* Directories are now created and opened with the 'opendir()' function and
|
||||
the directory entries are read with the 'queue_read()' and 'complete_read()'
|
||||
functions.
|
||||
|
||||
* Symbolic links are now created and opened with the 'openlink()' function and
|
||||
the link target is read with the 'queue_read()' and 'complete_read()'
|
||||
functions and written with the 'write()' function.
|
||||
|
||||
* The 'write()' function does not wait for signals anymore. This can have the
|
||||
effect that data written by a VFS library user has not been processed by a
|
||||
file-system server when the library user asks for the size of the file or
|
||||
closes it (both done with RPC functions at the file-system server). For this
|
||||
reason, a user of the VFS library should request synchronization before
|
||||
calling 'stat()' or 'close()'. To make sure that a file-system server has
|
||||
processed all write request packets that a client submitted prior the
|
||||
synchronization request, synchronization is now requested at the file-system
|
||||
server with a synchronization packet instead of an RPC function. Because of
|
||||
this change, the synchronization interface of the VFS library has been split
|
||||
into the 'queue_sync()' and 'complete_sync()' functions.
|
||||
|
||||
|
||||
Making block sessions read-only by default
|
||||
==========================================
|
||||
|
||||
Genode server components are expected to apply the safest and strictest
|
||||
behavior when exposing cross-component state or persistent data. In practice
|
||||
block and file-system servers only allow access to clients with explicitly
|
||||
configured local policies. The file-system servers enforce an additional
|
||||
provision that sessions are implicitly read-only unless overridden by policy.
|
||||
This release introduces a similar restriction to the AHCI driver and partition
|
||||
multiplexer. Clients of these servers require an affirmative 'writeable'
|
||||
attribute on policies to permit the writing of blocks. Write permission at
|
||||
these servers may also be revoked by components that forward block-session
|
||||
requests by placing 'writeable="no"' into session-request arguments.
|
||||
|
||||
All users of _ahci_drv_ and _part_blk_ are advised that this change may break
|
||||
existing configurations without explicit 'writeable' policies.
|
||||
|
||||
|
||||
Refined time handling
|
||||
=====================
|
||||
|
||||
Release 17.05 introduced a
|
||||
[https://genode.org/documentation/release-notes/17.05#New_API_for_user-level_timing - new API for user-level timing]
|
||||
named _timeout framework_. Together with this new framework came a
|
||||
comprehensive test that stresses all aspects of the interface. During the past
|
||||
few months, this test has turned out to be an enrichment for Genode far beyond
|
||||
its original scope. As the test significantly raised the standards in
|
||||
user-level timing, it also sharpened our view on the measurement precision of
|
||||
various timer drivers and timestamps, which act as input for the framework.
|
||||
This revealed several problems previously unidentified. For instance, we
|
||||
improved the accuracy and stability of the time values provided by the drivers
|
||||
for the Raspberry-Pi timer, the Cortex-A9 timer, the PIT, and the LAPIC. We
|
||||
also were able to further optimize the calibration of the TSC in the NOVA
|
||||
kernel.
|
||||
|
||||
Additionally, the test also helped us to refine the timeout framework itself.
|
||||
The initial calibration of the framework - that previously took about 1.5
|
||||
seconds - is now performed much quicker. This makes microseconds-precise time
|
||||
available immediately after the timer connection switched to the modern
|
||||
fine-grained mode of operation, which is a prerequisite for hardware drivers
|
||||
that need such precision during their early initialization phase. The
|
||||
calculations inside the framework also became more flexible to better fit the
|
||||
characteristics of all the hardware and kernels Genode supports.
|
||||
|
||||
Finally, we were able to extend the application of the timeout framework. Most
|
||||
notably, our C runtime uses it as timing source to the benefit of all
|
||||
libc-using components. Another noteworthy case is the USB driver on the
|
||||
Raspberry Pi. It previously couldn't rely on the default Genode timing but
|
||||
required a local hardware timer to reach the precision that the host
|
||||
controller expected from software. With the timeout framework, this workaround
|
||||
could be removed from the driver.
|
||||
|
||||
|
||||
FatFS-based VFS plugin
|
||||
======================
|
||||
|
||||
Genode has supported VFAT file-systems since the 9.11 release when the
|
||||
[http://elm-chan.org/fsw/ff/00index_e.html - FatFS] library was first ported.
|
||||
The 11.08 release fit the library into the libc plugin architecture and
|
||||
in 12.08 FatFS was used in the _ffat_fs_ file-system server. Now, the 17.08
|
||||
release revisits FatFS to mold the library into the newer and more flexible
|
||||
VFS plugin system. The _vfs_fatfs_ plugin may be fitted into the VFS server or
|
||||
used directly by arbitrary components linked to the VFS library. As the
|
||||
collection of VFS plugins in combination with the VFS file-system server has a
|
||||
lower net maintenance cost than multiple file-system servers, the _ffat_fs_
|
||||
server will be retired in a future release.
|
||||
|
||||
|
||||
Enhanced GUI primitives
|
||||
=======================
|
||||
|
||||
Even though we consider Qt5 as the go-to solution for creating advanced
|
||||
graphical user interfaces on top of Genode, we also continue to explore an
|
||||
alternative approach that facilitates Genode's component architecture to an
|
||||
extreme degree. The so-called menu-view component takes an XML description of
|
||||
a dialog as input and produces rendered pixels as output. It also gives
|
||||
feedback to user input such as the hovered widget at a given pointer position.
|
||||
The menu view does not implement any application logic but is meant to be
|
||||
embedded as a child component into the actual application. This approach
|
||||
relieves the application from the complexity (and potential bugs) of widget
|
||||
rendering. It also reinforces a rigid separation of a view and its underlying
|
||||
data model.
|
||||
|
||||
The menu view was first introduced in
|
||||
[https://genode.org/documentation/release-notes/14.11#New_menu_view_application - version 14.11].
|
||||
The current release improves it in the following ways:
|
||||
|
||||
* The new '<float>' widget aligns a child widget within a
|
||||
larger parent widget by specifying the boolean attributes 'north', 'south',
|
||||
'east', and 'west'. If none is specified, the child is centered. If opposite
|
||||
attributes are specified, the child is stretched.
|
||||
|
||||
* A new '<depgraph>' widget arranges child widgets in the form of a
|
||||
dependency graph, which will be the cornerstone for Genode's upcoming
|
||||
interactive component-composition feature. As a prerequisite for
|
||||
implementing the depgraph widget, Genode's set of basic graphical primitives
|
||||
received new operations for drawing sub-pixel-accurate anti-aliased lines
|
||||
and bezier curves.
|
||||
|
||||
* All geometric changes of the widget layout are animated now. This includes
|
||||
structural changes of the new '<depgraph>' widget.
|
||||
|
||||
[image depgraph]
|
||||
|
||||
The menu-view component is illustrated by the run script at
|
||||
_gems/run/menu_view.run_.
|
||||
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
The growing number of ported applications used on Genode is accompanied by the
|
||||
requirement of extensive POSIX compatibility of our C runtime. Therefore, we
|
||||
enhanced our implementation by half a dozen features (e.g., O_ACCMODE
|
||||
tracking) during the past release cycle. We thank the contributors of patches
|
||||
and test cases and will continue our efforts to accommodate more ported
|
||||
open-source components in the future.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Mesa adjustments
|
||||
================
|
||||
|
||||
The Mesa update required the adaption of all components that use OpenGL.
|
||||
In particular that means the Qt5 framework. Furthermore, we also enabled
|
||||
OpenGL support in our SDL1 port.
|
||||
|
||||
As playground, there are a few OpenGL examples. The demos are located under
|
||||
_repos/libports/src/test/mesa_demos_, which use the EGLUT bindings. There
|
||||
are also some SDL based examples in the world repository under
|
||||
_repos/world/src/test/sdl_opengl_.
|
||||
|
||||
|
||||
Package management
|
||||
==================
|
||||
|
||||
The previous release featured the initial version of Genode's
|
||||
[https://genode.org/documentation/release-notes/17.05#Package_management - custom package-management tools].
|
||||
Since then, we continued this line of work in three directions.
|
||||
|
||||
First, we refined the depot tools and the integration of the depot with our
|
||||
custom work-flow ("run") tool. One important refinement is a simplification of
|
||||
the depot's directory layout for library binaries. We found that the initial
|
||||
version implied unwelcome complexities down the road. Instead of placing
|
||||
library binaries in a directory named after their API, they are now placed
|
||||
directly in the architecture directory along with regular binaries.
|
||||
|
||||
Second, driven by the proliferated use of the depot by more and more run
|
||||
scripts, we enhanced the depot with new depot recipes as needed.
|
||||
|
||||
Third, we took the first steps to use the depot on-target. The experimentation
|
||||
with on-target depots is eased by the new 'create_tar_from_depot_binaries'
|
||||
function of the run tool, which allows one to assemble a new depot in the form
|
||||
of a tar archive out of a subset of packages. Furthermore, the new
|
||||
_depot_query_ component is able to scan an on-target depot for runtime
|
||||
descriptions and returns all the information needed to start a subsystem based
|
||||
on the depot content. The concept is exemplified by the new
|
||||
_gems/run/depot_deploy.run_ script, which executes the "fs_report" test case
|
||||
supplied via a depot package.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Genode as Xen DomU
|
||||
==================
|
||||
|
||||
We want to widen the application scope of Genode by enabling users to easily
|
||||
deploy Genode scenarios on Xen-based cloud platforms.
|
||||
|
||||
As a first step towards this goal, we enhanced our run tool to support running
|
||||
Genode scenarios as a local Xen DomU, managed from within the Genode build
|
||||
system on Linux running as Xen Dom0.
|
||||
|
||||
The Xen DomU runs in HVM mode (full virtualization) and loads Genode from an
|
||||
ISO image. Serial log output is printed to the text console and graphical
|
||||
output is shown in an SDL window.
|
||||
|
||||
To use this new target platform, the following run options should be defined in
|
||||
the 'build/x86_*/etc/build.conf' file:
|
||||
|
||||
! RUN_OPT = --include boot_dir/$(KERNEL)
|
||||
! RUN_OPT += --include image/iso
|
||||
! RUN_OPT += --include power_on/xen
|
||||
! RUN_OPT += --include log/xen
|
||||
! RUN_OPT += --include power_off/xen
|
||||
|
||||
The Xen DomU is managed using the 'xl' command line tool and it is possible to
|
||||
add configuration options in the 'xen_args' variable of a run script. Common
|
||||
options are:
|
||||
|
||||
* Disabling the graphical output:
|
||||
|
||||
! append xen_args { sdl="0" }
|
||||
|
||||
* Configuring a network device:
|
||||
|
||||
! append xen_args { vif=\["model=e1000,mac=02:00:00:00:01:01,bridge=xenbr0"\] }
|
||||
|
||||
* Configuring USB input devices:
|
||||
|
||||
! append xen_args { usbdevice=\["mouse","keyboard"\] }
|
||||
|
||||
Note that the 'xl' tool requires super-user permissions. Interactive
|
||||
password input can be complicated in combination with 'expect' and is not
|
||||
practical for automated tests. For this reason, the current implementation
|
||||
assumes that no password input is needed when running 'sudo xl', which can
|
||||
be achieved by creating a file '/etc/sudoers.d/xl' with the content
|
||||
|
||||
! user ALL=(root) NOPASSWD: /usr/sbin/xl
|
||||
|
||||
where 'user' is the Linux user name.
|
||||
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
UEFI support
|
||||
------------
|
||||
|
||||
Analogously to our work on the seL4 and NOVA kernels in this release, we
|
||||
extended our base-hw kernel to become a Multiboot2 compliant kernel. When used
|
||||
together with GRUB2, it can be started on x86 UEFI machines missing legacy
|
||||
BIOS support (i.e., CSM).
|
||||
|
||||
|
||||
RISC-V
|
||||
------
|
||||
|
||||
With Genode version 17.05, we updated base-hw's RISC-V support to privileged
|
||||
ISA revision 1.9.1. Unfortunately, this implied that dynamic linking was not
|
||||
supported on the RISC-V architecture anymore. Since dynamic linking is now
|
||||
required for almost all Genode applications by default, this became a severe
|
||||
limitation. Therefore, we revisited our RISC-V implementation - in particular
|
||||
the kernel entry code - to lift the limitation of being able to execute only
|
||||
statically linked binaries.
|
||||
|
||||
Additionally, we integrated the Berkeley Boot Loader (BBL), which bootstraps
|
||||
the system and implements the machine mode, more closely into our build
|
||||
infrastructure. We also added a new timer implementation to base-hw by using
|
||||
the _set timeout SBI_ call of BBL.
|
||||
|
||||
What still remains missing is proper FPU support. While we are building the
|
||||
Genode tool chain with soft float support, we still encounter occasions where
|
||||
FPU code is generated, which in turn triggers compile time errors. We will
|
||||
have to investigate this behavior more thoroughly, but ultimately we want to
|
||||
add FPU support for RISC-V to our kernel and enable hardware floating point in
|
||||
the tool chain.
|
||||
|
||||
|
||||
Muen separation kernel
|
||||
======================
|
||||
|
||||
Besides updating the Muen port to the latest kernel version as of end of June,
|
||||
Muen has been added to Genode's automated testing infrastructure. This
|
||||
includes the revived support for VirtualBox 4 on top of this kernel.
|
||||
|
||||
|
||||
NOVA microhypervisor
|
||||
====================
|
||||
|
||||
The current release extends NOVA to become a Multiboot2 compliant kernel. Used
|
||||
together with GRUB2, NOVA can now be started on x86 UEFI machines missing
|
||||
legacy BIOS support (called CSM).
|
||||
|
||||
GRUB2 provides the initial ACPI RSDP (Root System Description Pointer) to a
|
||||
Multiboot2 kernel. The RSDP contains vital information required to bootstrap
|
||||
the kernel and the operating system in general on today's x86 machines. To
|
||||
make this information available to the user-level ACPI and ACPICA drivers, the
|
||||
kernel propagates the RSDP to Genode's core, which - in turn - exposes it to
|
||||
the user land as part of the _platform_info_ ROM module.
|
||||
|
||||
In order to ease the setup of an UEFI bootable image, we added a new image
|
||||
module to our run-tool infrastructure. The run option 'image/uefi' can be used
|
||||
instead of 'image/iso' in order to create a raw image that contains a EFI
|
||||
system partition in a GUID partition table (GPT). The image is equipped by the
|
||||
new 'image/uefi' module with the GRUB2 boot loader, a GRUB2 configuration, and
|
||||
the corresponding Genode run scenario. The final image can be copied with 'dd'
|
||||
to a bootable USB stick. Additionally, we added support to boot such an image
|
||||
on Qemu leveraging [http://www.tianocore.org - TianoCore's] UEFI firmware.
|
||||
|
||||
As a side project, minor virtualization support for AMD has been added to
|
||||
Virtualbox 4 and to the NOVA kernel on Genode. This enables us to run a 32-bit
|
||||
Windows 7 VM on a 32-bit Genode/NOVA host on an (oldish) AMD Phenom II X4 test
|
||||
machine.
|
||||
830
doc/release_notes/08-11.txt
Normal file
830
doc/release_notes/08-11.txt
Normal file
@@ -0,0 +1,830 @@
|
||||
|
||||
|
||||
==============================================
|
||||
Release notes for the Genode OS Framework 8.11
|
||||
==============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
Summary
|
||||
#######
|
||||
|
||||
This document presents the new features and major changes introduced
|
||||
in version 8.11 of the Genode OS Framework. It is geared towards
|
||||
people interested in closely following the progress of the Genode
|
||||
project and to developers who want to adopt their software to our
|
||||
mainline development. The document aggregates important fragments
|
||||
of the updated documentation such that you won't need to scan existing
|
||||
documents for the new bits. Furthermore, it attempts to provide our
|
||||
rationale behind the taken design decisions.
|
||||
|
||||
The general theme for the release 8.11 is enabling the use of the
|
||||
Genode OS framework for real-world applications. Because we regard
|
||||
the presence of device drivers and a way to reuse existing library
|
||||
code as fundamental prerequisites for achieving this goal, the major
|
||||
new additions are an API for device drivers written in C, an API for
|
||||
handling asynchronous notifications, and a C runtime. Other noteworthy
|
||||
improvements are the typification of capabilities at the C++-language
|
||||
level, a way for receiving and handling application faults, the
|
||||
introduction of managed dataspaces, and a new API for scheduling
|
||||
timed events.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
This section documents the new features and changes affecting the
|
||||
'base' repository, in particular the base API.
|
||||
|
||||
|
||||
New features
|
||||
============
|
||||
|
||||
Connection handling
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The interaction of a client with a server involves the definition of
|
||||
session-construction arguments, the request of the session creation via
|
||||
its parent, the initialization of the matching RPC-client stub code
|
||||
with the received session capability, the actual use of the session
|
||||
interface, and the closure of the session. A typical procedure of
|
||||
using a service looks like this:
|
||||
|
||||
!#include <rom_session/client.h>
|
||||
!...
|
||||
!
|
||||
!/* construct session-argument string and create session */
|
||||
!char *args = "filename=config, ram_quota=4K");
|
||||
!Capability session_cap = env()->parent()->session("ROM", args);
|
||||
!
|
||||
!/* initialize RPC stub code */
|
||||
!Rom_session_client rsc(session_cap);
|
||||
!
|
||||
!/* invoke remote procedures, 'dataspace' is a RPC function */
|
||||
!Capability ds_csp = rsc.dataspace();
|
||||
!...
|
||||
!
|
||||
!/* call parent to close the session */
|
||||
!env()->parent()->close(session_cap);
|
||||
|
||||
Even though this procedure does not seem to be overly complicated,
|
||||
is has raised the following questions and criticism:
|
||||
|
||||
* The quota-donation argument is specific for each server. Most services
|
||||
use client-donated RAM quota only for holding little meta data and,
|
||||
thus, are happy with a donation of 4KB. Other services maintain larger
|
||||
client-specific state and require higher RAM-quota donations. The
|
||||
developer of a client has to be aware about the quota requirements for
|
||||
each service used by his application.
|
||||
|
||||
* There exists no formalism for documenting session arguments.
|
||||
|
||||
* Because session arguments are passed to the 'session'-call as a plain
|
||||
string, there are no syntax checks for the assembled string performed
|
||||
at compile time. For example, a missing comma would go undetected until
|
||||
a runtime test is performed.
|
||||
|
||||
* There are multiple lines of client code needed to open a session to
|
||||
a service and the session capability must be maintained manually for
|
||||
closing the session later on.
|
||||
|
||||
The new 'Connection' template provides a way to greatly simplify the
|
||||
handling of session arguments, session creation, and destruction on the
|
||||
client side. By implementing a service-specific connection class
|
||||
inherited from 'Connection', session arguments become plain constructor
|
||||
arguments, session functions can be called directly on the 'Connection'
|
||||
object, and the session gets properly closed when destructing the
|
||||
'Connection'. By convention, the 'Connection' class corresponding to a
|
||||
service resides in a file called 'connection.h' in the directory of the
|
||||
service's RPC interface. For each service, a corresponding 'Connection'
|
||||
class becomes the natural place where session arguments and quota
|
||||
donations are documented. With this new mechanism in place, the example
|
||||
above becomes as simple as:
|
||||
|
||||
!#include <rom_session/connection.h>
|
||||
!...
|
||||
!
|
||||
!/* create connection to the ROM service */
|
||||
!Rom_connection rom("config");
|
||||
!
|
||||
!/* invoke remote procedure */
|
||||
!Capability ds_csp = rom.dataspace();
|
||||
|
||||
[https://genode.org/documentation/api/base_index#Connecting_to_services - See the API documentation for the connection template...]
|
||||
|
||||
|
||||
Typed capabilities
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A plain 'Capability' is an untyped reference to a remote object of any
|
||||
type. For example, a capability can reference a thread object or a
|
||||
session to a service. It is loosely similar to a C void pointer, for which
|
||||
the programmer maintains the knowledge about which data type is actually
|
||||
referenced. To facilitate the type-safe use of RPC interfaces at the C++
|
||||
language level, we introduced a template for creating specialized
|
||||
capability types ('Typed_capability' in 'base/typed_capability.h') and
|
||||
the convention that each RPC interface declares a dedicated capability
|
||||
type. Note that type-safety is not maintained across RPC interfaces. As
|
||||
illustrated in Figure [layered_ipc], typification is done at the
|
||||
object-framework level on the server side and via in the 'Connection'
|
||||
classes at the client side.
|
||||
|
||||
[image layered_ipc]
|
||||
|
||||
From the application-developer's perspective, working with capabilities
|
||||
has now become type-safe, making the produced code more readable and robust.
|
||||
|
||||
[https://genode.org/documentation/api/base_index#Capability_representation - See the updated API documentation for the capability representation...]
|
||||
|
||||
|
||||
Fifo data structure
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Because the 'List' data type inserts new list elements at the list head,
|
||||
it cannot be used for implementing wait queues requiring first-in
|
||||
first-out semantics. For such use cases, we introduced a dedicated
|
||||
'Fifo' template. The main motivation for introducing 'Fifo' into the
|
||||
base API is the new semaphore described below.
|
||||
|
||||
[https://genode.org/documentation/api/base_index#Structured_data_types - See the new API documentation for the fifo template...]
|
||||
|
||||
|
||||
Semaphore
|
||||
~~~~~~~~~
|
||||
|
||||
Alongside lock-based mutual exclusion of entering critical sections,
|
||||
organizing threads in a producer-consumer relationship via a semaphore
|
||||
is a common design pattern for thread synchronization. Prior versions
|
||||
of Genode provided a preliminary semaphore implementation as part of
|
||||
the 'os' repository. This implementation, however, supported only one
|
||||
consumer thread (caller of the semaphore's 'down' function). We have
|
||||
now enhanced our implementation to support multiple consumer threads
|
||||
and added the semaphore to Genode's official base API. We have made
|
||||
the wake-up policy in the presence of multiple consumers configurable
|
||||
via a template argument. The default policy is first-in-first-out.
|
||||
|
||||
[https://genode.org/documentation/api/base_index#Synchronization - See the new API documentation for the semaphore...]
|
||||
|
||||
Thanks to Christian Prochaska for his valuable contributions to the new
|
||||
semaphore design.
|
||||
|
||||
|
||||
Asynchronous notifications
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Inter-process communication via remote procedure calls requires both
|
||||
communication partners to operate in a synchronous fashion. The caller
|
||||
of an RPC blocks as long as the RPC is not answered by the called
|
||||
server. In order to receive the call, the server has to explicitly
|
||||
wait for incoming messages. There are a number of situations where
|
||||
synchronous communication is not suited.
|
||||
|
||||
For example, a GUI server wants to deliver a notification to one of its
|
||||
clients about new input events being available. It does not want to
|
||||
block on a RPC to one specific client because it has work to do for
|
||||
other clients. Instead, the GUI server wants to deliver this
|
||||
_notification_ with _fire-and-forget_ semantics and continue with
|
||||
its operation immediately, regardless of whether the client received
|
||||
the notification or not. The client, in turn, does not want to poll
|
||||
for new input events at the GUI server but it wants to be _waken_up_
|
||||
when something interesting happens. Another example is a block-device
|
||||
driver that accepts many requests for read/write operations at once.
|
||||
The operations may be processed out of order and may take a long time.
|
||||
When having only synchronous communication available, the client and
|
||||
the block device driver would have to employ one distinct thread for
|
||||
each request, which is complicated and a waste of resources. Instead,
|
||||
the block device driver just wants to acknowledge the completeness of
|
||||
an operation _asynchronously_.
|
||||
|
||||
Because there are many more use cases for asynchronous inter-process
|
||||
communication, we introduced a new signalling framework that complements
|
||||
the existing synchronous RPC mode of communication with an interface for
|
||||
issuing and receiving asynchronous notifications. It defines interfaces
|
||||
for signal transmitters and signal receivers. A signal receiver can
|
||||
receive signals from multiple sources, whereas the sources of incoming
|
||||
signals are clearly distinguishable. One or multiple threads can either
|
||||
poll or block for incoming signals. Each signal receiver is addressable
|
||||
via a capability. The signal transmitter provides fire-and-forget
|
||||
semantics for submitting signals to exactly one signal receiver. Signals
|
||||
are communicated in a reliable fashion, which means that the exact number
|
||||
of signals submitted to a signal transmitter is communicated to the
|
||||
corresponding signal receiver. If notifications are generated at a higher
|
||||
rate than as they can be processed at the receiver, the transmitter
|
||||
counts the notifications and delivers the total amount with the next
|
||||
signal transmission. This way, the total number of notifications gets
|
||||
properly communicated to the receiver even if the receiver is not highly
|
||||
responsive. Notifications do not carry any payload because this payload
|
||||
would have to be queued at the transmitter.
|
||||
|
||||
[image signals]
|
||||
|
||||
Image [signals] illustrates the roles of signaller thread,
|
||||
transmitter, receiver, and signal-handler thread.
|
||||
|
||||
[https://genode.org/documentation/api/base_index#Asynchronous_notifications - See the new API documentation for asynchronous notifications...]
|
||||
|
||||
The current generic implementation of the signalling API employs one
|
||||
thread at each transmitter and one thread at each receiver. Because
|
||||
the used threads are pretty heavy weight with regard to resource usage,
|
||||
ports of Genode should replace this implementation with platform-
|
||||
specific variants, for example by using inter-process semaphores or
|
||||
native kernel support for signals.
|
||||
|
||||
|
||||
Region-manager faults
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In Genode, region-manager (RM) sessions are used to manage the
|
||||
address-space layout for processes. A RM session is an address-space
|
||||
layout that can be populated by attaching (portions of) dataspaces to
|
||||
(regions of) the RM session. Normally, the RM session of a process is
|
||||
first configured by the parent when decoding the process' ELF binary.
|
||||
During the lifetime of the process, the process itself may attach
|
||||
further dataspaces to its RM session to access the dataspace's content.
|
||||
Core as the provider of the RM service uses this information for
|
||||
resolving page faults raised by the process. In prior versions of
|
||||
Genode, core ignored unresolvable page faults, printed a debug message
|
||||
and halted the page-faulted thread. However, this condition may be of
|
||||
interest, in particular to the process' parent for reacting on the
|
||||
condition of a crashed child process. Therefore, we enhanced the RM
|
||||
interface by a fault-handling mechanism. For each RM session, a fault
|
||||
handler can be installed by registering a signal receiver capability.
|
||||
If an unresolvable page fault occurs, core delivers a signal to the
|
||||
registered fault handler. The fault handler, in turn, can request the
|
||||
actual state of the RM session (page-fault address) and react upon
|
||||
the fault. One possible reaction is attaching a new dataspace at the
|
||||
fault address and thereby implicitly resolving the fault. If core
|
||||
detects that a fault is resolved this way, it resumes the operation
|
||||
of the faulted thread.
|
||||
|
||||
This mechanism works analogously to how page faults are handled by
|
||||
CPUs, but on a more abstract level. A (n-level) page table corresponds
|
||||
to a RM session, a page-table entry corresponds to a dataspace-
|
||||
attachment, the RM-fault handler corresponds to a page-fault
|
||||
exception handler, and the resolution of page-faults (RM fault)
|
||||
follows the same basic scheme:
|
||||
|
||||
# Application accesses memory address with no valid page-table-entry
|
||||
(RM fault)
|
||||
# CPU generates page-fault exception (core delivers signal to fault
|
||||
handler)
|
||||
# Kernel reads exception-stack frame or special register to determine
|
||||
fault address (RM-fault handler reads RM state)
|
||||
# Kernel adds a valid page-table entry and returns from exception
|
||||
(RM-fault handler attaches dataspace to RM session, core resumes
|
||||
faulted thread)
|
||||
|
||||
The RM-fault mechanism is not only useful for detecting crashing child
|
||||
processes but it enables a straight-forward implementation of growing
|
||||
stacks and heap transparently for a child process. An example for
|
||||
using RM-faults is provided at 'base/src/test/rm_fault'.
|
||||
|
||||
Note that this mechanism is only available on platforms on which core
|
||||
resolves page faults. This is the case for kernels of the L4 family.
|
||||
On Linux however, the Linux kernel resolves page faults and suspends
|
||||
processes performing unresolvable memory accesses (segmentation fault).
|
||||
|
||||
|
||||
Managed dataspaces (experimental)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The RM-fault mechanism clears the way for an exciting new feature
|
||||
of Genode 8.11 called managed dataspaces. In prior versions of Genode,
|
||||
each dataspace referred to a contiguous area of physical memory (or
|
||||
memory-mapped I/O) obtained by one of core's RAM, ROM, or IO_MEM
|
||||
services, hence we call them physical dataspaces. We have now added
|
||||
a second type of dataspaces called managed dataspaces. In contrast
|
||||
to a physical dataspace, a managed dataspace is backed by the content
|
||||
described by an RM session. In fact, each RM session can be used as
|
||||
dataspace and can thereby be attached to other RM sessions.
|
||||
|
||||
Combined with the RM fault mechanism described above, managed
|
||||
dataspaces enable a new realm of applications such as dataspaces
|
||||
entirely managed by user-level services, copy-on-write dataspaces,
|
||||
non-contiguous large memory dataspaces that are immune to physical
|
||||
memory fragmentation, process-local RM fault handlers (e.g., managing
|
||||
the own thread-stack area as a sub-RM-session), and sparsely populated
|
||||
dataspaces.
|
||||
|
||||
Current limitations
|
||||
-------------------
|
||||
|
||||
Currently, managed dataspaces still have two major limitations. First,
|
||||
this mechanism allows for creating cycles of RM sessions. Core must
|
||||
detect such cycles during page-fault resolution. Although, a design for
|
||||
an appropriate algorithm exists, cycle-detection is not yet implemented.
|
||||
The missing cycle detection would enable a malicious process to force
|
||||
core into an infinite loop. Second, RM faults are implemented using the
|
||||
new signalling framework. With the current generic implementation, RM
|
||||
sessions are far more resource-demanding than they should be. Once the
|
||||
signalling framework is optimized for L4, RM sessions and thereby
|
||||
managed dataspaces will become cheap. Until then, we do not recommend
|
||||
to put this mechanism to heavy use.
|
||||
|
||||
Because of these current limitations, managed dataspaces are marked as
|
||||
an experimental feature. When building Genode, experimental features are
|
||||
disabled by default. To enable them, add a file called 'specs.conf'
|
||||
with the following content to the 'etc/' subdirectory of your build
|
||||
directory:
|
||||
|
||||
! SPECS += experimental
|
||||
|
||||
For an example of how to use the new mechanism to manage a part of a
|
||||
process' own address space by itself, you may take a look at
|
||||
'base/src/test/rm_nested'.
|
||||
|
||||
|
||||
Changes
|
||||
=======
|
||||
|
||||
Besides the addition of the new features described above, the following
|
||||
parts of the base framework underwent changes worth describing.
|
||||
|
||||
|
||||
Consistent use of typed capabilities and connection classes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We applied capability typification to all interfaces of Genode including
|
||||
the base API and the interfaces defined in the 'os' repository. Figure
|
||||
[base_cap_types] provides an overview about the capability types
|
||||
provided by the base API.
|
||||
|
||||
[image base_cap_types]
|
||||
Overview about the capability types provided by the base API
|
||||
|
||||
Furthermore, we have complemented all session interfaces with
|
||||
appropriate 'Connection' classes taking service-specific session
|
||||
arguments into account.
|
||||
|
||||
For session-interface classes, we introduced the convention to declare
|
||||
the service name as part of the session-interface via a static member
|
||||
function:
|
||||
! static const char *service_name();
|
||||
|
||||
|
||||
Allocator refinements
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Throughout Genode, allocators are not only used for allocating memory
|
||||
but also for managing address-space layouts and ranges of physical
|
||||
resources such as I/O-port ranges or IRQ ranges. In these cases, the
|
||||
address '0' may be a valid value. Consequently, this value cannot be
|
||||
used to signal allocation errors as done in prior versions of Genode.
|
||||
Furthermore, because managed dataspaces use the RM session interface to
|
||||
define the dataspace layout, the address-'0' problem applies here as
|
||||
well. We have now refined our allocator interfaces and the RM-session
|
||||
interface to make them fit better for problems other than managing
|
||||
virtual memory.
|
||||
|
||||
|
||||
Misc changes
|
||||
~~~~~~~~~~~~
|
||||
|
||||
We revised all interfaces to consistently use _exceptions_ to signal
|
||||
error conditions rather than delivering error codes as return values.
|
||||
This way, error codes become exception types that have a meaningful
|
||||
name and, in contrast to global 'errno' definitions, an error exception
|
||||
type can be defined local to the interface it applies to. Furthermore,
|
||||
the use of exceptions allows for creating much cleaner looking interfaces.
|
||||
|
||||
Traditionally, we have provided our custom _printf_ implementation as C
|
||||
symbol to make this function available from both C and C++ code. However,
|
||||
we observed that we never called this function from C code and that the
|
||||
'printf' symbol conflicts with the libc. Hence, we turned 'printf'
|
||||
into a C++ symbol residing in the 'Genode' namespace.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
This section documents the new features and changes affecting
|
||||
the 'os' repository.
|
||||
|
||||
New Features
|
||||
============
|
||||
|
||||
Device-driver framework for C device drivers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Genode's base API features everything needed to create user-level device
|
||||
drivers. For example, the 'os' repository's PS/2 input driver and the
|
||||
PCI bus driver are using Genode's C++ base API directly. However, most of
|
||||
today's device drivers are written in C. To ease the reuse of existing
|
||||
drivers on Genode, we have introduced a C API for device drivers into
|
||||
Genode's 'os' repository. The API is called DDE kit (DDE is an acronym
|
||||
for device-driver environment) and it is located at 'os/include/dde_kit'.
|
||||
|
||||
The DDE kit API is the result of long-year experiences with porting device
|
||||
drivers from Linux and FreeBSD to custom OS environments. The following
|
||||
references are the most significant contributions to the development of
|
||||
the API.
|
||||
;
|
||||
Christian Helmuth created the initial version of the Linux device-driver
|
||||
environment for L4. He describes his effort of reusing unmodified sound
|
||||
drivers on the L4 platform in his thesis
|
||||
[https://os.inf.tu-dresden.de/papers_ps/helmuth-diplom.pdf - Generische Portierung von Linux-Gerätetreibern auf die DROPS-Architektur].
|
||||
;
|
||||
Gerd Griessbach approached the problem of re-using Linux USB drivers
|
||||
by following the DDE approach in his diploma thesis
|
||||
[https://os.inf.tu-dresden.de/papers_ps/griessbach-diplom.pdf - USB for DROPS].
|
||||
;
|
||||
Marek Menzer adapted Linux DDE to Linux 2.6 and explored the DDE
|
||||
approach for block-device drivers in his student research project
|
||||
[https://os.inf.tu-dresden.de/papers_ps/menzer-beleg.pdf - Portierung des DROPS Device Driver Environment (DDE) für Linux 2.6 am Beispiel des IDE-Treibers ]
|
||||
and his diploma thesis
|
||||
[https://os.inf.tu-dresden.de/papers_ps/menzer-diplom.pdf - Entwicklung eines Blockgeräte-Frameworks für DROPS].
|
||||
;
|
||||
Thomas Friebel generalized the DDE approach and introduced the DDE kit
|
||||
API to enable the re-use of device driver from other platforms than
|
||||
Linux. In particular, he experimented with the block-device drivers of
|
||||
FreeBSD in his diploma thesis
|
||||
[https://os.inf.tu-dresden.de/papers_ps/friebel-diplom.pdf - Übertragung des Device-Driver-Environment-Ansatzes auf Subsysteme des BSD-Betriebssystemkerns].
|
||||
;
|
||||
Dirk Vogt successfully re-approached the port of USB device drivers
|
||||
from the Linux kernel to L4 in his student research project
|
||||
[https://os.inf.tu-dresden.de/papers_ps/beleg-vogt.pdf - USB for the L4 Environment].
|
||||
|
||||
The current incarnation of the DDE kit API provides the following
|
||||
features:
|
||||
|
||||
* General infrastructure such as init calls, assertions, debug output
|
||||
* Interrupt handling (attach, detach, disable, enable)
|
||||
* Locks, semaphores
|
||||
* Memory management (slabs, malloc)
|
||||
* PCI access (find device, access device config space)
|
||||
* Virtual page tables (translation between physical and virtual
|
||||
addresses)
|
||||
* Memory-mapped I/O, port I/O
|
||||
* Multi-threading (create, exit, thread-local storage, sleep)
|
||||
* Timers, jiffies
|
||||
|
||||
For Genode, we have created a complete reimplementation of the DDE kit
|
||||
API from scratch by fully utilizing the existing Genode infrastructure
|
||||
such as the available structured data types, core's I/O services,
|
||||
the synchronization primitives, and the thread API.
|
||||
|
||||
[image dde_kit]
|
||||
|
||||
Figure [dde_kit] illustrates the role of DDE kit when re-using an
|
||||
unmodified device driver taken from the Linux kernel. DDE kit translates
|
||||
Genode's C++ base API to the DDE kit C API. The DDE kit API, in turn, is
|
||||
used as back end by the Linux driver environment, which translates Linux
|
||||
kernel interfaces to calls into DDE kit. With this translation in place,
|
||||
an unmodified Linux device driver can be embedded into the Linux driver
|
||||
environment. The device API is specific for a class of devices such as
|
||||
NICs, block devices, or input devices. It can either be used directly as
|
||||
a function interface by an application that is using the device driver
|
||||
as a library, or it can be made accessible to external processes via an
|
||||
RPC interface.
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
The PCI sub system is not completely implemented, yet.
|
||||
|
||||
|
||||
Alarm API providing a timed event scheduler
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The scheduling of timed events is a recurring pattern found in device
|
||||
drivers, application frameworks such as Qt4 ('qeventdispatcher'), and
|
||||
applications. Therefore, we have added a timed event scheduler to the
|
||||
'os' repository. The new alarm API ('os/include/os/alarm.h') allows
|
||||
for the scheduling of both one-shot alarms and periodic alarms.
|
||||
|
||||
|
||||
Changes
|
||||
=======
|
||||
|
||||
PS/2 input driver
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The original PS/2 driver tried to switch the PS/2 keyboard to
|
||||
scan-code set 2 and assumed that all modern keyboards support this
|
||||
mode of operation. However, this assumption was wrong. We observed
|
||||
that the legacy PS/2 support of some USB keyboards covers only the
|
||||
emulated (xlate) scan-code set 1 mode. This is also case for the PS/2
|
||||
emulation in VirtualBox. Therefore, we changed our PS/2 driver to
|
||||
never touch the keyboard mode but to only detect the current mode
|
||||
of operation. The driver has now to support both, scan-code set 1 and
|
||||
scan-code set 2. This change comes along with a slightly more complex
|
||||
state machine in the driver. Hence, we moved the state machine from
|
||||
the IRQ handler to a distinct class and changed the control flow of
|
||||
the driver to fetch only one value from the i8042 PS/2 controller
|
||||
per received interrupt.
|
||||
|
||||
|
||||
PCI bus driver
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Until now, Genode's PCI bus driver was only used for experimentation
|
||||
purposes. With the forthcoming driver framework however, the PCI bus
|
||||
driver will play a central role in the system. Therefore, we adapted
|
||||
the interface of the PCI driver to these requirements. Specifically,
|
||||
the scanning of the PCI bus can now be performed without constraining
|
||||
the results by a specific vendor ID.
|
||||
|
||||
|
||||
Nitpicker GUI server
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We improved the _output_latency_ of the Nitpicker GUI server by flushing
|
||||
pixels eagerly and deferring the next periodically scheduled flush.
|
||||
This change has a positive effect on the responsiveness of the GUI to
|
||||
user input.
|
||||
|
||||
|
||||
Misc changes
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Prior versions of the 'os' repository came with a custom 'os/include/base'
|
||||
directory with interfaces extending the base API. To avoid confusion
|
||||
between the 'base' repository and the 'os' repository, 'os'-local API
|
||||
extensions are now located at 'os/include/os'. This way, the folder
|
||||
prefix of include statements indicates well from which repository the
|
||||
included header files comes from.
|
||||
|
||||
|
||||
C runtime
|
||||
#########
|
||||
|
||||
Most of existing libraries rely on the presence of a C library. For
|
||||
making the reuse of this software on Genode possible, we have now
|
||||
made a complete C library available for Genode. It comes as a separate
|
||||
source-code repository called 'libc' and is based on the code of FreeBSD.
|
||||
The original code is available at the official FreeBSD website.
|
||||
|
||||
:FreeBSD website:
|
||||
[https://www.freebsd.org/developers/cvs.html]
|
||||
|
||||
Our libc port comprises the libraries 'gdtoa', 'gen', 'locale', 'stdio',
|
||||
'stdlib', 'stdtime', 'string', and 'msun'. Currently, it supports the
|
||||
x86 architecture. Support for other architectures is planned as future
|
||||
addition. At the current stage, our back end is very basic and most of
|
||||
its functions are dummy stubs. We used Christian Prochaska's forthcoming
|
||||
Genode port of Qt4 as test case and successfully used the new libc as
|
||||
foundation for building graphical Qt4 applications. We will further
|
||||
extend the back end in correspondence to the growing feature set of the
|
||||
Genode OS framework.
|
||||
|
||||
:Usage:
|
||||
|
||||
To use the libc in your application, just add 'libc' to the 'LIBS'
|
||||
declaration in your build-description file. This declaration will make
|
||||
the libc headers available for the include path of your target and link
|
||||
the C library. When building, make sure that the 'libc' repository is
|
||||
included in your build configuration ('etc/build.conf').
|
||||
|
||||
:Limitations:
|
||||
|
||||
The current version of the C library is not thread-safe. For most
|
||||
string and math functions, this is not a problem (as these functions
|
||||
do not modify global state) but be careful with using more complex
|
||||
functions such as 'malloc' from multiple threads. Also, 'errno' may
|
||||
become meaningless when calling libc functions from multiple threads.
|
||||
|
||||
We have left out the following files from the Genode port of the
|
||||
FreeBSD libc: gdtoa 'strtodnrp.c' (gdtoa), 'getosreldate.c' (gen),
|
||||
'strcoll.c', 'strxfrm.c', 'wcscoll.c', 'wcsxfrm.c' (string),
|
||||
's_exp2l.c' ('msun').
|
||||
|
||||
The current back end is quite simplistic and it may help you to revisit
|
||||
the current state of the implementation in the 'libc/src/lib/libc'
|
||||
directory. If one of the functions in 'dummies.c' is called, you will
|
||||
see the debug message:
|
||||
! "<function-name> called, not yet implemented!"
|
||||
However, some of the back-end function implemented in the other files
|
||||
have dummy semantics but have to remain quiet because they are called
|
||||
from low-level libc code.
|
||||
|
||||
|
||||
Build infrastructure
|
||||
####################
|
||||
|
||||
Build-directory creation tool
|
||||
=============================
|
||||
|
||||
Because we think that each Genode developer benefits from knowing the
|
||||
basics about the functioning of the build system, the manual creation of
|
||||
build directories is described in Genode's getting-started document.
|
||||
However, for regular developers, creating build directories becomes a
|
||||
repetitive task. Hence, it should be automated. We have now added a
|
||||
simple build-directory creation tool that creates pre-configured build
|
||||
directories for some supported platforms. The tool is located at
|
||||
'tool/builddir/create_builddir'. To print its usage information, just
|
||||
execute the tool without arguments.
|
||||
|
||||
|
||||
Improved linking of binary files
|
||||
================================
|
||||
|
||||
For linking binary data, binary file have to be converted to object
|
||||
files. Over the time, we have used different mechanisms for this
|
||||
purpose. Originally, we used 'ld -r -b binary'. Unfortunately, these
|
||||
linker options are not portable. Therefore, the mechanism was changed
|
||||
to a 'hexdump' and 'sed' magic that generated a C array from binary data.
|
||||
This solution however, is complicated and slow. Now, we have adopted
|
||||
an idea of Ludwig Hähne to use the 'incbin' directive of the GNU
|
||||
assembler, which is a very clean, flexible, and fast solution.
|
||||
|
||||
|
||||
Lib-import mechanism
|
||||
====================
|
||||
|
||||
Libraries often require specific include files to be available at the
|
||||
default include search location. For example, users of a C library
|
||||
expect 'stdio.h' to be available at the root of the include search
|
||||
location. Placing the library's include files in the root of the
|
||||
default search location would pollute the include name space for
|
||||
all applications, regardless if they use the library or not. To
|
||||
keep library-include files well separated from each other, we have
|
||||
enhanced our build system by a new mechanism called lib-import.
|
||||
For each library specified in the 'LIBS' declaration of a build
|
||||
description file, the build system incorporates a corresponding
|
||||
'import-<libname>.mk' file into the build process. Such as file
|
||||
defines library-specific compiler options, in particular additional
|
||||
include-search locations. The build system searches for lib-import
|
||||
files in the 'lib/import/' subdirectories of all used repositories.
|
||||
|
||||
|
||||
Using 'ar' for creating libraries
|
||||
=================================
|
||||
|
||||
The previous versions of Genode relied on incremental linking ('ld -r')
|
||||
for building libraries. This approach is convenient because the linker
|
||||
resolves all cross-dependencies between libraries regardless of the
|
||||
order of how libraries are specified at the linker's command line.
|
||||
However, incremental linking prevents the linker from effectively
|
||||
detecting dead code. In contrast, when linking '.a' files, the linker
|
||||
detects unneeded object files. Traditionally, we have only linked our
|
||||
own framework containing no dead code. This changed with the new 'libc'
|
||||
support. When linking the 'libc', the presence of dead code becomes
|
||||
the normal case rather than the exception. Consequently, our old
|
||||
incremental-linking approach produced exceedingly large binaries
|
||||
including all functions that come with the 'libc'. We have now adopted
|
||||
the classic 'ar' mechanism for assembling libraries and use the linker's
|
||||
'start-group' 'end-group' feature to resolve inter-library-dependencies.
|
||||
This way, dead code gets eliminated at the granularity of object files.
|
||||
In the future, we will possible look into the '-ffunction-sections' and
|
||||
'-gc-sections' features of the GNU tool chain to further improve the
|
||||
granularity to function level.
|
||||
|
||||
If your build-description files rely on custom rules referring to
|
||||
'lib.o' files, these rules must be adapted to refer to 'lib.a' files
|
||||
instead.
|
||||
|
||||
|
||||
Misc changes
|
||||
============
|
||||
|
||||
* Added sanity check for build-description files overriding 'INC_DIR'
|
||||
instead of extending it.
|
||||
|
||||
* Restrict inclusion of dependency files to those that actually matter
|
||||
when building libraries within 'var/libcache'. This change significantly
|
||||
speeds up the build process in the presence of large libraries such as
|
||||
Qt4 and libc.
|
||||
|
||||
* Added rule for building 'cpp' files analogously to the 'cc' rule.
|
||||
Within Genode, we name all C++ implementation files with the 'cc'
|
||||
suffix. However, Qt4 uses 'cpp' as file extension so we have to
|
||||
support both.
|
||||
|
||||
* Build-description files do no longer need the declaration
|
||||
'REQUIRES = genode'. Genode's include search locations are now
|
||||
incorporated into the build process by default.
|
||||
|
||||
|
||||
Applications
|
||||
############
|
||||
|
||||
This section refers to the example applications contained in Genode's
|
||||
'demo' repository.
|
||||
|
||||
We have enhanced the _Scout_widgets_ as used by the launchpad and the
|
||||
Scout tutorial browser to perform all graphical output double-buffered,
|
||||
which effectively eliminates drawing artifacts that could occur when
|
||||
exposing intermediate drawing states via direct (unbuffered) output.
|
||||
Furthermore, we have added a way to constrain the maximum size of
|
||||
windows to perform pixel-buffer allocations on realistic window sizes.
|
||||
|
||||
Both launchpad and Scout can now start child applications. In Scout
|
||||
this functionality is realized by special "execute" links. We have
|
||||
generalized the underlying application logic for creating and
|
||||
maintaining child processes between both applications and placed
|
||||
the unification into a separate 'launchpad' library.
|
||||
|
||||
We have replaced the default document presented in Scout with an
|
||||
_interactive_walk-through_guide_ explaining the basic features of Genode.
|
||||
The document uses the new "execute" link facility to let the user start
|
||||
a launchpad instance by clicking on a link.
|
||||
|
||||
|
||||
Platform-specific changes
|
||||
#########################
|
||||
|
||||
Genode used to define _fixed-width_integer_types_ in a file 'stdint.h'
|
||||
placed in a directory corresponding to bit-width of the platform, for
|
||||
example 'include/32bit/stdint.h'. When building for a 32bit platform,
|
||||
the build system included the appropriate directory into the
|
||||
include-search path and thereby made 'stdint.h' available at the root
|
||||
of the include location. Unfortunately, this clashes with the 'stdint.h'
|
||||
file that comes with the C library. To avoid conflict with libc header
|
||||
files, we moved the definition of fixed-width integer types to
|
||||
'32bit/base/fixed_stdint.h'.
|
||||
|
||||
For the L4/Fiasco version of Genode, there existed some x86-specific
|
||||
header files that did not specifically depend on L4/Fiasco, for example
|
||||
atomic operations. Because these files are not L4/Fiasco-specific and
|
||||
may become handy for other platforms as well, we moved them to the
|
||||
generic 'base' repository.
|
||||
|
||||
|
||||
Linux 32bit
|
||||
===========
|
||||
|
||||
:Dissolving Genode's dependency from the glibc:
|
||||
|
||||
The port of the C runtime to Genode posed an interesting challenge to
|
||||
the Linux version of Genode. This version used to rely on certain
|
||||
functions provided by the underlying glibc:
|
||||
|
||||
* For creating and destroying threads, we used to rely on POSIX threads
|
||||
as provided by the 'pthread' library
|
||||
|
||||
* The lock implementation was based on the POSIX semaphore functions
|
||||
'sem_init', 'sem_wait', and 'sem_post'
|
||||
|
||||
* Shared memory was realized by using files ('open', 'close',
|
||||
'ftruncate') and the 'mmap' interface
|
||||
|
||||
* Starting and killing processes was implemented using 'fork' and 'kill'
|
||||
|
||||
* Inter-process communication used the glibc's socket functions
|
||||
|
||||
For our custom C runtime, we want to override the glibc functionality
|
||||
with our own implementation. For example, we want to provide the 'mmap'
|
||||
interface to a Genode application by implementing 'mmap' with
|
||||
functions of our base API. On Linux, however, this base API, in turn,
|
||||
used to rely on 'mmap'. This is just an example. The problem applies
|
||||
also for the other categories mentioned above. We realized that we cannot
|
||||
rely on the glibc on one hand but at the same time replace it by a custom
|
||||
C runtime (in fact, we believe that such a thing is possible by using
|
||||
awkward linker magic but we desire a clean solution). Consequently, we
|
||||
have to remove the dependency of Genode from the glibc on Linux. Step
|
||||
by step, we replaced the used glibc functions by custom Linux system-call
|
||||
bindings. Each binding function has a prefix 'lx_' such that the symbol
|
||||
won't collide with 'libc' symbols. The new bindings are located at the file
|
||||
'base-linux/src/platform/linux_syscalls.h'. It consist of 20 functions,
|
||||
most of them resembling the original interface ('socket', 'connect',
|
||||
'bind', 'getsockname', 'recvfrom', 'write', 'close', 'open', 'fork',
|
||||
'execve', 'mmap', 'ftruncate', 'unlink', 'tkill', 'nanosleep').
|
||||
For other functions, we simplified the semantics for our use case
|
||||
('sigaction', 'sigpending', 'sigsetmask', 'create_thread'). The most
|
||||
noteworthy changes are the creation and destruction of threads by
|
||||
directly using the 'clone' and 'tkill' system calls, and the lock
|
||||
implementation. Because we cannot anymore rely on the convenience of
|
||||
using futexes indirectly through the POSIX semaphore interface, we
|
||||
have adopted the simple locking approach that we already use for the
|
||||
L4/Fiasco version. This lock implementation is a simple sleeping
|
||||
spinlock.
|
||||
|
||||
|
||||
:Compromises:
|
||||
|
||||
The introduction of custom Linux system-call bindings for Genode has
|
||||
several pros and cons. With this change, The Linux version of Genode is
|
||||
not anymore easy to port to other POSIX platforms such as the Darwin
|
||||
kernel. For each POSIX kernel used as Genode platform, a custom
|
||||
implementation of our system-call bindings must be created. The
|
||||
original POSIX variant could still be reanimated, but this version
|
||||
would inherently lack support for Genode's C runtime, and thus would
|
||||
have limited value. A positive side effect of this solution, however,
|
||||
is that 'linux_syscalls.h' documents well the subset of the Linux'
|
||||
kernel interface that we are actually using.
|
||||
|
||||
The replacement of POSIX semaphores with sleeping spinlocks decreases
|
||||
locking performance quite significantly. In the contention case, the
|
||||
wakeup from sleeping introduces a high latency of up to one millisecond.
|
||||
Furthermore, fairness is not guaranteed and the spinning produces a bit
|
||||
of system load. If this approach turns out to become a serious performance
|
||||
bottleneck, we will consider creating custom bindings for Linux' futexes.
|
||||
|
||||
|
||||
L4/Fiasco
|
||||
=========
|
||||
|
||||
The concepts of _RM_faults_ and _managed_dataspaces_ as described in
|
||||
Section [Base framework], had been implemented into the L4/Fiasco
|
||||
version of core. Although the introduction of these concepts involved
|
||||
only minimal changes at the API level, the required core-internal
|
||||
changes had been quite invasive, affecting major parts of the pager
|
||||
and RM-session implementations.
|
||||
|
||||
Prior versions of the L4/Fiasco version of core did not implement
|
||||
the _cancel-blocking_mechanism_ as specified by the CPU-session API.
|
||||
The missing implementation resulted in lock-ups when destructing a
|
||||
thread that blocks for lock. With the new implementation based on
|
||||
L4/Fiasco's inter-task ex-regs system call, such threads can now
|
||||
be gracefully destructed.
|
||||
460
doc/release_notes/09-02.txt
Normal file
460
doc/release_notes/09-02.txt
Normal file
@@ -0,0 +1,460 @@
|
||||
|
||||
==============================================
|
||||
Release notes for the Genode OS Framework 9.02
|
||||
==============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
Summary
|
||||
#######
|
||||
|
||||
Whereas the focus of the previous release 8.11 was the refinement of
|
||||
Genode's base API and the creation of the infrastructure needed to build
|
||||
real-world applications, the release 9.02 is focused on functional
|
||||
enhancements in two directions. The first direction is broadening the
|
||||
number of possible base platforms for the framework. At present, most
|
||||
microkernels bring along a custom user land, which is closely tied to the
|
||||
particular kernel. Our vision is to establish Genode as a common ground for
|
||||
developing applications, protocol stacks, and device drivers in such a way
|
||||
that the software becomes easily portable among different kernels. This
|
||||
release makes Genode available on the L4ka::Pistachio kernel. Hence,
|
||||
software developed with the Genode API can now run unmodified on
|
||||
Linux/x86, L4/Fiasco, and L4ka::Pistachio. In the second direction, we
|
||||
are steadily advancing the functionality available on top of Genode. With
|
||||
this release, we introduce a basic networking facility and support for
|
||||
native Qt4 applications as major new features. Thanks to Genode's
|
||||
portability, these features become automatically available on all
|
||||
supported base platforms.
|
||||
|
||||
Our original plan for the release 9.02 also comprised the support of a
|
||||
Linux-on-Genode (para-)virtualization solution. Initially, we intended to
|
||||
make [https://os.inf.tu-dresden.de/L4/LinuxOnL4/ - L4Linux] available on
|
||||
the L4/Fiasco version of Genode. However, we identified several downsides
|
||||
with this approach. Apparently, the development of the officially available
|
||||
version of L4/Fiasco has become slow and long-known issues remain unfixed.
|
||||
L4Linux, however, is closely tied to L4/Fiasco and the L4 environment. For
|
||||
us at Genode Labs, maintaining both a custom port of L4Linux for Genode
|
||||
and L4/Fiasco by ourself in addition to developing Genode is unfeasible.
|
||||
In contrast, the Pistachio kernel features more advanced options for
|
||||
virtualization ([http://l4ka.org/projects/virtualization/afterburn/ - Afterburner]
|
||||
and VT support) that we want to explore. Furthermore, there exists another
|
||||
version of L4Linux called OKLinux for the OKL4 kernel developed at
|
||||
[http://ok-labs.com - OK-Labs], which is very interesting as well.
|
||||
Therefore, we decided against an ad-hoc solution and deferred this feature
|
||||
to the next release. [https://genode.org/about/road-map - See our updated road map...]
|
||||
|
||||
|
||||
Major new Features
|
||||
##################
|
||||
|
||||
Genode on L4ka::Pistachio
|
||||
=========================
|
||||
|
||||
From the very beginning, the base API of the Genode OS Framework was
|
||||
designed for portability. We put a lot of effort into finding API
|
||||
abstractions that are both implementable on a wide range of kernels and as
|
||||
close to the hardware as possible to keep the abstraction overhead low. For
|
||||
this reason, we developed the framework in parallel for the Linux kernel and
|
||||
the L4/Fiasco kernel. To validate our claim that Genode is highly portable,
|
||||
Julian Stecklina ported the framework to another member of the L4 family,
|
||||
namely the [http://l4ka.org/projects/pistachio/ - L4ka::Pistachio kernel].
|
||||
This high-performance kernel implements the latest official L4 API called
|
||||
L4.x2 and has a number of advanced features such as multi-processor support
|
||||
and virtualization support.
|
||||
|
||||
After Julian successfully created the first Pistachio version of Genode,
|
||||
we successively refined his work and conducted further unifications among
|
||||
the platform-dependent code for the different kernels. The result of this
|
||||
effort is included in this release and comes in the form of the
|
||||
'base-pistachio' source-code repository.
|
||||
|
||||
;Interesting technical notes:
|
||||
|
||||
* The IRQ handling on Pistachio is slightly different from L4/Fiasco.
|
||||
On L4/Fiasco, an IRQ becomes unmasked only when the user-level IRQ
|
||||
handler thread blocks for an IRQ by issuing an IPC call to the
|
||||
kernel's corresponding IRQ thread. In contrast, Pistachio unmasks an
|
||||
IRQ as soon as the user-level IRQ handler associates itself with an
|
||||
IRQ. Thus, an IRQ message may occur not only when the user-level IRQ
|
||||
handler blocks for any IRQ but anytime. In particular, IRQ messages
|
||||
may interfere with the IRQ handler's IPC communication with other
|
||||
threads. To ensure that IRQ messages do only occur when expecting
|
||||
them, we lazily associate the IRQ handler thread to the IRQ the
|
||||
first time we wait for an IRQ and issue an unmasking IPC call
|
||||
subsequent times.
|
||||
|
||||
* Genode provides a mechanism for gracefully destructing threads that
|
||||
are in a blocking state, for example waiting for an IPC message.
|
||||
Such a thread may hold locks or other resources that would not
|
||||
get properly freed when just killing the thread by force. Therefore,
|
||||
Genode provides a way to issue the cancellation of a blocking
|
||||
operation by another thread (e.g., the thread calling the destructor).
|
||||
Once, a blocking operation got canceled, a C++ exception
|
||||
('Blocking_canceled') is raised such the thread can fall back into
|
||||
a defined state and then be destructed. On L4ka::Pistachio, we use
|
||||
Pistachio's pager-exchange-registers feature in combination with
|
||||
the user-defined UTCB handle for cancelling blocking operations and
|
||||
detecting cancellations. The interesting code bits can be found in
|
||||
'src/base/ipc/ipc.cc', 'src/base/lock/lock.cc',
|
||||
'src/core/platform_thread.cc', and in the Pistachio-specific
|
||||
timer-service implementation.
|
||||
|
||||
* During the refinement of the Pistachio version, we were able to further
|
||||
generalize code that was previously specific for L4/Fiasco and
|
||||
L4ka::Pistachio respectively. Now, the platform-specific code comprises
|
||||
less than 3,000 lines of code (LOC) for L4/Pistachio, circa 2,000 LOC
|
||||
for L4/Fiasco, and circa 1,000 LOC for Linux. Hence, we expect that
|
||||
porting the framework to further kernels is possible at reasonable
|
||||
engineering costs.
|
||||
|
||||
:Current limitations:
|
||||
|
||||
* The current version does not use superpages (4M mappings) because we
|
||||
experienced problems with mapping 4K pages out of 4M pages. This is an
|
||||
issue that we like to investigate further because using 4M mappings
|
||||
would improve the boot time and reduce the kernel-memory usage.
|
||||
|
||||
* Currently, we use a simple sleeping spinlock for synchronization, which
|
||||
is not optimal for several reasons. There are no fairness guarantees,
|
||||
the spinning consumes CPU time, and threads that got blocked in the
|
||||
contention case are woken up at the coarse granularity of the kernel's
|
||||
timer tick, which is typically one millisecond.
|
||||
|
||||
* Nested RM sessions as introduced as an experimental feature in the
|
||||
Genode release 8.11 are not yet supported.
|
||||
|
||||
:Further details:
|
||||
|
||||
You can find further technical details and usage instructions at this
|
||||
dedicated [https://genode.org/documentation/platforms/pistachio - page].
|
||||
|
||||
|
||||
Qt4 on Genode
|
||||
=============
|
||||
|
||||
The minimalism of the Genode OS Framework with regard to its code
|
||||
complexity raised the question of whether this framework is feasible
|
||||
for hosting real-world applications and widely used runtime environments.
|
||||
Christian Prochaska took the challenge to port Trolltech's Qt4 application
|
||||
framework, which serves as the basis for the popular KDE desktop, to Genode.
|
||||
|
||||
Because Christian started his work more than a year ago at a time when no
|
||||
C library was available on Genode, several intermediate steps were needed.
|
||||
The first step was the integration of the Qt4 tools such as the meta-object
|
||||
compiler (moc) and resource compiler properly into the our build systion.
|
||||
With the tools in place, the Linux version of Genode came to an advantage.
|
||||
In this environment, a Genode application is able to use glibc functionality.
|
||||
So the problem of a missing C library could be deferred and Christian was
|
||||
able to focus on interfacing Qt with the existing Genode services such as
|
||||
the Nitpicker GUI sever. Next, the glibc dependencies were successively
|
||||
replaced by custom implementations or simple dummy stubs. Thereby, all
|
||||
needed functionalities such as timed semaphores and thread-local storage
|
||||
had to be mapped to existing Genode API calls. Once, all glibc dependencies
|
||||
had been dissolved, Qt could be compiled for the L4/Fiasco version.
|
||||
|
||||
Since a C library has become available in Genode 8.11, we were able to
|
||||
replace Christian's intermediate stub codes with a real C library. We also
|
||||
utilize recently added features of Genode such as its alarm framework to
|
||||
simplify the Qt4 port. Furthermore, we were able to remove all
|
||||
platform-specific bits such that the Qt4 port has now become completely
|
||||
generic with regard to the underlying kernel. Qt4 can be executed on Linux,
|
||||
L4/Fiasco, and L4ka::Pistachio without any changes. Figure [qt4_screenshot]
|
||||
shows a screenshot of Qt's Tetrix example running side-by-side with native
|
||||
Genode applications.
|
||||
|
||||
[image qt4_screenshot]
|
||||
|
||||
:Current state:
|
||||
|
||||
* The Qt4 port comes in the form of a source-code repository, which contains
|
||||
all Qt source codes, and some example programs such as Tetrix. You can
|
||||
download the Qt4 repository as a separate archive at the download page of
|
||||
the Genode release 9.2. For the next release, we plan to separate the
|
||||
Genode-specific parts from Qt original code and make the Genode-specific
|
||||
parts a regular component of the Genode main line.
|
||||
|
||||
* The Qt4 port consists of Qt's Core library, GUI library, Script library,
|
||||
XML library, and the UI tools library. Other libraries such as Webkit
|
||||
are not ported yet.
|
||||
|
||||
* This first version of Qt4 on Genode is not to be considered as stable.
|
||||
There are several known issues yet to be addressed. In particular,
|
||||
the 'QEventDispatcher' is still work in progress and not fully stabilized.
|
||||
|
||||
* Because, we use to statically link programs, the binaries of Qt
|
||||
applications are exceedingly large. For example the Tetrix binary is
|
||||
100MB including debug information and 11MB in the stripped form. For
|
||||
employing Qt on Genode at a larger scale, Genode should be enhanced with
|
||||
shared-library support.
|
||||
|
||||
|
||||
Networking
|
||||
==========
|
||||
|
||||
With Genode 8.11, we introduced the Device-Driver-Environment Kit (DDE Kit)
|
||||
API, which is a C API specifically designed for implementing and porting
|
||||
device drivers written in plain C. We have now complemented DDE Kit with an
|
||||
environment for executing Linux device drivers natively on Genode. This
|
||||
library is called 'dde_linux26' and contained in our new 'linux_drivers'
|
||||
source-code repository. The environment consists of several parts, which
|
||||
correspond to the different sub systems of the Linux kernel 2.6, such as
|
||||
'arch', 'drivers', 'kernel'.
|
||||
|
||||
The first class of device-drivers supported by DDE Linux 2.6 is networking.
|
||||
At the current stage, the DDE Linux network library comprises general
|
||||
network-device infrastructure as well as an exemplary driver for the PCnet32
|
||||
network device.
|
||||
|
||||
Based on this library, we have created a basic TCP/IP test utilizing the
|
||||
uIP stack, which uses the DDE Linux network library as back end. The test
|
||||
program implements a basic web server displaying uIP packet statistics.
|
||||
When executed on Qemu, you can use your host's web browser to connect to
|
||||
the web server running on Genode:
|
||||
|
||||
For booting Genode on L4/Fiasco with the web-server demo, use a GRUB
|
||||
entry in your 'menu.lst' file as follows.
|
||||
|
||||
! title Genode: DDE Linux 2.6 NET on L4/Fiasco
|
||||
! kernel /fiasco/bootstrap -maxmem=64 -modaddr=0x02000000
|
||||
! module /fiasco/fiasco -nokd -serial -serial_esc
|
||||
! module /fiasco/sigma0
|
||||
! module /genode/core
|
||||
! module /genode/init
|
||||
! module /config
|
||||
! module /genode/timer
|
||||
! module /genode/pci_drv
|
||||
! module /genode/test-dde_linux26_net
|
||||
|
||||
The first four lines are L4/Fiasco specific. When using L4ka::Pistachio,
|
||||
the 'menu.lst' entry looks like this:
|
||||
|
||||
! title Genode: DDE Linux 2.6 NET on L4/Pistachio
|
||||
! kernel /pistachio/kickstart
|
||||
! module /pistachio/x86-kernel
|
||||
! module /pistachio/sigma0
|
||||
! module /genode/core
|
||||
! module /genode/init
|
||||
! module /config
|
||||
! module /genode/timer
|
||||
! module /genode/pci_drv
|
||||
! module /genode/test-dde_linux26_net
|
||||
|
||||
The web-server test requires the PCI bus driver and the timer service.
|
||||
Therefore, the 'config' file for Genode's init should have following
|
||||
content:
|
||||
! <config>
|
||||
! <start>
|
||||
! <filename>timer</filename>
|
||||
! <ram_quota>512K</ram_quota>
|
||||
! </start>
|
||||
! <start>
|
||||
! <filename>pci_drv</filename>
|
||||
! <ram_quota>512K</ram_quota>
|
||||
! </start>
|
||||
! <start>
|
||||
! <filename>test-dde_linux26_net</filename>
|
||||
! <ram_quota>16M</ram_quota>
|
||||
! </start>
|
||||
! </config>
|
||||
|
||||
Now, its time to create an ISO image from all files specified in
|
||||
the GRUB configuration. For this, the new utility 'tool/create_iso'
|
||||
becomes handy. The ISO image can then be booted on Qemu using the
|
||||
following arguments:
|
||||
! qemu -m 64 -serial stdio -no-kqemu -cdrom <iso-image> \
|
||||
! -net nic,model=pcnet -net user -redir tcp:5555::80
|
||||
|
||||
The '-redir' argument tells qemu to redirect TCP connections with
|
||||
localhost:5555 to the guest OS at port 80. After having booted
|
||||
up Genode on Qemu, you can use your host's web browser to access
|
||||
the web server:
|
||||
! firefox http://localhost:5555
|
||||
|
||||
:Notes about using the TAP version:
|
||||
|
||||
* Preparations
|
||||
* You must be permitted to sudo and have installed the tunctl
|
||||
utility. Under Debian/Ubuntu execute
|
||||
|
||||
! sudo apt-get install uml-utilities
|
||||
|
||||
* Create TAP device
|
||||
! TAPDEV=$(sudo tunctl -b -u $USER)
|
||||
! sudo /sbin/ifconfig $TAPDEV 10.0.0.1
|
||||
|
||||
* setup DHCP server on $TAPDEV and 10.0.0.0/8
|
||||
|
||||
* Run qemu
|
||||
! qemu -m 64 -serial stdio -no-kqemu -cdrom dde.iso \
|
||||
! -net nic,model=pcnet \
|
||||
! -net tap,ifname=$TAPDEV,script=no,downscript=no
|
||||
|
||||
* Ping
|
||||
|
||||
* Cleanup
|
||||
* Stop DHCP server
|
||||
* Remove TAP device
|
||||
! sudo tunctl -d $TAPDEV
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
C Runtime
|
||||
=========
|
||||
|
||||
We have replaced the 'malloc' implementation of the original FreeBSD C
|
||||
library with a custom implementation, which relies on Genode's 'Heap' as
|
||||
allocator. The FreeBSD libc reserves a default memory pool of 1MB, which
|
||||
is no problem on FreeBSD because virtual memory is backed lazily with
|
||||
physical pages on demand. On Genode however, we immediately account the
|
||||
allocated memory, which implicates high quota requirements even for
|
||||
applications that use little memory. In contrast, Genode's heap allocates
|
||||
and accounts its backing store in relatively small chunks of a few KB.
|
||||
Therefore, the quota accounting for applications is much more in line with
|
||||
the actual memory usage. Furthermore, our custom 'malloc' implementation
|
||||
has the additional benefit of being thread safe.
|
||||
|
||||
* Added i386-specific parts of gen lib, in particular longjmp, setjmp.
|
||||
|
||||
|
||||
Device-Driver-Environment Kit
|
||||
=============================
|
||||
|
||||
* The DDE Kit uses our alarm framework (located in the 'os' repository) now
|
||||
rather than its own event-scheduler implementation formerly called 'Tick'.
|
||||
|
||||
* We refined the DDE Kit API and reduced the number of custom types. For
|
||||
example, we removed the custom 'dde_kit_lock_t' and using
|
||||
'struct dde_kit_lock' instead, and replaced 'dde_kit_thread_t' with
|
||||
'struct dde_kit_thread'.
|
||||
|
||||
Because of the apparent stabilization of the DDE Kit API, we have now added
|
||||
this API to Genode's official API reference.
|
||||
[https://genode.org/documentation/api/dde_kit_index - See the documentation of the DDE Kit API...]
|
||||
|
||||
|
||||
PS/2 input driver
|
||||
=================
|
||||
|
||||
We improved the PS/2 keyboard driver by adding missing scan-code translations
|
||||
for the scan code set 1, in particular the cursor keys.
|
||||
|
||||
|
||||
Applications
|
||||
############
|
||||
|
||||
Launchpad configuration
|
||||
=======================
|
||||
|
||||
Launchpad is a graphical application for interactively starting and killing
|
||||
programs. It is used for the default demonstration of Genode. By default,
|
||||
launchpad displays a preconfigured list of programs and their respective
|
||||
default memory quotas. The user can tweak the memory quota for each entry
|
||||
with mouse and then start a program by clicking on its name. As an
|
||||
alternative to using the default list, you can now define the list manually
|
||||
by supplying a configuration to Launchpad. The following example tells
|
||||
launchpad to display a list of two launcher entries:
|
||||
|
||||
!<config>
|
||||
! <launcher>
|
||||
! <filename>sdl_pathfind</filename>
|
||||
! <ram_quota>10M</ram_quota>
|
||||
! </launcher>
|
||||
! <launcher>
|
||||
! <filename>liquid_fb</filename>
|
||||
! <ram_quota>10M</ram_quota>
|
||||
! </launcher>
|
||||
!</config>
|
||||
|
||||
To use this configuration for a Launchpad started via init, you can simply
|
||||
insert the launchpad configuration into the '<start>' node of the launchpad
|
||||
entry in init's 'config' file.
|
||||
|
||||
|
||||
Platform-specific changes
|
||||
#########################
|
||||
|
||||
L4/Fiasco
|
||||
=========
|
||||
|
||||
* Raise 'Blocking_canceled' exceptions on canceled IPC calls
|
||||
|
||||
32-bit Linux
|
||||
============
|
||||
|
||||
* We continued dissolving the dependency of Genode from the glibc by using
|
||||
a custom 'getenv' implementation used during process creation.
|
||||
* By default, we compile now with '-nostdinc' and explicitly specify
|
||||
'/usr/include' as include search directory only when needed. Previously,
|
||||
a Genode application, which included a host include file by mistake, has
|
||||
not raised any compilation error when compiled for the Linux version of
|
||||
Genode. Now, all Genode platforms behave equally with regard to include
|
||||
search directories.
|
||||
* We enforce using the actual compiler's C++ support libraries rather than
|
||||
the default libraries installed on the host.
|
||||
|
||||
|
||||
Tools and build infrastructure
|
||||
##############################
|
||||
|
||||
Official tool chain
|
||||
===================
|
||||
|
||||
At the download section of our website, we used to provide a crosstool-based
|
||||
tool chain as pre-compiled binaries. Since we got several requests about
|
||||
how to build such a tool chain from scratch, we created custom utility for
|
||||
downloading, building, and installing the official Genode tool chain. You
|
||||
can find the utility at 'tool/tool_chain'. For usage instructions, just
|
||||
start 'tool_chain' without arguments. Because this utility is a plain script,
|
||||
you can follow and verify each step that we use for creating the Genode tool
|
||||
chain. Currently, this official tool chain is based on binutils 2.18 and
|
||||
gcc 4.2.4.
|
||||
|
||||
As an alternative to installing the tool chain from source, we also
|
||||
provide pre-compiled binaries at the download section of our website.
|
||||
[https://genode.org/download/tool-chain - Visit our tool-chain download website...]
|
||||
|
||||
For the Linux version of Genode, we still use the host's default gcc
|
||||
as tool chain. This way, we spare the hassle of downloading and installing
|
||||
a custom tool chain for somebody who wants to give Genode a quick try.
|
||||
With this is mind, we have fixes several small issues with gcc 4.3.2:
|
||||
|
||||
* Fixed dependency generation for gcc-4.3.2. Older version of gcc used to
|
||||
append a '.o' dependency at the target of '.d'-files. However, gcc-4.3.2
|
||||
seems to handle the option '-MT' differently, resulting in a rule that
|
||||
contains only the '.d' as target. Now, we explicitly specify both the
|
||||
'.o' file and the '.d' file as target. Consequently, on older gcc
|
||||
versions, the '.o' file appears twice but that is no problem.
|
||||
|
||||
* Fixed assembler issue with the 'fnstsw' instruction in the C library.
|
||||
This instruction does not accept eax but only ax as argument.
|
||||
|
||||
Build-directory creation tool
|
||||
=============================
|
||||
|
||||
We added a rule for creating a pre-configured build directory for the
|
||||
Pistachio version to our build-directory creation tool
|
||||
('tool/builddir/create_builddir'). Furthermore, we changed the default
|
||||
build configuration such that the official Genode tool chain is used for
|
||||
L4/Fiasco and L4ka::Pistachio.
|
||||
|
||||
Build system
|
||||
============
|
||||
|
||||
* Improved clean rule - visit each target directory only once
|
||||
* Stop the build process on the first error by default, for continuing
|
||||
the build process depite of an error, you can use the '-i' argument
|
||||
of make.
|
||||
* Compiler flags can now be set specific for compiling C and C++ sources.
|
||||
This is needed because both variants allow different sets of warning
|
||||
options. The new variables are called 'CC_CXX_OPT' and 'CC_C_OPT'.
|
||||
|
||||
ISO image creation tool
|
||||
=======================
|
||||
|
||||
We have created a convenient front end for 'genisoimage', which we
|
||||
use for testing Genode on Qemu. You can find this ISO-image-creation
|
||||
tool at 'tool/create_iso'. For usage instructions, simply start the
|
||||
tool without arguments.
|
||||
|
||||
585
doc/release_notes/09-05.txt
Normal file
585
doc/release_notes/09-05.txt
Normal file
@@ -0,0 +1,585 @@
|
||||
|
||||
==============================================
|
||||
Release notes for the Genode OS Framework 9.05
|
||||
==============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
Shortly after including support for the L4ka::Pistachio kernel in the
|
||||
previous release, the Genode version 9.05 gives a further evidence of
|
||||
Genode's high portability by making the framework available on top of
|
||||
the OKL4 kernel. This kernel is a commercial-grade microkernel
|
||||
developed by [http://ok-labs.com - Open Kernel Labs]. In Section
|
||||
[Supporting the OKL4 kernel as new base platform], we elaborate on the
|
||||
new base platform and summarize the experiences made during our porting
|
||||
work.
|
||||
|
||||
The previous Genode release was accompanied by a source-code archive containing
|
||||
the initial version of Qt4 for Genode. Our approach is to make the Qt4
|
||||
framework available for building Genode applications running natively on the
|
||||
microkernel rather than within a virtualization environment. As advertised in
|
||||
our [https://genode.org/about/road-map - road map], we have now seamlessly
|
||||
integrated the Qt4 framework into our mainline source tree. Furthermore, we
|
||||
have adapted our port to the Qt4 version 4.5.1. Section [Integration of Qt4
|
||||
into the mainline repository] gives a rough overview of the changes and an
|
||||
introduction on how to use the Qt4 framework with Genode.
|
||||
|
||||
The third major feature of the release is the addition of preliminary USB
|
||||
support. We have been able to port major parts of Linux' USB infrastructure
|
||||
to Genode using the DDE Kit introduced in autumn 2008. Section [USB support]
|
||||
presents an overview about the pursued design and the current state of
|
||||
implementation.
|
||||
|
||||
Section [OKLinux on Genode] outlines our ongoing efforts of running Linux
|
||||
as a node in Genode's process tree.
|
||||
|
||||
|
||||
Supporting the OKL4 kernel as new base platform
|
||||
###############################################
|
||||
|
||||
The OKL4 kernel developed by Open Kernel Labs started as a fork of the
|
||||
L4ka::Pistachio kernel. Whereas L4ka::Pistachio remained true to the L4
|
||||
x.2 specification, OKL4 was subject of major API changes geared towards high
|
||||
performance on the ARM architecture. OKL4 earned much fame for executing a
|
||||
user-level variant of Linux (OKLinux) on top the microkernel, which turned out
|
||||
to be faster than executing Linux natively on the ARM9 architecture. Even
|
||||
though OKL4 is primary targeted at the ARM architecture, we wanted to go for
|
||||
the x86 variant because of two reasons. First, there exists the just mentioned
|
||||
user-level port of Linux for OKL4, which looks like an attractive way to execute
|
||||
Linux on Genode once Genode runs on OKL4. Second, we think that distributing
|
||||
Genode in the form of ISO images bootable on plain PC hardware is the best
|
||||
way to reach the OS community. Therefore, we decided to use OKL4 version 2.1 as
|
||||
the base for our work. In contrast to later releases, this version supports
|
||||
both x86 and ARM. The following section reviews the unique features of the
|
||||
OKL4 kernel from our perspective.
|
||||
|
||||
|
||||
OKL4 viewed from the angle of a Genode developer
|
||||
================================================
|
||||
|
||||
On the kernel-API level, OKL4 has several interesting properties that had been
|
||||
both welcome and challenging. We want to highlight the following points:
|
||||
|
||||
In contrast to prior L4 kernels, OKL4 has *removed wall-clock timeouts* from
|
||||
the kernel interface. On L4, timeouts were used as arguments for for blocking
|
||||
IPC operations serving two purposes. First, specifying IPC timeouts allowed the
|
||||
IPC caller for regaining control over the blocking thread after the specified
|
||||
time elapsed. This is considered as important in the case that the called
|
||||
thread misbehaves and never answers the call. However, the problem of choosing
|
||||
an appropriate timeout was never properly resolved. When dimensioning the
|
||||
timeout too small, the called thread may miss the timeout just because it had
|
||||
no chance to be selected by the scheduler in time. Such timeouts rely on the
|
||||
presumption that there is low load on the system. On the other hand, when
|
||||
dimensioning the timeout too high, the system will become sluggish when the
|
||||
called thread misbehaves. For example, a simple GUI server may want to send
|
||||
input events to its clients with a timeout to be robust against misbehaving
|
||||
clients that never wait for events. When choosing a timeout too small, chances
|
||||
are high that an event will occur at a time when the receiver is handling a
|
||||
previous event. The timeout would trigger and the event would get lost. When
|
||||
choosing the timeout too large, say 1 second, any misbehaving client could make
|
||||
the GUI server freeze for 1 second. Therefore, timeouts for regaining control
|
||||
over a blocked thread seem to be a bad idea. So we welcome their absence in
|
||||
OKL4. The second use of timeouts is their use as user-level time source. On L4,
|
||||
sleep is typically implemented as a blocking IPC with a timeout set to the
|
||||
sleep value. For this purpose, a system built on top of OKL4 has to employ a
|
||||
user level device driver accessing a timer device. In Genode, we already have a
|
||||
timer service for this purpose. So we won't miss timeouts at all.
|
||||
|
||||
Classical L4 kernels provide two variants of *synchronous IPC*. So called long
|
||||
IPC could copy any amount of memory from the sending to the receiving address
|
||||
space. This is complicated operation because either communication partner may
|
||||
specify communication buffers that contain unmapped pages. Hence, page faults
|
||||
may occur during long-IPC operations. On L4, page faults, in turn, are handled
|
||||
by the user land. Not until a user-level pager thread resolves the page fault
|
||||
by establishing a mapping at the faulting address, the kernel can proceed the
|
||||
IPC operation. This sounds pretty complicated, and it is. The second IPC
|
||||
variant is called short IPC. It constrains the transferable payload to CPU
|
||||
registers. Hence, these IPC operations should only be used for messages with a
|
||||
payload of a maximum of 2 machine words. Because short IPCs are never touching
|
||||
user-level memory pages, no page faults can occur.
|
||||
On OKL4, there is only one IPC operation, which copies payload from the
|
||||
sender's user-level thread-control block (UTCB) to the receiver's UTCB. An
|
||||
UTCB is an always-mapped memory region. Hence no page faults can occur during
|
||||
IPC operations. On Genode, the UTCB size of 256 bytes may become a limitation
|
||||
when RPC messages get large. For example, session requests may include large
|
||||
session-argument strings specifying session-constructor arguments. Current
|
||||
services rely only on a few arguments so the size limitation is not an
|
||||
apparent problem. But that may change for future services. Furthermore, in
|
||||
contrast to L4 x.2, OKL4 does not allow for transferring payload other than
|
||||
plain data. In particular, OKL4 does not support the transfer of memory
|
||||
mappings via IPC. Removing memory mappings from the IPC operation is a very
|
||||
good idea. On Genode, only roottask (core) establishes mappings and shared
|
||||
memory is implemented as a user-level protocol (data spaces). There is no need
|
||||
to allow arbitrary processes to establish memory mapping via IPC.
|
||||
|
||||
The *boot procedure* of OKL4 largely differs from other L4 kernels. This is
|
||||
attributed to Open Kernel Labs' focus on embedded systems, which mostly rely on
|
||||
single-image boot loading. OKL4 employs a tool (elfweaver) for creating a
|
||||
bootable image from a bunch of files and an XML configuration file. Among the
|
||||
declarations about which processes to be loaded and which policies to enforce,
|
||||
the configuration file contains platform parameters such as the amount of
|
||||
physical memory of the machine. This static approach to configure a system is
|
||||
certainly useful for embedded systems but PC hardware uses to vary a lot. In
|
||||
this case, evaluating boot-time memory descriptors would be the preferred
|
||||
solution.
|
||||
|
||||
OKL4 introduces kernel support for *user-level synchronization*. Prior L4
|
||||
kernels facilitated user-level synchronization through a combination of
|
||||
synchronous IPC operations with either priorities or delayed preemption.
|
||||
OKL4's mutexes can make the life in the user land much easier. However, we have
|
||||
not looked into OKL4 mutexes yet.
|
||||
|
||||
There does not exist a recursive *map operation* as the source operand of the
|
||||
map operation is a physical memory descriptor rather than a virtual address in
|
||||
the mapper's address space. Consequently, this design eliminates the need for
|
||||
having a recursive unmap operation and thereby, the need to maintain a mapping
|
||||
data base in the kernel. This is cool because Genode keeps track of the
|
||||
mappings at the user level anyway (within core). From our perspective, there is
|
||||
no need to maintain mapping relationships in the kernel. Removing the mapping
|
||||
database effectively discards a lot of much-discussed problems about how to
|
||||
manage the mapping database in a clever way.
|
||||
|
||||
There exists *no root memory manager* (sigma0). Because the map operation
|
||||
takes a physical memory descriptor as argument instead of a virtual address
|
||||
in the mapper's address space. The mapper does not need to have the mapped
|
||||
page locally mapped within its own address space. In fact, core (as the only
|
||||
mapper in a Genode system) does only have very little memory mapped locally.
|
||||
This design accelerates the boot time because there is no need to map each
|
||||
physical page in core at startup as performed when running core on the other
|
||||
L4 kernels.
|
||||
|
||||
These differences of OKL4 compared with the microkernels already supported
|
||||
by Genode posed a number of interesting challenges and opportunities. We have
|
||||
thoroughly documented the process in
|
||||
[https://genode.org/documentation/articles/genode-on-okl4 - Bringing Genode to OKL4].
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
For using Genode with OKL4, please refer to the following dedicated page:
|
||||
|
||||
:[https://genode.org/documentation/platforms/okl4 - Genode on the OKL4 microkernel]:
|
||||
Site about building and using Genode with the OKL4 kernel.
|
||||
|
||||
|
||||
Limitations of the current implementation
|
||||
=========================================
|
||||
|
||||
The current implementation is able to execute the complete Genode demonstration
|
||||
scenario on OKL4. This means, we can build and destroy arbitrary trees of
|
||||
processes, have all the needed infrastructure in place to execute user-level
|
||||
device drivers such as VESA and PS/2, perform inter-process communication
|
||||
via RPC and shared memory, and have all basic framework API functions available.
|
||||
We regard the current state as the first functional version. However, there are
|
||||
the following points that need improvement and are subject to our future work.
|
||||
|
||||
:Incomplete timer driver:
|
||||
|
||||
On x86, the timer driver should program the PIT to dispatch sleep requests.
|
||||
However, the I/O ports of the PIT can only by made available to one party in
|
||||
the system (which naturally would be the timer driver). Unfortunately, there
|
||||
are some VESA BIOSes around, which try using the PIT directly. The current
|
||||
version of our VESA driver does not virtualize these accesses. It rather
|
||||
tries to gain direct access to the I/O ports from core. This would not work
|
||||
if the timer already uses this device resource. Our plan is to supplement
|
||||
our VESA driver with a virtual PIT that uses the timer service as back end.
|
||||
Then we can safely use the PIT by the timer driver.
|
||||
|
||||
:Signalling framework not yet implemented:
|
||||
|
||||
We have not yet implemented Genode's API for asynchronous notifications
|
||||
in the OKL4 version. In fact, the goal of the initial version of the
|
||||
OKL4 support was running the default demonstration scenario, which does
|
||||
not rely on signals. The second and more technical reason is that we
|
||||
consider exploiting OKL4's event mechanism for implementing the signalling
|
||||
API but have not finalized the design. The generic implementation as used
|
||||
on the other platforms cannot be used on OKL4 because this implementation
|
||||
utilizes one helper thread per signal transmitter. Within core, each RM
|
||||
session is a potential signal transmitter, which means that we need to
|
||||
create a helper thread per process. Unfortunately, by default, OKL4
|
||||
limits the number of threads within roottask (core) to only 8 threads,
|
||||
which would impose a severe limit on the number of processes we could
|
||||
run on OKL4.
|
||||
|
||||
:OKL4's kernel mutexes yet to be used:
|
||||
|
||||
We have not yet explored the use of mutexes provided by the OKL4 kernel
|
||||
for implementing Genode synchronization APIs but we rather rely on a
|
||||
yielding spin lock for now. This has a number of drawbacks such as high
|
||||
wake-up latencies in the contention case (depending on the scheduling
|
||||
time slice), no support for priorities, and no fairness. Although it
|
||||
is a simple and robust solution to start with, we plan to facilitate
|
||||
the OKL4 kernel feature with our upcoming work.
|
||||
|
||||
:Overly simplistic UTCB allocation:
|
||||
|
||||
Right now, we allocate a fixed amount of 32 UTCBs per address space and
|
||||
thereby limit the maximum number of threads per process. In the future,
|
||||
this limit should be made configurable.
|
||||
|
||||
:Managed dataspaces not yet supported:
|
||||
|
||||
The support of managed dataspaces relies on the signal API, which is
|
||||
not yet available for OKL4.
|
||||
|
||||
:Message buffers are limited to 256 bytes:
|
||||
|
||||
Because OKL4 performs message-based inter-process communication by
|
||||
copying data between the UTCBs of the communicating threads, the
|
||||
UTCB size constaints the maximum message size. Therefore, message
|
||||
must not exceed 256 bytes. This is not a huge problem for the currently
|
||||
available Genode programs but we can imagine session argument-lists
|
||||
to become larger in the future.
|
||||
|
||||
:Advanced thread functions are incomplete:
|
||||
|
||||
Thread functions such as querying registers of remote threads are not yet
|
||||
implemented.
|
||||
|
||||
|
||||
Integration of Qt4 into the mainline repository
|
||||
###############################################
|
||||
|
||||
Qt4 is a tool kit for developing platform-independent applications. It
|
||||
comprises a complete platform-abstraction layer and a rich GUI tool kit
|
||||
widely used for commercial and open-source applications. It is particularly
|
||||
known as the technical foundation of the KDE project. The previous Genode
|
||||
release was accompanied by a snapshot of our initial port of Qt4 to Genode. For
|
||||
the current release, we have turned this proof-of-concept implementation into a
|
||||
properly integrated part of the Genode mainline development. This enables Qt4
|
||||
applications to be executed natively on the full range of kernels supported by
|
||||
Genode.
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
We complemented Genode's source tree with the new 'qt4' source-code repository,
|
||||
which contains the Genode-specific parts of the Qt4 framework. The most
|
||||
portions for the Qt4 framework are used unmodified and thereby have not been
|
||||
made part of the Genode source tree. Instead, we fetch the original Qt4 source
|
||||
code from Trolltech's FTP server. This way, our source tree remains tidy and
|
||||
neat.
|
||||
|
||||
For using Qt4 for your Genode applications, you first need to download and
|
||||
prepare the original Qt4 source codes and build a few Qt4 tools such as the
|
||||
meta-object compiler and the resource compiler. The makefile found in the
|
||||
top-level directory of the 'qt4' repository automates this task:
|
||||
|
||||
! make prepare
|
||||
|
||||
To include the 'qt4' repository into the Genode build process, just add the
|
||||
'qt4' directory to the 'REPOSITORIES' declaration of the 'etc/build.conf' file
|
||||
within your build directory. Make sure that the repositories 'demo' and 'libc'
|
||||
are included as well. The 'qt4' repository comes with a couple of demo applications.
|
||||
The 'qt_launchpad' is especially interesting because it makes use of both the
|
||||
Qt4 framework and the Genode framework in one application.
|
||||
|
||||
|
||||
Features and limitations
|
||||
========================
|
||||
|
||||
The Qt4 port comprises Qt's Core library, GUI library, Script library, XML
|
||||
library, and the UI tools library.
|
||||
|
||||
For using Qt4 on the Linux version of Genode, we recommend using the Genode
|
||||
tool chain rather than your host's tool chain. Qt4 makes use of a lot of libc
|
||||
functionality, supplied by Genode's 'libc' repository. However, on Linux we
|
||||
still link against your host's libc. This becomes a problem if your host
|
||||
compiler's C++ support code references libc functionality that is not part of
|
||||
Genode's libc. Thereby the linker will silently create references to glibc
|
||||
symbols, making both libraries collide. So if using Qt4, we recommend using the
|
||||
Genode tool chain:
|
||||
|
||||
:[https://genode.org/download/tool-chain]:
|
||||
Information about downloading and using the Genode tool chain
|
||||
|
||||
|
||||
USB support
|
||||
###########
|
||||
|
||||
This release introduces the first fragments of USB support to Genode, taking
|
||||
the USB human-interface device (HID) class as starting point. With this work,
|
||||
we follow our approach of reusing unmodified Linux device drivers executed
|
||||
within a device-driver environment called DDE Linux. In the previous release,
|
||||
we already utilized this approach for realizing basic networking on Genode.
|
||||
With this release, we complement DDE Linux with support required by USB
|
||||
drivers. We are grateful for being able to base our implementation on the
|
||||
excellent foundation laid by Dirk Vogt. He described his work in
|
||||
[https://os.inf.tu-dresden.de/papers_ps/beleg-vogt.pdf - USB for the L4 environment].
|
||||
|
||||
For USB HID support, we added the Linux USB and input subsystems to the DDE
|
||||
Linux 2.6 framework. Besides the 'dde_linux26/net.h' API for network drivers
|
||||
added in Genode 9.02, the current version also includes APIs for input
|
||||
('dde_linux26/input.h') and USB ('dde_linux26/usb.h'). We intend these
|
||||
interfaces to mature towards generic driver-library APIs in the future. For
|
||||
example, BSD-based drivers shall transparently provide the same functionality
|
||||
as the current Linux drivers, which permits the simple reuse of driver server
|
||||
implementations.
|
||||
|
||||
[image usb_current]
|
||||
|
||||
Image [usb_current] illustrates the current implementation of the USB-based
|
||||
human-interface device (HID) driver. In this monolithic setup, all parts of the
|
||||
USB stack and the device API are executed within one address space. These parts
|
||||
are
|
||||
|
||||
* Input server glue code
|
||||
* HID driver and input subsystem
|
||||
* Core functions for management of USB request buffers (URBs),
|
||||
attached devices, and registered drivers
|
||||
* Host controller drivers for UHCI, OHCI, and EHCI
|
||||
|
||||
[image usb_aspired]
|
||||
|
||||
We regard this as an intermediate step towards our goal to decompose the USB
|
||||
stack. Image [usb_aspired] shows our aspired design. In this design, the
|
||||
USB server and one or more USB gadget drivers run in dedicated address spaces.
|
||||
The USB server provides two interfaces called USB session interface and USB
|
||||
device interface. A USB session interface corresponds to a virtual root hub,
|
||||
from which USB devices can be queried. The client of the USB session interface
|
||||
is usually an USB gadget driver that uses the USB device interface. Because
|
||||
this interface is used for transferring the actual payload at a potentially
|
||||
high bandwidth, it is based on shared memory and signals. The USB server
|
||||
consists of the following components:
|
||||
|
||||
* USB server glue code
|
||||
* Virtual USB device driver managing all attached devices
|
||||
* Core functions including hardware hub management
|
||||
* Host controller drivers
|
||||
|
||||
The USB server presents a virtual USB hub to each USB gadget driver. Such
|
||||
a driver consists of:
|
||||
|
||||
* Device interface, e.g., input server glue code
|
||||
* Gadget driver, e.g., HID driver and input subsystem
|
||||
* Core functions
|
||||
* Virtual host controller
|
||||
* USB client glue code
|
||||
|
||||
The HID driver uses the USB session API to monitor ports of its virtual root
|
||||
hub and submit URBs to attached devices. The session interface facilitates the
|
||||
signalling framework for event notification and a shared-memory dataspace for
|
||||
URB transmission.
|
||||
|
||||
The 'os' repository already contains the USB session and USB device interfaces.
|
||||
However, the decomposition is not yet in a functional state.
|
||||
|
||||
|
||||
:Current limitations:
|
||||
|
||||
The current monolithic implementation of the USB HID service can already be
|
||||
used as a replacement of the PS/2 driver. However, both drivers cannot be used
|
||||
at the same time, yet. To enable the use of both USB HID and PS/2, we plan to
|
||||
create a further component that merges multiple streams of input events and
|
||||
passes the result to the GUI server.
|
||||
|
||||
|
||||
OKLinux on Genode
|
||||
#################
|
||||
|
||||
According to our road map, we pursued the goal to run Linux as a node in
|
||||
Genode's process tree. We explored two approaches:
|
||||
|
||||
:Reanimating the Afterburner project conducted by the [http://l4ka.org - L4Ka group]:
|
||||
This approach is the result of the L4Ka groups's long-year experience with
|
||||
manually supporting L4Linux on top of the L4ka::Pistachio kernel. Because of
|
||||
the high costs of maintaining the paravirtualized Linux kernel, a
|
||||
semiautomatic paravirtualization technique was created. According to the
|
||||
impressive results presented in
|
||||
[http://www.l4ka.org/l4ka/publ_2006_levasseur-ua_soft-layering.pdf - Pre-Virtualization: Soft Layering for Virtual Machines],
|
||||
this approach is able to drastically reduce maintenance costs while retaining
|
||||
good performance. Furthermore, the approach was applied not only to Linux
|
||||
running on the L4 kernel but also for using Xen or Linux as underlying
|
||||
host operating systems.
|
||||
|
||||
:Porting the OKL4-specific version of L4Linux to Genode:
|
||||
Open Kernel Labs maintain a custom version of L4Linux that runs on OKL4. This
|
||||
version is mostly referred to as OKLinux aka Wombat. Since Genode can now use OKL4
|
||||
as base platform, the reuse of OKLinux in combination with Genode has become
|
||||
a feasible option.
|
||||
|
||||
Both approaches have pros and cons. Whereas Afterburner is a intriguing
|
||||
approach, this project seems to be stalled. It relies on a rather old tool
|
||||
chain, and recent Linux features such as thread-local storage support are not
|
||||
considered, yet. To pick up this solution for Genode will require us to fully
|
||||
understand the mechanisms and the code. So we consider this as a mid-term
|
||||
solution. In short term, running OKLinux on Genode is more feasible. We were
|
||||
already able to create a prototype version of OKLinux running on Genode. This
|
||||
version starts up the kernel including all Linux kernel threads, mounts the
|
||||
boot partition supplied as memory image, and starts the init process. The
|
||||
engineering costs had been rather low. We replaced the Iguana user land
|
||||
libraries as originally used by Wombat by a Genode-specific reimplementation to
|
||||
keep our manual adaptions of the Linux kernel code as small as possible.
|
||||
Our custom reimplementation of the needed Iguana APIs consists of less than
|
||||
1,000 lines of code (SLOC). The diff for our changes to the OKLinux kernel code
|
||||
comprises less than 1,000 lines. We plan to make a snapshot of this prototype
|
||||
publicly available soon.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
Nitpicker GUI server
|
||||
====================
|
||||
|
||||
We optimized the performance of the 'refresh' call, which updates all views of
|
||||
a session, which display a given buffer portion. The new implementation restricts
|
||||
the redraw operations to the fragment of each view that displays the specified
|
||||
buffer portion. The performance improvement becomes most visible when updating
|
||||
only small parts of a buffer.
|
||||
|
||||
|
||||
USB session interface
|
||||
=====================
|
||||
|
||||
Genode's emerging USB support introduces two new interfaces to the 'os' repository,
|
||||
which are called USB session and USB device.
|
||||
|
||||
An _USB_session_ is a virtual USB bus with just one root hub with 'MAX_PORTS'
|
||||
downstream ports. The client of such as session submits USB request blocks
|
||||
(URBs) and is, in turn, informed about port changes on the root hub as well as
|
||||
request completion. Connected USB devices can be referenced by USB device
|
||||
capabilities and are associated with one port at the virtual root hub on
|
||||
server side.
|
||||
|
||||
An _USB_device_ references a hardware device connected to a virtual USB bus's
|
||||
root hub. The device capability enables the client to send USB request
|
||||
blocks to the hardware device.
|
||||
|
||||
|
||||
Input interface
|
||||
===============
|
||||
|
||||
We updated the key codes of the input interface in response to recent changes
|
||||
of Linux' 'dev/event' definitions.
|
||||
|
||||
|
||||
VESA driver
|
||||
===========
|
||||
|
||||
Until now, there existed different processes that tried to access the PCI bus
|
||||
via I/O ports, in particular the VESA framebuffer driver and the PCI bus
|
||||
driver.
|
||||
|
||||
Since core enforces that each I/O port can only be assigned exclusively to one
|
||||
component in the system, multiple processes that need access to the same I/O
|
||||
ports cannot run at the same time. For our default demonstration scenario, we
|
||||
had been able to allow the VESA driver to use the PCI I/O ports because nobody
|
||||
else needed them. However, our growing base of device drivers relies on the
|
||||
PCI bus driver. To be able to use the VESA driver together with other drivers,
|
||||
we virtualized the access to the PCI bus from within the VESA driver.
|
||||
|
||||
Our current PCI virtualization code is pretty limited. The VESA driver sees a
|
||||
virtual PCI bus with only the VGA card attached. For now, we only allow reading
|
||||
the PCI configuration space of this device, but not writing to it. Apparently,
|
||||
this simple approach is sufficient to run the VESA BIOS of Qemu. However, other
|
||||
VESA BIOS implementations may need further access to the PCI device's
|
||||
configuration space. For example, for querying the size of a PCI resource,
|
||||
write access to base address registers is required. In such an event, the VESA
|
||||
driver will print a message about the missing virtualization feature:
|
||||
! writing data register not supported
|
||||
If you see such a message, we are very interested to see your log output such
|
||||
that we can enhance our PCI virtualization code as needed. Please contact us!
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
In the process of bringing Genode to the OKL4 kernel, we have generalized much
|
||||
of former platform-specific code:
|
||||
|
||||
* The initialization of C++ exception handling has now become part of the
|
||||
generic 'cxx' library in the 'base' repository. All platforms except
|
||||
Linux are using this generic library now.
|
||||
|
||||
* The 'server' library used to contain a platform-specific part that
|
||||
implemented the 'manage' function of a 'Server_entrypoint'. The
|
||||
generalized version of this library is now being used on all platforms
|
||||
other than Linux.
|
||||
|
||||
* We unified core-internal interfaces and their implementations such as
|
||||
'Dataspace_component', 'Cap_session_component', 'Rm_session_component',
|
||||
and 'Irq_session_component'. The result has become part of the 'base'
|
||||
repository.
|
||||
|
||||
* On OKL4, threads need to execute small startup code for querying their
|
||||
own thread IDs. Therefore, we have extended the 'Thread_base' interface
|
||||
with a platform-specific hook function called '_thread_bootstrap'.
|
||||
|
||||
* The types defined in 'base/native_types.h' had been complemented by a
|
||||
new 'Native_thread_id' type. This type is exclusively used by core and the
|
||||
framework libraries. For using the Genode API, this type is meaningless.
|
||||
|
||||
* For the 64bit support, we slightly refined the interfaces of some utility
|
||||
template functions in 'util/misc_math.h'. Furthermore, parts of the generic
|
||||
marshalling code of the IPC framework needed refinement, but no API changes
|
||||
were needed.
|
||||
|
||||
|
||||
Linux-specific changes
|
||||
######################
|
||||
|
||||
Adaptation to 64 bit
|
||||
====================
|
||||
|
||||
Because most Genode developers tend to work with the Linux version of Genode,
|
||||
supporting 64-bit Linux becomes increasingly important. With the current release,
|
||||
we start to officially support 64-bit Linux as base platform. This comes
|
||||
along with the following changes:
|
||||
|
||||
* We replaced the 'spec-x86.mk' file with new 'spec-x86_32.mk' and 'spec-x86_64.mk'
|
||||
files. The default version of 'base-linux/etc/specs.conf' automatically
|
||||
chooses the right spec file according to the output of 'uname -m'. Therefore,
|
||||
output of the build processes matches your host architecture. This behaviour
|
||||
can be changed by placing a customized 'spec.conf' file in your build directory's
|
||||
'etc/' subdirectory.
|
||||
|
||||
* We added type definitions for 64-bit-specific fixed-size integers in the form
|
||||
of a 64-bit-specific 'fixed_stdint.h' file.
|
||||
|
||||
* Because using 64 bit instead of 32 bit changes the payload size of RPC
|
||||
messages, we had to adjust several message buffers such as 'Ram_session_client'
|
||||
and 'Input::Session_client', and adapted the used stack sizes.
|
||||
|
||||
* Towards the goal of completely dissolving Genode's dependency on the Linux' glibc,
|
||||
we implemented custom system-call bindings. Apparently, Linux' syscall interface
|
||||
differs between 32 bit and 64 bit. For example, the 32-bit version handles
|
||||
all socket-related calls via a compound 'socketcall' whereas the 64-bit
|
||||
version uses distinct syscalls. Another difference is the handling of the
|
||||
'mmap' syscall and different behaviour of 'tkill'. The latter problem was
|
||||
resolved by replacing 'tkill' with 'tgkill' and setting the thread-group
|
||||
argument of the corresponding PID. Therefore, a 'Native_thread_id' on Linux
|
||||
now comprises both the TID and the PID.
|
||||
|
||||
* The 'Platform_env' on Linux contains a local implementation of the 'Rm_session'
|
||||
interface, which uses 'mmap' to attach dataspaces to the process' address
|
||||
space and maintains the region list in the form of a static array. This array
|
||||
was dimensioned to 256 entries, which constrained the maximum amount of
|
||||
usable memory when allocating a lot of small blocks via Genode's heap. Since
|
||||
the heap allocates backing store at the granularity of only 16KB, the worst
|
||||
case for reaching this limit was about 4MB. This was OK for our simple test
|
||||
applications. But for using Qt4, in particular on 64 bit, this has become a
|
||||
serious limitation. For now, we increased the region limit to 4096 and plan
|
||||
to replace the static array with a dynamically growing data structure.
|
||||
Furthermore, we made the heap granularity depend on the actual machine-word
|
||||
size. Therefore, the heap allocates its backing store in 32KB blocks when
|
||||
running on 64 bit.
|
||||
|
||||
|
||||
Debugging hooks
|
||||
===============
|
||||
|
||||
On Linux, we use gdb for debugging Genode. This is feasible as long as the
|
||||
targeted process is running. However, during low-level debugging, we had the
|
||||
recurring problem of a thread dying shortly after starting up. So we added a hook
|
||||
for halting a thread at the startup in order to be able to attach gdb to the
|
||||
thread before it dies. This simple hook lets the thread wait for a key press by
|
||||
directly calling the 'read' syscall. We also added a simple debug facility for
|
||||
printing debug messages bypassing Genode's LOG service by calling the 'write'
|
||||
syscall directly. Both hooks are now part of the Linux version of the 'env'
|
||||
library (see 'base-linux/src/base/env/debug.cc'). Note that these hooks are not
|
||||
part of the Genode API. There exists no header file.
|
||||
|
||||
1016
doc/release_notes/09-11.txt
Normal file
1016
doc/release_notes/09-11.txt
Normal file
File diff suppressed because it is too large
Load Diff
1224
doc/release_notes/10-02.txt
Normal file
1224
doc/release_notes/10-02.txt
Normal file
File diff suppressed because it is too large
Load Diff
1211
doc/release_notes/10-05.txt
Normal file
1211
doc/release_notes/10-05.txt
Normal file
File diff suppressed because it is too large
Load Diff
871
doc/release_notes/10-11.txt
Normal file
871
doc/release_notes/10-11.txt
Normal file
@@ -0,0 +1,871 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 10.11
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
During the past three months, the Genode project was primarily driven by our
|
||||
desire to create a bigger picture out of the rich set of components that we
|
||||
introduced over time, in particular over the last year. Looking back at the
|
||||
progress made since mid 2009, there were many functional additions to the
|
||||
framework, waiting to get combined. To name a few, we added support for
|
||||
networking, audio output, real-time priorities, mandatory access control,
|
||||
USB, ATAPI block devices, Python, hardware-accelerated 3D graphics, Qt4,
|
||||
the WebKit-based Arora browser, and the paravirtualized OKLinux kernel.
|
||||
So many wonderful toys waiting to get played with. This is how the idea of
|
||||
creating [https://genode.org/download/live-cds - the new Genode Live CD] was
|
||||
born. In the past, Genode was mostly used in settings with a relatively static
|
||||
configuration consisting of several components orchestrated to fulfill
|
||||
a few special-purpose functions. Now, the time has come for the next step,
|
||||
creating one dynamic setup that allows for the selection of different subsystems
|
||||
at runtime rather than at boot time.
|
||||
|
||||
This step is challenging in several ways. First, the processes that form
|
||||
the base system have to run during the entire time of all demo setups. If
|
||||
any of those processes contained stability problems or leaked memory, it would
|
||||
subvert the complete system. Second, the components of all subsystems combined
|
||||
are far too complex to be loaded into memory at boot time. This would not
|
||||
only take too long but would consume a lot of RAM. Instead, those components
|
||||
and their data had to be fetched from disk (CDROM) on demand. Third, because
|
||||
multiple demo subsystems can be active at a time, low-level resources such as
|
||||
networking and audio output must be multiplexed to prevent different
|
||||
subsystems from interfering with each other. Finally, we had to create a
|
||||
single boot and configuration concept that is able to align the needs of all
|
||||
demos, yet staying manageable.
|
||||
|
||||
Alongside these challenges, we came up with a lot of ideas about how Genode's
|
||||
components could be composed in new creative ways. Some of these ideas such
|
||||
as the browser-plugin concept and the http-based block server made it onto
|
||||
the Live CD. So for producing the Live CD, we not only faced the said
|
||||
technical challenges but also invested substantial development effort in new
|
||||
components, which contributed to our overall goal. Two weeks ago, we released
|
||||
the Live CD. This release-notes document is the story about how we got there.
|
||||
|
||||
To keep ourself focused on the mission described above, we deferred the
|
||||
original roadmap goal for this release, which was the creation of a Unix-like
|
||||
runtime environment to enable compiling Genode on Genode. This will be the
|
||||
primary goal for the next release.
|
||||
|
||||
|
||||
Execution environment for gPXE drivers
|
||||
######################################
|
||||
|
||||
Up to now, DDE Linux provided Genode with drivers for hardware devices
|
||||
ranging from USB HID to WLAN. In preparation of the live CD, we
|
||||
noticed the demand for support of a broader selection of ethernet
|
||||
devices. Intel's e1000 PCI and PCIe cards seemed to mark the bottom
|
||||
line of what we had to support. The major advantage of NIC drivers
|
||||
from Linux is their optimization for maximum performance. This emerges
|
||||
a major downside if DDE Linux comes into play: We have to provide all
|
||||
the nifty interfaces used by the driver in our emulation framework. To
|
||||
achieve our short-term goal of a great live CD experience, we had to
|
||||
walk a different path.
|
||||
|
||||
[https://gpxe.org/ - gPXE] is a lovely network boot loader / open-source
|
||||
PXE ROM project and the successor of the famous Etherboot
|
||||
implementation. Besides support for DNS, HTTP, iSCSI and AoE, gPXE
|
||||
includes dozens of NIC drivers and applies a plain driver framework.
|
||||
As we were also itching to evaluate DDE kit and the DDE approach at
|
||||
large with this special _donator OS_, we went for implementing the
|
||||
device-driver environment for gPXE (DDE gPXE).
|
||||
|
||||
The current version provides drivers for e1000, e1000e, and pcnet
|
||||
devices. The emulation framework comprises just about 600 lines of
|
||||
code compared to more than 22,000 LOC reused unmodified from gPXE.
|
||||
Benchmarks with the PCNet32 driver showed that DDE gPXE's performance
|
||||
is comparable to DDE Linux.
|
||||
|
||||
The gPXE driver environment comes in the form of the new 'dde_gpxe'
|
||||
repository. For building DDE gPXE, you first need to download and patch
|
||||
the original sources. The top-level makefile of this repository automates
|
||||
this task. Just issue:
|
||||
|
||||
! make prepare
|
||||
|
||||
Now, you need to include the DDE gPXE repository into your Genode
|
||||
build process. Just add the path to this directory to the
|
||||
'REPOSITORIES' declaration of the 'etc/build.conf' file within your
|
||||
build directory, for example
|
||||
|
||||
! REPOSITORIES += $(GENODE_DIR)/dde_gpxe
|
||||
|
||||
After successful build the DDE gPXE based ethernet driver is located
|
||||
at 'bin/gpxe_nic_drv'.
|
||||
|
||||
|
||||
On-demand paging
|
||||
################
|
||||
|
||||
In the [https://genode.org/documentation/release-notes/8.11#section-8 - release 8.11],
|
||||
we laid the foundation for implementing user-level dataspace managers.
|
||||
But so far, the facility remained largely unused except for managing thread
|
||||
contexts. This changed with this release.
|
||||
|
||||
So what is a user-level dataspace manager and who needs it? In short,
|
||||
Genode's memory management is based on dataspaces. A dataspace is a
|
||||
container for memory. Normally, it is created via core's RAM or ROM
|
||||
services. The RAM service hands out dataspaces containing contiguous
|
||||
physical memory. After allocating such a RAM dataspace, the creator can
|
||||
attach the dataspace to its own address space to access the dataspace
|
||||
content. In addition, it can pass a dataspace reference (called dataspace
|
||||
capability) to other processes, which, in turn, can than attach the same
|
||||
dataspace to their local address space, thereby establishing shared memory.
|
||||
Similarly, core's ROM service hands out boot-time binary data as dataspaces.
|
||||
|
||||
For the most use cases of Genode so far, these two core services were the
|
||||
only dataspace providers needed. However, there are use cases that require
|
||||
more sophisticated memory management. For example, to implement swapping,
|
||||
the content of a dataspace must be transferred to disk in a way that
|
||||
is transparent to the users of the dataspace. In monolithic kernels, such
|
||||
functionality is implemented in the kernel. But on a multi-server OS
|
||||
such as Genode, this is no option. Implementing such a feature into
|
||||
core would increase the trusted computing base of all applications
|
||||
including those who do not need swapping. Core would need a hard-disk
|
||||
driver, effectively subverting the Genode concept. Other examples for
|
||||
advanced memory-management facilities are copy-on-write memory and
|
||||
non-contiguous memory - complexity we wish to avoid at the root of the
|
||||
process tree. Instead of implementing such memory management facilities
|
||||
by itself, core provides a mechanism to let any process manage dataspaces.
|
||||
This technique is also called user-level page-fault handling.
|
||||
|
||||
For the Live CD, we decided to give Genode's user-level page-fault handling
|
||||
facility a go. The incentive was accessing files stored on CDROM in an
|
||||
elegant way. We wanted to make the CDROM access completely transparent to
|
||||
the applications. An application should be able to use a ROM session as
|
||||
if the file was stored at core's ROM service. But instead of being
|
||||
provided by core, the session request would be delegated to an
|
||||
alternative ROM service implementation that reads the data from disk
|
||||
as needed. Some of the files stored in the CDROM are large. For example,
|
||||
the disk image that we use for the Linux demo is 160MB. So reading
|
||||
this file at once and keeping it in memory is not an option. Instead, only
|
||||
those parts of the file should be read from disk, which are actually
|
||||
needed. To uphold the illusion of dealing with plain ROM files for
|
||||
the client, we need to employ on-demand-paging in the CDROM server.
|
||||
Here is how it works.
|
||||
|
||||
# The dataspace manager creates an empty managed dataspace. Core
|
||||
already provides a tool for managing address spaces called
|
||||
region manager (RM service). A RM session is an address space,
|
||||
to which dataspaces can be attached. This is exactly what is
|
||||
needed for a managed dataspace. So a dataspace manager uses the
|
||||
same core service to define the layout of a managed dataspace
|
||||
as is used to manage the address space of a process. In fact,
|
||||
any RM session can be converted into a managed dataspace.
|
||||
! enum { MANAGED_DS_SIZE = 64*1024*1024 };
|
||||
! Rm_connection rm(0, MANAGED_DS_SIZE);
|
||||
This code creates a RM session with the size of 64MB. This is an empty
|
||||
address space. A dataspace capability that corresponds to this address
|
||||
space can then be requested via
|
||||
! Dataspace_capability ds = rm.dataspace();
|
||||
|
||||
# The dataspace capability can be passed to a client, which may
|
||||
attach the dataspace to its local address space. Because the
|
||||
managed dataspace is not populated by any backing store, however,
|
||||
an access would trigger a page fault, halting the execution of
|
||||
the client. Here, the page-fault protocol comes into play.
|
||||
|
||||
# The dataspace manager registers itself for receiving a signal each time
|
||||
a fault occurs:
|
||||
! Signal_receiver rec;
|
||||
! Signal_context client;
|
||||
! Signal_context_capability sig_cap = rec.manage(client);
|
||||
! rm.fault_handler(sig_cap);
|
||||
When an empty part of the managed dataspace is accessed by any
|
||||
process, a signal is delivered. The dataspace manager can then
|
||||
retrieve the fault information (access type, fault address) and
|
||||
dispatch the page fault by attaching a real dataspace at the
|
||||
fault address of the managed dataspace. In a simple case, the code
|
||||
looks as follows:
|
||||
! while (true) {
|
||||
! Signal signal = rec.wait_for_signal();
|
||||
! for (int i = 0; i < signal.num(); i++) {
|
||||
! Rm_session::State state = rm.state();
|
||||
! ds = alloc_backing_store_dataspace(PAGE_SIZE);
|
||||
! rm.attach_at(ds, state.addr & PAGE_MASK);
|
||||
! }
|
||||
! }
|
||||
This simple page-fault handler would lazily allocate a page of
|
||||
backing store memory each time a fault occurs. When the backing
|
||||
store is attached to the managed dataspace, core will automatically
|
||||
wake up the faulted client.
|
||||
|
||||
# The example above has the problem that the dataspace manager has
|
||||
to pay for the backing store that is indirectly used by the client.
|
||||
To prevent the client from exhausting the dataspace manager's memory,
|
||||
the dataspace manager may choose to use a limited pool of backing
|
||||
store only. If this pool is exceeded, the dataspace manager can reuse
|
||||
an already used backing-store block by first revoking it from its
|
||||
current managed dataspace:
|
||||
! rm.detach(addr);
|
||||
This will flush all mappings referring to the specified address
|
||||
from all users of the managed dataspace. The next time, this
|
||||
address region is accessed, a new signal will be delivered.
|
||||
|
||||
This page-fault protocol has the following unique properties. First,
|
||||
because core is used as a broker between client and dataspace manager, the
|
||||
dataspace manager remains completely unaware of the identity of its client.
|
||||
It does not even need to possess the communication right to the client. In
|
||||
contrast, all other user-level page-fault protocols that we are aware of
|
||||
require direct communication between client and dataspace manager. Second,
|
||||
because dataspaces are used as first-level objects to resolve page faults,
|
||||
page faults can be handed at an arbitrary granularity (of course, a multiple
|
||||
of the physical page size). For example, a dataspace manager may decide to
|
||||
attach backing-store dataspaces of 64K to the managed dataspace. So the
|
||||
overhead produced by user-level page-fault handler can be traded for the
|
||||
page-fault granularity. But most importantly, the API is the same across
|
||||
all kernels that support user-level page fault handling. Thus the low-level
|
||||
page-fault handling code becomes inherently portable.
|
||||
|
||||
Having said that, we have completed the implementation of the described
|
||||
core mechanisms, in particular the 'detach' facility, for OKL4. The ISO9660
|
||||
driver as featured on the Live CD implements the 'ROM' interface and
|
||||
reads the contents of those files from CDROM on demand. It uses a
|
||||
fixed pool of backing store, operates at a page-fault granularity of
|
||||
64KB, and implements a simple fifo replacement strategy.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
There had been only a few changes to the base framework described as
|
||||
follows.
|
||||
|
||||
We unified the core-specific console implementation among all
|
||||
base platforms and added synchronization of 'vprintf' calls.
|
||||
The kernel-specific code resides now in the respective
|
||||
'base-<platform>/src/base/console/core_console.h' files.
|
||||
|
||||
We removed the argument-less constructor from 'Allocator_avl_tpl'.
|
||||
This constructor created an allocator that uses itself for
|
||||
meta-data allocation, which is the usual case when creating
|
||||
local memory allocators. However, on Genode, this code is typically
|
||||
used to build non-memory allocators such as address-space regions.
|
||||
For these use cases, the default policy is dangerous. Hence, we
|
||||
decided to remove the default policy.
|
||||
|
||||
The 'printf' helper macros have been unified and simplified. The
|
||||
available macros are 'PINF' for status information, 'PWRN' for warnings,
|
||||
'PLOG' for log messages, and 'PERR' for errors. By default, the message
|
||||
types are colored differently to make them easily distinguishable.
|
||||
In addition to normal messages, there is the 'PDBG' for debugging
|
||||
purposes. It remains to be the only macro that prints the function name
|
||||
as message prefix and is meant for temporary messages, to be removed
|
||||
before finalizing the code.
|
||||
|
||||
Genode's on-demand-paging mechanism relies on the signalling framework.
|
||||
Each managed dataspace is assigned to a distinct signal context.
|
||||
Hence, signal contexts need to be created and disposed alongside
|
||||
with managed dataspaces. We complemented the signalling framework
|
||||
with a 'dissolve' function to enable the destruction of signal
|
||||
contexts.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
Finished transition to new init concept
|
||||
=======================================
|
||||
|
||||
With the release 10.05, we introduced the
|
||||
[https://genode.org/documentation/release-notes/10.05#section-0 - current configuration concept of init].
|
||||
This concept supports mandatory access control and provides flexible
|
||||
ways for defining client-server relationships. Until now, we maintained
|
||||
the old init concept. With the current release, the transition to the
|
||||
new concept is finished and we removed the traditional init.
|
||||
We retained the support for loading configurations for individual subsystems
|
||||
from different files but adopted the syntax to the use of attributes.
|
||||
Instead of
|
||||
! <configfile>subsystem.config</configfile>
|
||||
the new syntax is
|
||||
! <configfile name="subsystem.config"/>
|
||||
|
||||
|
||||
Virtual network bridge (Proxy ARP)
|
||||
==================================
|
||||
|
||||
Since we originally added networking support to Genode, only one program could
|
||||
use the networking facilities at a time. In the simplest form, such a program
|
||||
included the network driver, protocol stack, and the actual application. For
|
||||
example, the uIP stack featured with release 9.02 followed this approach.
|
||||
In release 9.11 we added the 'Nic_session' interface to decouple the network
|
||||
driver from the TCP/IP protocol stack. But the 1-to-1 relation between
|
||||
application and network interface remained. With the current release, we
|
||||
introduce the 'nic_bridge' server, which is able to multiplex the 'Nic_session'
|
||||
interface.
|
||||
|
||||
The implementation is roughly based on the proxy ARP RFC 1027. At startup, the
|
||||
'nic_bridge' creates a 'Nic_session' to the real network driver and, in turn,
|
||||
announces a 'Nic' service at its parent. But in contrast to a network driver
|
||||
implementing this interface, 'nic_bridge' supports an arbitrary number of
|
||||
'Nic_sessions' to be opened. From the client's perspective, such a session
|
||||
looks like a real network adaptor.
|
||||
|
||||
This way, it has become possible to run multiple TCP/IP stacks in
|
||||
parallel, each obtaining a distinct IP address via DHCP. For example,
|
||||
is has become possible to run multiple paravirtualized Linux kernels
|
||||
alongside an lwIP-based web browser, each accessing the network via a
|
||||
distinct IP address.
|
||||
|
||||
As a side effect for developing the 'nic_bridge', we created a set
|
||||
of utilities for implementing network protocols. The utilities are
|
||||
located at 'os/include/net' and comprise protocol definitions for
|
||||
ethernet, IPv4, UDP, ARP, and DHCP.
|
||||
|
||||
|
||||
Nitpicker GUI server
|
||||
====================
|
||||
|
||||
Our work on the Live CD motivated several improvements of the Nitpicker
|
||||
GUI server.
|
||||
|
||||
|
||||
Alpha blending
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
In addition to nitpicker's plain pixel buffer interface that is compatible
|
||||
with a normal framebuffer session, each nitpicker session can now have
|
||||
an optional alpha channel as well as an corresponding input-mask channel
|
||||
associated. Both the alpha channel and the input mask are contained in the
|
||||
same dataspace as the pixel buffer. The pixel buffer is followed by
|
||||
the 8-bit alpha values, which are then followed by the input-mask values.
|
||||
This way, the presence of an alpha channel does not interfere with the
|
||||
actual pixel format. Each 8-bit input mask value specifies the user-input
|
||||
policy for the respective pixel. If the value is zero, user input
|
||||
referring to the pixel is not handled by the client but "falls through"
|
||||
the view that is visible in the background of the pixel. This is typically
|
||||
the case for drop shadows. If the input-mask value is '1', the input
|
||||
is handled by the client.
|
||||
|
||||
With the input-mask mechanism in place, we no longer have a definitive
|
||||
assignment of each pixel to a single client anymore. In principle, an
|
||||
invisible client is able to track mouse movements by creating a full-screen
|
||||
view with all alpha values set to '0' and all input-mask values set to '1'.
|
||||
Once, the user clicks on this invisible view, the user input gets routed
|
||||
to the invisible client instead of the actually visible view. This
|
||||
security risk can be addressed at two levels:
|
||||
* In X-Ray mode, nitpicker completely disables alpha blending
|
||||
and the input-mask mechanism such that the user can identify the
|
||||
client that is responsible for each pixel on screen.
|
||||
* The use of the alpha channel is a session argument, which is specified
|
||||
by nitpicker clients at session-creation time. Consequently, this
|
||||
session argument is subjected to the policy of all processes involved
|
||||
with routing the session request to nitpicker. Such a policy may permit
|
||||
the use of an alpha channel only for trusted applications.
|
||||
|
||||
_Caution:_ The use of alpha channels implies read operations from
|
||||
the frame buffer. On typical PC graphics hardware, such operations are
|
||||
extremely slow. For this reason, the VESA driver should operate in
|
||||
buffered mode when using alpha blending in Nitpicker.
|
||||
|
||||
|
||||
Tinted views in X-Ray mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We added support for tinting individual clients or groups of clients
|
||||
with different colors based on their label as reported at session-creation
|
||||
time. By using session colors, nitpicker assists the user to tell apart
|
||||
different security domains without reading textual information. In
|
||||
addition to the tinting effect, the title bar presents the session
|
||||
color of the currently focused session.
|
||||
|
||||
The following nitpicker configuration tints all views of the launchpad
|
||||
subsystem in blue except for those views that belong to the testnit
|
||||
child of launchpad. Those are tinted red.
|
||||
! <config>
|
||||
! <policy label="launchpad" color="#0000ff"/>
|
||||
! <policy label="launchpad -> testnit" color="#ff0000"/>
|
||||
! </config>
|
||||
|
||||
|
||||
Misc Nitpicker changes
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We introduced a so-called 'stay-top' session argument, which declares
|
||||
that views created via this session should stay on top of other views.
|
||||
This function is useful for menus that should always remain accessible
|
||||
or banner images as used for Live CD.
|
||||
|
||||
Nitpicker's reserved region at the top of the screen used to cover up
|
||||
the screen area as seen by the clients. We have now excluded this area
|
||||
from the coordinate system of the clients.
|
||||
|
||||
We implemented the 'kill' mode that can be activated by the 'kill' key.
|
||||
(typically this is the 'Print Screen' key) This feature allows the user
|
||||
to select a client to be removed from the GUI. The client is not
|
||||
actually killed but only locked out. The 'kill' mode is meant as an
|
||||
emergency brake if an application behaves in ways not wanted by the
|
||||
user.
|
||||
|
||||
|
||||
ISO9660 server
|
||||
==============
|
||||
|
||||
As outlined in Section [On-demand paging], we revisited the ISO9660 server
|
||||
to implement on-demand-paged dataspaces. It is the first real-world
|
||||
use case for Genode's user-level page-fault protocol. The memory pool
|
||||
to be used as backing store for managed dataspaces is dimensioned according
|
||||
to the RAM assigned to the iso9660 server. The server divides this backing
|
||||
store into blocks of 64KB and assigns those blocks to the managed dataspaces
|
||||
in a fifo fashion. We found that using a granularity of 64KB improved the
|
||||
performance over smaller block sizes because this way, we profit from reading
|
||||
data ahead for each block request. This is particularly beneficial for
|
||||
CDROM drives because of their extremely long seek times.
|
||||
|
||||
|
||||
Audio mixer
|
||||
===========
|
||||
|
||||
We added a new *channel synchronization* facility to the 'Audio_out_session'
|
||||
interface. An 'Audio_out_session' refers to a single channel. For stereo
|
||||
playback, two sessions must be created. At session-creation time, the
|
||||
client can provide a hint about the channel type such as "front-left" as
|
||||
session-construction argument. This design principally allows for supporting
|
||||
setups with an arbitrary amount of channels. However, those channels must
|
||||
be synchronized. For this reason, we introduced the 'sync_session' function
|
||||
to the 'Audio_out_session' interface. It takes the session capability of
|
||||
another 'Audio_out_session' as argument. The specified session is then
|
||||
used as synchronization reference.
|
||||
|
||||
To reduce the latency when stopping audio replay, we introduced a new *flush*
|
||||
function to the 'Audio_out_session' interface. By calling this function,
|
||||
a client can express that it is willing to discard all audio data already
|
||||
submitted to the mixer.
|
||||
|
||||
Furthermore, we improved the audio mixer to support both long-running
|
||||
streams of audio and sporadic sounds. For the latter use case, low latency
|
||||
is particularly critical. In this regard, the current implementation is a
|
||||
vast improvement over the initial version. However, orchestrating the
|
||||
mixer with audio drivers as well as with different clients (in particular
|
||||
ALSA programs running on a paravirtualized Linux) is not trivial. In the
|
||||
process, we learned a lot, which will eventually prompt us to further
|
||||
optimize the current solution.
|
||||
|
||||
|
||||
Nitpicker-based virtual Framebuffer
|
||||
===================================
|
||||
|
||||
To support the browser-plugin demo, we introduced 'nit_fb', which is a
|
||||
framebuffer service that uses the nitpicker GUI server as back end. It
|
||||
is similar to the liquid framebuffer as featured in the 'demo' repository
|
||||
but in contrast to liquid framebuffer, 'nit_fb' is non-interactive.
|
||||
It has a fixed screen position and size. Furthermore, it does not
|
||||
virtualize the framebuffer but passes through the framebuffer portion of
|
||||
the nitpicker session, yielding better performance and lower latency.
|
||||
|
||||
If instantiated multiple times, 'nit_fb' can be used to statically arrange
|
||||
multiple virtual frame buffers on one physical screen. The size and screen
|
||||
position of each 'nit_fb' instance can be defined via Genode's configuration
|
||||
mechanism using the following attributes of the 'nit_fb' config node:
|
||||
! <config xpos="100" ypos="150"
|
||||
! width="300" height="200"
|
||||
! refresh_rate="25"/>
|
||||
If 'refresh_rate' isn't set, the server will not trigger any refresh
|
||||
operations by itself.
|
||||
|
||||
On the Live CD, each browser plugin instantiates a separate instance of
|
||||
'nit_fb' to present the plugin's content on screen. In this case, the
|
||||
view position is not fixed because the view is further virtualized by the
|
||||
loader, which imposes its policy onto 'nit_fb' - Genode's nested
|
||||
policies at work!
|
||||
|
||||
|
||||
TAR ROM service
|
||||
===============
|
||||
|
||||
For large setups, listing individual files as boot modules in single-image
|
||||
creation tools (e.g., elfweaver) or multiboot boot loaders can be
|
||||
cumbersome, especially when many data files or shared libraries are
|
||||
involved. To facilitate the grouping of files, 'tar_rom' is an
|
||||
implementation of the 'ROM' interface that operates on a 'tar' file.
|
||||
|
||||
The name of the TAR archive must be specified via the 'name' attribute of
|
||||
an 'archive' tag, for example:
|
||||
|
||||
! <config>
|
||||
! <archive name="archive.tar"/>
|
||||
! </config>
|
||||
|
||||
The backing store for the dataspaces exported via ROM sessions is accounted
|
||||
on the 'rom_tar' service (not on its clients) to make the use of 'rom_tar'
|
||||
transparent to the regular users of core's ROM service. Hence, this service
|
||||
must not be used by multiple clients that do not trust each other.
|
||||
Typically, 'tar_rom' is instantiated per client.
|
||||
|
||||
The Live CD uses the 'tar_rom' service for the browser demo. Each plugin
|
||||
is fetched from the web as a tar file containing the config file of the
|
||||
plugin subsystem as well as supplemental binary files that are provided
|
||||
to the plugin subsystem as ROM files. This way, a plugin can carry along
|
||||
multiple components and data that form a complete Genode subsystem.
|
||||
|
||||
|
||||
DDE Kit
|
||||
=======
|
||||
|
||||
The DDE kit underwent slight modifications since the previous release.
|
||||
It now provides 64-bit integer types and a revised virtual PCI bus
|
||||
implementation.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
PCI bus
|
||||
=======
|
||||
|
||||
Genode was tested on several hardware platforms in preparation of the
|
||||
current release. This revealed some deficiencies with the PCI bus
|
||||
driver implementation. The revised driver now efficiently supports
|
||||
platforms with many PCI busses (as PCIe demands) and correctly handles
|
||||
multi-function devices.
|
||||
|
||||
|
||||
VESA framebuffer
|
||||
================
|
||||
|
||||
We updated the configuration syntax of the VESA driver to better match
|
||||
the style of new init syntax, preferring the use of attributes rather than
|
||||
XML sub nodes. Please refer to the updated documentation at
|
||||
'os/src/drivers/framebuffer/vesa/README'.
|
||||
|
||||
:Buffered output:
|
||||
|
||||
To accommodate framebuffer clients that need to read from the frame buffer,
|
||||
in particular the nitpicker GUI server operating with alpha channels, we
|
||||
introduced a buffered mode to the VESA driver. If enabled, the VESA driver
|
||||
will hand out a plain memory dataspace to the client rather than the
|
||||
physical framebuffer. Each time, the client issues as 'refresh' operation
|
||||
on the framebuffer-session interface, the VESA driver copies the corresponding
|
||||
screen region from the client-side virtual framebuffer to the physical
|
||||
framebuffer. Note that the VESA driver will require additional RAM quota
|
||||
to allocate the client buffer. If the quota is insufficient, the driver will
|
||||
fall back to non-buffered output.
|
||||
|
||||
:Preinitialized video modes:
|
||||
|
||||
As an alternative to letting the VESA driver set up a screen mode, the
|
||||
driver has become able to reuse an already initialized mode, which is useful
|
||||
if the VESA mode is already initialized by the boot loader. If the screen
|
||||
is initialized that way, the 'preinit' attribute of the 'config' node can
|
||||
be set to '"yes"' to prevent the driver from changing the mode. This way,
|
||||
the driver will just query the current mode and make the already
|
||||
initialized framebuffer available to its client.
|
||||
|
||||
|
||||
Audio
|
||||
=====
|
||||
|
||||
We observed certain hardware platforms (in particular VirtualBox) to
|
||||
behave strangely after ALSA buffer-underrun conditions. It seems that the
|
||||
VirtualBox audio driver plays actually more frames than requested by
|
||||
ALSA's 'writei' function, resulting in recurring replay of data that
|
||||
was in the buffer at underrun time. As a work-around for this problem,
|
||||
we zero-out the sound-hardware buffer in the condition of an ALSA buffer
|
||||
underrun. This way, the recurring replay is still there, but it is
|
||||
replaying silence.
|
||||
|
||||
To improve the support for sporadic audio output, we added a check for the PCM
|
||||
state for buffer underruns prior issuing the actual playback. In the event of
|
||||
an underrun, we re-prepare the sound card before starting the playback.
|
||||
|
||||
Furthermore, we implemented the new flush and channel-synchronization
|
||||
abilities of the 'Audio_out_session' interface for the DDE Linux driver.
|
||||
|
||||
|
||||
Paravirtualized Linux
|
||||
#####################
|
||||
|
||||
To support the demo scenarios that showcase the paravirtualized Linux kernel,
|
||||
we enhanced our custom stub drivers of the OKLinux kernel. Thereby, we have
|
||||
reached a high level of integration of OKLinux with native Genode services,
|
||||
including audio output, block devices, framebuffer output, seamless integration
|
||||
with the Nitpicker GUI, and networking. All stub drivers are compiled in by
|
||||
default and are ready to use by specifying a device configuration in the config
|
||||
node for the Linux kernel. This way, one Linux kernel image can be easily used
|
||||
in different scenarios.
|
||||
|
||||
:Integration with the Nitpicker GUI:
|
||||
|
||||
We enhanced our fbdev stub driver with a mechanism to merge view reposition
|
||||
events. If a X11 window is moved, a lot of subsequent events of this type are
|
||||
generated. Using the new optimization, only the most recent state gets
|
||||
reported to Nitpicker, making the X11 GUI more responsive.
|
||||
|
||||
:UnionFS:
|
||||
|
||||
As we noticed that unionfs is required by all our Linux scenarios, we decided
|
||||
to include and enable the patch by default.
|
||||
|
||||
:Network support:
|
||||
|
||||
With the introduction of the 'nic_bridge', multiple networking stacks can run
|
||||
on Genode at the same time, which paves the way for new use cases. We have now
|
||||
added a stub driver using Genode's 'Nic_session' interface to make the new
|
||||
facility available to Linux.
|
||||
|
||||
:Audio output:
|
||||
|
||||
We adapted the ALSA stub driver to the changes of the 'Audio_out_session'
|
||||
interface, using the new channel synchronization and flush functions.
|
||||
Thereby, we optimized the stub driver to keep latency and seek times of
|
||||
Linux userland applications reasonably low.
|
||||
|
||||
:Removed ROM file driver:
|
||||
|
||||
With the addition of the 'Block_session' stub driver, the original ROM file
|
||||
driver is no longer required. So we removed the stub. For using ROM files as
|
||||
disk images for Linux, there is the 'rom_loopdev' server, which provides a
|
||||
block session that operates on a ROM file.
|
||||
|
||||
:Asynchronous block interface:
|
||||
|
||||
To improve performance, we changed the block stub driver to facilitate the
|
||||
asynchronous mode of operation as provided by the 'Block_session' interface.
|
||||
This way, multiple block requests can be issued at once, thereby shadowing
|
||||
the round trip times for individual requests.
|
||||
|
||||
|
||||
Protocol stacks and libraries
|
||||
#############################
|
||||
|
||||
Gallium3D / Intel GEM
|
||||
=====================
|
||||
|
||||
We improved the cache handling of our DRM emulation code (implementing
|
||||
'drm_clflush_pages') and our EGL driver, thereby fixing caching
|
||||
artifacts on i945 GPUs. Furthermore, we added a temporary work-around
|
||||
for the currently dysfunctional sequence-number tracking with i945 GPUs.
|
||||
On this chipset, issuing the 'MI_STORE_DWORD_INDEX' GPU command used
|
||||
for tracking sequence numbers apparently halts the processing the command
|
||||
stream. This condition is normally handled by an interrupt. However,
|
||||
we have not enabled interrupts yet.
|
||||
|
||||
To prepare the future support for more Gallium drivers than i915, we
|
||||
implemented a driver-selection facility in the EGL driver. The code
|
||||
scans the PCI bus for a supported GPU and returns the name of the
|
||||
corresponding driver library. If no driver library could be found,
|
||||
the EGL driver falls back to softpipe rendering.
|
||||
|
||||
|
||||
lwIP
|
||||
====
|
||||
|
||||
We revised our port of the lwIP TCP/IP stack, and thereby improved its
|
||||
stability and performance.
|
||||
|
||||
* The lwIP library is now built as shared object, following the convention
|
||||
for libraries contained in the 'libports' repository.
|
||||
* By default (when using the 'libc_lwip_nic_dhcp' library), lwIP will
|
||||
issue a DHCP request at startup. If this request times out, the loopback
|
||||
device is set as default.
|
||||
* If there is no 'Nic' service available, the lwIP stack will fall back to
|
||||
the loopback device.
|
||||
* We increased the default number of PCBs in lwIP to 64.
|
||||
* We removed a corner case of the timed semaphore that could occur
|
||||
when a timeout was triggered at the same time ,'up' was called.
|
||||
In this case, the semaphore was unblocked but the timeout condition
|
||||
was not reflected at the caller of 'down'. However, the lwIP code
|
||||
relies on detecting those timeouts.
|
||||
|
||||
|
||||
Qt4
|
||||
====
|
||||
|
||||
We implemented a custom *nitpicker plugin widget*, which allows for the
|
||||
seamless integration of arbitrary nitpicker clients into a Qt4 application.
|
||||
The primary use case is the browser plugin mechanism presented at
|
||||
the Live CD. In principle, the 'QNitpickerViewWidget' allows for creating
|
||||
mash-up allocations consisting of multiple native Genode programs. As shown
|
||||
by the browser plugin demo, a Qt4 application can even integrate other
|
||||
programs that run isolated from the Qt4 application, and thereby depend on
|
||||
on a significantly less complex trusted computing base than the Qt4
|
||||
application itself.
|
||||
|
||||
[image nitpicker_plugin]
|
||||
|
||||
The image above illustrates the use of the 'QNitpickerViewWidget' in the
|
||||
scenario presented on the Live CD. The browser obtains the Nitpicker view to be
|
||||
embedded into the website from the loader service, which virtualizes the
|
||||
Nitpicker session interface for the loaded plugin subsystem. The browser then
|
||||
tells the loader about where to present the plugin view on screen. But it has
|
||||
neither control over the plugin's execution nor can it observe any user
|
||||
interaction with the plugin.
|
||||
|
||||
|
||||
New Gems repository with HTTP-based block server
|
||||
################################################
|
||||
|
||||
To give the web-browser demo of our Live CD a special twist, and to show off
|
||||
the possibilities of a real multi-server OS, we decided to implement the
|
||||
somewhat crazy idea of letting a Linux OS run on a disk image fetched at
|
||||
runtime from a web server. This way, the Linux OS would start right away and
|
||||
disk blocks would be streamed over the network as needed. Implementing this
|
||||
idea was especially attractive because such a feature would be extremely hard
|
||||
to implement on a classical OS but is a breeze to realize on Genode where all
|
||||
device drivers and protocol stacks are running as distinct user-level
|
||||
components. The following figure illustrates the idea:
|
||||
|
||||
[image http_block]
|
||||
|
||||
The block stub driver of the Linux kernel gets connected to a special block
|
||||
driver called 'http_block', which does not access a real block device but
|
||||
rather uses TCP/IP and HTTP to fetch disk blocks from a web server.
|
||||
|
||||
Because the 'http_block' server is both user of high-level functionality (the
|
||||
lwIP stack) and provider of a low-level interface ('Block_session'), the
|
||||
program does not fit well into one of the existing source-code repositories.
|
||||
The 'os' repository, which is normally hosting servers for low-level interfaces
|
||||
is the wrong place for 'http_block' because this program would make the 'os'
|
||||
repository depend on the higher-level 'libports' repository where the 'lwip'
|
||||
stack is located. On the other hand, placing 'http_block' into the 'libports'
|
||||
repository is also wrong because the program is not a ported library. It merely
|
||||
uses libraries provided by 'libports'. In the future, we expect that native
|
||||
Genode components that use both low-level and high-level repositories will
|
||||
become rather the norm than an exception. Therefore, we introduced a new
|
||||
repository called 'gems' for hosting such programs.
|
||||
|
||||
|
||||
Tools
|
||||
#####
|
||||
|
||||
Automated coding-style checker
|
||||
==============================
|
||||
|
||||
As Genode's code base grows and new developers start to get involved,
|
||||
we noticed recurring questions regarding coding style. There is a
|
||||
[https://genode.org/documentation/developer-resources/coding_style - document]
|
||||
describing our coding style but for people just starting to get involved,
|
||||
adhering all the rules can become tedious. However, we stress the importance
|
||||
of a consistent coding style for the project. Not only does a consistent style
|
||||
make the framework more approachable for users, but it also eases the work
|
||||
of all regular developers, who can feel right at home at any part of
|
||||
the code.
|
||||
|
||||
To avoid wasting precious developer time with coding-style fixes, we
|
||||
have created a tool for the automated checking and (if possible) fixing
|
||||
the adherence of source code to Genode's coding style. The tool is
|
||||
located at 'tool/beautify'. It takes a source file as argument and
|
||||
reports coding-style violations. The checks are fairly elaborative:
|
||||
* Placement of braces and parenthesis
|
||||
* Indentation and alignment, trailing spaces
|
||||
* Vertical spacing (e.g., between member functions, above comments)
|
||||
* Naming of member variables and functions (e.g., private members start with '_')
|
||||
* Use of upper and lower case
|
||||
* Presence of a file header with the mandatory fields
|
||||
* Policy for function-header comments (comment at declaration, not
|
||||
at implementation)
|
||||
* Style of single-line comments, function-header comments, multi-line comments
|
||||
|
||||
The user of 'beautify' may opt to let the tool fix most of the violations
|
||||
automatically by specifying the command line arguments '-fix' and '-write'.
|
||||
With only the '-fix' argument, the tool will output the fixed version of
|
||||
the code via stdout. By specifying the '-write' argument, the changes will
|
||||
be written back to the original file. In any case, we strongly recommend
|
||||
to manually inspect all changes made by the tool.
|
||||
|
||||
Under the hood, the tool consists of two parts. A custom C++ parser called
|
||||
'parse_cxx' reads the source code and converts it to a syntax tree. In the
|
||||
syntax tree, all formating information such as whitespaces are preserved.
|
||||
The C++ parser is a separate command-line tool, which we also use for
|
||||
other purposes (e.g., generating the API documentation at the website).
|
||||
The actual 'beautify' tool calls 'parse_cxx', and applies its checks and
|
||||
fixes to the output of 'parse_cxx'. For this reason, both tools have to
|
||||
reside in the same directory.
|
||||
|
||||
|
||||
Platform-specific changes
|
||||
#########################
|
||||
|
||||
OKL4
|
||||
====
|
||||
|
||||
:Added support for shared interrupts:
|
||||
|
||||
The Genode Live CD operates on a large number of devices that trigger
|
||||
interrupts (USB, keyboard, mouse, ATAPI, timer, network). On most
|
||||
platforms, the chances are extremely high that some of them use
|
||||
the same IRQ line. Therefore, we enhanced core's IRQ service to
|
||||
allow multiple clients to request the same IRQ. If the interrupt occurs,
|
||||
all clients referring to this interrupt are notified. The interrupt
|
||||
gets cleared after all of those clients responded. Even though, we regard
|
||||
PIC interrupts as a legacy, the support of shared interrupts enables
|
||||
us to use OKL4 with such complex usage scenarios.
|
||||
|
||||
:Revised page-fault handling:
|
||||
|
||||
If a page fault occurs, the OKL4 kernel delivers a message to the page-fault
|
||||
handler. The message contains the page-fault address and type as well as the
|
||||
space ID where the fault happened. However, the identity of the faulting
|
||||
thread is not delivered. Instead, the sender ID of the page fault message
|
||||
contains the KTCB index of the faulting thread, which is only meaningful
|
||||
within the kernel. This KTCB index is used as a reply token for answering the
|
||||
page fault message. We wondered about why OKL4 choose to deliver the KTCB
|
||||
index rather then the global thread ID as done for plain IPC messages. The
|
||||
only reasonable answer is that by using the KTCB index directly in OKL4's
|
||||
page-fault protocol, one lookup from the userland-defined thread ID to the
|
||||
KTCB index can be avoided. However, this comes at the cost of losing the
|
||||
identity of the faulting thread. We used to take the space ID as a key for
|
||||
the fault context within core. However, with Genode's user-level page-fault
|
||||
mechanism, this simplification does not suffice anymore. We have to know the
|
||||
faulting thread as a page fault may not be answered immediately but at a
|
||||
later time. During that time, the page-fault state has to be stored at core's
|
||||
representation of the faulting thread. Our solution is reverting OKL4's
|
||||
page-fault protocol to operate with global thread IDs only and to never make
|
||||
kernel-internal KTCB indices visible at the user land. You can find the patch
|
||||
for the OKL4 kernel at 'base-okl4/patches/reply_tid.patch'.
|
||||
|
||||
:Reboot via kernel debugger:
|
||||
|
||||
We fixed the reboot code of OKL4's kernel debugger to improve our work
|
||||
flow. The patch can be found at 'base-okl4/patches/kdb_reboot.patch'.
|
||||
|
||||
:Relieved conflict with libc 'limits.h':
|
||||
|
||||
For some reason, the OKL4 kernel bindings provide definitions
|
||||
normally found in libc headers. This circumstance ultimately leads
|
||||
to trouble when combining OKL4 with a real C runtime. We have
|
||||
relieved the problem with the patch 'base-okl4/patches/char_bit.patch'.
|
||||
|
||||
:Exception handling:
|
||||
|
||||
We added a diagnostic message to core that reports about exceptions
|
||||
such as division by zero.
|
||||
|
||||
|
||||
Pistachio
|
||||
=========
|
||||
|
||||
Our revised syscall bindings for supporting position-independent code
|
||||
on L4ka::Pistachio have been integrated into the mainline development
|
||||
of the kernel. Therefore, the patch is not needed anymore when using
|
||||
a kernel revision newer than 'r791:0d25c1f65a3a'.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
On Linux, we let the kernel manage all virtual address spaces for us,
|
||||
except for the thread-context area. Because the kernel does not know
|
||||
about the special meaning of the thread-context area, it may choose to
|
||||
use this part of the virtual address space as target for 'mmap'. This
|
||||
may lead to memory corruption. Fortunately, there is a way to tell the
|
||||
kernel about virtual address regions that should be reserved. The
|
||||
trick is to pre-populate the said region with anonymous memory using
|
||||
the 'mmap' arguments 'MAP_PRIVATE', 'MAP_FIXED', 'MAP_ANONYMOUS', and
|
||||
'PROT_NONE'. The kernel will still accept a fixed-address mapping
|
||||
within such a reserved region (overmap) but won't consider using the
|
||||
region by itself. The reservation must be done at the startup of each
|
||||
process and each time when detaching a dataspace from the thread
|
||||
context area. For the process startup, we use the hook function
|
||||
'main_thread_bootstrap' in 'src/platform/_main_helper.h'. For reverting
|
||||
detached dataspaces to a reserved region within the context area, we
|
||||
added as special case to 'src/base/env/rm_session_mmap.cc'.
|
||||
For hybrid programs (Genode processes that link against native
|
||||
shared libraries of the Linux system), which are loaded by the dynamic
|
||||
linker of Linux, we must further prevent the dynamic linker from
|
||||
populating the thread-context area. This is achieved by adding a
|
||||
special program segment at the linking stage of all elf binaries.
|
||||
|
||||
876
doc/release_notes/11-02.txt
Normal file
876
doc/release_notes/11-02.txt
Normal file
@@ -0,0 +1,876 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 11.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
One year ago, the release 10.02 was our break-through with regard to the support
|
||||
of multiple kernels as base platform for Genode. With the added support for
|
||||
the NOVA hypervisor and the Codezero kernel, Genode applications could be executed
|
||||
on 6 different kernels. With the current release, we take our commitment to
|
||||
kernel platform support even further. With the added support for the Fiasco.OC
|
||||
kernel, we make Genode available on one of the most feature-rich modern microkernels.
|
||||
Additionally, we entered the realms of kernel design with our new platform support
|
||||
for the Xilinx MicroBlaze architecture. This platform support comes in the shape
|
||||
of a custom kernel specifically targeted to the MicroBlaze CPU architecture.
|
||||
Furthermore, we updated our support for the NOVA Hypervisor to the bleeding-edge
|
||||
version 0.3, which has been released earlier this month.
|
||||
|
||||
With the current support for 8 different kernel platforms (L4/Fiasco, Linux,
|
||||
L4ka::Pistachio, OKL4, NOVA, Codezero, Fiasco.OC, and native MicroBlaze), testing
|
||||
and integrating application scenarios across all platforms becomes increasingly
|
||||
challenging. Therefore, we introduce a new framework for automating such tasks.
|
||||
Thanks to the tight integration of the automation tool with Genode's build system,
|
||||
going back and forth between different kernels becomes an almost seamless
|
||||
experience.
|
||||
|
||||
Functionality-wise, the release carries on our vision to create a highly secure
|
||||
yet easy to use general-purpose operating system. Because the Genode framework
|
||||
is developed on Linux using the wonderful GNU tools, we consider the
|
||||
availability of the GNU user land on Genode as crucial for using the system by
|
||||
ourself. This motivation drives the creation of a custom execution environment
|
||||
for GNU software on top of Genode. With the current release, we are proud to
|
||||
present the first pieces of this execution environment. Even though not fully
|
||||
functional yet, it clearly shows the direction of where we are heading.
|
||||
|
||||
|
||||
Support for Fiasco.OC
|
||||
#####################
|
||||
|
||||
The OC in the name of the Fiasco.OC kernel stands for "object capability", hinting
|
||||
at the most significant feature that sets current-generation microkernels such as
|
||||
NOVA, seL4, and Fiasco.OC apart from their predecessors. Whereas previous L4 kernels
|
||||
succeeded in protecting subsystems from each other, the new generation of kernels
|
||||
is geared towards strict security policies. Traditionally, two protection domains
|
||||
were able to communicate with each other if they both agreed. Communication partners
|
||||
were typically globally known via their respective thread/task IDs. Obviously, this
|
||||
policy is not able to guarantee the separation of subsystems. If two subsystems
|
||||
conspire, they could always share information. Object-capability-based kernels
|
||||
are taking the separation much further by prohibiting any communication between
|
||||
protection domains by default. Two protection domains can communicate only if
|
||||
a common acquaintance of both agrees. This default-deny policy facilitates the
|
||||
creation of least-privilege security policies. From the ground up, Genode has
|
||||
been designed as a capability-based system which is naturally capable of leveraging
|
||||
kernel-based object-capability support if present. After NOVA, Fiasc.OC is the
|
||||
second of Genode's base platforms that provides this feature.
|
||||
|
||||
Apart from being a capability-based kernel, Fiasco.OC has a number of compelling
|
||||
features such as thorough support for ARM platforms and the x86 32/64 bit
|
||||
architectures. It supports SMP, hardware virtualization, and provides special
|
||||
optimizations for running paravirtualized operating systems.
|
||||
|
||||
Technically, Fiasco.OC is the successor of the L4/Fiasco kernel developed by
|
||||
the OS group of the TU-Dresden. However, the kernel interface of Fiasco.OC has
|
||||
not much in common with L4/Fiasco. Some heritages are still there (e.g., IPC
|
||||
timeouts) but the kernel API has evolved to a fully object-oriented model.
|
||||
|
||||
:Thanks:
|
||||
|
||||
We are indebted to the main developer of Fiasco.OC Alexander Warg for being
|
||||
very reponsive to our inquiries while doing the porting work. Thanks to his
|
||||
support, the adaptation of Genode to this kernel has been an almost smooth
|
||||
ride.
|
||||
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
You need GNU C & C++ Compilers, GNU Binutils, GNU Make, and Perl to use the
|
||||
Fiasco.OC build system. On Debian/Ubuntu systems, you have to install the
|
||||
following packages:
|
||||
|
||||
! apt-get install make gawk g++ binutils pkg-config subversion
|
||||
|
||||
Moreover, you need to download and install the tool-chain used by Genode. Have
|
||||
a look at this page:
|
||||
|
||||
:[https://genode.org/download/tool-chain]:
|
||||
Genode tool-chain
|
||||
|
||||
|
||||
Downloading and building Fiasco.OC
|
||||
==================================
|
||||
|
||||
Checkout the Fiasco.OC sources and tool-chain to an appropriated directory:
|
||||
|
||||
! export REPOMGR_SVN_REV=27
|
||||
! svn cat https://svn.tudos.org/repos/oc/tudos/trunk/repomgr |\
|
||||
! perl - init https://svn.tudos.org/repos/oc/tudos fiasco l4re
|
||||
|
||||
|
||||
Building the kernel
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Create the build directory for the kernel:
|
||||
|
||||
! cd <path_to_fiasco_src_dir>/src/kernel/fiasco
|
||||
! make BUILDDIR=<path_to_kernel_build_dir>
|
||||
|
||||
Go to the build directory, configure the kernel:
|
||||
|
||||
! cd mybuild
|
||||
! make config
|
||||
|
||||
This will launch the configuration menu. Here you can configure your kernel.
|
||||
The default config is just fine to test the Genode port. It will build a
|
||||
uniprocessor IA32 kernel with debugging features enabled. You can exit the menu and
|
||||
save the configuration by simply typing 'x'.
|
||||
|
||||
Now, build Fiasco.OC by invoking:
|
||||
|
||||
! make
|
||||
|
||||
|
||||
Building necessary tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To practically use Fiasco.OC, you need in addition to the kernel a tool to
|
||||
bootstrap it, and the initial pager of the system, namely 'sigma0'. Both tools
|
||||
can be found in the L4 runtime environment's base directory. Outgoing from
|
||||
the directory where you checked out the sources, you have to change to the
|
||||
following directory:
|
||||
|
||||
! cd <path_to_fiasco_src_dir>/src/l4
|
||||
|
||||
Create another build directory:
|
||||
|
||||
! make B=<path_to_l4re_build_dir>
|
||||
|
||||
Again, you might want to tweak the configuration:
|
||||
|
||||
! make O=<path_to_l4re_build_dir> config
|
||||
|
||||
Finally, build the tools:
|
||||
|
||||
! make O=<path_to_l4re_build_dir>
|
||||
|
||||
|
||||
Building the Fiasco.OC version of Genode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Fiasco.OC version of Genode is available at the Genode public subversion repository:
|
||||
|
||||
:https://genode.org/download/subversion-repository:
|
||||
Information about accessing the Genode public subversion repository
|
||||
|
||||
Go to a directory where you want the Genode/Fiasco.OC build directory to remain. Use
|
||||
the helper script in the 'tool/builddir' directory of the Genode source tree to
|
||||
create the initial build environment. You need to state the absolute path to the
|
||||
build directory of the L4 runtime environment as 'L4_DIR', as it contains the kernel
|
||||
bindings needed by the Genode port.
|
||||
|
||||
! <path_to_genode_src_dir>/tool/builddir/create_builddir foc_x86_32 \
|
||||
! L4_DIR=<path_to_l4re_build_dir> \
|
||||
! GENODE_DIR=<path_to_genode_src_dir> \
|
||||
! BUILD_DIR=<path_to_genode_build_dir>
|
||||
|
||||
Now, go to the newly created build directory and type make.
|
||||
|
||||
! cd <path_to_genode_build_dir>
|
||||
! make
|
||||
|
||||
|
||||
Booting Genode on top of Fiasco.OC
|
||||
==================================
|
||||
|
||||
Example GRUB configuration entry:
|
||||
|
||||
! timeout 0
|
||||
! default 0
|
||||
!
|
||||
! title Genode on Fiasco.OC
|
||||
! kernel /bootstrap -modaddr=0x01100000
|
||||
! module /fiasco -serial_esc
|
||||
! module /sigma0
|
||||
! module /core
|
||||
! module /init
|
||||
! module /config
|
||||
! module /pci_drv
|
||||
! module /vesa_drv
|
||||
! module /ps2_drv
|
||||
! module /timer
|
||||
! module /nitpicker
|
||||
! module /launchpad
|
||||
! module /liquid_fb
|
||||
! module /scout
|
||||
! module /testnit
|
||||
! module /nitlog
|
||||
|
||||
For an example of a matching Genode 'config' file, please take a look
|
||||
at 'os/config/demo'.
|
||||
|
||||
The Genode binaries are located in '<path_to_genode_build_dir>/bin',
|
||||
the 'fiasco' kernel in '<path_to_kernel_build_dir>'. Assuming you compiled
|
||||
for x86/586 (the default), you can find the 'bootstrap' binary in
|
||||
'bin/x86_586' and 'sigma0' in 'bin/x86_586/l4f' within the
|
||||
'<path_to_l4re_build_dir>' directory.
|
||||
|
||||
|
||||
Current state
|
||||
=============
|
||||
|
||||
The adaptation of Genode to Fiasco.OC covers most parts of the Genode API
|
||||
including advanced semantics such as cancelable locks and support for
|
||||
real-time priorities. So far, it has been tested on the x86 architecture.
|
||||
Because 'base-foc' does not contain x86-specific code, we expect no major
|
||||
roadblocks for running Genode on Fiasco.OC on ARM. However, we have not
|
||||
exercised tests in this regard.
|
||||
|
||||
As of today, there exist the following limitations of the Fiasco.OC support:
|
||||
|
||||
* The dynamic linker is not yet adapted to Fiasco.OC. Special care must
|
||||
be taken for handling the parent capability for dynamically loaded
|
||||
programs. We have already covered this issue for the NOVA version but
|
||||
the adaptation to Fiasco.OC remains yet to be done.
|
||||
|
||||
* The destruction of sub systems is not yet fully stable. Because Genode
|
||||
forms a more dynamic workload than the original userland accompanied with
|
||||
the kernel, the usage pattern of the kernel API triggers different
|
||||
effects. We are working with the Fiasco.OC developers to remedy this
|
||||
issue.
|
||||
|
||||
* The signalling framework is not yet supported. A design exist but it is
|
||||
not implemented yet.
|
||||
|
||||
We believe however that none of these limitations are a significant hurdle for
|
||||
starting to use Genode with this kernel. Please expect this issues to be
|
||||
resolved with the upcoming Genode release.
|
||||
|
||||
|
||||
Technical details about 'base-foc'
|
||||
==================================
|
||||
|
||||
The following technical bits are worth noting when exploring the use of
|
||||
Genode with the 'base-foc' platform.
|
||||
|
||||
* The timer implementation uses a one thread-per-client mode of operation.
|
||||
We use IPC timeouts as time source. Hence, the timer driver is hardware
|
||||
independent and should work out of the box on all hardware platforms
|
||||
supported by Fiasco.OC.
|
||||
|
||||
* Each 'Server_object' of Genode corresponds to a so-called IPC gate,
|
||||
which is the Fiasco.OC kernel object used for capability invocation.
|
||||
Therefore, protection and object integrity is provided at the fine
|
||||
granularity of single 'Server_objects'. This is in line with our
|
||||
support for NOVA's implementation of capability-based security.
|
||||
|
||||
* In contrast to the lock implementation that we used with the original
|
||||
L4/Fiasco kernel, the 'base-foc' lock is a fully-featured Genode lock
|
||||
with support for lock cancellation and blocking. For blocking and
|
||||
waking up lock applicants, we use Fiasco.OC's IRQ objects.
|
||||
|
||||
* The allocator used for managing process-local capability selectors
|
||||
does not yet support the reuse of capability selectors.
|
||||
|
||||
|
||||
Further Information
|
||||
===================
|
||||
|
||||
:genode/tool/builddir/README:
|
||||
Reference manual for the 'create_builddir' script
|
||||
|
||||
:[https://os.inf.tu-dresden.de/fiasco]:
|
||||
Official website for the Fiasco.OC microkernel.
|
||||
|
||||
|
||||
Noux - an execution environment for the GNU userland
|
||||
####################################################
|
||||
|
||||
Even though Genode is currently mainly geared to the classical special-purpose
|
||||
application domains for microkernel-based systems, the main property that sets
|
||||
Genode apart from traditional systems is the thorough support for dynamic
|
||||
workloads and the powerful mechanisms for handling hardware resources and
|
||||
security policies in highly dynamic setting. We are convinced that Genode's
|
||||
architecture scales far beyond static special-purpose domains and believe in
|
||||
the feasibility of Genode as a solid foundation for a fully-fledged general
|
||||
purpose operating system. Internally at Genode Labs, we set up the ultimate
|
||||
goal to switch from Linux to Genode for our day-to-day work. We identified
|
||||
several functionalities that we could not live without and systematically try
|
||||
to bring those features to Genode. Of course, the most fundamental programs
|
||||
are the tools needed to develop and build Genode. Currently we are developing
|
||||
on Linux and enjoy using the GNU userland.
|
||||
|
||||
Consequently, we require a solution for using this rich tool set on Genode.
|
||||
The straight-forward way for making these tools available on Genode would be
|
||||
running them within a virtualized Linux instance (e.g., using OKLinux on OKL4).
|
||||
However, this approach would defeat our actual goal to create a highly secure
|
||||
yet easy to use working environment because adding Linux to the picture would
|
||||
involve administering the virtualized Linux system. We would prefer a native
|
||||
solution that makes the overall system less, not more, complicated. This way
|
||||
the idea for a native execution environment for the GNU userland on Genode
|
||||
was born. The implementation is called Noux and the first bits of code are
|
||||
featured in the 'ports' repository. Noux consists of two parts, a build
|
||||
environment for compiling GNU programs such that they can be run as Genode
|
||||
processes and an execution environment that provides the classical UNIX
|
||||
functionality to these programs.
|
||||
|
||||
|
||||
Noux build environment
|
||||
======================
|
||||
|
||||
From our experience, porting existing UNIX applications to a non-UNIX system
|
||||
tends to be a task of manual and time-consuming labour. One has to loosely
|
||||
understand the build system and the relationship of the involved source codes,
|
||||
implement dummy functions for unresolved references, and develop custom glue
|
||||
code that interfaces the ported application to the actual system. Taking the
|
||||
shortcut of changing the original code has to be avoided at any cost because
|
||||
this produces recurring costs in the future when updating the application. In
|
||||
short, this long-winding process does not scale. For porting a tool set such as
|
||||
the GNU userland consisting of far more than a three-digit number of individual
|
||||
programs, this manual approach becomes unfeasible. Therefore, we have created
|
||||
a build environment that facilitates the use of the original procedure of
|
||||
invoking './configure && make'. The challenge is to supply configure with
|
||||
the right arguments and environment variables ('CFLAGS' and the like) such that
|
||||
the package is configured against the Genode environment. The following
|
||||
considerations must be taken:
|
||||
|
||||
* Configure must not detect any global headers (e.g., '/usr/include/')
|
||||
or libraries (e.g., '/usr/lib/'). This can be achieved by the '-nostdinc' and
|
||||
'-nostdlib' options
|
||||
* Configure has to use the same include-search paths as used for compiling
|
||||
normal libc-using Genode programs
|
||||
* Configure must use the Genode tool chain
|
||||
* The final linking stage must use the Genode linker script, the Genode
|
||||
base libraries, and other Genode-specific linker arguments.
|
||||
|
||||
Thanks to the power of the GNU build system, all this can be achieved by
|
||||
supplying arguments to './configure' and indirectly to the 'make' process via
|
||||
environment variables. The new Noux build environment takes care of these
|
||||
precautions. It comes in the form of the 'ports/mk/noux.mk' file which enables
|
||||
the seamless integration of GNU packages with the Genode build system. To
|
||||
compile a GNU package, the manual steps needed are reduced to the creation of a
|
||||
'target.mk' file representing the package. This 'target.mk' defines the name
|
||||
of the package (by default, the basename of the 'target.mk' enclosing directory
|
||||
is assumed) and the location of the source package. With this approach, we
|
||||
managed to build 'coreutils' (over 100 small UNIX utilities such as 'ls', 'cp',
|
||||
'sort'), 'binutils' (GNU linker, assembler, object-file tools), 'findutils'
|
||||
('find', 'xargs'), 'bash', 'dash', GNU make, and finally the GNU compiler
|
||||
collection including 'g++'. The resulting binaries are ready to be executed as
|
||||
native Genode processes. However, without the right environment that presents
|
||||
the program the needed UNIX functionality, those programs won't do much.
|
||||
This leads us to the Noux execution environment.
|
||||
|
||||
|
||||
Noux execution environment
|
||||
==========================
|
||||
|
||||
The Noux execution environment plays the role of a UNIX kernel for programs
|
||||
built via the Noux build environment. In contrast to a real kernel, the Noux
|
||||
environment is a plain Genode user-level process that plays the role of being
|
||||
the parent of one or multiple Noux processes. In addition of providing the
|
||||
'Genode::Parent' interface, Noux also provides a locally implemented service called
|
||||
'Noux::Session' that offers UNIX-like system-calls via an RPC interface. Each
|
||||
hosted program is linked against a special Noux libc plugin that catches all
|
||||
libc calls that would normally result in a system call. It then transparently
|
||||
forwards this function call to the 'Noux::Session' interface.
|
||||
|
||||
Currently the Noux execution environment implements the following
|
||||
system calls: 'getcwd', 'write', 'stat', 'fstat', 'fcntl', 'open',
|
||||
'close', 'dirent', 'fchdir', 'read', and 'execve'.
|
||||
|
||||
The execution environment submits arguments (argc, argv, environment) to the
|
||||
hosted program, manages its current working directory and receives its exit
|
||||
code. File operations are targeted to a custom VFS infrastructure, which
|
||||
principally allows a flexible configuration of the virtual file system visible
|
||||
to the hosted programs. At the current stage, Noux supports mounting plain tar
|
||||
archives obtained from core's ROM service as read-only file system. On startup,
|
||||
the Noux environment starts one process (the init process) and connects the
|
||||
file descriptor 1 (stdout) to Genode's LOG service.
|
||||
|
||||
State of the implementation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The infrastructure implemented so far already allows the execution of many simple
|
||||
UNIX tools such as 'ls -lRa', 'echo', 'seq', 'find'. The 'execve' system call
|
||||
is implemented such that a new process is started that inherits the file
|
||||
descriptors and the PID of the calling process. This allows using the exec
|
||||
functionality of the 'bash' shell. However, because 'fork' is not implemented
|
||||
yet, there is currently no way to start multiple programs hosted in a single
|
||||
Noux execution environment.
|
||||
|
||||
As of today, the Noux environment is not considered to be usable for practical
|
||||
purposes. However, it clearly shows the feasibility of the path we are walking.
|
||||
With the foundation laid, we are looking forward to expanding Noux to a capable
|
||||
solution for running our beloved GNU userland tools on Genode.
|
||||
|
||||
Vision
|
||||
~~~~~~
|
||||
|
||||
The most significant intermediate result of pursuing the development of Noux is
|
||||
the realization that such an environment is not exceedingly complex. Because of
|
||||
the combination with Genode, we only need to provide a comfortable runtime as
|
||||
expected by user processes but we can leave much of intricate parts of UNIX out
|
||||
of the picture. For example, because we handle device drivers on Genode, we do
|
||||
not need to consider device-user interaction in Noux. As another example,
|
||||
because the problem of bootstrapping the OS is already solved by Genode, there
|
||||
is no need to run an 'init' process within Noux. Our vision foresees that Noux
|
||||
runtimes are to be created on demand for individual tasks such as editing a
|
||||
file (starting a custom Noux instance containing only the file to edit and the
|
||||
text editor), compiling source code (starting a custom Noux instance with only
|
||||
the source code and the build tools). Because Noux is so simple, we expect the
|
||||
runtime overhead of starting a Noux instance to be not more than the time
|
||||
needed to spawn a shell in a normal UNIX-like system.
|
||||
|
||||
Test drive
|
||||
~~~~~~~~~~
|
||||
|
||||
To give Noux a spin, we recommend using Linux as base platform as this is
|
||||
the platform we use for developing it. First, you will need to download the
|
||||
source code of the GNU packages. From within the 'ports' repository,
|
||||
use the following command:
|
||||
|
||||
! make prepare PKG=coreutils
|
||||
|
||||
This command will download the source code of the GNU coreutils. You may
|
||||
also like to give the other packages a try. To see what is available,
|
||||
just call 'make' without any argument.
|
||||
|
||||
Create a build directory (e.g., using tool/builddir/create_builddir).
|
||||
Change to the build directory and issue the command
|
||||
|
||||
! make run/noux
|
||||
|
||||
This command will execute the run script provided at 'ports/run/noux.run'.
|
||||
First it builds core, init, and coreutils. Then it creates a tar archive
|
||||
containing the installed coreutils. Finally, it starts the Noux environment on
|
||||
Genode. Noux then mounts the TAR archive as file system and executes 'ls -laR',
|
||||
showing the directory tree.
|
||||
|
||||
|
||||
Approaching platform support for Xilinx MicroBlaze
|
||||
##################################################
|
||||
|
||||
With the release 11.02, we are excited to include the first version of our
|
||||
custom platform support for the Xilinx MicroBlaze CPU architecture. MicroBlaze
|
||||
is a so-called softcore CPU, which is commonly used as part of FPGA-based
|
||||
System-on-Chip designs. At Genode Labs, we are regularly using this IP core,
|
||||
in particular for our Genode FPGA Graphics Project, which is a GUI software stack
|
||||
and a set of IP cores for implementing fully-fledged windowed GUIs on FPGAs:
|
||||
|
||||
:Website of the Genode FPGA Graphics Project:
|
||||
|
||||
[https://genode-labs.com/products/fpga-graphics]
|
||||
|
||||
Ever since we first released the Genode FPGA project, we envisioned to combine
|
||||
it with the Genode OS Framework. In Spring 2010, Martin Stein joined our team
|
||||
at Genode Labs and accepted the challenge to bring the Genode OS Framework to
|
||||
the realms of FPGA-based SoCs. Technically, this implies porting the framework
|
||||
to the MicroBlaze CPU architecture. In contrast to most softcore CPUs such as
|
||||
the popular Lattice Mico32, the MicroBlaze features a MMU, which is a fundamental
|
||||
requirement for implementing a microkernel-based system. Architecturally-wise
|
||||
MicroBlaze is a RISC CPU similar to MIPS. Many system parameters of the CPU
|
||||
(caches, certain arithmetic and shift instructions) can be parametrized at
|
||||
synthesizing time of the SoC. We found that the relatively simple architecture
|
||||
of this CPU provides a perfect playground for pursuing some of our ideas about
|
||||
kernel design that go beyond the scope of current microkernels. So instead of
|
||||
adding MicroBlaze support into one of the existing microkernels already
|
||||
supported by Genode, we went for a new kernel design. Deviating from the typical
|
||||
microkernel, which is a self-sufficient program running in kernel mode that
|
||||
executes user-level processes on top, our design regards the kernel as a part of
|
||||
Genode's core. It is not a separate program but a library that implements the
|
||||
glue between user-level core and the raw CPU. Specifically, it provides the
|
||||
entrypoint for hardware exceptions, a thread scheduler, an IPC mechanism, and
|
||||
functions to manipulate virtual address spaces (loading and flushing entries
|
||||
from the CPU's software-loaded TLB). It does not manage any physical memory
|
||||
resources or the relationship between processes. This is the job of core.
|
||||
From the kernel-developer's point of view, the kernel part can be summarized as
|
||||
follows:
|
||||
|
||||
* The kernel provides user-level threads that are scheduled in a round-robin
|
||||
fashion.
|
||||
* Threads can communicate via synchronous IPC.
|
||||
* There is a mechanism for blocking and waking up threads. This mechanism
|
||||
can be used by Genode to implement locking as well as asynchronous
|
||||
inter-process communication.
|
||||
* There is a single kernel thread, which never blocks in the kernel code paths.
|
||||
So the kernel acts as a state machine. Naturally, there is no concurrency in the
|
||||
execution paths traversed in kernel mode, vastly simplifying these code parts.
|
||||
However, all code paths are extremely short and bounded with regard to
|
||||
execution time. Hence, we expect the interference with interrupt latencies
|
||||
to be low.
|
||||
* The IPC operation transfers payload between UTCBs only. Each thread has a
|
||||
so-called user-level thread control block which is mapped transparently by
|
||||
the kernel. Because of this mapping, user-level page faults cannot occur
|
||||
during IPC transfers.
|
||||
* There is no mapping database. Virtual address spaces are manipulated by
|
||||
loading and flushing physical TLB entries. There is no caching of mappings
|
||||
done in the kernel. All higher-level information about the interrelationship
|
||||
of memory and processes is managed by the user-level core.
|
||||
* Core runs in user mode, mapped 1-to-1 from the physical address space
|
||||
except for its virtual thread-context area.
|
||||
* The kernel paths are executed in physical address space (MicroBlaze).
|
||||
Because both kernel code and user-level core code are observing the same
|
||||
address-space layout, both worlds appear to run within a single address
|
||||
space.
|
||||
* User processes can use the entire virtual address space (4G) except for a
|
||||
helper page for invoking syscalls and a page containing atomic operations.
|
||||
There is no reservation used for the kernel.
|
||||
* The MicroBlaze architecture lacks an atomic compare-and-swap instruction. On
|
||||
user-level, this functionality is emulated via delayed preemption. A kernel-
|
||||
provided page holds the sequence of operations to be executed atomically and
|
||||
prevents (actually delays) the preemption of a thread that is currently
|
||||
executing instructions at that page.
|
||||
* The MicroBlaze MMU supports several different page sizes (1K up to 16MB).
|
||||
Genode fully supports this feature for page sizes >= 4K. This way, the TLB
|
||||
footprint can be minimized by choosing sensible alignments of memory
|
||||
objects.
|
||||
|
||||
Current state
|
||||
=============
|
||||
|
||||
The MicroBlaze platform support resides in the 'base-mb' repository. At the
|
||||
current stage, core is able to successfully start multiple nested instances of
|
||||
the init process. Most of the critical kernel functionality is working. This
|
||||
includes inter-process communication, address-space creation, multi-threading,
|
||||
thread synchronization, page-fault handling, and TLB eviction.
|
||||
|
||||
This simple scenario already illustrates the vast advantage of
|
||||
using different page sizes supported by the MicroBlaze CPU. If using
|
||||
4KB pages only, a scenario with three nested init processes produces more than
|
||||
300.000 page faults. There is an extremely high pressure on the TLB, which
|
||||
only contains 64 entries. Those entries are constantly evicted so that
|
||||
threshing effects are likely to occur. By making use of flexible page
|
||||
sizes (4K, 16K, 64K, 256K, 1M, 4M, 16M), the number of page faults gets
|
||||
slashed to only 1.800, speeding up the boot time by factor 10.
|
||||
|
||||
Currently, there is no restriction of IPC communication rights. Threads are
|
||||
addressed using their global thread IDs (in fact, using their respective
|
||||
indices in the KTCB array). For the future, we are planning to add
|
||||
capabilty-based delegation of communication rights.
|
||||
|
||||
Building and using Genode on MicroBlaze
|
||||
=======================================
|
||||
|
||||
For building Genode for the MicroBlaze platform, you need the MicroBlaze
|
||||
tool chain as it comes with the Xilinx EDK. The tool chain is typically
|
||||
prefixed with 'mb-'. Please make sure that the tool chain's 'bin/' directory
|
||||
is included in your 'PATH' environment variable.
|
||||
|
||||
For building and starting Genode on MicroBlaze, you first need to create
|
||||
a build directory using the build-directory creation tool:
|
||||
|
||||
! tool/builddir/create_builddir microblaze \
|
||||
! BUILD_DIR=</path/to/build/dir> \
|
||||
! GENODE_DIR=</path/to/genode/dir>
|
||||
|
||||
The 'base-mb' repository comes with support for Genode's run tool. In order to
|
||||
use it, you will first need to declare the location of your qemu binary using
|
||||
the 'QEMU=/path/to/qemu' variable in the '<build-dir>/etc/microblaze.conf'
|
||||
file. Then you will be able to start an example scenario by issuing the
|
||||
following command from within your build directory:
|
||||
|
||||
! make run/nested_init
|
||||
|
||||
Thereby, the 'run' tool will attempt to start core using the microblaze version
|
||||
of qemu.
|
||||
|
||||
You can also find a simple hello-world example at 'base-mb/src/test/hello'.
|
||||
The corresponding run script is located at 'base-mb/run/hello.run'. You can
|
||||
execute it via 'make run/hello' from the build directory.
|
||||
|
||||
Note that currently, all boot modules are linked against the core binary.
|
||||
To change the boot modules, the file 'base-mb/src/core/boot_modules.s' must
|
||||
be modified.
|
||||
|
||||
For reference, we are using the following tools:
|
||||
|
||||
* mb-g++ (GCC) 4.1.1 20060524 (Xilinx 11.2 Build EDK_LS2.2
|
||||
20 Apr 2009 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009)
|
||||
* GNU ld version 2.16 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009
|
||||
* GNU assembler 2.16 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009
|
||||
* QEMU emulator version 0.14.50, Copyright (c) 2003-2008 Fabrice Bellard
|
||||
Petalogix linux reference design targeting Xilinx Spartan 3ADSP-1800 boards.
|
||||
|
||||
|
||||
Supporting the NOVA hypervisor version 0.3
|
||||
##########################################
|
||||
|
||||
NOVA is a so called microhypervisor - a modern capability-based microkernel
|
||||
with special support for hardware-based virtualization and IOMMUs. Since we
|
||||
incorporated the initial support for the NOVA hypervisor in Genode one year
|
||||
ago, this kernel underwent multiple revisions. The latest version was released
|
||||
earlier this month. To our delight, much of the features that we missed from
|
||||
the initial release had been implemented during the course of the last year. We
|
||||
are especially happy about the fully functional 'revoke' system call and the
|
||||
support for remote kernel-object creation.
|
||||
|
||||
With the Genode release 11.02, we officially support the latest NOVA version.
|
||||
The update of Genode to the new version required two steps. First, because many
|
||||
details of the kernel interface were changed between version 0.1 and version
|
||||
0.3, we had to revisit our syscall bindings and adapting our code to changed
|
||||
kernel semantics. Second, we filled our 'base-nova' code related to object
|
||||
destruction and unmapping with life to benefit from NOVA's 'revoke' system
|
||||
call. Consequently, we are now able to run the complete Genode software stack
|
||||
including the dynamic linker on NOVA.
|
||||
|
||||
Note that for using Genode on NOVA, you will need to apply a small patch to the
|
||||
NOVA source code. This patch enables the re-use of user-level thread control
|
||||
blocks in the kernel. The patch can be found at 'base-nova/patches/utcb.patch'.
|
||||
|
||||
When executing NOVA on qemu, please specify the '-cpu coreduo' argument to the
|
||||
qemu command line. When using Genode 'run' tool, you may assign this argument
|
||||
to the 'QEMU_OPT' variable in '<build-dir>/etc/build.conf'.
|
||||
|
||||
:Thanks:
|
||||
|
||||
We are grateful for the ongoing very pleasant collaboration with Udo Steinberg
|
||||
who is the driving force behind NOVA. Thanks for the ultra-fast responses to our
|
||||
questions and for considering our suggestions regarding the feature set of
|
||||
NOVA's kernel interface!
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Upgrading existing sessions
|
||||
===========================
|
||||
|
||||
Genode enables a client of a service to lend parts of its own resources to
|
||||
the service when opening a session. This way, servers do not need to allocate
|
||||
own resources on behalf of their clients and become inherently robust against
|
||||
resource-exhaustion-based denial-of-service attacks.
|
||||
|
||||
However, there are cases when the client can not decide about the amount of
|
||||
resources to lend at session-creation time. In such cases, we used to devise an
|
||||
overly generous client policy. Now, we have added a new 'upgrade' function to
|
||||
the 'Parent' and 'Root' interfaces that enables a client to upgrade the
|
||||
resources of an existing session.
|
||||
|
||||
For the 'env()->rm_session()' and 'env()->ram_session()' of processes using
|
||||
the Genode 'env' library, we implemented a transparent quota upgrade that kicks in
|
||||
in the event of an exceeded metadata backing store.
|
||||
|
||||
|
||||
Comprehensive accounting of core resources
|
||||
==========================================
|
||||
|
||||
We changed all services of core to limit their respective resource usage
|
||||
specifically for each individual session. For example, the number of dataspaces
|
||||
that can be handled by a particular region-manager (RM) session depends on the
|
||||
resource donation attached to the session. To implement this accounting scheme
|
||||
throughout core, we added a generic 'Allocator_guard' utility to
|
||||
'base/include/'. We recommend using this utility when implementing resource
|
||||
multiplexers, in particular multi-level services. Thanks to this change in
|
||||
core, the need for a slack memory reservation in core has vanished.
|
||||
|
||||
|
||||
Various changes
|
||||
===============
|
||||
|
||||
The remaining parts of the base API underwent no fundamental revision. The
|
||||
changes are summarized as follows.
|
||||
|
||||
:C++ Support:
|
||||
|
||||
We removed 'libgcc' from our C++ support library ('cxx') and link
|
||||
it to each individual final target and shared library instead. This change alleviates
|
||||
the need to abuse the 'KEEP_SYMBOLS' mechanism that we used in 'cxx' to
|
||||
keep libc-dependencies of GCC's support libraries local to the 'cxx'
|
||||
library. Besides the benefit of reducing heuristics, this change improves
|
||||
the compatibility with recent cross-compiling tool chains.
|
||||
Furthermore, we added 'realloc' to the local libc support of the 'cxx'
|
||||
library because recent ARM tool chains tend to use this function.
|
||||
|
||||
:Argument handling for 'main()':
|
||||
|
||||
We added a hook to the startup code to enable the implementation of
|
||||
custom facilities for passing arguments to the main function. The
|
||||
hook uses the global variables 'genode_argc' and 'genode_argv'.
|
||||
|
||||
:Child-exit policy hook:
|
||||
|
||||
We enhanced the 'Child_policy' with a new policy interface that allows
|
||||
a simplified implementation of policies related to program termination.
|
||||
|
||||
:Changed API of 'Range_allocator':
|
||||
|
||||
We changed the return value of 'alloc_addr' to distinguish different error
|
||||
conditions. Note that the boolean meaning of the return value is inverted.
|
||||
Please check your uses of 'alloc_addr'!
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
C Runtime
|
||||
=========
|
||||
|
||||
In conjunction with our work on Noux, we improved Genode's C runtime at many
|
||||
places. First, we added libstdtime and some previously missing bits of libgdtoa
|
||||
to the libc. These additions largely alleviate the need for dummy stubs, in
|
||||
particular time-related functions. Second, we added the following functions to
|
||||
our libc plugin interface: 'dup2', 'fchdir', 'fcntl', 'fstat', 'stat', and
|
||||
'write'. This enables the creation of advanced libc plugins simulating a whole
|
||||
file system as done with Noux. Still, there are a number of dummy stubs found
|
||||
at 'libc/src/lib/libc/dummy.cc'. However, those stubs are now all defined as
|
||||
weak symbols such that they can be overridden by libc plugins. Finally, we have
|
||||
replaced the original 'exit' implementation that comes with the libc with a
|
||||
Genode-specific version. The new version reports the exit code of the
|
||||
application to the parent process via an 'Parent::exit()' RPC call.
|
||||
|
||||
Until now, Genode's libc magically handled output to stdout and stderr by
|
||||
printing messages via Genode's LOG interface. We have now replaced this
|
||||
hard-wired interface by an optional libc plugin called 'libc_log'. If present, write
|
||||
operations to stdout are caught at the libc plugin interface and delegated to
|
||||
the plugin, which implements the output to the LOG interface. If you have an
|
||||
application using Genode's libc, you might consider adding the 'libc_log'
|
||||
library to your 'target.mk' file.
|
||||
|
||||
|
||||
Support for big numbers by the means of libgmp and libmpfr
|
||||
==========================================================
|
||||
|
||||
We have now include both the GNU Multiple Precision Arithmetic Library and
|
||||
(GMP) and MPFR to the 'ports' repository. This work was specifically motivated
|
||||
by our port of GCC to Genode as GCC version 4.4.5 requires both libraries.
|
||||
Because we intend to use those libraries primarily on x86_32, the current port
|
||||
covers only this architecture. However, expanding the port to
|
||||
further CPU architectures should be straight-forward if needed.
|
||||
|
||||
Furthermore, you can now also find GCC's 'longlong.h' header at
|
||||
'libports/include/gcc'.
|
||||
|
||||
|
||||
Qt4 updated to version 4.7.1
|
||||
############################
|
||||
|
||||
The current release bumps the supported Qt4 version from 4.6.2 to 4.7.1 and the
|
||||
Arora web browser (located at the ports repository) from version 0.10.2 to
|
||||
version 0.11. Of course, we updated our custom additions such as our custom
|
||||
Nitpicker plugin widget that enables the seamless integration of native
|
||||
Nitpicker GUI clients into Qt4 applications to work with the new Qt4 version.
|
||||
|
||||
|
||||
Tools
|
||||
#####
|
||||
|
||||
Tool chain update to GCC 4.4.5 and Binutils 2.21
|
||||
================================================
|
||||
|
||||
We upgraded the official Genode tool chain from gcc 4.2.4 to gcc 4.4.5. Please
|
||||
update your tool chain by downloading the new binary archive (available for x86_32)
|
||||
or building the tool chain from source using our 'tool/tool_chain' utility.
|
||||
|
||||
New support for automated integration and testing
|
||||
=================================================
|
||||
|
||||
With the growing number of supported base platforms, the integration and testing
|
||||
of Genode application scenarios across all kernels becomes
|
||||
increasingly challenging. Each kernel has a different boot mechanism and
|
||||
specific requirements such as the module order of multiboot modules (Fiasco's
|
||||
bootstrap, Pistachio's sigma0 and kickstart), kernel parameters, or the
|
||||
invocation of a single-image creation tool (OKL4's elfweaver). To make our
|
||||
life supporting all those platforms easier, we have created a tool called
|
||||
'run', which is tightly integrated within Genode's build system. In short 'run'
|
||||
gathers the intrinsics in the form of a 'run/env' file specific for the
|
||||
platform used by the current build directory from the respective
|
||||
'base-<platform>' repository. It then executes a so-called run script, which
|
||||
contains all steps needed to configure, build, and integrate an application
|
||||
scenario. For example, a typical run script for building and running a test
|
||||
case resides in a file called '<any-repository>/run/<run-script-name>.run' and
|
||||
looks as follows:
|
||||
|
||||
! build "core init test/exception"
|
||||
! create_boot_directory
|
||||
! install_config {
|
||||
! <config>
|
||||
! <parent-provides>
|
||||
! <!--<service name="ROM"/>-->
|
||||
! <service name="LOG"/>
|
||||
! </parent-provides>
|
||||
! <default-route>
|
||||
! <any-service> <parent/> </any-service>
|
||||
! </default-route>
|
||||
! <start name="test-exception">
|
||||
! <resource name="RAM" quantum="1M"/>
|
||||
! </start>
|
||||
! </config>
|
||||
! }
|
||||
! build_boot_image "core init test-exception"
|
||||
! append qemu_args "-nographic -m 64"
|
||||
! run_genode_until {.*Exception \(label 0xffb0\) occured.*} 10
|
||||
|
||||
First, the build system is instructed to create the targets specified as argument
|
||||
for the 'build' function. Next, for the integration part, a new boot directory is
|
||||
created. On most kernel platform, the respective location of the boot directory
|
||||
is '<build-dir>/var/run/<run-script-name>'. Initially, this directory is empty.
|
||||
It gets populated with a 'config' file specified as argument of the 'install_config'
|
||||
command, and by the boot modules specified at the 'build_boot_image' command.
|
||||
Now that the integration is complete, the scenario is executed via the
|
||||
'run_genode_until' command. This command takes a regular expression as
|
||||
argument, which determines the successful termination of the test case. The
|
||||
second argument is a timeout (is seconds). In the example, the test case will
|
||||
fail if its output does not match the regular expression within the execution
|
||||
time of 10 seconds.
|
||||
|
||||
The command 'append qemu_args' specifies run-script-specific qemu arguments in
|
||||
the case that qemu is used to execute the scenario. This is the case for most
|
||||
kernel platforms (except for Linux where core gets executed directly on the host).
|
||||
Additional build-directory-specific qemu arguments can be specified in the
|
||||
'etc/build.conf' file by defining the 'QEMU_OPT' variable. For example, to
|
||||
prevent KVM being used on Ubuntu Linux, specify:
|
||||
|
||||
! QEMU_OPT = -no-kvm
|
||||
|
||||
To execute the run script from with build directory, you need to have Expect
|
||||
installed. Typically, the Linux package is called 'expect'. Simply issue
|
||||
the following command from within your build directory:
|
||||
|
||||
! make run/<run-script>
|
||||
|
||||
Note that you will need to have a GRUB 'stage2_eltorito' binary available
|
||||
at '<genode-dir>/tool/grub' on base platforms that use an ISO image as boot
|
||||
stategy.
|
||||
|
||||
Because the whole chain of actions, building, integrating, executing, and
|
||||
validating an application scenario is now at the fingertips of issuing a
|
||||
single command with no kernel-specific considerations needed, it has never
|
||||
been easier to run the same scenario on a wide range of different kernels.
|
||||
Please find further instructive examples at 'os/run/'. The 'ldso' run
|
||||
script executes the test of the dynamic linker. It is completely generic.
|
||||
The 'demo' run script starts Genode's default demo scenario and shows how
|
||||
platform-specific considerations (e.g., which device drivers to use) can be
|
||||
taken into account.
|
||||
|
||||
We found that the 'run' tool significantly boosted our productivity not
|
||||
only for testing purposes but also for accelerating the development-test
|
||||
cycle during our day-to-day work.
|
||||
|
||||
:Technical notes:
|
||||
|
||||
The 'run' tool uses Expect as automation tool. Expect is a Tcl interpreter,
|
||||
which is accompanied by special functionality for automating interactive
|
||||
command-line applications. Technically, a run script is an Expect script
|
||||
which gets included by the 'tool/run' script. For the reference of
|
||||
run-specific functions, please revise the documentation in the 'tool/run'
|
||||
script. Because each run script is actual Expect source code, it is possible
|
||||
to use all Tcl and Expect scripting features in a run script.
|
||||
In particular, a run script may issue shell commands using Tcl's 'exec'
|
||||
function. This way, even complex integration tasks can be accomplished.
|
||||
For example, the integration of the Genode Live CD was done via a single
|
||||
run script.
|
||||
|
||||
|
||||
Build system
|
||||
============
|
||||
|
||||
To facilitate the integration of 3rd-party build systems into the Genode build
|
||||
process, we added support for pseudo targets that do not require any 'SRC'
|
||||
declaration. Such 'target.mk' may contain custom rules that will be executed
|
||||
when the target is revisited by the build system. The bindings are as follows:
|
||||
|
||||
! build_3rd_party:
|
||||
! ...custom commands...
|
||||
!
|
||||
! $(TARGET): build_3rd_party
|
||||
!
|
||||
! clean_3rd_party:
|
||||
! ...custom commands...
|
||||
!
|
||||
! clean_prg_objects: clean_3rd_party:
|
||||
|
||||
|
||||
1289
doc/release_notes/11-05.txt
Normal file
1289
doc/release_notes/11-05.txt
Normal file
File diff suppressed because it is too large
Load Diff
703
doc/release_notes/11-08.txt
Normal file
703
doc/release_notes/11-08.txt
Normal file
@@ -0,0 +1,703 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 11.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
One of Genode's most distinctive properties is its support for various
|
||||
different kernels as base platforms. Each of the 8 currently supported kernels
|
||||
differs with regard to features, security, hardware support, complexity, and
|
||||
resource management. Even though different applications call for different
|
||||
kernel properties, through Genode, those properties can be leveraged using a
|
||||
unified API. The growing number of supported base platforms, however, poses two
|
||||
challenges, which are the comprehension of the large diversity of tools and
|
||||
boot concepts, and capturing of the semantic differences of all the kernels.
|
||||
|
||||
With the version 11.08, the framework mitigates the former challenge by
|
||||
introducing a unified way to download, build, and use each of the
|
||||
kernels with Genode's user-level infrastructure. The new tools empower users of
|
||||
the framework to instantly change the underlying kernel without the need to know
|
||||
the peculiarities of the respective kernels. Using microkernels has never been
|
||||
easier.
|
||||
|
||||
The second challenge of translating each kernel's specific behaviour to the
|
||||
framework's unified API longs for an automated testing infrastructure that
|
||||
systematically exercises all the various facets of the API on all base
|
||||
platforms. The new version introduces the tooling support especially designed
|
||||
for conducting such quality-assurance measures. These tools largely remove the
|
||||
burden of manual testing while helping us to uphold the stability and quality
|
||||
of the framework as it grows in terms of functional complexity and number of
|
||||
base platforms.
|
||||
|
||||
Speaking of functional enhancements, the work on version 11.08 was focused
|
||||
on our block-device infrastructure and ARM support. The block-device-related
|
||||
work is primarily motivated by our fundamental goal to scale Genode to a
|
||||
general-purpose computing platform. The additions comprise new drivers for
|
||||
SD-cards, IDE, SATA, USB storage as well as a new partition server. All those
|
||||
components provide Genode's generic block interface, which is meant to be used
|
||||
as back end for file systems. On file-system level, a new libc plugin utilizes
|
||||
libffat to enable the straight-forward use of VFAT partitions by libc-using
|
||||
programs.
|
||||
|
||||
The current release comes with far-reaching improvements with respect to
|
||||
ARM-based platforms. The paravirtualized L4Linux kernel has been updated to
|
||||
Linux version 2.6.39 running on both x86_32 and ARM. Also, Qt4 including Webkit
|
||||
has become functional on ARMv6-based platforms.
|
||||
|
||||
Among the further improvements are many new examples in the form of
|
||||
ready-to-use run scripts as well as a comprehensive documentation update.
|
||||
|
||||
Originally, we had planned to complement the Noux runtime environment to
|
||||
support interactive command-line applications by the time of the current
|
||||
release. However, we realized that the current users of the framework would
|
||||
value the new streamlined tooling support, the enhanced documentation, and the
|
||||
new quality-assurance infrastructure over such a functional addition. Hence, we
|
||||
prioritized the topics accordingly. Even though you will find the first bits of
|
||||
interactive GNU application support in this release, we deferred working on
|
||||
this topic in full steam to the upcoming version 11.11.
|
||||
|
||||
|
||||
Blurring the boundaries between different kernels
|
||||
#################################################
|
||||
|
||||
Before the Genode project was born, each microkernel carried along its own
|
||||
userland. For example, the L4/Fiasco kernel came with the L4 environment, the
|
||||
OKL4 kernel came with Iguana, or the L4ka::Pistachio kernel came with a small
|
||||
set of example components. Those user-level counterparts of the kernel
|
||||
complemented their respective kernels with a runtime for user-level
|
||||
applications and components while exposing significant parts of the kernel
|
||||
interface at API level. Consequently, most if not all applications developed
|
||||
against these APIs were tied to a particular kernel. On the one hand, this
|
||||
approach enabled developers to fine-tune their programs using kernel-specific
|
||||
features. On the other hand, much effort was wasted by duplicating other
|
||||
people's work. Eventually, all of the mentioned userlands stayed limited to
|
||||
special purposes - for the most part the purposes of operating-systems
|
||||
researchers. Consequently, none of the microkernels gained much attention in
|
||||
general-purpose computing. Another consequence of the highly fragmented
|
||||
microkernel community was the lack of a common ground to compare different
|
||||
kernels in an unbiased way because each userland provided a different set of
|
||||
components and libraries.
|
||||
|
||||
Different application areas call for different kernel features such as
|
||||
security mechanisms, scheduling, resource management, and hardware support.
|
||||
Naturally, each kernel exhibits a specific profile of these parameters
|
||||
depending on its primary purpose. If one microkernel attempted to accommodate
|
||||
too many features, it would certainly sacrifice the fundamental idea of being
|
||||
minimally complex. Consequently, kernels happen to be vastly different. During
|
||||
the past three years, however, Genode has demonstrated that one carefully
|
||||
crafted API can target highly diverse kernels, and thereby enables users of
|
||||
the framework to select the kernel that fits best with the requirements
|
||||
dictated by each application scenario individually. For us Genode developers,
|
||||
it was extremely gratifying to see that kernels as different as Linux and NOVA
|
||||
can be reconciled at the programming-interface level. Still, each kernel comes
|
||||
with different tools, configuration mechanisms, and boot concepts. Even though
|
||||
Genode programs can be developed in a kernel-independent way, the deployment of
|
||||
such programs still required profound insights into the peculiarities of the
|
||||
respective kernel.
|
||||
|
||||
With the current release, we introduce a fundamentally new way of using
|
||||
different microkernels by unifying the procedures of downloading and building
|
||||
kernels as well as integrating and running Genode programs with each of them.
|
||||
Existing Genode application scenarios can be ported between kernels in an
|
||||
instant without the need for deep insights into the kernel's technicalities. As
|
||||
a teaser, consider the following commands for building and running Genode's
|
||||
graphical demo scenario on the OKL4 microkernel:
|
||||
|
||||
! # check out Genode
|
||||
! svn co https://genode.svn.sourceforge.net/svnroot/genode/trunk genode
|
||||
!
|
||||
! # download the kernel, e.g., OKL4
|
||||
! make -C genode/base-okl4 prepare
|
||||
!
|
||||
! # create Genode build directory
|
||||
! genode/tool/create_builddir \
|
||||
! okl4_x86 BUILD_DIR=build
|
||||
!
|
||||
! # build everything and execute the interactive demo
|
||||
! make -C build run/demo
|
||||
|
||||
The same principle steps can be used for any of the OKL4, NOVA,
|
||||
L4/Fiasco, Fiasco.OC, L4ka::Pistachio, or Codezero kernels. You should
|
||||
nevertheless consult the documentation at 'base-<platform>/doc/' before
|
||||
starting to use a specific kernel because some base platforms require
|
||||
the installation of additional tools.
|
||||
|
||||
Under the hood, this seamless way of dealing with different kernels is made
|
||||
possible by the following considerations:
|
||||
|
||||
:Repository preparation:
|
||||
|
||||
Each kernel comes from a different source such as a Git/SVN/Mercurial
|
||||
repository or a packaged archive. Some kernels require additional patches. For
|
||||
example, OKL4 needs to be patched to overcome problems with modern tool chains.
|
||||
Now, each 'base-<platform>' repository hosts a 'Makefile' that automates the
|
||||
download and patch procedure. To download the source code of a kernel,
|
||||
issue 'make prepare' from within the kernel's 'base-<platform>' directory. The
|
||||
3rd-party source code will be located at 'base-<platform>/contrib/'.
|
||||
|
||||
:Building the kernel:
|
||||
|
||||
Each kernel has a different approach when it comes to configuration and
|
||||
compilation. For example, NOVA comes with a simple 'Makefile', OKL4 relies on a
|
||||
complex SCons-based build system, L4ka::Pistachio uses CML2 and autoconf (for
|
||||
the userland tools). Furthermore, some kernels require the setting of specific
|
||||
configuration values. We have streamlined all these procedures into the Genode
|
||||
build process by the means of a 'kernel' pseudo target and a 'platform' pseudo
|
||||
library. The kernel can be compiled directly from the Genode build directory by
|
||||
issuing 'make kernel'. The 'platform' pseudo library takes care of making the
|
||||
kernel headers available to Genode. For some kernels such as OKL4 and NOVA, we
|
||||
replaced the original build mechanism with a Genode target. For other kernels
|
||||
such as L4ka::Pistachio or Fiasco.OC, we invoke the kernel's build system.
|
||||
|
||||
:Genode build directory:
|
||||
|
||||
Genode build directories are created via the 'tool/create_builddir' tool.
|
||||
This tool used to require certain kernel-specific arguments such as the
|
||||
location of the kernel source tree. Thanks to the unified way of preparing
|
||||
kernels, the need for such arguments has vanished. Now, the only remaining
|
||||
arguments to 'create_builddir' are the actual platform and the location
|
||||
of the build directory to create.
|
||||
|
||||
:System integration and booting:
|
||||
|
||||
As diverse the build systems of the kernels are, so are the boot concepts. Some
|
||||
kernels rely on a multiboot-compliant boot loader whereas others have special
|
||||
tools for creating boot images. Thankfully, Genode's run concept allows us to
|
||||
hide the peculiarities of booting behind a neat and easy-to-use facade. For
|
||||
each platform we have crafted a dedicated run environment located at
|
||||
'base-<platform>/run/env', which contains the rules for system integration and
|
||||
booting. Therefore, one and the same run script can be used to build and
|
||||
execute one application scenario across various different kernels. For an
|
||||
illustrative example, the 'os/src/run/demo.run' script can be executed on all
|
||||
base platforms (except for base-mb) by issuing 'make run/demo' from within the
|
||||
build directory.
|
||||
|
||||
|
||||
Emerging block-device infrastructure
|
||||
####################################
|
||||
|
||||
Since version 10.08, Genode is equipped with a block-session interface. Its
|
||||
primary use cases so far were the supply of the paravirtualized OKLinux kernel
|
||||
with backing store, and the access of the content of a bootable Live CD.
|
||||
However, for our mission to use Genode as general-purpose computing platform,
|
||||
disk device access is crucial. Therefore, we dedicated our attention to
|
||||
various aspects of Genode's block-device infrastructure, reaching from
|
||||
programming APIs for block drivers, over partition handling, to file-system
|
||||
access.
|
||||
|
||||
:Block session interface:
|
||||
|
||||
The glue that holds all block-device-related components together is the generic
|
||||
block interface 'os/include/block_session'. It is based on the framework's
|
||||
packet-stream facility, which allows the communication of bulk data via shared
|
||||
memory and a data-flow protocol using asynchronous notifications. The interface
|
||||
supports arbitrary allocation schemes and the use of multiple outstanding
|
||||
requests. Hence, it is generally suited for scatter-gather DMA and the use of
|
||||
command queuing as offered by the firmware of modern block-device controllers.
|
||||
(albeit the current drivers do not exploit this potential yet)
|
||||
|
||||
:Block component framework:
|
||||
|
||||
Our observation that components implementing the block session interface share
|
||||
similar code patterns prompted us to design a framework API for implementing
|
||||
this family of components. The set of classes located at 'os/include/block'
|
||||
facilitate the separation of device-specific code from application logic.
|
||||
Whereas 'component.h' provides the application logic needed to implement the
|
||||
block service, the 'driver.h' is an abstract interface to be implemented by the
|
||||
actual device driver. This new infrastructure significantly reduces code
|
||||
duplication among new block-device drivers.
|
||||
|
||||
:Device-driver implementations:
|
||||
|
||||
The new block-device drivers introduced with the current release address
|
||||
common types of block devices:
|
||||
|
||||
* By adding ATA read/write support to the ATAPI driver ('os/src/drivers/atapi'),
|
||||
this driver can be used to access IDE disks now.
|
||||
* The new fully-functional SD-card driver ('os/src/drivers/sdcard') enables the
|
||||
use of SD-cards connected via the PL180 controller.
|
||||
* The USB storage driver ('linux_drivers/src/drivers/usb') has been adapted
|
||||
to the block-session interface and can be used on PC hardware.
|
||||
* The new AHCI driver ('os/src/drivers/ahci') enables the access of disks
|
||||
connected via SATA on PC hardware.
|
||||
|
||||
Because all drivers are providing the generic block-session interfaces, they
|
||||
can be arbitrarily combined with components that use this interface as back
|
||||
end, for example, the partition server and file systems.
|
||||
|
||||
:Partition manager as resource multiplexer:
|
||||
|
||||
The new partition manager ('os/src/server/part_blk') multiplexes one back-end
|
||||
block session to multiple block sessions, each accessing a different partition.
|
||||
Its natural role is being "plugged" between a block-device driver and a file
|
||||
system.
|
||||
|
||||
:File-system access:
|
||||
|
||||
Even though a session interface for file systems does not exist yet, we
|
||||
enabled the use of VFAT partitions through a libc plugin. This libc plugin uses
|
||||
the ffat library to access files stored on a block device. An
|
||||
application using this plugin can be directly connected to a block session.
|
||||
|
||||
|
||||
New documentation
|
||||
#################
|
||||
|
||||
The new way of dealing with different kernels motivated us to revisit and
|
||||
complement our exiting documentation. The following documents are new or
|
||||
have received considerable attention:
|
||||
|
||||
:[https://genode.org/documentation/developer-resources/getting_started - Getting started]:
|
||||
The revised guide of how to explore Genode provides a quick way to
|
||||
test drive Genode's graphical demo scenario with a kernel of your
|
||||
choice and gives pointers to documents needed to proceed your
|
||||
exploration.
|
||||
|
||||
:[https://genode.org/documentation/developer-resources/build_system - Build system manual]:
|
||||
The new build-system manual explains the concepts behind Genode's
|
||||
build system, provides guidance with creating custom programs and
|
||||
libraries, and covers the tool support for the automated integration
|
||||
and testing of application scenarios.
|
||||
|
||||
:[https://genode.org/documentation/components - Components overview]:
|
||||
The new components-overview document explains the categorization of
|
||||
Genode's components and lists all components that come with the framework.
|
||||
|
||||
:[https://genode.org/documentation/developer-resources/init - Configuration of the init process]:
|
||||
The document describes Genode's configuration concept, the routing of
|
||||
service requests, and the expression of mandatory access-control policies.
|
||||
|
||||
:[https://genode.org/community/wiki - Wiki]:
|
||||
The platform-specific Wiki pages for L4/Fiasco, L4ka::Pistachio, NOVA,
|
||||
Codezero, Fiasco.OC, and OKL4 have been updated to reflect the new flows of
|
||||
working with the respective base platforms.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
The RPC API for performing procedure calls across process boundaries
|
||||
introduced with the version 11.05 was the most significant API change
|
||||
in Genode's history. To make the transition from the old client-server
|
||||
API to the new RPC API as smooth as possible, we temporarily upheld
|
||||
compatibility to the old API. Now, the time has come to put the old
|
||||
API at rest. The changes that are visible at API level are as follows:
|
||||
|
||||
* The old client-server API in the form of 'base/server.h' is no more.
|
||||
The functionality of the original classes 'Server_entrypoint' and
|
||||
'Server_activation' is contained in the 'Rpc_entrypoint' class provided
|
||||
via 'base/rpc_server.h'.
|
||||
|
||||
* When introducing the RPC API, we intentionally left the actual session
|
||||
interfaces as unmodified as possible to proof the versatility of the new
|
||||
facility. However, it became apparent that some of the original interfaces
|
||||
could profit from using a less C-ish style. For example, some interfaces used
|
||||
to pass null-terminated strings as 'char const *' rather than via a dedicated
|
||||
type. The methodology of using the new RPC API while leaving the original
|
||||
interfaces intact was to implement such old-style functions as wrappers
|
||||
around new-style RPC functions. These wrappers were contained in
|
||||
'rpc_object.h' files, e.g. for 'linux_dataspace', 'parent', 'root',
|
||||
'signal_session', 'cpu_session'. Now, we have taken the chance to modernise
|
||||
the API by disposing said wrappers. Thereby, the need for 'rpc_object.h'
|
||||
files has (almost) vanished.
|
||||
|
||||
* The remaining users of the old client-server API have been adapted to the
|
||||
new RPC API, most prominently, the packet-stream-related interfaces such as
|
||||
'block_session', 'nic_session', and 'audio_session'.
|
||||
|
||||
* We removed 'Typed_capability' and the second argument of the 'Capability'
|
||||
template. The latter was an artifact that was only used to support the
|
||||
transition from the old to the new API.
|
||||
|
||||
* The 'ipc_client' has no longer an 'operator int'. The result of an IPC can
|
||||
be requested via the 'result' function.
|
||||
|
||||
* We refined the accessors of 'Rpc_in_buffer' in 'base/rpc_args.h'. The
|
||||
'addr()' has been renamed to 'base()', 'is_valid_string()' considers the
|
||||
buffer's capacity, and the new 'string()' function is guaranteed to return a
|
||||
null-terminated string.
|
||||
|
||||
* We introduced a new 'Rm_session::Local_addr' class, which serves two
|
||||
purposes. It allows the transfer of the bit representation of pointers across
|
||||
RPC calls and effectively removes the need for casting the return type of
|
||||
'Rm_session::attach' to the type needed at the caller side.
|
||||
|
||||
* The 'Connection' class template has been simplified, taking the session
|
||||
interface as template argument (rather than the capability type). This change
|
||||
simplified the 'Connection' classes of most session interfaces.
|
||||
|
||||
* The never-used return value of 'Parent::announce' has been removed. From the
|
||||
child's perspective, an announcement always succeeds. The way of how the
|
||||
announcement is treated is entirely up to the parent. The client should never
|
||||
act differently depending on the parent's policy anyway.
|
||||
|
||||
* The new 'Thread_base::cap()' accessor function allows obtaining the thread's
|
||||
capability as used for the argument to CPU-session operations.
|
||||
|
||||
|
||||
Operating-system services and libraries
|
||||
#######################################
|
||||
|
||||
Dynamic linker
|
||||
==============
|
||||
|
||||
As a follow-up to the major revision of the dynamic linker that was featured
|
||||
with the previous release, we addressed several corner cases related to
|
||||
exception handling and improved the handling of global symbols.
|
||||
|
||||
The dynamic linker used to resolve requests for global symbols by handing out
|
||||
its own symbols if present. However, in some cases, this behaviour is
|
||||
undesired. For example, the dynamic linker contains a small set of libc
|
||||
emulation functions specifically for the ported linker code. In the presence of
|
||||
the real libc, however, these symbols should never be considered at all. To
|
||||
avoid such ambiguities during symbol resolution, the set of symbols to be
|
||||
exported is now explicitly declared by the white-list contained in the
|
||||
'os/src/lib/ldso/symbol.map' file.
|
||||
|
||||
We changed the linkage of the C++ support library ('cxx') against dynamic
|
||||
binaries to be consistent with the other base libraries. Originally, the 'cxx'
|
||||
library was linked to both the dynamic linker and the dynamic binary, which
|
||||
resulted in subtle problems caused by the duplication of cxx-internal data
|
||||
structures. By linking 'cxx' only to the dynamic linker and exporting the
|
||||
'__cxa' ABI as global symbols, these issues have been resolved. As a positive
|
||||
side effect, this change reduces the size of dynamic binaries.
|
||||
|
||||
C++ exception handling in the presence of shared libraries turned out to be
|
||||
more challenging than we originally anticipated. For example, the
|
||||
'_Unwind_Resume' symbol is exported by the compiler's 'libsupc++' as a hidden
|
||||
global symbol, which can only be resolved when linking this library to the
|
||||
binary but is not seen by the dynamic linker. This was the actual reason of why
|
||||
we used to link 'cxx' against both dynamic binaries and shared libraries
|
||||
causing the problem mentioned in the previous paragraph. Normally, this problem
|
||||
is addressed by a shared library called 'libgcc_s.so' that comes with the
|
||||
compiler. However, this library depends on glibc, which prevents us from using
|
||||
it on Genode. Our solution is renaming the hidden global symbol using a
|
||||
'_cxx__' prefix and introducing a non-hidden global wrapper function
|
||||
('__cxx__Unwind_Resume' in 'unwind.cc'), which is resolved at runtime by the
|
||||
dynamic linker.
|
||||
|
||||
Another corner case we identified is throwing exceptions from within the
|
||||
dynamic linker. In contrast to the original FreeBSD version of the dynamic
|
||||
linker, which is a plain C program that can never throw a C++ exception,
|
||||
Genode's version relies on C++ code that makes use of exceptions. To support
|
||||
C++ exceptions from within the dynamic linker, we have to relocate the
|
||||
linkers's global symbols again after having loaded the dynamic binary. This
|
||||
way, type information that is also present within the dynamic binary becomes
|
||||
relocated to the correct positions.
|
||||
|
||||
|
||||
Block partition server
|
||||
======================
|
||||
|
||||
The new block-partition server uses Genode's block-session interfaces as both
|
||||
front and back end, leading to the most common use case where this server will
|
||||
reside between a block driver and a higher level component like a file-system
|
||||
server.
|
||||
|
||||
At startup, the partition server will try to parse the master boot record (MBR)
|
||||
of its back-end block session. If no partition table is found, the whole block
|
||||
device is exported as partition '0'. In the other case, the MBR and possible
|
||||
extended boot records (EBRs) are parsed and offered as separate block sessions
|
||||
to the front-end clients. The four primary partitions will receive partition
|
||||
numbers '1' to '4' whereas the first logical partition will be assigned to '5'.
|
||||
|
||||
The policy of which partition is exposed to which client can be expressed
|
||||
in the config supplied to the 'part_blk' server. Please refer to the
|
||||
documentation at 'os/src/server/part_blk/README' for further details. As an
|
||||
illustration of the practical use of the 'part_blk' server, you can find a run
|
||||
script at 'os/run/part_blk.run'.
|
||||
|
||||
|
||||
Skeleton of text terminal
|
||||
=========================
|
||||
|
||||
As part of the ongoing work towards using interactive text-based GNU software
|
||||
on Genode, we created the first bits of the infrastructure required for
|
||||
pursuing this quest:
|
||||
|
||||
The new terminal-session interface at 'os/include/terminal_session/' is the
|
||||
designated interface to be implemented by terminal programs.
|
||||
|
||||
After investigating the pros and cons of various terminal protocols and
|
||||
terminal emulators, we settled for implementing a custom terminal emulator
|
||||
implementing the Linux termcap. This termcap offers a reasonable small set of
|
||||
commands while providing all essential features such as function-key support
|
||||
and mouse support. Thanks to Peter Persson for pointing us to the right
|
||||
direction! The preliminary code for parsing the escape sequences for the Linux
|
||||
termcap is located at 'gems/include/terminal/'.
|
||||
|
||||
We have created a simplistic terminal service that implements the
|
||||
terminal-session interface using a built-in font. Please note that the
|
||||
implementation at 'gems/src/server/terminal/' is at an early stage. It is
|
||||
accompanied by a simple echo program located at 'gems/src/test/terminal_echo'.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
USB HID and USB storage
|
||||
=======================
|
||||
|
||||
We replaced the former DDE-Linux-based USB-related driver libraries (at the
|
||||
'linux_drivers/' repository) by a single USB driver server that offers the
|
||||
'Input' and 'Block' services. This enables us to use both USB HID and USB
|
||||
storage at the same time. The new USB driver is located at
|
||||
'linux_drivers/src/drivers/usb/'.
|
||||
|
||||
For using the USB driver as input service (supporting USB HID), add the
|
||||
'<hid/>' tag to the 'usb_drv' configuration. Analogously, for using the driver
|
||||
as block service, add the '<storage/>' tag. Both tags can be combined.
|
||||
|
||||
For testing the USB stack, the 'linux_drivers' repository comes with the run
|
||||
scripts 'usb_hid.run' and 'usb_storage.run'.
|
||||
|
||||
|
||||
ATA read/write support
|
||||
======================
|
||||
|
||||
The ATAPI driver has been extended to support IDE block devices for both
|
||||
read and write transactions. To use the new facility, supply 'ata="yes"'
|
||||
as XML attribute to the config node of 'atapi_drv'. Please note that this
|
||||
driver was primarily tested on Qemu. Use it with caution.
|
||||
|
||||
|
||||
SATA driver
|
||||
===========
|
||||
|
||||
The new SATA driver at 'os/src/drivers/ahci/' implements the block-driver
|
||||
API ('os/include/block'), thus exposing the block-session interface as
|
||||
front-end. AHCI depends on Genode's PCI driver as well as the timer server. For
|
||||
a usage example see: 'os/run/ahci.run'.
|
||||
|
||||
Limitations and known issues
|
||||
----------------------------
|
||||
|
||||
Currently, the server scans the PCI bus at startup and retrieves the first available
|
||||
AHCI controller, scans the controller ports and uses the first non-ATAPI port
|
||||
where a device is present.
|
||||
|
||||
On real hardware and on kernels taking advantage of I/O APICs (namely NOVA and
|
||||
Fiasco.OC) we still lack support for ACPI parsing and thus for interrupts,
|
||||
leading to a non-working driver.
|
||||
|
||||
|
||||
SD-card driver
|
||||
==============
|
||||
|
||||
The first fragments of our SD-card driver that we introduced with the previous
|
||||
release have been complemented. The new SD-card driver located at
|
||||
'os/src/drivers/sd_card/' implements the block-session interface by using
|
||||
MMC/SD-cards and the PL180 controller as back end. Currently the driver
|
||||
supports single-capacity SD cards. Therefore, the block file for Qemu should
|
||||
not exceed 512 MB. Because the driver provides the generic block-session
|
||||
interface, it can be combined with the new 'libc_ffat' plugin in a
|
||||
straight-forward way. To give the driver a quick spin, you may give the
|
||||
'libports/run/libc_ffat.run' script on the 'foc_pbxa9' platform a try.
|
||||
|
||||
|
||||
ARM Realview PL011 UART driver
|
||||
==============================
|
||||
|
||||
The new PL011 UART driver at 'os/src/drivers/uart/' implements the LOG session
|
||||
interface using the PL011 device. Up to 4 UARTs are supported. The assignment
|
||||
of UARTs to clients can be defined via a policy supplied to the driver's config
|
||||
node. For further information, please refer to the README file within the
|
||||
'uart' directory.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Hello tutorial
|
||||
==============
|
||||
|
||||
The 'hello_tutorial/' repository contains a step-by-step guide for building
|
||||
a simple client-server scenario. The tutorial has been rewritten for the new
|
||||
RPC API and is now complemented by a run script for testing the final scenario
|
||||
on various base platforms.
|
||||
|
||||
C and C++ runtimes
|
||||
==================
|
||||
|
||||
:Support for standard C++ headers:
|
||||
|
||||
Triggered by public demand for using standard C++ headers for Genode applications,
|
||||
we introduced a generally usable solution in the form of the 'stdcxx' library
|
||||
to the 'libc' repository. The new 'stdcxx' library is not a real library. (you
|
||||
will find the corresponding 'lib/mk/stdcxx.mk' file empty) However, it comes
|
||||
with a 'lib/import/import-stdcxx.mk' file that adds the compiler's C++ includes
|
||||
to the default include-search path for any target that has 'stdcxx' listed in
|
||||
its 'LIBS' declaration.
|
||||
|
||||
:Libc back end for accessing VFAT partitions:
|
||||
|
||||
The new 'libc_ffat' libc plugin uses a block session via the ffat library. It
|
||||
can be used by a Genode application to access a VFAT file system via the libc
|
||||
file API. The file-system access is performed via the 'ffat' library. To
|
||||
download this library and integrate it with Genode, change to the 'libports'
|
||||
repository and issue the following command:
|
||||
! make prepare PKG=ffat
|
||||
For an example of how to use the libc-ffat plugin, please refer to the run
|
||||
script 'libports/run/libc_ffat.run'. The source code of the test program can be
|
||||
found at 'libports/src/test/libc_ffat/'.
|
||||
|
||||
Qt4
|
||||
===
|
||||
|
||||
Qt4 version 4.7.1 has been enabled on ARMv6-based platforms, i.e., PBX-A9 on
|
||||
Fiasco.OC. The support comprises the entire Qt4 framework including qt_webcore
|
||||
(Webkit).
|
||||
|
||||
L4Linux
|
||||
=======
|
||||
|
||||
L4Linux enables the use of one or multiple instances of Linux-based operating
|
||||
systems as subsystems running on the Fiasco.OC kernel. The Genode version of
|
||||
L4Linux has seen the following improvements:
|
||||
|
||||
:Kernel version: has been updated to Linux 2.6.39.
|
||||
|
||||
:ARM support: The L4Linux kernel can be used on ARM-based platforms now.
|
||||
The PBX-A9 platform is supported via the 'l4linux.run' script as found
|
||||
at 'ports-foc/run/'. Please find more information at 'ports-foc/README'.
|
||||
|
||||
:Genode-specific stub drivers outside the kernel tree:
|
||||
The stub drivers that enable the use of Genode's services as virtual
|
||||
devices for L4Linux have been moved outside the kernel patch, which
|
||||
makes them much easier to maintain. These stub drivers are located
|
||||
under 'ports-foc/src/drivers/'.
|
||||
|
||||
|
||||
Platform support
|
||||
################
|
||||
|
||||
All base platforms are now handled in a unified fashion. Downloading 3rd-party
|
||||
source code is performed using the 'prepare' rule of the 'Makefile' provided by
|
||||
the respective kernel's 'base-<platform>' repository. Once, the platform's base
|
||||
repository is prepared, the kernel can be built directly from the Genode
|
||||
build directory using 'make kernel'. All base platforms are now supported by
|
||||
Genode's run mechanism that automates the tasks of system integration and
|
||||
testing. For more details about each specific kernel, please revisit the
|
||||
updated documentation within the respective 'base-<platform>/doc/' directory.
|
||||
|
||||
:L4/Fiasco:
|
||||
|
||||
The kernel has been updated to revision 472, enabling the use of recent
|
||||
GNU tool chains.
|
||||
|
||||
:Fiasco.OC:
|
||||
|
||||
The kernel as been updated to revision 36, which remedies stability problems
|
||||
related to interaction of the IPC path with thread destruction. The new version
|
||||
improves the stability of highly dynamic workloads that involve the frequent
|
||||
creation and destruction of subsystems. However, we experienced the new kernel
|
||||
version to behave instable on the x86_64 architecture. If you depend on x86_64,
|
||||
we recommend to temporarily stick with Genode 11.05 and Fiasco.OC revision 31.
|
||||
|
||||
:L4ka::Pistachio:
|
||||
|
||||
The kernel has been updated to revision 803, enabling the use of recent
|
||||
versions of binutils.
|
||||
|
||||
:OKL4:
|
||||
|
||||
OKL4v2 is showing its age. Apparently, the use of the original distribution
|
||||
requires tools (i.e., python 2.4) that do not ship with current Linux
|
||||
distributions anymore. This makes it increasingly difficult to use this kernel.
|
||||
Still, we find ourselves frequently using it for our day-to-day development. To
|
||||
streamline the use of OKL4v2, we have now incorporated the kernel compilation
|
||||
into the Genode build system and thereby weakened the kernel's dependency on
|
||||
ancient tools. However, we decided to drop support for OKL4/ARM for now. We
|
||||
figured that the supported GTA01 platform is hardly used anymore and hard to
|
||||
test because it is unsupported by Qemu. Newer ARM platforms are supported by
|
||||
other kernels anyway.
|
||||
|
||||
:Codezero:
|
||||
|
||||
Even though B-Labs apparently abandoned the idea of developing the Codezero
|
||||
kernel in the open, we adapted Genode to the kernel's most recent Open-Source
|
||||
version that is still available at the official Git repository. Furthermore,
|
||||
the kernel is now fully supported by Genode's new 'make prepare' procedure and
|
||||
run environment. Therefore, run scripts such as 'run/demo' can now easily be
|
||||
executed on Codezero without the need to manually configure the kernel.
|
||||
|
||||
Note that, for now, we have disabled Codezero's capabilities because they do
|
||||
not allow the assignment of device resources. Consequently, 'sys_map' fails for
|
||||
MMIO regions when performing the capability check (calling 'cap_map_check').
|
||||
Furthermore, the current version of the kernel requires a workaround for a
|
||||
current limitation regarding the definition of a thread's pager. At some point,
|
||||
Codezero abandoned the facility to define the pager for a given thread via the
|
||||
exregs system call. Instead, the kernel hard-wires the creator of the thread as
|
||||
the thread's pager. This is conflicting with Genode's way of creating and
|
||||
paging threads. In the current version of Genode for this kernel, all threads
|
||||
are paged by one thread (thread 3 happens to be the global pager) within core.
|
||||
As a workaround to Codezero's current limitation, we define thread 3 to be the
|
||||
pager of all threads. The patch of the upstream code is automatically being
|
||||
applied by the 'make prepare' mechanism.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
In addition to the major change with respect to the integration of the various
|
||||
base platforms, Genode's tool support received the following incremental
|
||||
improvements:
|
||||
|
||||
|
||||
Build system
|
||||
============
|
||||
|
||||
:Simplification of 'create_builddir' tool:
|
||||
|
||||
The 'create_builddir' tool has been relocated from
|
||||
'tool/builddir/create_builddir' to 'tool/create_builddir' to make it more
|
||||
readily accessible. Furthermore, we simplified the usage of the tool by
|
||||
removing the mandatory 'GENODE_DIR' argument. If not explicitly specified, the
|
||||
tool deduces 'GENODE_DIR' from the its known location within the Genode source
|
||||
tree.
|
||||
|
||||
:Booting from USB sticks:
|
||||
|
||||
For most x86-based base platforms, their respective run environments execute
|
||||
Genode from an ISO image via Qemu. Naturally, such an ISO image can be burned
|
||||
onto a CD-ROM to be used to boot a real machine. However, booting from CD-ROM
|
||||
is slow and optical drives are becoming scarce. Therefore we changed the
|
||||
procedure of creating ISO images to support writing the resulting images to a
|
||||
USB stick. Under the hood, the boot mechanism chain-loads GRUB via ISOLinux.
|
||||
The files to implement the boot concept are located at 'tool/boot/'.
|
||||
|
||||
:Support for source files in target sub directories:
|
||||
|
||||
Until now, the 'SRC_*' declarations in target description files contained
|
||||
a list of plain file names. The location of the files within the directory
|
||||
tree had to be defined via 'vpath'. This led to inconveniences when building
|
||||
3rd-party code that contains files with the same name at different subdirectories.
|
||||
To resolve such an ambiguity, the target had to be decomposed into multiple
|
||||
libraries each building a different set of subdirectories. To make the
|
||||
build system more convenient to use, we have now added support for specifying
|
||||
source codes with a relative pathname. For example, instead of using
|
||||
! SRC_CC = main.cc addon.cc
|
||||
! vpath addon.cc $(PRG_DIR)/contrib
|
||||
we can now use
|
||||
! SRC_CC = main.cc contrib/addon.cc
|
||||
|
||||
|
||||
Automated testing across multiple kernels
|
||||
=========================================
|
||||
|
||||
To execute one or multiple test cases on more than one base platform, we
|
||||
introduced a dedicated tool located at 'tool/autopilot'. Its primary purpose is
|
||||
the nightly execution of test cases. The tool takes a list of platforms and a
|
||||
list of run scripts as arguments and executes each run script on each platform.
|
||||
The build directory for each platform is created at
|
||||
'/tmp/autopilot.<username>/<platform>' and the output of each run script is
|
||||
written to a file called '<platform>.<run-script>.log'. On stderr, autopilot
|
||||
prints the statistics about whether or not each run script executed
|
||||
successfully on each platform. If at least one run script failed, autopilot
|
||||
returns a non-zero exit code, which makes it straight forward to include
|
||||
autopilot into an automated build-and-test environment.
|
||||
|
||||
1008
doc/release_notes/11-11.txt
Normal file
1008
doc/release_notes/11-11.txt
Normal file
File diff suppressed because it is too large
Load Diff
862
doc/release_notes/12-02.txt
Normal file
862
doc/release_notes/12-02.txt
Normal file
@@ -0,0 +1,862 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 12.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The release of Genode 12.02 marks an exciting point in the history of the
|
||||
project as it is the first version developed in the open rather than within the
|
||||
chambers of Genode Labs. Thereby, we have embraced GitHub as central facility
|
||||
for discussion and source-code management. This change has benefits for users
|
||||
and developers of the framework alike. For users, it has become possible to get
|
||||
hold of the latest developments using the official 'genodelabs/master' branch and
|
||||
get involved with discussing the current activities. For regular Genode
|
||||
developers, the public Git repository replaces a former mix of public
|
||||
Subversion and company-internal Mercurial repositories, making life much
|
||||
easier. In Section [Liberation of the development process], we outline the
|
||||
motivation behind this change and give pointers to the new resources.
|
||||
|
||||
The major new additions to the base system are a new framework API for accessing
|
||||
memory-mapped I/O resources, special support for using Genode as user-level
|
||||
component framework on Linux, and API support for the reuse of existing
|
||||
components in the form of sandboxed libraries. These changes are accompanied
|
||||
with new device-driver infrastructure such as the first version of a device
|
||||
driver manager and a new ACPI parser.
|
||||
|
||||
Feature-wise, the current release takes the first steps towards the goal of the
|
||||
[https://genode.org/about/road-map - Roadmap for 2012], turning Genode into a
|
||||
general-purpose OS ready for everyday use by its developers. According to the
|
||||
roadmap, we enhanced the Noux runtime with fork semantics so that we can run
|
||||
command-line based GNU programs such as the bash shell and coreutils unmodified
|
||||
and natively on various microkernels. Furthermore, the library infrastructure
|
||||
has been enhanced by porting and updating libraries such as Qt 4.7.4 and the
|
||||
MuPDF PDF rendering engine.
|
||||
|
||||
|
||||
Liberation of the development process
|
||||
#####################################
|
||||
|
||||
In summer 2011, we started a discussion within Genode Labs about changing the
|
||||
mode of how Genode is developed. Until then, most design discussions and the
|
||||
actual development work took place locally at the company. At quarterly
|
||||
intervals, we used to publish our work in the form of official Genode
|
||||
releases. This way of development seemed to work quite well for us, we were
|
||||
satisfied about the pace of development, and with each release, our project got
|
||||
more recognition.
|
||||
|
||||
However, the excellent book [https://producingoss.com/ - Producing Open Source Software]
|
||||
made us realize that even though we released our work under an Open-Source
|
||||
license, our development process was actually far from being open and may have
|
||||
discouraged participation of people outside the inner circle of developers.
|
||||
Because we believe that the framework has reached a state where it becomes
|
||||
interesting for a wider audience of users and developers, the idea was born
|
||||
to liberate the project from its closed fashion of development.
|
||||
|
||||
In the beginning of December, the vague idea has become a plan. So we finally
|
||||
brought the topic to our mailing list
|
||||
([https://genode.org/news/steps-towards-an-open-development-process - Steps towards an open development process]).
|
||||
We decided to take the release cycle for Genode 12.02 as the opportunity to put
|
||||
our plan to practice. The central element of this endeavour was moving the
|
||||
project over to GitHub and adapt our workflows and tooling support accordingly.
|
||||
First, we started to embrace GitHub's issue tracker for the management of
|
||||
working topics:
|
||||
|
||||
:[https://github.com/genodelabs/genode/issues]: Issue Tracker
|
||||
|
||||
The most significant step was leaving our Genode-Labs-internal code
|
||||
repositories behind and starting a completely public Git repository instead:
|
||||
|
||||
:[https://github.com/genodelabs]: Genode Labs at GitHub
|
||||
|
||||
With the code repository going public, the way was cleared to opening up design
|
||||
discussions as well. Instead of having such discussions internally at Genode
|
||||
Labs, we try to increasingly take them to our mailing list and issue tracker.
|
||||
With this new way of development, we hope to make the project much more
|
||||
approachable for people who want to get involved and let Genode reach far out
|
||||
beyond the reach of our little company.
|
||||
|
||||
The changes mentioned above are actually just the tip of the iceberg. For
|
||||
example, the transition phase required us to rethink the way the project
|
||||
website is maintained. From now on, almost all of the content of genode.org
|
||||
comes directly from the project's Git repository. So maintaining website
|
||||
content is done in the same coherent and transparent way as working on Genode's
|
||||
code base. So we could finally put the old Wiki to rest. In the process, we
|
||||
largely revisited the existing content. For example, we rewrote the
|
||||
[https://genode.org/community/contributions - contributions] document in a
|
||||
tutorial-like style and incorporated several practical hints, in particular
|
||||
related to the recommended use of Git.
|
||||
|
||||
Although it is probably too early to judge the outcome of our transition, we
|
||||
are excited how smooth this massive change went. We attribute this pleasant
|
||||
experience mostly to the excellent GitHub hosting platform, which instantly
|
||||
ignited a spirit of open collaboration among us. We are excited to see new
|
||||
people approaching us and showing their interest for teaming up, and we are
|
||||
curious about where this new model of development will take Genode in the
|
||||
future.
|
||||
|
||||
|
||||
Base framework, low-level OS infrastructure
|
||||
###########################################
|
||||
|
||||
RPC framework refinements
|
||||
=========================
|
||||
|
||||
Until now, the RPC framework did not support const RPC functions. Rather than
|
||||
being a limitation inherent to the concept, const RPC functions plainly did not
|
||||
exist. So supporting them was not deemed too important. However, there are uses
|
||||
of RPC interfaces that would benefit from a way to declare an RPC function as
|
||||
const. Candidates are functions like 'Framebuffer::Session::mode()' and
|
||||
'Input::Session::is_pending()'.
|
||||
|
||||
With the current version, we clear the way towards declaring such functions as
|
||||
const. Even though the change is pretty straight-forward, the thorough support
|
||||
for const-qualified RPC functions would double the number of overloads for the
|
||||
'call_member' function template (in 'base/include/util/meta.h'). For this
|
||||
reason, as of now, the support of const functions is limited to typical getter
|
||||
functions with no arguments. This appears to be the most common use of such
|
||||
functions.
|
||||
|
||||
|
||||
API support for enslaving services
|
||||
==================================
|
||||
|
||||
While evolving and using the framework, we always keep an eye on recurring
|
||||
patterns of how its API is used. Once such a pattern becomes obvious, we try
|
||||
to take a step back, generalize the observed pattern, and come up with a new
|
||||
building block that unifies the former repetitive code fragments.
|
||||
|
||||
One of those patterns that was far from obvious when we designed Genode years
|
||||
ago is the use of a service running as child of its own client. At the first
|
||||
glance, this idea seems counter-intuitive because normally, services are
|
||||
understood as components that operate independently and protected from their
|
||||
(untrusted) clients. But there is a class of problems where this approach
|
||||
becomes extremely useful: The reuse of protocol implementations as a
|
||||
library-like building block. Most services are actually protocol stacks that
|
||||
translate a low-level protocol to a more abstract API. For example, a block
|
||||
device driver translates a specific device API to the generic 'Block_session'
|
||||
interface. Or the 'iso9660' service translates the 'Block_session' interface to
|
||||
the 'Rom_session' interface by parsing the ISO9660 file system. Or similarly,
|
||||
the 'tar_rom' service parses the tar file format to make its content available
|
||||
via the 'Rom_session' interface.
|
||||
|
||||
If a particular functionality is needed by multiple programs, it is common
|
||||
practice to move this functionality into a dedicated library to avoid the
|
||||
duplication of the same code at many places. For example, if a program would
|
||||
need to parse a tar archive, it might be tempting to move the tar-parsing code
|
||||
from the 'tar_rom' service into a dedicated library, which can then be used by
|
||||
both the 'tar_rom' service and the new program. An alternative approach is to
|
||||
just re-use the 'tar_rom' service as a black box and treat it like it was a
|
||||
library. That is, start the 'tar_rom' service as a child process, supply the
|
||||
resources the component needs to operate and, in turn, use its API (now in the
|
||||
form of an RPC interface) to get work done. Because the service is started as a
|
||||
mere tool at the discretion of its client, we call it *slave*. It turns out
|
||||
that this idea works exceedingly well in many cases. In a way, it resembles the
|
||||
Unix philosophy to solve complex problems by combining many small tools each
|
||||
with a specific purpose. In contrast to the use of libraries, the reuse of
|
||||
entire components has benefits with regard to fault isolation. Because the
|
||||
reused functionality is sandboxed within a distinct process, the environment
|
||||
exposed to this code can be tailored to a rigid subset of the host program's
|
||||
environment. In the event of a fault within the reused component, the reach of
|
||||
problem is therefore limited.
|
||||
|
||||
On the other hand, we observed that even though this idea works as intended,
|
||||
implementing the idea for a particular use case involved a good deal of
|
||||
boiler-plate code where most of this code is needed to define the slave's
|
||||
environment and resources. Hence, we reviewed the existing occurrences of the
|
||||
slave pattern and condensed their common concerns into the 'Slave_policy' and
|
||||
'Slave' classes residing in 'os/include/os/slave.h'. The 'Slave' class is meant
|
||||
to be used as is. It is merely a convenience wrapper for a child process and
|
||||
its basic resources. The 'Slave_policy' is meant as a hook for service-specific
|
||||
customizations. The best showcase is the new 'd3m' component located at
|
||||
'gems/src/server/d3m'. D3m extensively uses the slave pattern by instantiating
|
||||
and destroying drivers and file-system instances on-the-fly. A further instance
|
||||
of this pattern can be found in the new ACPI driver introduced with the current
|
||||
release.
|
||||
|
||||
|
||||
Support for resizable framebuffers
|
||||
==================================
|
||||
|
||||
The framebuffer-session interface has remained largely untouched since the
|
||||
original release of Genode in 2008. Back then, we were used to rely on C-style
|
||||
out parameters in RPC functions. The current RPC framework, however, promotes
|
||||
the use of a more object-oriented style. So the time has come to revisit the
|
||||
framebuffer session interface. Instead of using C-style out parameters, the new
|
||||
'mode()' RPC call returns the mode information as an object of type 'Mode'.
|
||||
Consequently, mode-specific functions such as 'bytes_per_pixel()' have been
|
||||
moved to the new 'Framebuffer::Mode' class. The former 'info()' function is
|
||||
gone.
|
||||
|
||||
In addition to the overhaul of the RPC interface, we introduced basic support
|
||||
for resizable framebuffers. The new 'mode_sigh()' function enables a client to
|
||||
register a signal handler at the framebuffer session. This signal handler gets
|
||||
notified in the event of server-side mode changes. Via the new 'release()'
|
||||
function, the client is able to acknowledge a mode change. By calling it, the
|
||||
client tells the framebuffer service that it no longer uses the original
|
||||
framebuffer dataspace. So the server can replace it by a new one. After having
|
||||
called 'release()', the client can obtain the dataspace for the new mode by
|
||||
calling 'dataspace()' again.
|
||||
|
||||
|
||||
MMIO access framework
|
||||
=====================
|
||||
|
||||
As the arsenal of native device drivers for Genode grows, we are observing
|
||||
an increased demand to formalize the style of how drivers are written to
|
||||
foster code consistency. One particular cause of inconsistency used to be
|
||||
the way of how memory-mapped I/O registers are accessed. C++ has poor support
|
||||
for defining bit-accurate register layouts in memory. Therefore, driver code
|
||||
usually carries along a custom set of convenience functions for reading and
|
||||
writing registers of different widths as well as a list of bit definitions in
|
||||
the form of enum values or '#define' statements. To access parts of a register,
|
||||
the usual pattern is similar to the following example (taken from the pl011
|
||||
UART driver:
|
||||
|
||||
! enum {
|
||||
! UARTCR = 0x030, /* control register */
|
||||
! UARTCR_UARTEN = 0x0001, /* enable bit in control register */
|
||||
! ...
|
||||
! }
|
||||
! ...
|
||||
!
|
||||
! /* enable UART */
|
||||
! _write_reg(UARTCR, _read_reg(UARTCR) | UARTCR_UARTEN);
|
||||
|
||||
This example showcases two inconveniences: The way the register layout is
|
||||
expressed and the manual labour needed to access parts of registers. In the
|
||||
general case, a driver needs to also consider 'MASK' and 'SHIFT' values to
|
||||
implement access to partial registers properly. This is not just inconvenient
|
||||
but also error prone. For lazy programmers as ourselves, it's just too easy to
|
||||
overwrite "undefined" bits in a register instead of explicitly masking the
|
||||
access to the actually targeted bits. Consequently, the driver may work fine
|
||||
with the current generation of devices but break with the next generation.
|
||||
|
||||
So the idea was born to introduce an easy-to-use formalism for this problem. We
|
||||
had two goals: First, we wanted to cleanly separate the declaration of register
|
||||
layouts from the program logic of the driver. The actual driver program should
|
||||
be free from any intrinsics in the form of bit-masking operations. Second, we
|
||||
wanted to promote uncluttered driver code that uses names (i.e., in the form of
|
||||
type names) rather than values to express its operations. The latter goal is
|
||||
actually achieved by the example above by the use of enum values, but this is
|
||||
only achieved through discipline. We would prefer to have an API that
|
||||
facilitates the use of proper names as the most convenient way to express an
|
||||
operation.
|
||||
|
||||
The resulting MMIO API comes in the form of two new header files located at
|
||||
'base/include/util/register.h' and 'base/include/util/mmio.h'.
|
||||
|
||||
|
||||
Register declarations
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The class templates found in 'util/register.h' provide a means to express
|
||||
register layouts using C++ types. In a way, these templates make up for
|
||||
C++'s missing facility to define accurate bitfields. Let's take a look at
|
||||
a simple example of the 'Register' class template that can be used to define
|
||||
a register as well as a bitfield within this register:
|
||||
|
||||
! struct Vaporizer : Register<16>
|
||||
! {
|
||||
! struct Enable : Bitfield<2,1> { };
|
||||
! struct State : Bitfield<3,3> {
|
||||
! enum{ SOLID = 1, LIQUID = 2, GASSY = 3 };
|
||||
! };
|
||||
!
|
||||
! static void write (access_t value);
|
||||
! static access_t read ();
|
||||
! };
|
||||
|
||||
In the example, 'Vaporizer' is a 16-bit register, which is expressed via the
|
||||
'Register' template argument. The 'Register' class template allows for
|
||||
accessing register content at a finer granularity than the whole register
|
||||
width. To give a specific part of the register a name, the 'Register::Bitfield'
|
||||
class template is used. It describes a bit region within the range of the
|
||||
compound register. The bit 2 corresponds to true if the device is enabled and
|
||||
bits 3 to 5 encode the 'State'. To access the actual register, the methods
|
||||
'read()' and 'write()' must be provided as backend, which performs the access
|
||||
of the whole register. Once defined, the 'Vaporizer' offers a handy way to
|
||||
access the individual parts of the register, for example:
|
||||
|
||||
! /* read the whole register content */
|
||||
! Vaporizer::access_t r = Vaporizer::read();
|
||||
!
|
||||
! /* clear a bit field */
|
||||
! Vaporizer::Enable::clear(r);
|
||||
!
|
||||
! /* read a bit field value */
|
||||
! unsigned old_state = Vaporizer::State::get(r);
|
||||
!
|
||||
! /* assign new bit field value */
|
||||
! Vaporizer::State::set(r, Vaporizer::State::LIQUID);
|
||||
!
|
||||
! /* write whole register */
|
||||
! Vaporizer::write(r);
|
||||
|
||||
|
||||
Memory-mapped I/O
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The utilities provided by 'util/mmio.h' use the 'Register' template class as
|
||||
a building block to provide easy-to-use access to memory-mapped I/O registers.
|
||||
The 'Mmio' class represents a memory-mapped I/O region taking its local base
|
||||
address as constructor argument. Let's take a simple example to see how it is
|
||||
supposed to be used:
|
||||
|
||||
! class Timer : Mmio
|
||||
! {
|
||||
! struct Value : Register<0x0, 32> { };
|
||||
! struct Control : Register<0x4, 8> {
|
||||
! struct Enable : Bitfield<0,1> { };
|
||||
! struct Irq : Bitfield<3,1> { };
|
||||
! struct Method : Bitfield<1,2>
|
||||
! {
|
||||
! enum { ONCE = 1, RELOAD = 2, CYCLE = 3 };
|
||||
! };
|
||||
! };
|
||||
!
|
||||
! public:
|
||||
!
|
||||
! Timer(addr_t base) : Mmio(base) { }
|
||||
!
|
||||
! void enable();
|
||||
! void set_timeout(Value::access_t duration);
|
||||
! bool irq_raised();
|
||||
! };
|
||||
|
||||
The memory-mapped timer device consists of two registers: The 32-bit 'Value'
|
||||
register and the 8-bit 'Control' register. They are located at the MMIO offsets
|
||||
0x0 and 0x4, respectively. Some parts of the 'Control' register have specific
|
||||
meanings as expressed by the 'Bitfield' definitions within the 'Control'
|
||||
struct.
|
||||
|
||||
Using these declarations, accessing the individual bits becomes almost a
|
||||
verbatim description of how the device is used. For example:
|
||||
|
||||
! void enable()
|
||||
! {
|
||||
! /* access an individual bitfield */
|
||||
! write<Control::Enable>(true);
|
||||
! }
|
||||
!
|
||||
! void set_timeout(Value::access_t duration)
|
||||
! {
|
||||
! /* write complete content of a register */
|
||||
! write<Value>(duration);
|
||||
!
|
||||
! /* write all bitfields as one transaction */
|
||||
! write<Control>(Control::Enable::bits(1) |
|
||||
! Control::Method::bits(Control::Method::ONCE) |
|
||||
! Control::Irq::bits(0));
|
||||
! }
|
||||
!
|
||||
! bool irq_raised()
|
||||
! {
|
||||
! return read<Control::Irq>();
|
||||
! }
|
||||
|
||||
In addition to those basic facilities, further noteworthy features of the new
|
||||
API are the support for register arrays and the graceful overflow handling
|
||||
with respect to register and bitfield boundaries.
|
||||
|
||||
|
||||
C Runtime
|
||||
=========
|
||||
|
||||
We extended our FreeBSD-based C runtime to accommodate the needs of the Noux
|
||||
runtime environment and our port of the MuPDF application.
|
||||
|
||||
* The dummy implementation of '_ioctl()' has been removed. This function is
|
||||
called internally within the libc, i.e., by 'tcgetattr()'. For running
|
||||
libreadline in Noux, we need to hook into those ioctl operations via the
|
||||
libc plugin interface.
|
||||
|
||||
* The 'libc/regex' and 'libc/compat' modules have been added to the libc.
|
||||
These libraries are needed by the forthcoming port of Slashem to Noux.
|
||||
|
||||
* We added a default implementation of 'chdir()'. It relies on the sequence of
|
||||
'open()', 'fchdir()', 'close()'.
|
||||
|
||||
* The new libc plugin 'libc_rom' enables the use of libc file I/O functions
|
||||
to access ROM files as provided by Genode ROM session.
|
||||
|
||||
* We changed the libc dummy implementations to always return ENOSYS. Prior
|
||||
this change, 'errno' used to remain untouched by those functions causing
|
||||
indeterministic behaviour of code that calls those functions, observes the
|
||||
error return value (as returned by most dummies), and evaluates the error
|
||||
condition reported by errno.
|
||||
|
||||
* If using the libc for Noux programs, the default implementations of
|
||||
time-related functions such as 'gettimeofday()' cannot be used because they
|
||||
rely on a dedicated timeout-scheduler thread. Noux programs, however, are
|
||||
expected to contain only the main thread. By turning the functions into weak
|
||||
symbols, we enabled the noux libc-plugin to provide custom implementations.
|
||||
|
||||
|
||||
DDE Kit
|
||||
=======
|
||||
|
||||
Linux DDE used to implement Linux spin locks based on 'dde_kit_lock'. This
|
||||
works fine if a spin lock is initialized only once and used from then on. But
|
||||
if spin locks are initialized on-the-fly at a high rate, each initialization
|
||||
causes the allocation of a new 'dde_kit_lock'. Because in contrast to normal
|
||||
locks, spinlocks cannot be explicitly destroyed, the spin-lock emulating locks
|
||||
are never freed. To solve the leakage of locks, we complemented DDE Kit with
|
||||
the new 'os/include/dde_kit/spin_lock.h' API providing the semantics as
|
||||
expected by Linux drivers.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New and updated libraries
|
||||
=========================
|
||||
|
||||
:Qt4 updated to version 4.7.4:
|
||||
|
||||
We updated Qt4 from version 4.7.1 to version 4.7.4. For the most part, the
|
||||
update contains bug fixes as detailed in the release notes for the versions
|
||||
[https://qt.nokia.com/products/changes/changes-4.7.2 - 4.7.2],
|
||||
[https://qt.nokia.com/products/changes/changes-4.7.3 - 4.7.3], and
|
||||
[https://labs.qt.nokia.com/2011/09/01/qt-4-7-4-released - 4.7.4].
|
||||
|
||||
:Update of zlib to version 1.2.6:
|
||||
|
||||
Because zlib 1.2.5 is no more available at zlib.net, we bumped the zlib
|
||||
version to 1.2.6.
|
||||
|
||||
:New ports of openjpeg, jbig2dec, and mupdf:
|
||||
|
||||
MuPDF is a fast and versatile PDF rendering library with only a few
|
||||
dependencies. It depends on openjpeg (JPEG2000 codec) and jbig2dec (b/w image
|
||||
compression library). With the current version, we integrated those libraries
|
||||
alongside the MuPDF library to the 'libports' repository.
|
||||
|
||||
|
||||
GDB monitor refinements and automated test
|
||||
==========================================
|
||||
|
||||
We improved the support for GDB-based user-level debugging as introduced with
|
||||
the previous release.
|
||||
|
||||
For the x86 architecture, we fixed a corner-case problem with using the
|
||||
two-byte 'INT 0' instruction for breakpoints. The fix changes the breakpoint
|
||||
instruction to the single-byte 'HLT'. 'HLT' is a privileged instruction and
|
||||
triggers an exception when executed in user mode.
|
||||
|
||||
The new 'gdb_monitor_interactive.run' script extends the original
|
||||
'gdb_monitor.run' script with a startup sequence that automates the
|
||||
initial break-in at the 'main()' function of a dynamically linked binary.
|
||||
|
||||
The revised 'gdb_monitor.run' script has been improved to become a full
|
||||
automated test case for GDB functionalities. It exercises the following
|
||||
features (currently on Fiasco.OC only):
|
||||
* Breakpoint in 'main()'
|
||||
* Breakpoint in a shared-library function
|
||||
* Stack trace when not in a syscall
|
||||
* Thread info
|
||||
* Single stepping
|
||||
* Handling of segmentation-fault exception
|
||||
* Stack trace when in a syscall
|
||||
|
||||
|
||||
PDF viewer
|
||||
==========
|
||||
|
||||
According to our road map for 2012, we pursued the port of an existing PDF
|
||||
viewer as native application to Genode.
|
||||
|
||||
We first looked at the [https://poppler.freedesktop.org - libpoppler],
|
||||
which seems to be the most popular PDF rendering engine in the world of
|
||||
freedesktop.org. To get a grasp on what the porting effort of this engine may
|
||||
be, we looked at projects using this library as well as the library source
|
||||
code. By examining applications such as the light-weight epdfview
|
||||
application, we observed that libpoppler's primary design goal is to integrate
|
||||
well with existing freedesktop.org infrastructure rather than to reimplement
|
||||
functionality that is provided by another library. For example, fontconfig is
|
||||
used to obtain font information and Cairo is used as rendering backend. In the
|
||||
context of freedesktop.org, this makes perfect sense. But in our context,
|
||||
porting libpoppler would require us to port all this infrastructure to Genode
|
||||
as well. To illustrate the order of magnitude of the effort needed, epdfview
|
||||
depends on 65 shared libraries. Of course, at some point in the future, we will
|
||||
be faced to carry out this porting work. But for the immediate goal to have a
|
||||
PDF rendering engine available on Genode, it seems overly involved. Another
|
||||
criterion to evaluate the feasibility of integrating libpoppler with Genode is
|
||||
its API. By glancing at the API, it seems to be extremely feature rich and
|
||||
complex - certainly not a thing to conquer in one evening with a glass of wine.
|
||||
The Qt4 backend of the library comprises circa 8000 lines of code. This value
|
||||
can be taken as a vague hint at the amount of work needed to create a custom
|
||||
backend, i.e., for Genode's framebuffer-session interface.
|
||||
|
||||
Fortunately for us, there exists an alternative PDF rendering engine named
|
||||
MuPDF. The concept of MuPDF is quite the opposite of that of libpoppler.
|
||||
MuPDF tries to be as self-sufficient as possible in order to be suitable
|
||||
for embedded systems without comprehensive OS infrastructure. It comes with a
|
||||
custom vector-graphics library (instead of using an existing library such as
|
||||
Cairo) and it even has statically linked-in all font information needed to
|
||||
display PDF files that come with no embedded fonts. That said, it does not
|
||||
try to reinvent the wheel in every regard. For example, it relies on
|
||||
common libraries such as zlib, libpng, jpeg, freetype, and openjpeg. Most
|
||||
of them are already available on Genode. And the remaining libraries are rather
|
||||
free-standing and easy to port. To illustrate the low degree of dependencies,
|
||||
the MuPDF application on GNU/Linux depends on only 15 shared libraries. The
|
||||
best thing about MuPDF from our perspective however, is its lean and clean API,
|
||||
and the wonderfully simple example application. Thanks to this example, it was
|
||||
a breeze to integrate the MuPDF engine with Genode's native framebuffer-session
|
||||
and input-session interfaces. The effort needed for this integration work lies
|
||||
in the order of less than 300 lines of code.
|
||||
|
||||
At the current stage, the MuPDF rendering engine successfully runs on Genode
|
||||
in the form of a simple interactive test program, which can be started
|
||||
via the 'libports/run/mupdf' run script. The program supports the basic key
|
||||
handling required to browse through a multi-page PDF document
|
||||
(page-up or enter -> next page, page-down or backspace -> previous page).
|
||||
|
||||
|
||||
Improved terminal performance
|
||||
=============================
|
||||
|
||||
The terminal component used to make all intermediate states visible to the
|
||||
framebuffer in a fully synchronous fashion. This is an unfortunate behaviour
|
||||
when scrolling through large text outputs. By decoupling the conversion of the
|
||||
terminal state to pixels from the 'Terminal::write()' RPC function,
|
||||
intermediate terminal states produced by sub sequential write operations do not
|
||||
end up on screen one by one but only the final state becomes visible. This
|
||||
improvement drastically improves the speed in situations with a lot of
|
||||
intermediate states.
|
||||
|
||||
|
||||
Noux support for fork semantics
|
||||
===============================
|
||||
|
||||
Genode proclaims to be a framework out of which operating systems can be built.
|
||||
There is no better way of putting this claim to the test than to use the
|
||||
framework for building a Unix-like OS. This is the role of the Noux runtime
|
||||
environment.
|
||||
|
||||
During the past releases, Noux evolved into a runtime environment that is able
|
||||
to execute complex command-line-based GNU software such as VIM with no
|
||||
modification. However, we cannot talk of Unix without talking about its
|
||||
fundamental concept embodied in the form of the 'fork()' system call. We did
|
||||
not entirely dismiss the idea of implementing 'fork()' into Noux but up to now,
|
||||
it was something that we willingly overlooked. However, the primary goal of
|
||||
Noux is to run the GNU userland natively on Genode. This includes a good deal
|
||||
of programs that rely on fork semantics. We could either try to change all the
|
||||
programs to use a Genode-specific way of starting programs or bite in the
|
||||
bullet and implement fork. With the current release, we did the latter.
|
||||
|
||||
The biggest challenge of implementing fork was to find a solution that is not
|
||||
tied to one kernel but one that works across all the different base platforms.
|
||||
The principle problem of starting a new process in a platform-independent
|
||||
manner is already solved by Genode in the form of the 'Process' API. But this
|
||||
startup procedure is entirely different from the semantics of fork. The key to
|
||||
the solution was Genode's natural ability to virtualize the access to low-level
|
||||
platform resources. To implement fork semantics, all Noux has to do is to
|
||||
provide local implementations of core's RAM, RM, and CPU session interfaces.
|
||||
|
||||
The custom implementation of the CPU session interface is used to tweak the
|
||||
startup procedure as performed by the 'Process' class. Normally, processes
|
||||
start execution immediately at creation time at the ELF entry point. For
|
||||
implementing fork semantics, however, this default behavior does not work.
|
||||
Instead, we need to defer the start of the main thread until we have finished
|
||||
copying the address space of the forking process. Furthermore, we need to start
|
||||
the main thread at a custom trampoline function rather than at the ELF entry
|
||||
point. Those customizations are possible by wrapping core's CPU service.
|
||||
|
||||
The custom implementation of the RAM session interface provides a pool of RAM
|
||||
shared by Noux and all Noux processes. The use of a shared pool alleviates the
|
||||
need to assign RAM quota to individual Noux processes. Furthermore, the custom
|
||||
implementation is needed to get hold of the RAM dataspaces allocated by each
|
||||
Noux process. When forking a process, the acquired information is used to
|
||||
create a shadow copy of the forking address space.
|
||||
|
||||
Finally, a custom RM service implementation is used for recording all RM
|
||||
regions attached to the region-manager session of a Noux process. Using the
|
||||
recorded information, the address-space layout can then be replayed onto a new
|
||||
process created via fork.
|
||||
|
||||
With the virtualized platform resources in place, the only puzzle piece that
|
||||
is missing is the bootstrapping of the new process. When its main thread is
|
||||
started, it has an identical address-space content as the forking process but
|
||||
it has to talk to a different parent entrypoint and a different Noux session.
|
||||
The procedure of re-establishing the relationship of the new process to its
|
||||
parent is achieved via a small trampoline function that re-initializes the
|
||||
process environment and then branches to the original forking point via
|
||||
setjmp/longjmp. This mechanism is implemented in the libc_noux plugin.
|
||||
|
||||
As the immediate result of this work, a simple fork test can be executed across
|
||||
all base platforms except for Linux (Linux is not supported yet). The test
|
||||
program is located at 'ports/src/test/noux_fork' and can be started with the
|
||||
'ports/run/noux_fork.run' script.
|
||||
|
||||
Furthermore, as a slightly more exciting example, there is a run script for
|
||||
running a bash shell on a tar file system that contains coreutils. By starting
|
||||
the 'ports/run/noux_bash.run' script, you get presented an interactive bash
|
||||
shell. The shell is displayed via the terminal service and accepts user input.
|
||||
It allows you to start one of the coreutils programs such as ls or cat. Please
|
||||
note that the current state is still largely untested, incomplete, and flaky.
|
||||
But considering that Noux is comprised of less than 2500 lines of code, we are
|
||||
quite surprised of how far one can get with such little effort.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Driver improvements to accommodate dynamic (re-)loading
|
||||
=======================================================
|
||||
|
||||
To support the dynamic probing of devices as performed by the new d3m
|
||||
component, the ATAPI and USB device drivers have been enhanced to support the
|
||||
subsequent closing and re-opening of sessions.
|
||||
|
||||
|
||||
First bits of the d3m device-driver manager
|
||||
===========================================
|
||||
|
||||
The abbreviation d3m stands for demo device-driver manager. It is our current
|
||||
solution for the automated loading of suitable drivers as needed for running
|
||||
Genode from a Live CD or USB stick. Because of the current narrow focus of d3m,
|
||||
it is not a generic driver-management solution but a first step in this
|
||||
direction. We hope that in the long run, d3m will evolve to become a generic
|
||||
driver-management facility so that we can remove one of the "D"s from its name.
|
||||
In the current form d3m solves the problems of merging input-event streams,
|
||||
selecting the boot device, and dealing with failing network drivers.
|
||||
|
||||
When using the live CD, we expect user input to come from USB HID devices or
|
||||
from a PS/2 mouse and keyboard. The live system should be operational if at
|
||||
least one of those sources of input is available. In the presence of multiple
|
||||
sources, we want to accumulate the events of all of them.
|
||||
|
||||
The live CD should come in the form of a single ISO image that can be burned onto a CDROM or
|
||||
alternatively copied to an USB stick. The live system should boot fine in both
|
||||
cases. The first boot stage is accommodated by syslinux and the GRUB boot
|
||||
loader using BIOS functions. But once Genode takes over control, it needs to
|
||||
figure out on its own from where to fetch data. A priori, there is no way to
|
||||
guess whether the ATAPI driver or the USB storage driver should be used.
|
||||
|
||||
[image d3m_what_next]
|
||||
|
||||
Therefore, d3m implements a probing mechanism that starts each of the drivers,
|
||||
probes for the presence of a particular file on an iso9660 file system.
|
||||
|
||||
[image d3m_probing]
|
||||
|
||||
Once d3m observes a drivers that is able to successfully access the magic file,
|
||||
it keeps the driver and announces the driver's service to its own parent. For
|
||||
the system outside of d3m, the probing procedure is completely transparent. D3m
|
||||
appears to be just a service that always provides the valid block session for
|
||||
the boot medium.
|
||||
|
||||
[image d3m_ready]
|
||||
|
||||
The network device drivers that we ported from the iPXE project cover the
|
||||
range of most common wired network adaptors, in particular the E1000 family.
|
||||
But we cannot presume that a computer running the live system comes equipped
|
||||
with one of the supported devices. If no supported network card could be
|
||||
detected the driver would simply fail. Applications requesting a NIC session
|
||||
would block until a NIC service becomes available, which won't happen. To
|
||||
prevent this situation, d3m wraps the NIC driver and provides a dummy NIC
|
||||
service in the event the drivers fails. This way, the client application won't
|
||||
block infinitely but receive an error on the first attempt to use the NIC.
|
||||
|
||||
|
||||
ACPI support
|
||||
============
|
||||
|
||||
To accommodate kernels like Fiasco.OC or NOVA that take advantage of x86's
|
||||
APIC, we have introduced a simple ACPI parser located at 'os/src/drivers/acpi'.
|
||||
The server traverses the ACPI tables and sets the interrupt line of devices
|
||||
within the PCI config space to the GSIs found in the ACPI tables. Internally it
|
||||
uses Genode's existing PCI driver as a child process for performing PCI access
|
||||
and, in turn, announces a PCI service itself.
|
||||
|
||||
For obtaining the IRQ routing information from the ACPI tables without
|
||||
employing a full-blown ACPI interpreter, the ACPI driver uses an ingenious
|
||||
technique invented by Bernhard Kauer, which is described in the following
|
||||
paper:
|
||||
|
||||
:[https://os.inf.tu-dresden.de/papers_ps/tr-atare-2009.pdf - ATARE - ACPI Tables and Regular Expressions]:
|
||||
_TU Dresden technical report TUD-FI09-09, Dresden, Germany, August 2009_
|
||||
|
||||
:Usage:
|
||||
|
||||
Start the 'acpi_drv' in your Genode environment. Do not start the 'pci_drv'
|
||||
since this will be used as a slave of the 'acpi_drv'. You still must load the
|
||||
'pci_drv' in your boot loader. To integrate the ACPI driver into your boot
|
||||
configuration, you may take the following snippet as reference:
|
||||
|
||||
!<start name="acpi">
|
||||
! <resource name="RAM" quantum="2M"/>
|
||||
! <binary name="acpi_drv"/>
|
||||
! <provides><service name="PCI"/></provides>
|
||||
! <route>
|
||||
! <service name="ROM"> <parent/> </service>
|
||||
! <any-service> <any-child/> <parent/> </any-service>
|
||||
! </route>
|
||||
!</start>
|
||||
|
||||
:Limitations and known issues:
|
||||
|
||||
Currently there is no interface to set the interrupt mode for core's IRQ
|
||||
sessions (e.g., level or edge triggered). This is required by Fiasco.OCs kernel
|
||||
interface. We regard this as future work.
|
||||
|
||||
|
||||
Platform support
|
||||
################
|
||||
|
||||
Fiasco.OC microkernel
|
||||
=====================
|
||||
|
||||
The support for the Fiasco.OC base platform is still lacking proper handling
|
||||
for releasing resources such as kernel capabilities. Although this is a known
|
||||
issue, we underestimated the reach of the problem when Genode's signal API is
|
||||
used. Each emitted signal happens to consume one kernel capability within core,
|
||||
ultimately leading to a resource outage when executing signal-intensive code
|
||||
such as the packet-stream interface. The current release comes with an interim
|
||||
solution. To remedy the acute problem, we extended the 'Capability_allocator'
|
||||
class with the ability to register the global ID of a Genode capability so
|
||||
that the ID gets associated with a process-local kernel capability. Whenever
|
||||
a Genode capability gets unmarshalled from an IPC message, the
|
||||
capability-allocator is asked, with the global ID as key, whether the
|
||||
kernel-cap already exists. This significantly reduces the waste of
|
||||
kernel-capability slots.
|
||||
|
||||
To circumvent problems of having one and the same ID for different kernel
|
||||
objects, the following problems had to be solved:
|
||||
|
||||
* Replace pseudo IDs with unique ones from core's badge allocator
|
||||
* When freeing a session object, free the global ID _after_ unmapping
|
||||
the kernel object, otherwise the global ID might get re-used in some
|
||||
process and the registry will find a valid but wrong capability
|
||||
for the ID
|
||||
|
||||
Because core aggregates all capabilities of all different processes, its
|
||||
capability registry needs much more memory compared to a regular process.
|
||||
By parametrizing capability allocators differently for core and non-core
|
||||
processes, the global memory overhead for capability registries is kept
|
||||
at a reasonable level.
|
||||
|
||||
Please note that this solution is meant as an interim fix until we have
|
||||
resolved the root of the problem, which is the proper tracking and releasing
|
||||
of capability selectors.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Linux is one of the two original base platforms of Genode. The original
|
||||
intension behind supporting Linux besides a microkernel was to facilitate
|
||||
portability of the API design and to have a convenient testing environment for
|
||||
platform-independent code. Running Genode in the form of a bunch of plain Linux
|
||||
processes has become an invaluable feature for our fast-paced development.
|
||||
|
||||
To our delight, we lately discovered that the use of running Genode on Linux
|
||||
can actually go far beyond this original incentive. Apparently, on Linux, the
|
||||
framework represents an equally powerful component framework as on the other
|
||||
platforms. Hence, Genode has the potential to become an attractive option for
|
||||
creating complex component-based user-level software on Linux.
|
||||
|
||||
For this intended use, however, the framework has to fulfill the following
|
||||
additional requirements:
|
||||
|
||||
* Developers on Linux expect that their components integrate seamlessly with
|
||||
their existing library infrastructure including all shared libraries
|
||||
installed on Linux.
|
||||
|
||||
* The use of a custom tool chain is hard to justify to developers who regard
|
||||
Genode merely as an application framework. Hence, a way to use the normal
|
||||
tool chain as installed on the Linux host system is desired.
|
||||
|
||||
* Application developers are accustomed with using GDB for debugging and expect
|
||||
that GDB can be attached to an arbitrary Genode program in an intuitive way.
|
||||
|
||||
Genode's original support for Linux as base platform did not meet those
|
||||
expectations. Because Genode's libc would ultimately collide with the Linux
|
||||
glibc, Genode is built with no glibc dependency at all. It talks to the kernel
|
||||
directly using custom kernel bindings. In particular, Genode threads are created
|
||||
directly via the 'clone()' system call and thread-local storage (TLS) is managed
|
||||
in the same way as for the other base platforms. This has two implications.
|
||||
First, because Genode's TLS mechanism is different than the Linux TLS
|
||||
mechanism, Genode cannot be built with the normal host tool chain. This
|
||||
compiler would generate code that would simply break on the first attempt to
|
||||
use TLS. We solved this problem with our custom tool chain, which is configured
|
||||
for Genode's needs. The second implication is that GDB is not able to handle
|
||||
threads created differently than those created via the pthread library. Even
|
||||
though GDB can be attached to each thread individually, the debugger would not
|
||||
correctly handle a multi-threaded Genode process as a multi-threaded Linux
|
||||
program. With regard to the use of Linux shared libraries, Genode used to
|
||||
support a few special programs that used both the Genode API and Linux
|
||||
libraries. Those programs (called hybrid Linux/Genode programs) were typically
|
||||
pseudo device drivers that translate a Linux API to a Genode service. For
|
||||
example, there exists a framebuffer service that uses libSDL as back end.
|
||||
Because those programs were a rarity, the support by the build system for such
|
||||
hybrid targets was rather poor.
|
||||
|
||||
Fortunately, all the problems outlined above could be remedied pretty easily.
|
||||
It turns out that our custom libc is simply not relevant when Genode is
|
||||
used as plain application framework on Linux. For this intended use, we always
|
||||
want to use the host's normal libc. This way, the sole reason for using plain
|
||||
system calls instead of the pthread library vanishes, which, in turn,
|
||||
alleviates the need for a custom tool chain. Genode threads are then simply
|
||||
pthreads compatible with the TLS code as emitted by the host compiler and
|
||||
perfectly recognised by GDB. With the surprisingly little effort of creating a
|
||||
new implementation of Genode's thread API to target pthreads instead of using
|
||||
syscalls, we managed to provide a decent level of support for using Genode as
|
||||
user-level component framework on Linux.
|
||||
|
||||
These technical changes alone, however, are not sufficient to make Genode
|
||||
practical for real-world use. As stated above, the few hybrid Linux/Genode
|
||||
programs used to be regarded as some leprous artifacts. When using Genode as
|
||||
Linux application framework, however, this kind of programs are becoming the
|
||||
norm rather than an exception. For this reason, we introduced new support for
|
||||
such hybrid programs into the build system. By listing the 'lx_hybrid'
|
||||
library in the 'LIBS' declaration of a target, this target magically becomes a
|
||||
hybrid Linux/Genode program. It gets linked to the glibc and uses pthreads
|
||||
instead of direct syscalls. Furthermore, host libraries can be linked to the
|
||||
program by stating their respective names in the 'LX_LIBS' variable. For an
|
||||
example, please refer to the libSDL-based framebuffer at
|
||||
'os/src/drivers/framebuffer/sdl/target.mk'.
|
||||
|
||||
To enforce the build of all targets as hybrid Linux/Genode programs, the build
|
||||
system features the 'alyways_hybrid' 'SPEC' value. To make it easy to create a
|
||||
build directory with all targets forced to be hybrid, we have added the new
|
||||
'lx_hybrid_x86' platform to the 'create_builddir' tool.
|
||||
|
||||
|
||||
OKL4
|
||||
====
|
||||
|
||||
:Sending an invalid-opcode exception IPC on OKL4:
|
||||
|
||||
When an invalid opcode gets executed, OKL4 switches to the kernel debugger
|
||||
console instead of sending an exception IPC to the userland. We fixed this
|
||||
problem by removing the code that invokes the debugger console from the kernel.
|
||||
|
||||
:Hard-wire OKL4 elfweaver to Python 2:
|
||||
|
||||
Recent Linux distributions use Python version 3 by default. But OKL4's
|
||||
elfweaver is not compatible with this version of Python. For this reason, we
|
||||
introduced a patch for pinning the Python version used by elfweaver to
|
||||
version 2.
|
||||
|
||||
Both patches get automatically applied when preparing the 'base-okl4'
|
||||
repository via 'make prepare'.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
:Facility for explicitly building all libraries:
|
||||
|
||||
During its normal operation, the build system creates libraries as mere side
|
||||
effects of building targets. There is no way to explicitly trigger the build of
|
||||
libraries only. However, in some circumstances (for example for testing the
|
||||
thorough build of all libraries), a mechanism for explicitly building libraries
|
||||
would be convenient. Hence we introduced this feature in the form of the pseudo
|
||||
target located at 'base/src/lib/target.mk'. By issuing 'make lib' in a build
|
||||
directory, this target triggers the build of all libraries available for the
|
||||
given platform.
|
||||
1029
doc/release_notes/12-05.txt
Normal file
1029
doc/release_notes/12-05.txt
Normal file
File diff suppressed because it is too large
Load Diff
665
doc/release_notes/12-08.txt
Normal file
665
doc/release_notes/12-08.txt
Normal file
@@ -0,0 +1,665 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 12.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
With Genode 12.08, the project focused on platform support. It enters the world
|
||||
of OMAP4-based ARM platforms, revived and vastly enhanced the support for the
|
||||
NOVA hypervisor, and becomes able to run directly on ARM platforms without the
|
||||
need for an underlying kernel.
|
||||
|
||||
The new 'base-hw' platform is a deviation from Genode's traditional approach to
|
||||
complement existing kernels with user-land infrastructure. It completely leaves
|
||||
the separate kernel out of the picture and thereby dwarfs the base line of the
|
||||
trusted computing base of Genode-based systems to approximately the half. The
|
||||
new base platform is described in Section [Genode on naked ARM hardware].
|
||||
|
||||
Speaking of base platforms, we are happy to have promoted the NOVA hypervisor
|
||||
to a first-class citizen among the base platforms. During the last months, this
|
||||
kernel underwent fundamental changes regarding its mode of development and its
|
||||
feature set. This prompted us to vastly improve Genode's support for this
|
||||
platform and leverage its unique features. If considering the use of Genode on
|
||||
x86-based hardware, NOVA has become a very attractive foundation. Section
|
||||
[Embracing the NOVA Hypervisor] describes the NOVA-specific changes.
|
||||
|
||||
The improvement of platform support with the current release does not entail
|
||||
the base platforms only but extends to profound additions of device drivers, in
|
||||
particular for the ARM-based OMAP4 SoC as used on the popular Pandaboard. We
|
||||
are proud to announce the availability of device drivers for HDMI output,
|
||||
SD-card, USB HID, and networking for this platform.
|
||||
|
||||
Beyond the low-level platform improvements, the new version comes with several
|
||||
new services, optimizations of existing components, and new ported libraries.
|
||||
In particular, the Noux runtime has reached a point where we can principally
|
||||
execute serious networking applications such as the Lynx web browser natively
|
||||
on Genode. Another example is the new FFAT-based file-system service, which
|
||||
makes persistent storage available via Genode's file-system interface. By
|
||||
combining this new service with existing components such as the partition
|
||||
service, Noux, or the file-system plugin of the libc, a lot of new application
|
||||
scenarios become available. Thanks to these new components, the framework has
|
||||
become able to perform on-target debugging via GDB running in Noux, or host
|
||||
the genode.org website via the lighttpd web server,
|
||||
|
||||
|
||||
:What about the road map?:
|
||||
|
||||
Those of you who track the milestones laid out in our [https://genode.org/about/road-map - road map]
|
||||
may wonder how Genode 12.08 relates to the stated goals. In fact, several
|
||||
points of the road map haven't received the attention as originally planned.
|
||||
As an explanation, let us quote the paragraph right atop of the road-map page:
|
||||
"The road map is not fixed. If there is commercial interest of pushing the
|
||||
Genode technology to a certain direction, we are willing to revisit our plans."
|
||||
Well, this is what happened. So we traded the work on the tiled window manager,
|
||||
the Intel wireless driver, and SMP support for the work on the platform topics
|
||||
outlined above. Nevertheless, we stick to our overall plan to turn Genode into
|
||||
a general-purpose OS that is fit for use by its developers by the end of the
|
||||
year. If looking closely at the additions that come with the current release,
|
||||
it will become apparent how well they fit into the big picture.
|
||||
|
||||
|
||||
Genode on naked ARM hardware
|
||||
############################
|
||||
|
||||
One of Genode's most distinguishing properties is the ability to use the framework
|
||||
on top of a range of different kernels. This way, users of the framework
|
||||
benefit from the wide variety of features provided by those kernels while
|
||||
only dealing with a single API and configuration concept. For example, we
|
||||
frequently find ourselves using the Linux kernel as base platform while
|
||||
developing services, interfaces, and protocol stacks. By being able to start
|
||||
Genode as a regular program, we effectively eliminate the reboot-time for each
|
||||
test run and enjoy using commodity debugging and profiling tools. On the other
|
||||
hand, if high security is a concern, NOVA and Fiasco.OC provide
|
||||
capability-based security at kernel-level. So the use of one of those kernels
|
||||
is desirable. Genode allows for switching between those vastly different
|
||||
kernels almost seamlessly.
|
||||
|
||||
In general, a Genode system consists of a kernel, Genode's core, and the
|
||||
largely generic components on top of core. Core abstracts away the
|
||||
peculiarities of the respective kernel and provides a unified API to the
|
||||
components on top. From the application's point of view both kernel and core
|
||||
are always at the root of the process tree and thereby are a inherent part of
|
||||
the application's trusted computing base (TCB). The distinction of both
|
||||
programs is almost superficial.
|
||||
|
||||
Since both the kernel and core must be ultimately trusted, the complexity of
|
||||
both programs is critical for each Genode-based system. On our quest for
|
||||
minimizing the TCB complexity so far, however, we did not question the role of
|
||||
the kernel as an inherent part of the TCB and focused our attention to the
|
||||
software stack on top. However, with more and more kernels entering the
|
||||
picture, we identified that there is typically a considerable overlap in
|
||||
functionality between kernel and core. For example, both need to know about
|
||||
address spaces and their relationship to physical memory objects. Most kernels
|
||||
keep track of memory mappings in an in-kernel database. Core also needs to keep
|
||||
track of this information. Consequently, we found several information
|
||||
replicated without a clear benefit. With this comes a seemingly significant
|
||||
redundancy of code for data structures, allocators, and utility functions.
|
||||
Furthermore, there exists a class of problems that must be solved by the kernel
|
||||
and core alike. In particular the resource management of dynamically allocated
|
||||
in-kernel objects respectively in-core objects. Whereas core uses Genode's
|
||||
resource-trading concept to solve this problem, most kernels lack a good
|
||||
solution for the management of in-kernel resources and are consequently prone
|
||||
to resource exhaustion problems.
|
||||
|
||||
Out of these observations, the idea was born to explore the opportunities of
|
||||
merging both programs into one and thereby eliminating the redundancies. Our
|
||||
first attempt to go into this direction was the 'base-mb' platform, which
|
||||
enabled us to run Genode on the Xilinx MicroBlaze softcore CPU. With this
|
||||
experiment, we gained confidence that the approach is generally feasible. So we
|
||||
took on the challenge to implement the idea of a hybrid kernel/core on a more
|
||||
complex architecture namely ARM Cortex-A9.
|
||||
|
||||
The 'base-hw' platform introduced with the current release is the intermediate
|
||||
result of our experiment. With this base platform, core plays the role of core
|
||||
and the kernel within one program. A few code paths that require execution in
|
||||
privileged mode are executed in kernel mode whereas most code paths are
|
||||
executed in user mode. Both user mode code and kernel mode code run in the same
|
||||
address space. The kernel portion merely provides a few basic mechanisms
|
||||
without performing complex operations such as dynamic memory allocations. For
|
||||
example, if core is requested to create a new thread via core's CPU session
|
||||
interface, the user-level code within core allocates a KTCB (kernel thread
|
||||
control block) and UTCB (user-level thread-control block) from the physical
|
||||
memory allocator and passes both physical addresses to the kernel function that
|
||||
spawns the actual thread. This way, we can employ Genode's resource-trading
|
||||
concept for managing typical kernel resources.
|
||||
|
||||
The experiment turned out to be a great success. Traditionally, we would account
|
||||
at least 10,000 lines of code (LOC) for the kernel. Most kernels are actually
|
||||
much larger than that. Core comes at a complexity of another 10,000 LOC. So
|
||||
both kernel and core make up a base line of TCB complexity of more than 20,000
|
||||
LOC. By co-locating core with the kernel, we end up with a program of just
|
||||
about 13,000 LOC. The vast reduction of TCB complexity compared to having
|
||||
kernel and core as separate programs strikes us.
|
||||
|
||||
The 'base-hw' version of core supports the complete Genode API covering support
|
||||
for user-level device drivers, synchronous RPCs, asynchronous notifications,
|
||||
shared memory, and managed dataspaces. It is thereby able to execute the
|
||||
sophisticated Genode scenarios on top including the GUI, the dynamic linker,
|
||||
and user-level device drivers. That said, we regard the current version still
|
||||
as work in progress. We successfully use it as an experimentation platform for
|
||||
ongoing research activities (i.e., for exploring ARM TrustZone) but some
|
||||
important features such as capability-based security are not yet implemented.
|
||||
|
||||
:Using the base-hw platform:
|
||||
|
||||
The new base platform is fully integrated with Genode's build system.
|
||||
When listing the supported base platforms via the 'tool/create_builddir' tool,
|
||||
you will see the new 'hw_panda_a2', 'hw_vea9x4', 'hw_pbxa9' choices of
|
||||
build-directory templates. The latter platform enables you to run a
|
||||
'base-hw' Genode system on Qemu.
|
||||
|
||||
[https://genode.org/documentation/platforms/hw - Learn more about using the new base-hw platform...]
|
||||
|
||||
For running Genode directly on the Pandaboard, please refer to the
|
||||
[https://genode.org/documentation/platforms/hw_panda_a2 - Pandaboard-specific documentation...]
|
||||
|
||||
|
||||
Embracing the NOVA Hypervisor
|
||||
#############################
|
||||
|
||||
NOVA is a so-called microhypervisor for the x86 architecture. It combines the
|
||||
principles of microkernels with capability-based security and hardware-assisted
|
||||
virtualization. Among the various base platforms supported by Genode, NOVA's
|
||||
kernel interface stands out for being extremely minimalistic and orthogonal,
|
||||
even by microkernel standards.
|
||||
|
||||
Genode has supported NOVA as base platform since 2010. But because we used NOVA
|
||||
solely for sporadic research activities and NOVA's lack of a regular release
|
||||
schedule, the framework's platform support received only little attention. This
|
||||
has changed now. NOVA's main developer Udo Steinberg moved from TU Dresden to
|
||||
Intel Labs where he leads the development of NOVA as a true Open-Source
|
||||
project. In fact, the code is now being hosted at GitHub:
|
||||
|
||||
:[https://github.com/IntelLabs/NOVA]:
|
||||
NOVA hypervisor at GitHub
|
||||
|
||||
Since its move to GitHub, the hypervisor has already seen significant
|
||||
improvements. The repository is continuously updated, which enables us to stay
|
||||
in a close feedback loop with the NOVA developers. This change of how NOVA's
|
||||
development is conducted ignited our renewed interest in promoting this
|
||||
platform to a first-level citizen of our framework. The first noteworthy
|
||||
improvement is the recently added 64-bit support of NOVA. We enabled Genode to
|
||||
work with both variants of the kernel - 32 bit and 64 bit.
|
||||
|
||||
But this was just the first step. The second major change addresses the
|
||||
allocation of kernel resources. Early versions of the hypervisor allowed each
|
||||
process to create kernel objects and thereby indirectly consume the limited
|
||||
memory resources of the kernel. This is perfectly fine for a research project
|
||||
but it becomes a potential denial-of-service problem in real-world use cases.
|
||||
For this reason, newer versions introduced the ability to retain the allocation
|
||||
of kernel objects within a trusted component only. In the Genode world, this
|
||||
component is naturally core. Even though NOVA still lacks a flexible concept for
|
||||
kernel-resource management as of now, Genode has become able to use NOVA
|
||||
without suffering the inherent resource management limitation. This is achieved
|
||||
because core is able to arbitrate the allocation of kernel resources.
|
||||
|
||||
The third fundamental change is the abolishment of the last traces of global
|
||||
names in a NOVA-based Genode system. There are no thread IDs, object IDs, or
|
||||
any other kind of globally meaningful names. Each process has a local view on
|
||||
(a small part of) the system only. If a process interacts with another process,
|
||||
the kernel translates the references to remote objects from one namespace to
|
||||
the other. The security implications are eminent. First, a process can only
|
||||
interact with or refer to objects for which it has a name, which vastly reduces
|
||||
problems of ambient authority. Second, because the kernel translates names, it
|
||||
becomes impossible to forge object identities. If a process tried to pass a
|
||||
forged object reference to another process, the translation would simply fail,
|
||||
rendering the attack ineffective.
|
||||
|
||||
The described changes do not come without issues, though. To make the NOVA
|
||||
kernel fit with Genode's requirements, minor patches of the hypervisor are
|
||||
needed. The patches are located at 'base-nova/patches/'. However, those patches
|
||||
are meant as interim solutions until we find mechanisms that fit well with the
|
||||
design of the hypervisor and also fulfil our requirements.
|
||||
|
||||
So far, we greatly enjoyed the revived collaboration with the NOVA developers
|
||||
and congratulate Udo Steinberg for the new mode of development of the
|
||||
hypervisor.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
In the following, we describe changes of the base API that may affect users of
|
||||
the framework.
|
||||
|
||||
:Allocation of DMA buffers:
|
||||
|
||||
We extended the RAM session interface with the ability to allocate DMA buffers.
|
||||
The client specifies the type of RAM dataspace to allocate via the new 'cached'
|
||||
argument of the 'Ram_session::alloc()' function. By default, 'cached' is true,
|
||||
which corresponds to the common case and the original behavior. When setting
|
||||
'cached' to 'false', core takes the precautions needed to register the memory
|
||||
as uncached in the page table of each process that has the dataspace attached.
|
||||
|
||||
Currently, the support for allocating DMA buffers is implemented for Fiasco.OC
|
||||
only. On x86 platforms, it is generally not needed. But on platforms with more
|
||||
relaxed cache coherence (such as ARM), user-level device drivers should always
|
||||
use uncacheable memory for DMA transactions.
|
||||
|
||||
|
||||
:MMIO framework improvements:
|
||||
|
||||
As we find ourselves increasingly using the 'Register' and 'Mmio' templates
|
||||
provided by 'util/register.h' and 'util/mmio.h' for dealing with memory-mapped
|
||||
devices, we extended the utilities with support for 64-bit registers and a new
|
||||
interface for polling bit states. The latter functionality is provided by the
|
||||
new 'wait_for' function template. To decouple the MMIO-related utility code
|
||||
from an actual timer facility, the function takes a so-called 'delayer' functor
|
||||
as argument. This way the user of the MMIO framework is able to pick a timer
|
||||
facility that fits best with the device.
|
||||
|
||||
|
||||
:New 'memcpy' implementation:
|
||||
|
||||
The memory-copy functions provided by 'util/string.h' are extremely simple
|
||||
and arguably slow, particularly on platforms where byte-wise copy operations
|
||||
are not supported by the CPU (i.e., ARM). Hence, we have added a CPU-specific
|
||||
memcpy function ('memcpy_cpu') to 'cpu/string.h', which enables us to
|
||||
provide optimized implementations. So far, we did so for the ARM architecture.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
FFat-based file-system service
|
||||
==============================
|
||||
|
||||
With the previous release, we introduced Genode's file-system interface
|
||||
accompanied with a simple in-memory file-system service. With the addition of
|
||||
'ffat_fs', the current release adds the first persistent file system to the
|
||||
framework. The service is located at 'libports/src/server/ffat_fs'. It uses
|
||||
Genode's 'Block::Session' interface as back end. Therefore, it can be combined
|
||||
with any of Genode's block-device drivers and the partition service called
|
||||
'part_blk'. To see the new 'ffat_fs' service in action, please refer to the new
|
||||
'libports/run/libc_ffat_fs.run' script.
|
||||
|
||||
On the course of our work on the 'ffat_fs' service, we enabled support for long
|
||||
file names in libffat and added 'lseek' support to the 'libc_ffat' plugin.
|
||||
|
||||
|
||||
TAR-based file-system service
|
||||
=============================
|
||||
|
||||
The new 'tar_fs' service located at 'os/src/server/tar_fs' provides a read-only
|
||||
file-system session interface by reading data from a TAR archive, which, in
|
||||
turn, is fetched from a ROM service. By combining 'tar_fs' with the 'libc_fs'
|
||||
plugin, it becomes easy to provide customized pseudo file systems to individual
|
||||
Genode programs. For example, one instance of 'tar_fs' containing a static
|
||||
website and a web-server configuration can be provided as file system to a web
|
||||
server. The configuration is similar to the patterns known from the 'tar_rom'
|
||||
and 'ram_fs' servers:
|
||||
|
||||
! <config>
|
||||
! <archive name="tar_archive.tar" />
|
||||
! <policy label="label_of_client" root="/rootdir/for/client" />
|
||||
! </config>
|
||||
|
||||
The policy node allows for assigning different parts of one TAR archive to
|
||||
different clients. For a practical usage example of 'tar_fs', please refer to
|
||||
the 'libports/run/libc_fs_tar_fs.run' script.
|
||||
|
||||
|
||||
Terminal improvements
|
||||
=====================
|
||||
|
||||
Our work on running a growing number of command-line-based Unix programs via
|
||||
Noux prompted us to improve our terminal implementation as needed. To ease
|
||||
debugging for terminal colors, we changed the previous default color scheme to
|
||||
fully saturated combinations of red, green, and blue. Albeit this looks quite
|
||||
painful on the eyes, it is easier to spot wrong colors when using a program
|
||||
that uses ncurses, for example Lynx. Furthermore, we added the handling of
|
||||
sgr0 and sgr escape sequences and thereby enabled Lynx to become almost
|
||||
usable when running within Noux.
|
||||
|
||||
|
||||
Terminal cross-link service
|
||||
===========================
|
||||
|
||||
The 'Terminal::Session' interface gets increasingly popular within Genode.
|
||||
It is used by the UART drivers, the graphical terminal, GDB monitor, the TCP
|
||||
terminal, and Noux. For most of these programs, their respective client or
|
||||
server role is quite clear but we find ourselves tempted to combine components
|
||||
in unusual ways. For example, to let Noux run an instance of GDB, which operates
|
||||
on a terminal via a virtual character device. For remote debugging, GDB plays
|
||||
the role of a terminal client and the UART driver plays the role of the server.
|
||||
But when running GDB monitor on the same machine, GDB monitor will also
|
||||
expect to play the role of the client. In order to connect GDB monitor
|
||||
to a local instance of GDB, both of them being terminal clients, we need an
|
||||
adapter component. This is where the new terminal cross-link service enters
|
||||
the picture. It plays the role of a terminal server between exactly two
|
||||
clients. The output of one client ends up as input to the other and vice
|
||||
versa. Data sent to the server gets stored in a buffer of 4096 bytes (one
|
||||
buffer per client). As long as the data to be written fits into the buffer, the
|
||||
'write()' call returns immediately. If no more data fits into the buffer, the
|
||||
'write()' call blocks until the other client has consumed some of the data from
|
||||
the buffer via the 'read()' call. The 'read()' call never blocks. A signal
|
||||
receiver can be used to block until new data is ready for reading.
|
||||
|
||||
The new terminal crosslink can be tested via the 'os/run/terminal_crosslink.run'
|
||||
script. It is also used for the just mentioned on-target debugging scenario
|
||||
demonstrated by the 'ports/run/noux_gdb.run' script.
|
||||
|
||||
|
||||
DMA-aware and optimized packet streams
|
||||
======================================
|
||||
|
||||
Motivated by our work on OMAP4 platform support, we introduced API extensions
|
||||
for handling of DMA buffers to the following interfaces:
|
||||
|
||||
:'Attached_ram_dataspace':
|
||||
|
||||
The convenience utility for allocating and locally mapping a RAM dataspace
|
||||
has been enhanced with the 'cached' constructor argument, which is true
|
||||
by default. When using 'Attached_ram_dataspace' for allocating DMA buffers,
|
||||
this argument should be set to false.
|
||||
|
||||
:Block and network packet stream:
|
||||
|
||||
The 'Block::Session' and 'Nic::Session' interfaces use Genode's packet stream
|
||||
facility for transferring bulk payload between processes. A packet stream
|
||||
combines shared memory with asynchronous notifications and thereby facilitates
|
||||
the use of batched packet processing. To principally enable zero-copy semantics
|
||||
for device drivers, the packet-stream buffer is now explicitly allocated as DMA
|
||||
buffer. This clears the way to let the SD-card driver direct DMA transactions
|
||||
right into the packet stream buffer. Consequently, when attaching the SD-card
|
||||
driver directly to a file system, there is no copy of payload needed.
|
||||
|
||||
The 'Nic::Session' interface has further been improved by using a fast
|
||||
bitmap allocator for allocations within the packet-stream buffer. This is
|
||||
possible because networking packets have the MTU size as an upper limit.
|
||||
In contrast to the 'Block::Session' interface where requests are relatively
|
||||
large, 'Nic::Session' packets are tiny, and thus, greatly benefit from the
|
||||
optimized allocator.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
:File I/O:
|
||||
|
||||
We complemented our C runtime with support for the 'pread', 'pwrite', 'readv',
|
||||
and 'writev' functions. The 'pread' and 'pwrite' functions are shortcuts for
|
||||
randomly accessing different parts of a file. Under the hood, the functions are
|
||||
implemented via 'lseek' and 'read/write'. To provide the atomicity of the
|
||||
functions, a lock guard prevents the parallel execution of either or both
|
||||
functions if called concurrently by multiple threads. The 'readv' and 'writev'
|
||||
functions principally enable the chaining of multiple I/O requests.
|
||||
Furthermore, we added 'ftruncate', 'poll', and basic support for (read-only)
|
||||
mmapped files to the C runtime.
|
||||
|
||||
:Libc RPC framework headers:
|
||||
|
||||
Certain RPC headers of the libc are needed for compiling 'getaddrinfo.c'.
|
||||
Unfortunately that means we have to generate a few header files, which we do
|
||||
when we prepare the libc.
|
||||
|
||||
|
||||
New and updated 3rd-party libraries
|
||||
===================================
|
||||
|
||||
:Expat:
|
||||
|
||||
[https://expat.sourceforge.net - Expat] is an XML parsing library. The port of
|
||||
this library was motivated by our goal to use the GNU debugger for on-target
|
||||
debugging. GDB depends on this library.
|
||||
|
||||
:MPC and GMP:
|
||||
|
||||
We complemented our existing port of the
|
||||
[https://gmplib.org - GNU multiple precision arithmetic library (libgmp)] with
|
||||
support for the x86_64 and ARM architectures. This change combined with the
|
||||
port of the [http://www.multiprecision.org/index.php?prog=mpc - MPC library]
|
||||
enables us to build the Genode tool chain for these architectures.
|
||||
|
||||
:OpenSSL:
|
||||
|
||||
Our port of OpenSSL has been updated to version 1.0.1c. Because libcrypto
|
||||
provides certain optimized assembler functions, which unfortunately are not
|
||||
expressed with position-independent code, we removed this assembler code and
|
||||
build libcrypto with '-DOPENSSL_NO_ASM'. Because the assembler code is not
|
||||
needed anymore, its generation is also removed from 'openssl.mk'.
|
||||
|
||||
:Light-weight IP stack (lwIP):
|
||||
|
||||
We enabled the lwIP TCP/IP stack for 64-bit machines and updated the library to
|
||||
version 1.4.1-rc1. With the new version, the call of 'lwip_loopback_init' is
|
||||
not needed anymore because lwIP always creates a loopback device. Hence, we
|
||||
will be able to remove the 'libc_lwip_loopback' in the future. For now, we keep
|
||||
it around so we currently do not need to update the other targets that depend
|
||||
on it.
|
||||
|
||||
:PCRE:
|
||||
|
||||
[https://www.pcre.org/ - PCRE] is a library for parsing regular rexpressions. We
|
||||
require this library for our ongoing work on porting the lighttpd webserver.
|
||||
|
||||
|
||||
Lighttpd web server
|
||||
===================
|
||||
|
||||
The [https://www.lighttpd.net/ - Lighttpd] web server has been added to the
|
||||
'ports' repository. The port runs as a native Genode application and ultimately
|
||||
clears the way to hosting the genode.org website on Genode. To test drive this
|
||||
scenario, please give the 'ports/run/genode_org.run' script a try.
|
||||
|
||||
At the current stage, the port is still quite limited. For example, it does not
|
||||
make use of non-blocking sockets yet. But the 'genode_org.run' run script
|
||||
already showcases very well how simple a Genode-based web-server appliance can
|
||||
look like.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
OMAP4 platform drivers
|
||||
======================
|
||||
|
||||
:HDMI output:
|
||||
|
||||
The new HDMI driver at 'os/src/drivers/framebuffer/omap4' implements Genode's
|
||||
'Framebuffer::Session' interface by using the HDMI output of OMAP4. The current
|
||||
version sets up a fixed XGA screen mode of 1024x768 with the RGB565 pixel
|
||||
format.
|
||||
|
||||
|
||||
:SD-card:
|
||||
|
||||
The new SD card driver at 'os/src/drivers/sd_card/omap4' allows the use of a
|
||||
HDSD card with the Pandaboard as block service. The driver can be tested using
|
||||
the 'os/run/sd_card.run' script. Because it implements the generic
|
||||
'Block::Session' interface, it can be combined with a variety of other
|
||||
components such as 'part_blk' (for accessing individual partitions) or
|
||||
'ffat_fs' for accessing a VFAT file system on the SD card.
|
||||
|
||||
The driver uses the master DMA facility of the OMAP4 SD-card controller, which
|
||||
yields to good performance at low CPU utilization. The throughput matches (and
|
||||
in some cases outperforms) the Linux kernel driver. In the current version,
|
||||
both modes of operation PIO and DMA are functional. However, PIO mode is
|
||||
retained for benchmarking purposes only and will possibly be removed to further
|
||||
simplify the driver.
|
||||
|
||||
|
||||
:USB HID:
|
||||
|
||||
The OMAP4-based Pandaboard relies on USB for attaching input devices.
|
||||
Therefore, we need a complete USB stack to enable the interactive use of the
|
||||
board. Instead of implementing a USB driver from scratch, we built upon the USB
|
||||
driver introduced with the Genode release 12.05. This driver was ported from the
|
||||
Linux kernel.
|
||||
|
||||
|
||||
:Networking:
|
||||
|
||||
The Pandaboard realizes network connectivity via the SMSC95xx chip attached to
|
||||
the USB controller. Therefore, we enhanced our USB driver with support for USB
|
||||
net and the smsc95xx driver. In addition to enabling the actual device-driver
|
||||
functionality, the USB stack has received much attention concerning performance
|
||||
optimizations. To speed up the allocation of SKBs, we replaced the former
|
||||
AVL-tree based allocator with a fast bitmap allocator. For anonymous
|
||||
allocations, we introduced a slab-based allocator. Furthermore, we introduced
|
||||
the distinction between memory objects that are subjected to DMA operations
|
||||
from non-DMA memory objects. The most profound conceptual optimization is the
|
||||
use of transmit bursts by the driver. The Linux kernel, which our driver
|
||||
originates from, does not provide an API for transmitting multiple packets as a
|
||||
burst. For our driver, however, this optimization opportunity opened up thanks
|
||||
to Genode's packet stream interface, which naturally facilitates the batching
|
||||
of networking packets. So the driver has all the information needed to create
|
||||
burst transactions.
|
||||
|
||||
|
||||
USB driver
|
||||
==========
|
||||
|
||||
By testing our new USB driver on a variety of real PC hardware, we discovered
|
||||
several shortcomings, which we resolved. In particular, we added support for
|
||||
more than one UHCI controller, make sure that the 'PIRQ' bit in the legacy
|
||||
support register (PCI config space) of the UHCI controller is enabled and that
|
||||
the 'Trap on IRQ' bit is disabled.
|
||||
|
||||
With those modifications in place, the USB driver works reliably on the tested
|
||||
platforms.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Noux
|
||||
====
|
||||
|
||||
Noux enables the easy reuse of unmodified GNU software on Genode by providing
|
||||
a Unix-like kernel interface as user-level service. Because Noux is pivotal for
|
||||
our plan to use Genode for productive work, we significantly enhanced and
|
||||
complemented its feature set.
|
||||
|
||||
|
||||
:Noux on ARM and x86_64:
|
||||
|
||||
For keeping the scope of the development manageable, the initial version of
|
||||
Noux was tied to the x86_32 platform. This was not a principal limitation of
|
||||
the approach but rather an artificial restriction to keep us focused on
|
||||
functionality first. Now that Noux reaches a usable state, we desire to use it
|
||||
on platforms other than x86_32. The current release enables Noux for the 64-bit
|
||||
x86 and ARM architectures.
|
||||
|
||||
The level of support is pretty far-reaching and even includes the building and
|
||||
execution of the Genode tool chain on those platforms. In the process of
|
||||
enabling these platforms, we updated the Noux package for GCC to version 4.6.1,
|
||||
which matches the version of the current Genode tool chain.
|
||||
|
||||
|
||||
:Terminal file system:
|
||||
|
||||
Noux supports the concept of stacked file systems. The virtual file system
|
||||
is defined at the start of a Noux instance driven by the static Noux
|
||||
configuration. This way, arbitrary directory structures can be composed out
|
||||
of file-system sessions and TAR archives. The VFS concept allows for the
|
||||
easy addition of new file system types. To allow programs running in a Noux
|
||||
instance to communicate over a dedicated terminal session, we added a new
|
||||
file-system type that corresponds to a virtual character device node attached
|
||||
to a terminal session.
|
||||
|
||||
|
||||
:GDB running in the Noux environment:
|
||||
|
||||
With the terminal file system in place, we are ready to execute GDB within
|
||||
Noux and let it talk to a GDB monitor instance over the terminal session
|
||||
interface. From GDB's point of view, the setup looks like a remote debugging
|
||||
session. But in reality both the debugging target and GDB reside in different
|
||||
subtrees of the same Genode system.
|
||||
|
||||
|
||||
:Executing shell scripts:
|
||||
|
||||
By inspecting the program specified to the execve system call, Noux has become
|
||||
able to spawn scripts that use the '#!' syntax. If such a file is detected, it
|
||||
executes the specified interpreter instead and passes the arguments specified
|
||||
after the '#!' marker, followed by command-line arguments.
|
||||
|
||||
|
||||
:Networking support:
|
||||
|
||||
Our work on porting various networking tools to Noux triggers us to steadily
|
||||
improve the networking support introduced with Genode 12.05. In particular, we
|
||||
added proper support for DNS resolving, which enables us to execute the
|
||||
command-line based Lynx web browser within Noux.
|
||||
|
||||
|
||||
:User information:
|
||||
|
||||
Because there are certain programs, which need the information that is stored
|
||||
in 'struct passwd', we introduced configurable user information support to
|
||||
Noux. One can set the user information via the '<user>' node in the Noux
|
||||
config:
|
||||
|
||||
! <config>
|
||||
! <user name="baron" uid="1" gid="1">
|
||||
! <shell name="/bin/bash" />
|
||||
! <home name="/home" />
|
||||
! </user>
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
When '<user>' is not specified, default values are used. Currently these
|
||||
are 'root', 0, 0, '/bin/bash', '/'. Note that this is just a single user
|
||||
implementation because each Noux instance has only one user or rather one
|
||||
identity and there will be no complete multi-user support in Noux. If you need
|
||||
different users, just start new Noux instances for each of them.
|
||||
|
||||
|
||||
:New '/dev/null' and '/dev/zero' pseudo devices:
|
||||
|
||||
These device are mandatory for most programs (well, at least null is required
|
||||
to be present for a POSIX compliant OS, which Noux is actually not). But for
|
||||
proper shell-script support we will need them anyway. Under the hood, both
|
||||
pseudo devices are implemented as individual file-systems and facilitate Noux's
|
||||
support for stacked file systems. The following example configuration snippet
|
||||
creates the pseudo devices under the '/dev' directory.
|
||||
|
||||
! <config>
|
||||
! <fstab>
|
||||
! <dir name="dev" >
|
||||
! <null /> <zero />
|
||||
! </dir>
|
||||
! ...
|
||||
! <fstab>
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
|
||||
Vancouver
|
||||
=========
|
||||
|
||||
The comprehensive rework of the NOVA base platform affected the Genode version
|
||||
of the Vancouver virtual machine monitor as this program used to speak directly
|
||||
to the NOVA kernel. Since no kernel objects can be created outside of core
|
||||
anymore, the Vancouver port had to be adjusted to solely use Genode interfaces.
|
||||
|
||||
|
||||
L4Linux
|
||||
=======
|
||||
|
||||
To improve the stability and performance of L4Linux on OMAP4 platforms, we
|
||||
reworked parts of the Genode-specific stub drivers, in particular the
|
||||
networking code. Among the improvements are the use of a high-performance
|
||||
allocator for networking packets, improved IRQ safety of IPC calls (to
|
||||
the Genode world), and tweaks of the TCP rmem and wmem buffer sizes to
|
||||
achieve good TCP performance when running Linux with little memory.
|
||||
|
||||
Furthermore, we added two ready-to-use run scripts residing within
|
||||
'ports-foc/run' as examples for executing L4Linux on the OMAP4-based
|
||||
Pandaboard. The 'linux_panda.run' script is meant as a blue print for
|
||||
experimentation. It integrates one instance of L4Linux with the native SD-card
|
||||
driver, the HDMI driver, and the USB HID input driver. The
|
||||
'two_linux_panda.run' script is a more elaborative example that executes two
|
||||
instances of L4Linux, a block-device test, and a simple web server. Each of
|
||||
the L4Linux instances accesses a different SD-card partition whereas the
|
||||
block-device test operates on a third partition.
|
||||
|
||||
|
||||
735
doc/release_notes/12-11.txt
Normal file
735
doc/release_notes/12-11.txt
Normal file
@@ -0,0 +1,735 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 12.11
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The central theme of version 12.11 of the Genode OS Framework is
|
||||
self-hosting Genode on Genode. With self-hosting, we understand the execution of the
|
||||
entire Genode build system within the Genode environment. There are two motivations
|
||||
for pursing this line of work. First, it is a fundamental prerequisite for the
|
||||
Genode developers to move towards using Genode as a day-to-day OS. Of course,
|
||||
this prerequisite could be realized using one of the available virtualization
|
||||
solutions. For example, we could run L4Linux on top of Genode on the Fiasco.OC
|
||||
kernel and use the Genode build system from within an L4Linux instance.
|
||||
However, this defeats the primary incentive behind Genode to reduce system
|
||||
complexity. By having both Genode and L4Linux in the picture, we would indeed
|
||||
increase the overall complexity in configuring, maintaining, and using the
|
||||
system. Therefore, we would largely prefer to remove the complex Linux user
|
||||
land from the picture. The second motivation is to prove that the framework and
|
||||
underlying base platforms are suited and stable enough for real-world use.
|
||||
If the system is not able to handle a workload like the build system,
|
||||
there is little point in arguing about the added value of having a
|
||||
microkernel-based system over current commodity OSes such as GNU/Linux.
|
||||
|
||||
We are happy to have reached the state where we can execute the unmodified
|
||||
Genode build system directly on Genode running on a microkernel. As the
|
||||
build system is based on GNU utilities and the GNU compiler collection,
|
||||
significant effort went into the glue between those tools and the Genode API.
|
||||
Section [Building Genode on Genode] provides insights into the way we achieved
|
||||
the goal and the current state of affairs.
|
||||
|
||||
Along with the work on bringing the build system to Genode came numerous
|
||||
stability improvements and optimizations all over the place, reaching from the
|
||||
respective kernels, over the C runtime, the file-system implementations, memory
|
||||
allocators, up to the actual programs the tool chain is composed of. Speaking
|
||||
of the tool chain, the official Genode tool chain has been updated from GCC
|
||||
version 4.6.1 to version 4.7.2. Thereby, all 3rd-party code packages were
|
||||
subjected to testing and fixing activities.
|
||||
|
||||
For running the build system, the project currently focuses on NOVA and
|
||||
Fiasco.OC as base platforms. However, our custom kernel platform for the ARM
|
||||
architecture has also received significant improvements. With added support for
|
||||
Freescale i.MX and Texas Instruments OMAP4, this platform proved to be very
|
||||
well adaptable to new SoCs whereas new cache handling brings welcome
|
||||
performance improvements. Furthermore, we have added experimental support for
|
||||
ARM TrustZone technology, which principally enables the execution of Genode in
|
||||
the so-called secure world of TrustZone while executing Linux in the so-called
|
||||
normal world.
|
||||
|
||||
As we discovered the increasing interest in using Genode as a middleware
|
||||
solution on Linux, we largely revisited the support for this kernel platform
|
||||
and discovered amazing new ways to align the concept of Genode with the
|
||||
mechanisms provided by the Linux kernel. Section [Linux] provides a summary
|
||||
of the new approaches taken for supporting this platform.
|
||||
|
||||
Functionality-wise, the new version introduces support for audio drivers of
|
||||
the Open Sound System, a new OMAP4 GPIO driver, improvements of the graphical
|
||||
terminal, and the initial port of an SSH client.
|
||||
|
||||
|
||||
Building Genode on Genode
|
||||
#########################
|
||||
|
||||
On the Genode developer's way towards using Genode as a day-to-day OS, the
|
||||
ability to execute the Genode build system within the Genode environment is a
|
||||
pivotal step - a step that is highly challenging because the build system is
|
||||
based on the tight interplay of many GNU programs. Among those
|
||||
programs are GNU make, coreutils, findutils, binutils, gcc, and bash. Even
|
||||
though there is a large track record of individual programs and libraries ported
|
||||
to the environment, those programs used to be self-sustaining applications that
|
||||
require only little interaction with other programs. In contrast, the build
|
||||
system relies on many utilities working together using mechanisms such as
|
||||
files, pipes, output redirection, and execve. The Genode base system does not
|
||||
come with any of those mechanisms let alone the subtle semantics of the POSIX
|
||||
interface as expected by those utilities. Being true to microkernel principles,
|
||||
Genode's API has a far lower abstraction level and is much more rigid in scope.
|
||||
|
||||
To fill the gap between the requirements of the build system and the bare
|
||||
Genode mechanisms, the Noux runtime environment was created. Noux is a Genode
|
||||
process that acts like a Unix kernel. When started, it creates a child process,
|
||||
which plays a similar role as the init process of Unix. This process communicates
|
||||
via RPC messages to Noux. Using those messages, the process can perform all the
|
||||
operations normally provided by a classical Unix kernel. When executed under
|
||||
Noux, a process can even invoke functionalities such as fork and execve, which
|
||||
would normally contradict with Genode's principles of resource management.
|
||||
|
||||
Over the course of the past year, more and more programs have been ported to
|
||||
the Noux environment. Thereby, the semantics provided by Noux have been
|
||||
successively refined so that those program behave as expected. This was an
|
||||
iterative process. For example, at the beginning, Noux did not consider the
|
||||
differences between 'lstat' and 'stat' as they did not matter for the first
|
||||
batch of GNU programs ported to Noux. As soon as the programs got more
|
||||
sophisticated, such shortcuts had to be replaced by the correct semantics. The
|
||||
Genode build system is by far the most complex scenario exposed to Noux so far.
|
||||
It revealed many shortcomings by both functionality implemented in Noux or the
|
||||
C runtime as well as the underlying base platforms. So it proved to be a great
|
||||
testing ground for analysing and improving those platform details. Therefore,
|
||||
the secondary effects of self-hosting Genode on Genode in terms of stability
|
||||
turned out to be extremely valuable.
|
||||
|
||||
The release comes with two ready-to-use run scripts for building bootable
|
||||
system images that are able to execute the Genode tool chain, one for targeting
|
||||
NOVA and one for targeting Fiasco.OC. Those run scripts are located at
|
||||
'ports/run/' and called 'noux_tool_chain_nova.run' and 'noux_tool_chain_foc.run'
|
||||
respectively. Each of those run scripts can be executed on either of those base
|
||||
platforms. For example, by executing 'noux_tool_chain_nova' on Fiasco.OC, the
|
||||
image will run Genode on Fiasco.OC and the tool chain will build binaries for
|
||||
NOVA. When started, a build directory will be created at '/home/build'.
|
||||
The Genode source code is located at '/genode'. In the '/bin' directory,
|
||||
there are all the GNU programs needed to execute the tool chain. For
|
||||
taking a look into the source code, 'vim' is available. To build core,
|
||||
change to the build directory '/home/build' and issue 'make core'.
|
||||
|
||||
On Fiasco.OC, the complete Genode demo scenario can be compiled. On NOVA, the
|
||||
incomplete life-time management of kernel objects will still result in an
|
||||
out-of-memory error of the kernel. This kernel issue is currently being worked
|
||||
on. Executing the tool chain on either of those platforms is still relatively
|
||||
slow as extensive trace output is being generated and no actions have been taken to
|
||||
optimize the performance so far. There are many opportunities for such
|
||||
optimizations, which will be taken on as the next step.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Genode's base framework has received new support for extending session
|
||||
interfaces and gained improvements with regard to interrupt handling on the x86
|
||||
platform. At the API level, there are minor changes related to the CPU session
|
||||
and 'Range_allocator' interfaces.
|
||||
|
||||
|
||||
Support for specializing session interfaces
|
||||
===========================================
|
||||
|
||||
With increasingly sophisticated application scenarios comes the desire to
|
||||
extend Genode's existing session interface with new functionality. For example,
|
||||
the 'Terminal::Session' interface covers plain read and write operations. It is
|
||||
implemented by services such as a graphical terminal, the telnet-like TCP
|
||||
terminal, or UART drivers. However, for the latter category, the breadth of the
|
||||
interface is severely limited as UART drivers tend to supplement the read / write
|
||||
interface with additional control functions, e.g., for setting the baud rate.
|
||||
|
||||
One way to go would be to extend the existing 'Terminal::Session' interface
|
||||
with those control functions. However, these functions would be meaningless for
|
||||
most implementations. Some of those other implementations may even desire their
|
||||
own share of additions. In the longer term, this approach might successively
|
||||
broaden the interface and each implementation will cover a subset only.
|
||||
|
||||
Because Genode aspires to keep interfaces as low-complex as possible while, at
|
||||
the same time, it wants to accommodate the growing sophistication of usage
|
||||
scenarios, we need a solution that scales. The solution turns out to be
|
||||
strikingly simple. The RPC framework already supports the inheritance of RPC
|
||||
interfaces. So it is possible to model the problem such that a new
|
||||
'Uart::Session' interface derived from the existing 'Terminal::Session' will
|
||||
be the host of UART-specific functionality. The only piece missing is the
|
||||
propagation of both 'Uart' and 'Terminal' through the parent interface while
|
||||
announcing the service. To spare the work of manually announcing the chain of
|
||||
inherited interfaces from the implementor, the 'Parent::announce()' function has
|
||||
been enhanced to automatically announce all service types implemented by the
|
||||
announced interface. This way, a UART driver will always announce a "Uart"
|
||||
and a "Terminal" service.
|
||||
|
||||
|
||||
Improved interrupt handling
|
||||
===========================
|
||||
|
||||
To accommodate modern x86 platforms, the session arguments of core's IRQ
|
||||
service have been supplemented with the IRQ mode. There are two degrees of
|
||||
freedom, namely the trigger (level / edge) and polarity (high / low). Thanks to
|
||||
this addition, device drivers have become able to supply their knowledge of
|
||||
devices to core.
|
||||
|
||||
In system scenarios with many peripherals, in particular when using the USB
|
||||
driver, IRQ lines are shared between devices. Until now, Genode supported
|
||||
shared interrupts for the OKL4 base platform only. To also cover the other
|
||||
x86 kernels, we have generalized the interrupt sharing code and enabled this
|
||||
feature on Fiasco.OC and NOVA.
|
||||
|
||||
|
||||
Revised CPU session interface
|
||||
=============================
|
||||
|
||||
We revisited the CPU session interface, removed no-longer used functions and
|
||||
added support for assigning threads to CPUs.
|
||||
|
||||
The original CPU session interface contained functions for iterating through
|
||||
the threads of a session. This interface was originally motivated by an
|
||||
experimental statistical profiling tool that was developed at an early stage of
|
||||
Genode. In the meanwhile, we discovered that the virtualization of the CPU
|
||||
session interface is much more elegant to cover this use case than the
|
||||
thread-iterator interface. Because the iteration has no transactional
|
||||
semantics, it was unsafe to use it anyway.
|
||||
|
||||
To enable the use of multiple CPUs on multi-processor systems, the CPU
|
||||
session interface has been enhanced with two functions, namely 'affinity'
|
||||
and 'num_cpus'. The interface extension principally allows the assignment of
|
||||
individual threads to CPUs. It is currently implemented on Fiasco.OC only.
|
||||
On all other base platforms, 'num_cpus' returns one CPU. Note that on
|
||||
the Linux platform, multiple CPUs will be used transparently.
|
||||
|
||||
The 'Cpu_session::state' function has been split into two functions, one
|
||||
for retrieving information and one for propagating state information. The
|
||||
prior interface was less explicit about the semantics of the 'state' function
|
||||
as it took a non-const pointer to a 'Thread_state' object as argument.
|
||||
|
||||
|
||||
Platform-tailored protection domains
|
||||
====================================
|
||||
|
||||
Genode tries to provide a uniform API across all the different base platforms.
|
||||
Yet, it also strives to make genuine platform features available to the
|
||||
users of the framework. Examples for such features are the virtualization
|
||||
support of the NOVA hypervisor or the special support for paravirtualizing
|
||||
Linux on Fiasco.OC. Another example is the security model as found on the Linux
|
||||
platform. Even though the security mechanisms of plain Linux are not as strong
|
||||
as Genode's capability concept on a conceptual level, we still want to leverage
|
||||
the available facilities such as user IDs and chroot as far as possible.
|
||||
Consequently, we need a way to assign platform-specific properties to PD
|
||||
sessions. With the new 'Native_pd_args' type introduced into
|
||||
'base/native_types.h', there is now a way to express those platform-specific
|
||||
concerns. This type is now used at all the places that deal with the creation
|
||||
of protection domains such as 'Process', 'Child', and the loader.
|
||||
|
||||
|
||||
Revised 'Range_allocator' interface
|
||||
===================================
|
||||
|
||||
The handling of allocation errors has been refined in order to distinguish
|
||||
different error conditions, in particular out-of-metadata and out-of-memory
|
||||
conditions. The user of the allocator might want to handle both cases
|
||||
differently. Hence we return an 'Alloc_return' value as result. In prior
|
||||
versions, this type was just an enum value. With the new version, the type has
|
||||
been changed to a class. This makes the differentiation of error conditions at
|
||||
the caller side more robust because, in contrast to enum values, typed objects
|
||||
don't get implicitly converted to bool values.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
New UART session interface
|
||||
==========================
|
||||
|
||||
To accommodate UART specific extensions of the 'Terminal::Session' interface,
|
||||
in particular setting the baud rate, we introduced the new 'Uart::Session'
|
||||
interface and changed the existing UART drivers to implement this
|
||||
interface instead of the 'Terminal::Session' interface. Because 'Uart::Session'
|
||||
inherits the 'Terminal::Session' interface, 'Uart' services announce both
|
||||
"Uart" and "Terminal" at their parent.
|
||||
|
||||
|
||||
New GPIO session interface
|
||||
==========================
|
||||
|
||||
Embedded SoCs such as OMAP4 provide many general-purpose I/O pins, which can be
|
||||
used for different purposes depending on the board where they are soldered on.
|
||||
For example, the Pandaboard uses such GPIO pins to detect the presence of a
|
||||
HDMI plug or control the power supply for the USB. If only one driver deals
|
||||
with GPIO pins, the GPIO programming can reside in the driver. However, if
|
||||
multiple drivers are used, the GPIO device resources cannot be handed out to
|
||||
more than one driver. This scenario calls for the creation of a GPIO driver as
|
||||
a separate component, which intermediates (and potentially multiplexes) the
|
||||
access to the physical GPIO pins. The new 'Gpio::Session' interface allows one
|
||||
or multiple clients to configure I/O pins, request states, as well as to
|
||||
register for events happening on the pins.
|
||||
|
||||
|
||||
Terminal
|
||||
========
|
||||
|
||||
The graphical terminal has been enhanced with support for different built-in
|
||||
font sizes and background-color handling.
|
||||
|
||||
In addition to those functional changes, the implementation has been decomposed
|
||||
into several parts that thereby became reusable. Those parts comprise the
|
||||
handling of key mappings, decoding the VT character stream, and the handling of
|
||||
the character array. These functionalities are now available at
|
||||
'gems/include/terminal'.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
:Allocator optimized for small-object allocations:
|
||||
|
||||
To optimize the performance of workloads that depend on a large number of small
|
||||
dynamic memory allocations, in particular the lwIP TCP/IP stack, we replaced
|
||||
the memory allocator of the libc with a more sophisticated strategy. Until now,
|
||||
the libc used 'Genode::Heap' as allocator. This implementation is an
|
||||
AVL-tree-based best-fit allocator that is optimized for low code complexity
|
||||
rather than performance for small allocations. The observation of the allocator
|
||||
usage pattern of lwIP prompted us to replace the original libc malloc/free with
|
||||
a version that uses slab allocators for small objects and relies on the
|
||||
'Genode::Heap' for large objects only.
|
||||
|
||||
:Symbolic links:
|
||||
|
||||
Because part of our ongoing refinements of the Noux runtime is the provision of
|
||||
symbolic links, support for symbolic links was added in the libc, libc plugins,
|
||||
and file system servers.
|
||||
|
||||
|
||||
lwIP
|
||||
====
|
||||
|
||||
We updated the light-weight IP stack to version STABLE-1.4.1. Additionally,
|
||||
the following optimizations were conducted to improve its performance and
|
||||
robustness.
|
||||
|
||||
We reduced the maximum segment lifetime from one minute to one second to avoid
|
||||
queuing up PCBs in TIME-WAIT state. This is the state, PCBs end up after
|
||||
closing a TCP connection socket at the server side. The number of PCBs in this
|
||||
state is apparently not limited by the value of 'MEMP_NUM_TCP_PCB'. One
|
||||
allocation costs around 160 bytes. If clients connect to the server at a high
|
||||
rate, those allocations accumulate quickly and thereby may exhaust the memory
|
||||
of the server. By reducing the segment lifetime, PCBs in TIME-WAIT state are
|
||||
cleaned up from the 'tcp_tw_pcbs' queue in a more timely fashion (by
|
||||
'tcp_slowtmr()').
|
||||
|
||||
To prevent the TCP/IP stack from artificially throttling TCP throughput,
|
||||
we adjusted lwIP's TCP_SND_BUF size.
|
||||
|
||||
From our work on optimizing the NIC stub-code performance of L4Linux as
|
||||
described [https://genode.org/documentation/articles/pandaboard - here],
|
||||
we learned that the use of a NIC-specific packet allocator for the
|
||||
packet-stream interface is beneficial. At the lwIP back end, we still relied on
|
||||
the original general-purpose allocator. Hence, we improved the lwIP back-end
|
||||
code by using the bitmap-based 'Nic::Packet_allocator' allocator instead.
|
||||
|
||||
|
||||
Standard C++ library
|
||||
====================
|
||||
|
||||
Genode used to rely on the standard C++ library that comes with the tool chain.
|
||||
However, this mechanism was prone to inconsistencies of the types defined in
|
||||
the header files used at compile time of the tool chain and the types provided
|
||||
by our libc. By building the C++ standard library as part of the Genode build
|
||||
process, such inconsistencies cannot happen anymore. The current version of the
|
||||
C++ standard library corresponds to GCC 4.7.2.
|
||||
|
||||
Note that the patch changes the meaning of the 'stdcxx' library for users that
|
||||
happened to rely on 'stdcxx' for hybrid Linux/Genode applications. For such
|
||||
uses, the original mechanism is still available, in the renamed form of
|
||||
'toolchain_stdcxx'.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Open Sound System
|
||||
=================
|
||||
|
||||
Genode tries to re-use existing device drivers as much as possible using an
|
||||
approach called device-driver environment (DDE). A DDE is a library that
|
||||
emulates the environment of the original driver by translating device accesses
|
||||
to the Genode API. There are many success stories of drivers successfully ported
|
||||
to the framework this way. For example, using DDE-Linux, we are able to use the
|
||||
Linux USB stack. Using DDE-ipxe, we are able to use iPXE networking drivers.
|
||||
With Genode 12.11 we extend our arsenal of DDEs with DDE-OSS, which is a
|
||||
device-driver environment for the audio drivers of the Open Sound System (OSS).
|
||||
|
||||
:Website of the Open Sound System:
|
||||
|
||||
[http://www.4front-tech.com]
|
||||
|
||||
The new 'dde_oss' contains all the pieces needed to use Intel HDA, AC97, and
|
||||
ES1370 audio cards on Genode. On first use, the 3rd-party code can be
|
||||
downloaded by issuing 'make prepare' from within the 'dde_oss' source-code
|
||||
repository. Also, you need to make sure to add the 'dde_oss' repository to your
|
||||
'REPOSITORIES' variable in 'etc/build.conf'.
|
||||
|
||||
An OSS demo configuration can be found under 'run/oss.run' and can be started
|
||||
via 'make run/oss' from a Genode build directory. Be sure to adjust the
|
||||
'filename' tag of the 'audio0' program. The file has to reside under
|
||||
'<build-dir>/bin/'. The file format is header-less two-channel float-32 at
|
||||
44100 Hz. You may use the 'sox' utility to create these audio files:
|
||||
|
||||
! sox -c 2 -r 44100 foo.mp3 foo.f32
|
||||
|
||||
|
||||
OMAP4 GPIO driver
|
||||
=================
|
||||
|
||||
The new OMAP4 GPIO driver is the first implementation of the just introduced
|
||||
'Gpio::Session' interface. The driver supports two ways of interacting
|
||||
with GPIO pins, by providing a static configuration, or by interacting with a
|
||||
session interface at runtime. An example for a static configuration looks as
|
||||
follows:
|
||||
|
||||
! <config>
|
||||
! <gpio num="121" mode="I"/>
|
||||
! <gpio num="7" mode="O" value="0"/>
|
||||
! <gpio num="8" mode="O" value="0"/>
|
||||
! </config>
|
||||
|
||||
The driver is located at 'os/src/drivers/gpio/omap4'. As reference for using
|
||||
the driver, please refer to the 'os/run/gpio_drv.run' script.
|
||||
|
||||
Thanks to Ivan Loskutov of Ksys-Labs for contributing the session interface
|
||||
and the driver!
|
||||
|
||||
|
||||
iPXE networking drivers
|
||||
=======================
|
||||
|
||||
We updated our device-driver environment for iPXE networking drivers to a
|
||||
recent git revision and enabled support for the x86_64 architecture.
|
||||
Currently, the driver covers Intel gigabit ethernet (e1000, e1000e, igb),
|
||||
Intel eepro100, and Realtek 8139/8169.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Noux
|
||||
====
|
||||
|
||||
The Noux runtime environment has received plenty of love thanks to the
|
||||
aspiration to execute the Genode build system.
|
||||
|
||||
:Time:
|
||||
|
||||
The build system uses GNU make, which depends on time stamps of files. We do
|
||||
not necessarily need a real clock. A monotonic increasing virtual time is
|
||||
enough. To provide such a virtual time, the libc was enhanced with basic
|
||||
support for functions like 'gettimeofday', 'clock_gettime', and 'utimes'. As
|
||||
there is currently no interface to obtain the real-world time in Genode, Noux
|
||||
simulates a pseudo real-time clock using a jiffies-counting thread. This
|
||||
limited degree of support for time is apparently sufficient to trick tools like
|
||||
ping, find, and make into working as desired.
|
||||
|
||||
:Improved networking support:
|
||||
|
||||
The Noux/net version of Noux extends the Noux runtime with the BSD-socket
|
||||
interface by using the lwIP stack. This version of Noux multiplexes the
|
||||
BSD-socket interface of lwIP to multiple Noux programs, each having a different
|
||||
socket-descriptor name space and the principal ability to use blocking calls
|
||||
such as 'select'. The code for multiplexing the lwIP stack among multiple Noux
|
||||
processes has been improved to cover corner cases exposed by sophisticated
|
||||
network clients, i.e., openssh.
|
||||
|
||||
:Directory cache for the TAR file system:
|
||||
|
||||
The original version of the TAR file system required a search in all TAR
|
||||
records for each file lookup. This takes a long time when composing a large
|
||||
directory tree out of multiple TAR archives stacked together. This is the case
|
||||
for the Genode build-system scenario where we have all the files of the GNU
|
||||
tools as well as the Genode source tree. Searching through thousands of records
|
||||
for each call of 'stat' quickly becomes a scalability issue. Therefore, we
|
||||
introduced a TAR indexing mechanism that scans each TAR file only once at the
|
||||
startup of Noux and generates a tree structure representing the directory
|
||||
layout. Looking up files using this index is quick.
|
||||
|
||||
:New packages:
|
||||
|
||||
With Genode-12.11, new 3rd-party packages have become available, namely
|
||||
OpenSSH, the 'which' command, and all tool-chain components in their current
|
||||
version. OpenSSH is still at an experimental stage. The run script at
|
||||
'ports/run/noux_net_openssh_interactive.run' demonstrates how SSH can be used
|
||||
to login into a remote machine.
|
||||
|
||||
:New pseudo file systems:
|
||||
|
||||
The new 'stdio' and 'random' file systems are intended to represent the pseudo
|
||||
devices '/dev/random' and '/dev/tty' on Noux. Both are needed to run OpenSSH.
|
||||
Note that the 'Arc4random' class, on which the random file system is based on,
|
||||
currently _does not collect enough_ random bytes! It should not be used for
|
||||
security-critical applications.
|
||||
|
||||
|
||||
L4Linux
|
||||
=======
|
||||
|
||||
The paravirtualized L4Linux kernel for the Fiasco.OC platform was updated to
|
||||
SVN revision 25, which matches the Fiasco.OC SVN revision 40. We further
|
||||
improved the integration of L4Linux with Genode by optimizing the stub drivers
|
||||
for block devices and networking, and added principal support for running
|
||||
L4Linux on SMP platforms.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
NOVA
|
||||
====
|
||||
|
||||
Genode follows the steady development of the NOVA microhypervisor very closely.
|
||||
The kernel used by the framework corresponds to the current state of the master
|
||||
branch of IntelLabs/NOVA.
|
||||
|
||||
|
||||
:Improvements towards GDB support:
|
||||
|
||||
The NOVA-specific implementation of the CPU session interface has been improved
|
||||
to accommodate the requirements posed by GDB. In particular, the 'pause',
|
||||
'resume', 'state', and 'single_step' functions have been implemented. Those
|
||||
functions can be used to manipulate the execution and register state of
|
||||
threads. Under the hood, NOVA's 'recall' feature is used to implement these
|
||||
mechanisms. By issuing a 'recall' for a given thread, the targeted thread is
|
||||
forced into an exception. In the exception, the current state of the thread can
|
||||
be obtained and its execution can be halted/paused.
|
||||
|
||||
|
||||
:Maximizing contiguous virtual space:
|
||||
|
||||
To enable the Vancouver virtual machine monitor to hand out large amounts of
|
||||
guest memory, we optimized core's virtual address space to retain large and
|
||||
naturally aligned contiguous memory regions. For non-core processes, the
|
||||
thread-context area that contains the stacks of Genode threads has been moved
|
||||
to the end of the available virtual address space.
|
||||
|
||||
|
||||
:Life-time management of kernel resources:
|
||||
|
||||
We improved the life-time management of kernel resources, in particular
|
||||
capabilities, within Genode. Still the management of such kernel resources
|
||||
is not on par with the Fiasco.OC version, partially because of missing
|
||||
kernel functionality. This is an ongoing topic that is being worked on.
|
||||
|
||||
|
||||
:Using the BIOS data area (BDA) to get serial I/O ports on x86:
|
||||
|
||||
If the I/O ports for the comport are non default (default is 0x3f8), we had to
|
||||
specify manually the correct I/O ports in the source code. To avoid the need
|
||||
for source-code modifications when changing test machines, we changed the core
|
||||
console to read the BDA and use the first serial interface that is available.
|
||||
If no serial interface is available, no device configuration will be
|
||||
undertaken. The BDA can be populated via a multi-boot chain loader. Bender is
|
||||
such a chain loader that can detect serial ports accessible via PCI and writes
|
||||
the I/O ports to the Bios Data area (BDA). These values get then picked up by
|
||||
core.
|
||||
|
||||
|
||||
Fiasco.OC
|
||||
=========
|
||||
|
||||
The Fiasco.OC kernel has been updated to the SVN revision 40. The update improves
|
||||
SMP support and comes with various bug fixes. There is no noteworthy change
|
||||
with regard to the kernel interface. We extended the number of supported
|
||||
Fiasco.OC-based platforms for Genode by including the Freescale i.MX53.
|
||||
|
||||
To enable the use of multiple CPUs by Genode processes, the CPU session
|
||||
interface has been enhanced to support configuring the affinity of threads with
|
||||
CPUs. We changed the default kernel configuration for x86 and ARM to
|
||||
enable SMP support and adapted L4Linux to use the new interface.
|
||||
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
The development of our custom platform for executing Genode directly on bare
|
||||
hardware with no kernel underneath went full steam ahead during the release
|
||||
cycle.
|
||||
|
||||
:Pandaboard:
|
||||
|
||||
The in-kernel drivers needed to accommodate the Pandaboard, more specifically
|
||||
the timer and interrupt controller, are now supported. So the Pandaboard can be
|
||||
used with both 'base-hw' and 'base-foc'. Also, the higher-level platform
|
||||
drivers for USB, HDMI, and SD-card that were introduced with the previous
|
||||
release, are equally functional on both platforms.
|
||||
|
||||
:Freescale i.MX31:
|
||||
|
||||
We added principal support for the Freescale i.MX line of SoCs taking the
|
||||
ARMv6-based i.MX31 as starting point. As of now, the degree of support is
|
||||
limited to the devices needed by the kernel to operate. Pure software-based
|
||||
scenarios are able to work, i.e., the nested init run script executes
|
||||
successfully.
|
||||
|
||||
:TrustZone support:
|
||||
|
||||
The new VM session interface of core provides a way to execute software
|
||||
in the normal world of a TrustZone system whereas Genode runs in the secure
|
||||
world. From Genode's point of view, the normal world looks like a virtual
|
||||
machine. Each time, the normal world produces a fault or issues a secure
|
||||
monitor call, control gets transferred to the virtual machine monitor, which is
|
||||
a normal user-level Genode process. The base-hw kernel has been enhanced to
|
||||
perform world switches between the secure and normal world and with the ability
|
||||
to handle fast interrupts (FIQs) in addition to normal interrupts. The latter
|
||||
extension is needed to assign a subset of devices to either of both worlds.
|
||||
|
||||
Currently, the only TrustZone capable platform is the ARM CoreTile Express
|
||||
CA9x4 for the Versatile Express board. For a virtual machine working properly
|
||||
on top, some platform resources must be reserved. Therefore, there exist two
|
||||
flavours of this platform now, one with the 'trustzone' spec-variable enabled
|
||||
and one without. If 'trustzone' is specified, most platform resources (DDR-RAM,
|
||||
and most IRQs) are reserved for the normal world and not available to the
|
||||
secure Genode world.
|
||||
|
||||
:Memory attributes and caching:
|
||||
|
||||
We successively activated various levels of caching and improved the handling
|
||||
of caching attributes propagated into the page tables. These changes resulted
|
||||
in a significant boost in performance on non-emulated platforms.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
The Linux version of Genode was originally meant as a vehicle for rapid
|
||||
development. It allows the framework components including core to be executed
|
||||
as plain Linux processes. But in contrast to normal Linux programs, which
|
||||
use the glibc, Genode's components interact with the kernel directly without
|
||||
any C runtime other than what comes with Genode. We use the Linux version on a
|
||||
regular basis to implement platform-agnostic functionality and protocols. Most
|
||||
of Genode's code (except for device drivers) falls in this category. Because
|
||||
the Linux version was meant as a mere tool, however, we haven't put much
|
||||
thought into the principle way to implementing Genode's security concept on
|
||||
this platform. Threads used to communicate over globally accessible Unix-domain
|
||||
sockets and memory objects were represented as globally accessible files within
|
||||
'/tmp'.
|
||||
|
||||
That said, even though Linux was not meant as a primary platform for Genode in
|
||||
the first place, Genode can bring additional value to Linux. When considering
|
||||
the implementation of a component-based system on Linux, there are several
|
||||
possible approaches to take. For example, components may use DBus to
|
||||
communicate, or components could pick from the manifold Unix mechanisms such as
|
||||
named pipes, files, sysv-shared memory, signals, and others. Unfortunately
|
||||
those mechanisms are not orthogonal and most of them live in the global name
|
||||
space of the virtual file system. Whereas those mechanisms are principally able
|
||||
to let processes communicate, questions about how processes get to know each
|
||||
other, access-control policy, synchronization of the startup of processes are
|
||||
left to the developer.
|
||||
|
||||
Genode, on the other hand, does provide an API for letting components
|
||||
communicate but also answers those tricky questions concerning the composition
|
||||
of components. This makes Genode an interesting option to build component based
|
||||
applications, even on Linux. However, when used in such a context, the
|
||||
limitations of the original Linux support need resolutions. Therefore, the
|
||||
current release comes with a largely revised platform support for the Linux
|
||||
base platform.
|
||||
|
||||
The changes can be summarized as follows:
|
||||
|
||||
:Using file descriptors as communication addresses:
|
||||
|
||||
Genode's synchronous RPC framework was using Unix domain sockets. Each RPC
|
||||
entrypoint was represented by a pair of named files, one for sending and one
|
||||
for receiving messages. In the new version, inter-process communication is
|
||||
performed via file descriptors only.
|
||||
|
||||
:Transfer of communication rights via RPC only:
|
||||
|
||||
Capabilities used to be represented as a pair of the destination thread ID and
|
||||
a global object ID. The thread ID has been replaced by a file descriptor that
|
||||
points to the corresponding RPC entrypoint. When capabilities are transferred
|
||||
as RPC arguments, those file descriptors are transferred via SCM rights
|
||||
messages. This is in line with Genode's way of capability-based delegation of
|
||||
access rights.
|
||||
|
||||
:Core-only creation of communication channels:
|
||||
|
||||
Communication channels used to be created locally by each process. The naming
|
||||
of those channels was a mere convention. In contrast, now, communication
|
||||
channels are created by core only and do not reside on the Linux virtual file
|
||||
system. When creating an RPC entrypoint, core creates a socket pair and hands
|
||||
out both ends to the creator of the entrypoint.
|
||||
|
||||
:Restricted access to memory objects:
|
||||
|
||||
Access to dataspace content was performed by mmap'ing a file. For a given
|
||||
dataspace, the file name could be requested at core via a Linux-specific RPC
|
||||
call. Now, core holds the file descriptors of all dataspaces, which are
|
||||
actually unlinked files. A process that is in possession of a dataspace
|
||||
capability can request the file descriptor for the content from core and mmap
|
||||
the file locally. This way, access to memory objects is subjected to the
|
||||
delegation of dataspace capabilities.
|
||||
|
||||
:Core-local process creation:
|
||||
|
||||
Genode used to create new processes by directly forking from the respective
|
||||
Genode parent using the process library. The forking process created a PD
|
||||
session at core merely for propagating the PID of the new process into core
|
||||
(for later destruction). This traditional mechanism has the following
|
||||
disadvantages:
|
||||
|
||||
First, the PID reported by the creating process to core cannot easily be
|
||||
validated by core. Therefore core has to trust the PD client to not specify a
|
||||
PID of an existing process, which would happen to be killed once the PD session
|
||||
gets destructed. Second, there is no way for a Genode process to detect the
|
||||
failure of any of its grandchildren. The immediate parent of a faulting process
|
||||
could use the SIGCHLD-and-waitpid mechanism to observe its children but this
|
||||
mechanism does not work transitively.
|
||||
|
||||
By performing the process creation exclusively within core, all Genode
|
||||
processes become immediate child processes of core. Hence, core can respond to
|
||||
failures of any of those processes and reflect such conditions via core's
|
||||
session interfaces. Furthermore, the PID associated to a PD session is locally
|
||||
known within core and cannot be forged anymore. In fact, there is actually no
|
||||
need at all to make processes aware of any PIDs of other processes.
|
||||
|
||||
:Handling of chroot, user IDs, and group IDs:
|
||||
|
||||
With the move of the process creation into core, the original chroot trampoline
|
||||
mechanism implemented in 'os/src/app/chroot' does not work anymore. A process
|
||||
could simply escape the chroot environment by spawning a new process via core's
|
||||
PD service. Therefore, chroot support has been integrated into core and the
|
||||
chroot policy becomes a mandatory part of the process creation. For each process
|
||||
created by core, core checks for a 'root' argument of the PD session. If a path
|
||||
is present, core takes the precautions needed to execute the new process in the
|
||||
specified chroot environment.
|
||||
|
||||
This conceptual change implies minor changes with respect to the Genode API and
|
||||
the configuration of the init process. The API changes are the enhancement of
|
||||
the 'Genode::Child' and 'Genode::Process' constructors to take the root path as
|
||||
argument. Init supports the specification of a chroot per process by specifying
|
||||
the new 'root' attribute to the '<start>' node of the process. In line with
|
||||
these changes, the 'Loader::Session::start' function has been enhanced with the
|
||||
additional (optional) PD argument.
|
||||
|
||||
In line with how the chroot path can be propagated into core, core has become
|
||||
able to assign customized UIDs and GIDs to individual Genode processes or whole
|
||||
Genode subsystems. The new 'base-linux/run/lx_uid.run' script contains an
|
||||
example of how to use the feature.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
The current release comes with a new tool chain based on GCC 4.7.2 and binutils
|
||||
2.22. The tool-chain upgrade involved adapting the Genode code base and fixing
|
||||
various issues in 3rd-party software. To obtain the new tool chain, please
|
||||
refer to the tool-chain website:
|
||||
|
||||
:Genode tool chain:
|
||||
|
||||
[https://genode.org/download/tool-chain]
|
||||
941
doc/release_notes/13-02.txt
Normal file
941
doc/release_notes/13-02.txt
Normal file
@@ -0,0 +1,941 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 13.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
Traditionally, the February release of Genode is focused on platform support.
|
||||
The version 13.02 follows this tradition by vastly improving Genode for the
|
||||
NOVA base platform and the extending the range of ARM SoCs supported by
|
||||
both our custom kernel platform and the Fiasco.OC kernel.
|
||||
|
||||
The NOVA-specific improvements concern three major topics, namely the added
|
||||
support for running dynamic workloads on this kernel, the use of IOMMUs, and
|
||||
the profound integration of the Vancouver virtual machine monitor with the
|
||||
Genode environment. The latter point is particularly exciting to us because
|
||||
this substantial work is the first contribution by Intel Labs to the Genode
|
||||
code base. Thanks to Udo Steinberg and Markus Partheymüller for making that
|
||||
possible.
|
||||
|
||||
Beyond the x86 architecture, the new version comes with principal support for
|
||||
the ARM Cortex-A15-based Exynos 5250 SoC and the Freescale i.MX53 SoC. The
|
||||
Exynos 5250 SoC has been enabled for our custom kernel as well as for the
|
||||
Fiasco.OC kernel. The most significant functional improvements are a new
|
||||
facility to detect faulting processes and a new mechanism for file-system
|
||||
notifications.
|
||||
|
||||
Besides those added functionalities, the release cycle was taken as an
|
||||
opportunity to revisit several aspects under the hood of the framework. A few
|
||||
examples are the reworked synchronization primitives, the simplified base
|
||||
library structure, the completely redesigned audio-output interface, and a
|
||||
modernized timer interface.
|
||||
|
||||
|
||||
DMA protection via IOMMU
|
||||
########################
|
||||
|
||||
Direct memory access (DMA) of devices is universally considered as the Achilles
|
||||
heel of microkernel-based operating systems. The most compelling argument in
|
||||
favour of using microkernels is that by encapsulating each system component
|
||||
within a dedicated user-level address space, the system as a whole becomes more
|
||||
robust and secure compared to a monolithic operating-system kernel. In the
|
||||
event that one component fails due to a bug or an attack, other components
|
||||
remain unaffected. The prime example for such buggy components are device
|
||||
drivers. By empirical evidence, those remain the most prominent trouble makers
|
||||
in today's operating systems. Unfortunately however, most commodity hardware
|
||||
used to render this nice argumentation moot because it left one giant loophole
|
||||
open, namely bus-master DMA.
|
||||
|
||||
Via bus-master DMA, a device attached to the system bus is able to directly
|
||||
access the RAM without involving the CPU. This mechanism is crucial for all
|
||||
devices that process large amounts of data such as network adapters, disk
|
||||
controllers, or USB controllers. Because those devices can issue bus requests
|
||||
targeting the RAM directly and not involving the CPU altogether, such requests
|
||||
are naturally not subjected by the virtual-memory mechanism implemented in the
|
||||
CPU in the form of an MMU. From the device's point of view there is just
|
||||
physical memory. Hence, if a driver sets up a DMA transaction, let's say a disk
|
||||
driver wants to read a block from the disk, the driver tells the device about
|
||||
the address and size of a physical-memory buffer where the it wants to receive
|
||||
the data. If the driver lives in a user-level process, as is the case for a
|
||||
microkernel-based system, it still needs to know the physical address to
|
||||
program the device correctly. Unfortunately, there is nothing to prevent the
|
||||
driver from specifying any physical address to the device. Consequently, a
|
||||
malicious driver could misuse the device to read and manipulate all parts of
|
||||
the memory, including the kernel.
|
||||
|
||||
[image no_iommu]
|
||||
Traditional machine without IOMMU. Direct memory accesses issued by the
|
||||
disk controller are not subjected to the MMU. The disk controller can
|
||||
access the entity of memory present in the system.
|
||||
|
||||
So - does this loop hole render the micro-kernel approach useless? Of course not.
|
||||
Putting each driver in a dedicated address space is still beneficial in two
|
||||
ways. First, classes of bugs that are unrelated to DMA remain confined in the
|
||||
driver's address space. In practice most driver issues arise from issues like
|
||||
memory leaks, synchronization problems, deadlocks, flawed driver logic, wrong
|
||||
state machines, or incorrect device-initialization sequences. For those classes
|
||||
of problems, the microkernel argument still applies. Second, executing a driver
|
||||
largely isolated from other operating-system code minimizes the attack surface
|
||||
of the driver. If the driver interface is rigidly small and well-defined, it is
|
||||
hard to compromise the driver by exploiting its interface.
|
||||
|
||||
Still the DMA issue remains to be addressed. Fortunately, modern PC hardware
|
||||
has closed the bus-master-DMA loophole by incorporating a so-called IOMMU into
|
||||
the system. As depicted in the following figure, the IOMMU sits between the RAM
|
||||
and the system bus where the devices are attached to. So each DMA request has
|
||||
to pass the IOMMU, which is not only able to arbitrate the access of DMA
|
||||
requests to the RAM but also able to virtualize the address space per device.
|
||||
Similar to how a MMU confines each process running on the CPU within a distinct
|
||||
virtual address space, the IOMMU is able to confine each device within a
|
||||
dedicated virtual address space. To tell the different devices apart, the IOMMU
|
||||
uses the PCI device's bus-device-function triplet as unique identification.
|
||||
|
||||
[image iommu]
|
||||
An IOMMU arbitrates and virtualizes DMA accesses issued by a device to the
|
||||
RAM. Only if a valid IOMMU mapping exists for a given DMA access, the memory
|
||||
access is performed.
|
||||
|
||||
Of the microkernels supported by Genode, NOVA is the first kernel that supports
|
||||
the IOMMU. NOVAs interface to the IOMMU is quite elegant. The kernel simply
|
||||
applies a subset of the (MMU) address space of a process (aka protection domain
|
||||
in NOVA speak) to the (IOMMU) address space of a device. So the device's
|
||||
address space can be managed in the same way as we normally manage the address
|
||||
space of a process. The only missing link is the assignment of device address
|
||||
spaces to process address spaces. This link is provided by the dedicated system
|
||||
call "assign_pci" that takes a process identifier and a device identifier as
|
||||
arguments. Of course, both arguments must be subjected to a security policy.
|
||||
Otherwise, any process could assign any device to any other process. To enforce
|
||||
security, the process identifier is a capability to the respective protection
|
||||
domain and the device identifier is a virtual address where the extended PCI
|
||||
configuration space of the device is mapped in the specified protection domain.
|
||||
Only if a user-level device driver got access to the extended PCI configuration
|
||||
space of the device, it is able to get the assignment in place.
|
||||
|
||||
To make NOVA's IOMMU support available to Genode programs, we enhanced the
|
||||
ACPI/PCI driver with the ability to hand out the extended PCI configuration
|
||||
space of a device and added a NOVA-specific extension to the PD session
|
||||
interface. The new 'assign_pci' function allows the assignment of a PCI device
|
||||
to the protection domain.
|
||||
|
||||
[image iommu_aware]
|
||||
NOVAs management of the IOMMU address spaces facilities the use of
|
||||
driver-local virtual addresses as DMA addresses.
|
||||
|
||||
Even though these mechanisms combined principally
|
||||
suffice to let drivers operate with the IOMMU enabled, in practice, the
|
||||
situation is a bit more complicated. Because NOVA uses the same
|
||||
virtual-to-physical mappings for the device as it uses for the process, the DMA
|
||||
addresses the driver needs to supply to the device must be virtual addresses
|
||||
rather than physical addresses. Consequently, to be able to make a device
|
||||
driver usable on systems without IOMMU as well as on systems with IOMMU, the
|
||||
driver needs to be IOMMU-aware and distinguish both cases. This is an
|
||||
unfortunate consequence of the otherwise elegant mechanism provided by NOVA. To
|
||||
relieve the device drivers from caring about both cases, we came up with a
|
||||
solution that preserves the original device interface, which expects physical
|
||||
addresses. The solution comes in the form of so called device PDs. A device PD
|
||||
represents the address space of a device as a Genode process. Its sole purpose
|
||||
is to hold mappings of DMA buffers that are accessible by the associated
|
||||
device. By using one-to-one physical-to-virtual mappings for those buffers
|
||||
within the device PD, each device PD contains a subset of the physical address
|
||||
space. The ACPI/PCI server performs the assignment of device PDs to PCI
|
||||
devices. If a device driver intends to use DMA, it asks the ACPI/PCI driver for
|
||||
a new DMA buffer. The ACPI/PCI driver allocates a RAM dataspace at core,
|
||||
attaches it to the device PD using the dataspace's physical address as virtual
|
||||
address, and hands out the dataspace capability to the driver. If the driver
|
||||
requests the physical address of the dataspace, the returned address will be a
|
||||
valid virtual address in the associated device PD. From this design follows
|
||||
that a device driver must allocate DMA buffers at the ACPI/PCI server (while
|
||||
specifying the PCI device the buffer is intended for) instead of using core's
|
||||
RAM service to allocate buffers anonymously. The current implementation of the
|
||||
ACPI/PCI server assigns all PCI devices to only one device PD. However, the
|
||||
design devises a natural way to partition devices into different device PDs.
|
||||
|
||||
[image iommu_agnostic]
|
||||
By modelling a device address space as a dedicated process (device PD),
|
||||
the traditional way of programming DMA transactions can be maintained,
|
||||
even with the IOMMU enabled.
|
||||
|
||||
Because the changed way of how DMA buffers are allocated, our existing drivers
|
||||
such as the AHCI disk driver, the OSS sound driver, the iPXE network driver,
|
||||
and the USB driver had to be slightly modified. We also extended DDE Kit with
|
||||
the new 'dde_kit_pci_alloc_dma_buffer' function for allocating DMA buffers.
|
||||
With those changes, the complete Genode user land can be used on systems with
|
||||
IOMMU enabled. Hence, we switched on the IOMMU on NOVA by default.
|
||||
|
||||
|
||||
Full virtualization on NOVA/x86
|
||||
###############################
|
||||
|
||||
Vancouver is a x86 virtual machine monitor that is designed to run as
|
||||
user-level process on top of the NOVA hypervisor. In
|
||||
[https://genode.org/documentation/release-notes/11.11#Faithful_x86_PC_Virtualization_enabled_by_the_Vancouver_VMM - Genode version 11.11],
|
||||
we introduced the preliminary adaptation of Vancouver to Genode. This version
|
||||
was meant as a mere proof of concept, which allowed the bootup of small Guest
|
||||
OSes (such as Fiasco.OC or Pistachio) inside the VMM. However, it did not
|
||||
support any glue code to Genode's session interface, which limited the
|
||||
usefulness of this virtualization solution at that point. We had planned to
|
||||
continue the integration of Vancouver with Genode once we observed public
|
||||
demand.
|
||||
|
||||
The move of NOVA's development to Intel Labs apparently created this demand.
|
||||
It is undeniable that combining the rich user land provided by Genode with the
|
||||
capabilities of the Vancouver VMM poses an attractive work load for NOVA. So
|
||||
the stalled line of the integration work of Vancouver with Genode was picked up
|
||||
within Intel Labs, more specifically by Markus Partheymüller. We are delighted
|
||||
to be able to merge the outcome of this undertaking into the mainline Genode
|
||||
development. Thanks to Intel Labs and Markus in particular for this substantial
|
||||
contribution!
|
||||
|
||||
The features added to the new version of Vancouver for Genode are as follows:
|
||||
|
||||
:VMX support:
|
||||
|
||||
Our initial version supported AMD's SVM technology only because this was
|
||||
readily supported by Qemu. With the added support for Intel VMX, Vancouver
|
||||
has become able to operate on both Intel and AMD processors with hardware
|
||||
virtualization support.
|
||||
|
||||
:Timer support:
|
||||
|
||||
With added support for timer interrupts, the VMM has become able to
|
||||
boot a complete Linux system.
|
||||
|
||||
:Console support:
|
||||
|
||||
With this addition, the guest VM can be provided with a frame buffer and
|
||||
keyboard input.
|
||||
|
||||
For the frame-buffer size in Vancouver, the configuration value in the
|
||||
machine XML node is used. It is possible to map the corresponding memory
|
||||
area directly to the guest regardless if it comes from nitpicker, a virtual
|
||||
frame buffer, or the VESA driver. The guest is provided with two modes (text
|
||||
mode 3 and graphics mode 0x114 (0x314 in Linux).
|
||||
|
||||
Pressing LWIN+END while a VM has focus resets the virtual machine. Also,
|
||||
RESET and DEBUG key presses will not be forwarded to the VM anymore.
|
||||
It is possible to dump a VM's state by pressing LWIN+INS keys.
|
||||
|
||||
The text console is able to detect idle mode, unmaps the buffer from the
|
||||
guest and stops interpreting. Upon the next page fault in this area, it
|
||||
resumes operation again. The code uses a simple checksum mechanism instead
|
||||
of a large buffer and 'memcmp' to detect an idle text console. False
|
||||
positives don't matter very much.
|
||||
|
||||
:Network support:
|
||||
|
||||
The VMM has become able to use the Intel 82576 device model from the NUL
|
||||
user land to give VMs access to the network via Genode's NIC bridge service
|
||||
or a NIC driver.
|
||||
|
||||
:Disk support:
|
||||
|
||||
The VMM can now assign block devices to guests using Genode's block-session
|
||||
interface. The machine has to be configured to use a specified drive, which
|
||||
could be theoretically routed to different partitions or services via policy
|
||||
definitions. Currently the USB driver only supports one device. Genode's AHCI
|
||||
driver is untested.
|
||||
|
||||
:Real-time clock:
|
||||
|
||||
By using the new RTC session interface, Vancouver is able to provide the
|
||||
wall-clock time to guest OSes.
|
||||
|
||||
To explore the new version of the Vancouver VMM, there exists a ready-to-use
|
||||
run script at 'ports/run/vancouver.run'. Only the guest OS binaries such as a
|
||||
Linux kernel image and a RAM disk must be manually supplied in the
|
||||
'<build-dir>/bin' directory. The run script is able to start one or multiple
|
||||
instances of the VMM using the graphical launchpad.
|
||||
|
||||
|
||||
Low-latency audio output
|
||||
########################
|
||||
|
||||
In version 10.05, we introduced an interface for the playback of audio data
|
||||
along with an audio mixer component and ALSA-based sound drivers ported from
|
||||
the Linux kernel. The original 'Audio_out' session interface was based on
|
||||
Genode's packet stream facility, which allows the communication of bulk data
|
||||
across address spaces via a combination of shared memory and signals. Whereas
|
||||
shared memory is used to transfer the payload in an efficient manner without
|
||||
the need to copy data via the kernel, signals are used to manage the data flow
|
||||
between the information source and sink.
|
||||
|
||||
[image packet_stream]
|
||||
|
||||
Figure [packet_stream] displays the life cycle of a packet of information
|
||||
transferred from the source to the sink. The original intent behind the
|
||||
packet-stream facility was the transmission of networking packets and blocks
|
||||
of block devices. At the time when we first introduced the 'Audio_out'
|
||||
interface, the packet stream seemed like a good fit for audio, too. However, in
|
||||
the meanwhile, we came to the conclusion that this is not the case when trying
|
||||
to accommodate streamed audio data and sporadic audio output at the same time.
|
||||
|
||||
For the output of streamed audio data, a codec typically decodes a relatively
|
||||
large portion of an audio stream and submits the sample data to the mixer. The
|
||||
mixer, in turn, mixes the samples of multiple sources and forwards the result
|
||||
to the audio driver. Each of those components the codec, the mixer, and the
|
||||
audio driver live in a separate process. By using large buffer sizes between
|
||||
them, the context-switching overhead is hardly a concern. Also, the driver can
|
||||
submit large buffers of sample data to the sound device without any further
|
||||
intervention needed.
|
||||
|
||||
In contrast, sporadic sounds are used to inform the user about an immediate
|
||||
event. It is ultimately expected that such sounds are played back without much
|
||||
latency. Otherwise the interactive experience (e.g., of games) would suffer.
|
||||
Hence, using large buffers between the audio source, the mixer, and the driver
|
||||
is not an option. By using the packet stream concept, we have to settle on a
|
||||
specific buffer size. A too small buffer increases CPU load caused by many
|
||||
context switches and the driver, which has to feed small chunks of sample data
|
||||
to the sound device. A too large buffer, however, makes sporadic sounds at low
|
||||
latencies impossible. We figured out that the necessity to find a sweet spot
|
||||
for picking a buffer size is a severe drawback. This observation triggered us
|
||||
to replace the packet-stream-based communication mechanism of the 'Audio_out'
|
||||
session interface by a new solution that we specifically designed to
|
||||
accommodate both corner cases of audio output.
|
||||
|
||||
[image audio_out]
|
||||
|
||||
Similarly to the packet-stream mechanism, the new interface is based on a
|
||||
combination of shared memory and signals. However, we dropped the notion of
|
||||
ownership of packets. When using the packet-stream protocol depicted as above,
|
||||
either the source or the sink is in charge of handling a given packet at a
|
||||
given time, not both. At the points 1, 2, and 4, the packet is owned by the
|
||||
source. At the points 3 and 4, the packet is owned by the sink. By putting a
|
||||
packet descriptor in the submit queue or acknowledgement queue, there is a
|
||||
handover of responsibility. The new interface weakens this notion of ownership
|
||||
by letting the source update once submitted audio frames even after submitting
|
||||
them. If there are solely continuous streams of audio arriving at the mixer,
|
||||
the mixer can mix those large batches of audio samples at once and pass the
|
||||
result to the driver.
|
||||
|
||||
[image mixer_streaming]
|
||||
The mixer processes incoming data from multiple streaming sources as batches.
|
||||
|
||||
Now, if a sporadic sound comes in, the mixer checks the
|
||||
current output position reported by the audio driver, and re-mixes those
|
||||
portions that haven't been played back yet by incorporating the sporadic sound.
|
||||
So the buffer consumed by the driver gets updated with new data.
|
||||
|
||||
[image mixer_sporadic]
|
||||
A sporadic occuring sound prompts the mixer to remix packets that are
|
||||
already submitted in the output queue.
|
||||
|
||||
Besides changing the way of how packets are populated with data, the second
|
||||
major change is turning the interface into a time-triggered concept. The
|
||||
driver produces periodic signals that indicate the completeness of a
|
||||
played-back audio packet. This signal triggers the mixer to become active,
|
||||
which in turn serves as a time base for its clients. The current playback
|
||||
position is denoted alongside the sample data as a field in the memory buffer
|
||||
shared between source and sink.
|
||||
|
||||
The new 'Audio_out' interface has the potential to align the requirements of
|
||||
both streamed audio with those of sporadic sounds. As a side benefit, the now
|
||||
domain-specific interface has become simpler than the original packet-stream
|
||||
based solution. This becomes nowhere as evident as in the implementation of the
|
||||
mixer, which has become much simpler (30% less code). The interface change
|
||||
is accompanied with updates of components related to audio output, in
|
||||
particular the OSS sound drivers contained in 'dde_oss', the ALSA audio driver
|
||||
for Linux, the avplay media player, and the libSDL audio back-end.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Signalling API improvements
|
||||
===========================
|
||||
|
||||
The signalling API provided by 'base/signal.h' is fairly low level. For
|
||||
employing the provided mechanism by application software, we used to craft
|
||||
additional glue code that translates incoming signals to C++ method
|
||||
invocations. Because the pattern turned out to be not only useful but a good
|
||||
practice, we added the so called 'Signal_dispatcher' class template to the
|
||||
signalling API.
|
||||
|
||||
In addition to being a 'Signal_context', a 'Signal_dispatcher' associates a
|
||||
member function with the signal context. It is intended to be used as a member
|
||||
variable of the class that handles incoming signals of a certain type. The
|
||||
constructor takes a pointer-to-member to the signal handling function as
|
||||
argument. If a signal is received at the common signal reception code, this
|
||||
function will be invoked by calling 'Signal_dispatcher_base::dispatch'. This
|
||||
pattern can be observed in the implementation of RAM file system
|
||||
('os/src/server/ram_fs').
|
||||
|
||||
Under the hood, the signalling implementation received a major improvement with
|
||||
regard to the life-time management of signal contexts. Based on the observation
|
||||
that 'Signal' objects are often referring to non-trivial objects derived from
|
||||
'Signal_context', it is important to defer the destruction of such objects to a
|
||||
point when no signal referring to the context is in flight anymore. We solved
|
||||
this problem by modelling 'Signal' type as a shared pointer that operates on a
|
||||
reference counter embedded in the corresponding 'Signal_context'. Based on
|
||||
reference counter, the 'Signal_receiver::dissolve()' function does not return
|
||||
as long as the signal context to be dissolved is still referenced by one or
|
||||
more 'Signal' objects.
|
||||
|
||||
|
||||
Trimmed and unified framework API
|
||||
=================================
|
||||
|
||||
A though-provoking
|
||||
[https://sourceforge.net/mailarchive/forum.php?thread_name=CAGQ-%3Dq27%2B_UooBiJmz9RdTE1gDmVcg9v0w-8TNgEH5fzHYiA%2BQ%40mail.gmail.com&forum_name=genode-main - posting]
|
||||
on our mailing list prompted us to explore the idea to make shared libraries
|
||||
and dynamically linked executables binary compatible among different kernels.
|
||||
This sounds a bit crazy at first but it is not downright infeasible.
|
||||
|
||||
As a baby step into this direction, we unified several public headers of the
|
||||
Genode API and tried to make headers private to the framework where possible.
|
||||
The latter is the case for the 'base/platform_env.h' header, which is actually
|
||||
not part of the generic Genode API. Hence, it was moved to the
|
||||
framework-internal 'src/base/env'. Another step was the removal of
|
||||
platform-specific types that are not necessarily platform-dependent. We could
|
||||
remove the 'Native_lock' type without any problems. Also, we were able to unify
|
||||
the IPC API, which was formerly split into the two parts 'base/ipc_generic.h'
|
||||
and 'base/ipc.h' respectively. Whereas 'base/ipc_generic.h' was shared among
|
||||
all platforms, the 'base/ipc.h' header used to contain platform-specific IPC
|
||||
marshalling and unmarshalling code. But by moving this code from the header to
|
||||
the corresponding (platform-specific) IPC library, we were able to discard the
|
||||
content of 'base/ipc.h' altogether. Consequently, the former
|
||||
'base/ipc_generic.h' could be renamed to 'base/ipc.h'. These changes imply no
|
||||
changes at the API level.
|
||||
|
||||
|
||||
Simplified structure of base libraries
|
||||
======================================
|
||||
|
||||
The Genode base API used to come in the form of many small libraries, each
|
||||
covering a dedicated topic. Those libraries were 'allocator_avl', 'avl_tree',
|
||||
'console', 'env', 'cxx', 'elf', 'env', 'heap', 'server', 'signal', 'slab',
|
||||
'thread', 'ipc', and 'lock'. The term "library" for those bits of code was
|
||||
hardly justified as most of the libraries consisted of only a few .cc files.
|
||||
Still the build system had to check for their inter-dependencies on each run of
|
||||
the build process. Furthermore, for Genode developers, specifying the list of
|
||||
base libraries in their 'target.mk' files tended to be an inconvenience. Also,
|
||||
the number of libraries and their roles (core only, non-core only, shared by
|
||||
both core and non-core) were not easy to capture. Hence, we simplified the way
|
||||
of how those base libraries are organized. They have been reduced to the
|
||||
following few libraries:
|
||||
|
||||
* 'cxx.mk' contains the C++ support library
|
||||
* 'startup.mk' contains the startup code for normal Genode processes
|
||||
On some platform, core is able to use the library as well.
|
||||
* 'base-common.mk' contains the parts of the base library that are
|
||||
identical by core and non-core processes.
|
||||
* 'base.mk' contains the complete base API implementation for non-core
|
||||
processes
|
||||
|
||||
Consequently, the 'LIBS' declaration in 'target.mk' files becomes simpler as
|
||||
well. In the normal case, only the 'base' library must be mentioned.
|
||||
|
||||
|
||||
New fault-detection mechanism
|
||||
=============================
|
||||
|
||||
Until now, it was hardly possible for a parent process to respond to crashes of
|
||||
child processes in a meaningful way. If a child process crashed, the parent
|
||||
would normally just not take notice. Even though some special use cases such as
|
||||
GDB monitor could be accommodated by the existing
|
||||
'Cpu_session::exception_handler' facility, this mechanism requires the
|
||||
virtualization of the 'Cpu_session interface' because an exception handler used
|
||||
to refer to an individual thread rather than the whole process. For ordinary
|
||||
parents, this mechanism is too cumbersome to use. However, there are several
|
||||
situations where a parent process would like to actively respond to crashing
|
||||
children. For example, the parent might like to restart a crashed component
|
||||
automatically, or enter a special failsafe mode.
|
||||
|
||||
To ease the implementation of such scenarios, we enhanced the existing
|
||||
'Cpu_session::exception_handler' mechanism with the provision of a
|
||||
default signal handler that is used if no thread-specific handler is installed.
|
||||
The default signal handler can be set by specifying an invalid thread
|
||||
capability and a valid signal-context capability. So for registering a signal
|
||||
handler to all threads of a process, no virtualization of the 'Cpu_session'
|
||||
interface is needed anymore. The new mechanism is best illustrated by the
|
||||
'os/run/failsafe.run' script, which creates a system that repeatedly spawns a
|
||||
crashing child process.
|
||||
|
||||
|
||||
Reworked synchronization primitives
|
||||
===================================
|
||||
|
||||
We reworked the framework-internal lock interface in order to be able to use
|
||||
the 'futex' syscall on the Linux base platform. Previously, the lock
|
||||
implementation on Linux was based on Unix signals. In the contention case, the
|
||||
applicant for a contended lock would issue a blocking system call, which gets
|
||||
canceled by the occurrence of a signal. We used 'nanosleep' for this purpose.
|
||||
Once the current owner of the lock releases the lock, it sends a signal to the
|
||||
next applicant of the lock. Because signals are buffered by the kernel, they
|
||||
are guaranteed to be received by the targeted thread. However, in situations
|
||||
with much lock contention, we observed the case where the signal was delivered
|
||||
just before the to-be-blocked thread could enter the 'nanosleep' syscall. In
|
||||
this case, the signal was not delivered at the next entrance into the kernel
|
||||
(when entering 'nanosleep') but earlier. Even though the signal handler was
|
||||
invoked, we found no elegant way to handle the signal such that the subsequent
|
||||
'nanosleep' call would get skipped. So we decided to leave our signal-based
|
||||
solution behind and went for the mainstream 'futex' mechanism instead.
|
||||
|
||||
Using this mechanism required us to re-design the internal lock API, which was
|
||||
originally designed with the notion of thread IDs. The 'Native_thread_id' type,
|
||||
which was previously used in the lock-internal 'Applicant' class to identify a
|
||||
thread to be woken up, was not suitable anymore for implementing this change.
|
||||
Hence, we replaced it with the 'Thread_base*' type, which also has the positive
|
||||
effect of making the public 'base/cancelable_lock.h' header file
|
||||
platform-independent.
|
||||
|
||||
In addition to reworking the basic locking primitives, we changed the
|
||||
'Object_pool' data structure to become safer to use. The former 'obj_by_*'
|
||||
functions have been replaced by 'lookup_and_lock' that looks up an object and
|
||||
locks it in one atomic operation. Additionally, the case that an object may
|
||||
already be in destruction is handled gracefully. In this case, the lookup will
|
||||
return that the object is not available anymore.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Notification mechanism for the file-system interface
|
||||
====================================================
|
||||
|
||||
To support dynamic system scenarios, we extended Genode's file-system interface
|
||||
with the ability to monitor changes of files or directories, similar to the
|
||||
inotify mechanism on Linux but simpler. The new 'File_system::sigh' function
|
||||
can be used to install a signal handler for an open file node. When a node is
|
||||
closed after a write operation, a prior registered signal handler for this file
|
||||
gets notified. Signal handlers can also be installed for directories. In this
|
||||
case, the signal handler gets informed about changes of immediate nodes hosted
|
||||
in the directory, i.e., the addition, renaming, or removal of nodes.
|
||||
|
||||
The 'ram_fs' server has been enhanced to support the new interface. So any file
|
||||
or directory change can now be observed by 'ram_fs' clients.
|
||||
|
||||
|
||||
New adapter from file-system to ROM session interface
|
||||
=====================================================
|
||||
|
||||
The new 'fs_rom' server translates the 'File_system' session interface to the
|
||||
'ROM' session' interface. Each request for a ROM file is handled by looking
|
||||
up an equally named file on the file system. If no such file can be found,
|
||||
then the server will monitor the file system for the creation of the
|
||||
corresponding file. Furthermore, the server reflects file changes as signals
|
||||
to the ROM session.
|
||||
|
||||
There currently exist two limitations: First, symbolic links are not handled.
|
||||
Second, the server needs to allocate RAM for each requested file. The RAM is
|
||||
always allocated from the RAM session of the server. Thereby, the RAM quota
|
||||
consumed by the server depends on the client requests and the size of the
|
||||
requested files. Therefore, one instance of the server should not be used by
|
||||
untrusted clients and trusted clients at the same time. In such situations,
|
||||
multiple instances of the server could be used.
|
||||
|
||||
The most interesting feature of the 'fs_rom' server is the propagation of
|
||||
file-system changes as ROM module changes. This clears the way to use this
|
||||
service to supply dynamic configurations to Genode programs.
|
||||
|
||||
|
||||
Dynamic re-configuration of the init process
|
||||
============================================
|
||||
|
||||
The init process has become able to respond to configuration changes by
|
||||
restarting the scenario using the new configuration. To make this feature
|
||||
useful in practice, init must not fail under any circumstances. Even on
|
||||
conditions that were considered previously as fatal and led to the abort of
|
||||
init (such as ambiguous names of the children or misconfiguration in general),
|
||||
init must stay alive and responsive to configuration changes.
|
||||
|
||||
With this change, the init process is one of the first use cases of the dynamic
|
||||
configuration feature enabled via the 'fs_rom' service and the new file-system
|
||||
notifications. By supplying the configuration of an init instance via the
|
||||
'fs_rom' and 'ram_fs' services, the configuration of this instance gets fetched
|
||||
from a file of the 'ram_fs' service. Each time, this file is changed, for
|
||||
example via VIM running within a Noux runtime environment, the init process
|
||||
re-evaluates its configuration.
|
||||
|
||||
In addition to the support for dynamic re-configurations, we simplified the use
|
||||
of conditional session routing, namely the '<if-args>' mechanism. When matching
|
||||
the 'label' session argument using '<if-args>' in a routing table, we can omit
|
||||
the child name prefix because it is always the same for all sessions
|
||||
originating from the child anyway. By handling the matching of session labels
|
||||
as a special case, the expression of label-specific routing
|
||||
becomes more intuitive.
|
||||
|
||||
|
||||
Timer interface turned into asynchronous mode of operation
|
||||
==========================================================
|
||||
|
||||
The 'msleep' function of 'Timer::Session' interface is one of the last relics
|
||||
of blocking RPC interfaces present in Genode. As we try to part away from
|
||||
blocking RPC calls inside servers and as a means to unify the timer
|
||||
implementation across the many different platforms supported by Genode, we
|
||||
changed the interface to an asynchronous mode of operation.
|
||||
|
||||
Synchronous blocking RPC interfaces turned out to be constant sources of
|
||||
trouble and code complexity. E.g., a timer client that also wants to respond to
|
||||
non-timer events was forced to be a multi-threaded process. Now, the blocking
|
||||
'msleep' call has been replaced by a mechanism for programming timeouts and
|
||||
receiving wakeup signals in an asynchronous fashion. Thereby signals
|
||||
originating from the timer can be handled, along with signals from other signal
|
||||
sources, by a single thread. Once a timer client has registered a signal
|
||||
handler using the 'Timer::sigh' function, it can program timeouts using the
|
||||
functions 'trigger_once' and 'trigger_periodic', which take an amount of
|
||||
microseconds as argument. For maintaining compatibility and convenience, the
|
||||
interface still contains the virtual 'msleep' function. However, it is not an
|
||||
RPC function anymore but a mere client-side wrapper around the 'sigh' and
|
||||
'trigger_once' functions. For use cases where sleeping at the granularity of
|
||||
milliseconds is too coarse (such as udelay calls by device drivers), we added
|
||||
a new 'usleep' call, which takes a number of microseconds as argument.
|
||||
|
||||
As a nice side effect of the interface changes, the platform-specific
|
||||
implementations could be vastly unified. On NOVA and Fiasco.OC, the need to use
|
||||
one thread per client has vanished. As a further simplification, we changed the
|
||||
timer to use the build system's library-selection mechanism instead of
|
||||
providing many timer targets with different 'REQUIRES' declarations. This
|
||||
reduces the noise of the build system. For all platforms, the target at
|
||||
'os/src/drivers/timer' is built. The target, in turn, depends on a 'timer'
|
||||
library, which is platform-specific. The various library description files are
|
||||
located under 'os/lib/mk/<platform>'. The common bits are contained in
|
||||
'os/lib/mk/timer.inc'.
|
||||
|
||||
Since the 'msleep' call is still available from the client's perspective,
|
||||
the change of the timer interface does not imply an API incompatibility.
|
||||
However, it provides the opportunity to simplify clients in cases that required
|
||||
the maintenance of a separate thread for the sole purpose of
|
||||
periodic signal generation.
|
||||
|
||||
|
||||
Loader
|
||||
======
|
||||
|
||||
The loader is a service that enables its clients to dynamically create Genode
|
||||
subsystems. Leveraging the new fault-detection support described in section
|
||||
[New fault-detection mechanism], we enabled loader clients to respond to
|
||||
failures that occur inside the spawned subsystem. This is useful for scenarios
|
||||
where subsystems should be automatically restarted or in situations where the
|
||||
system should enter a designated failsafe mode once an unexpected fault
|
||||
happens.
|
||||
|
||||
The loader provides this feature by installing an optional client-provided
|
||||
fault handler as default CPU exception handler and a RM fault handler for all
|
||||
CPU and RM sessions of the loaded subsystem. This way, the failure of any
|
||||
process within the subsystem gets reflected to the loader client as a signal.
|
||||
|
||||
The new 'os/run/failsafe.run' test illustrate this mechanism. It covers two
|
||||
cases related to the loader, which are faults produced by the immediate child
|
||||
of the loader and faults produced by indirect children.
|
||||
|
||||
|
||||
Focus events for the nitpicker GUI server
|
||||
=========================================
|
||||
|
||||
To enable a way for applications to provide visual feedback to changed keyboard
|
||||
focus, we added a new 'FOCUS' event type to the 'Input::Event' structure. To
|
||||
encode whether the focus was entered or left, the former 'keycode' member is
|
||||
used (value 0 for leaving, value 1 for entering). Because 'keycode' is
|
||||
misleading in this context, the former 'Input::Event::keycode' function was
|
||||
renamed to 'Input::Event::code'. The nitpicker GUI server has been adapted to
|
||||
deliver focus events to its clients.
|
||||
|
||||
|
||||
NIC bridge with support for static IP configuration
|
||||
===================================================
|
||||
|
||||
NIC bridge is a service that presents one physical network adaptor as many
|
||||
virtual network adaptors to its clients. Up to now, it required each client
|
||||
to obtain an IP address from a DHCP server at the physical network. However,
|
||||
there are situations where the use of static IPs for virtual NICs is useful.
|
||||
For example, when using the NIC bridge to create a virtual network between
|
||||
the lighttpd web server and the Arora web browser, both running as Genode
|
||||
processes without real network connectivity.
|
||||
|
||||
The static IP can be configured per client of the NIC bridge using a '<policy>'
|
||||
node of the configuration. For example, the following policy assigns a static
|
||||
address to a client with the session label "lighttpd".
|
||||
!<start name="nic_bridge">
|
||||
! ...
|
||||
! <config>
|
||||
! <policy label="lighttpd" ip_addr="10.0.2.55"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
Of course, the client needs to configure its TCP/IP stack to use the assigned
|
||||
IP address. This can be done via configuration arguments examined by the
|
||||
'lwip_nic_dhcp' libc plugin. For the given example, the configuration for the
|
||||
lighttpd process would look as follows.
|
||||
!<start name="lighttpd">
|
||||
! <config>
|
||||
! <interface ip_addr="10.0.2.55"
|
||||
! netmask="255.255.255.0"
|
||||
! gateway="10.0.2.1"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New terminal multiplexer
|
||||
========================
|
||||
|
||||
The new 'terminal_mux' server located at 'gems/src/server/terminal_mux' is able
|
||||
to provide multiple terminal sessions over one terminal-client session. The
|
||||
user can switch between the different sessions using a keyboard shortcut, which
|
||||
brings up an ncurses-based menu.
|
||||
|
||||
The terminal sessions provided by terminal_mux implement (a subset of) the
|
||||
Linux terminal capabilities. By implementing those capabilities, the server
|
||||
is interchangeable with the graphical terminal ('gems/src/server/terminal').
|
||||
The terminal session used by the server is expected to by VT102 compliant.
|
||||
This way, terminal_mux can be connected via an UART driver with terminal
|
||||
programs such as minicom, which typically implement VT102 rather than the Linux
|
||||
terminal capabilities.
|
||||
|
||||
When started, terminal_mux displays a menu with a list of currently present
|
||||
terminal sessions. The first line presents status information, in particular
|
||||
the label of the currently visible session. A terminal session can be selected
|
||||
by using the cursor keys and pressing return. Once selected, the user is able
|
||||
to interact with the corresponding terminal session. Returning to the menu is
|
||||
possible at any time by pressing control-x.
|
||||
|
||||
For trying out the new terminal_mux component, the 'gems/run/termina_mux.run'
|
||||
script sets up a system with three terminal sessions, two instances of Noux
|
||||
executing VIM and a terminal_log service that shows the log output of both Noux
|
||||
instances.
|
||||
|
||||
|
||||
New ported 3rd-party libraries
|
||||
==============================
|
||||
|
||||
To support our forthcoming port of Git to the Noux runtime environment, we
|
||||
have made the following libraries available via the libports repository:
|
||||
|
||||
* libssh-0.5.4
|
||||
* curl-7.29.0 (for now the port is x86_* only because it depends on libcrypto,
|
||||
which is currently not tested on ARM)
|
||||
* iconv-1.14
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Besides the changes concerning the use of IOMMUs, the following device driver
|
||||
have received improvements:
|
||||
|
||||
:UART drivers:
|
||||
|
||||
The OMAP4 platform support has been extended by a new UART driver, which
|
||||
enables the use of up to 4 UART interfaces. The new driver is located at
|
||||
'os/src/drivers/uart/omap4'.
|
||||
|
||||
All UART drivers implement the 'Terminal::Session' interface, which
|
||||
provides read/write functionality accompanied by a function to determine
|
||||
the terminal size. The generic UART driver code shared among the various
|
||||
implementations has been enhanced to support the detection of the terminal
|
||||
size using a protocol of escape sequences. This feature can be enabled by
|
||||
including the attribute 'detect_size="yes"' in the policy of a UART client.
|
||||
This is useful for combining UART drivers with the new 'terminal_mux'
|
||||
server.
|
||||
|
||||
:ACPI support for 64-bit machines:
|
||||
|
||||
In addition to IOMMU-related modifications, the ACPI driver has been enhanced
|
||||
to support 64-bit machines and MCFG table parsing has been added.
|
||||
|
||||
:PCI support for IOMMUs:
|
||||
|
||||
With the added support of IOMMUs, the 'Pci::Session' interface has been
|
||||
complemented with a way to obtain the extended PCI configuration space in the
|
||||
form of a 'Genode::Dataspace'. Also, the interface provides a way to allocate
|
||||
DMA buffers for a given PCI device. Device drivers that are meant to be used
|
||||
on system with and without IOMMUs should use this interface rather than
|
||||
core's RAM session interface to allocate DMA buffers.
|
||||
|
||||
:Real-time clock on x86:
|
||||
|
||||
Up to now, the x86 real-time clock driver served as a mere example for
|
||||
accessing I/O ports on x86 machines but the driver did not expose any service
|
||||
interface. With the newly added 'os/include/rtc_session' interface and the
|
||||
added support of this interface in the RTC driver, Genode programs have now
|
||||
become able to read the real-time clock. Currently, the interface is used by
|
||||
the Vancouver VMM.
|
||||
|
||||
:USB driver restructured, support for Arndale board added:
|
||||
|
||||
While adding support for the Exynos-5-based Arndale board, we took the
|
||||
chance to restructure the driver to improve portability to new
|
||||
platforms. The most part of the driver has become a library, which is
|
||||
built in a platform-specific way. The build system automatically selects
|
||||
the library that fits for the platform as set up for the build directory.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
NOVA
|
||||
====
|
||||
|
||||
The NOVA base platform received major improvements that address the kernel
|
||||
as well as Genode's NOVA-specific code. We pursued two goals with this line
|
||||
of work. The first goal was the use of NOVA in highly dynamic settings, which
|
||||
was not possible before, mainly due to lacking kernel features. The second
|
||||
goal was the use of IOMMUs.
|
||||
|
||||
NOVA is ultimately designed for accommodating dynamic workloads on top of the
|
||||
kernel. But we found that the implementation of crucial functionality was
|
||||
missing. In particular, the kernel lacked the ability to destroy all kinds of
|
||||
kernel objects and to reuse memory of kernel objects that had been destroyed.
|
||||
Consequently, when successively creating and destroying kernel objects such as
|
||||
threads and protection domains, the kernel would eventually run out of memory.
|
||||
This issue became a show stopper for running the Genode tool chain on NOVA
|
||||
because this scenario spawns and destroys hundreds of processes. For this
|
||||
reason, we complemented the kernel with the missing functionality. This step
|
||||
involved substantial changes in the kernel code. So our approach of using the
|
||||
upstream kernel and applying a hand full of custom patches started to show its
|
||||
limitations.
|
||||
|
||||
To streamline our work flow and to track the upstream kernel in a structured
|
||||
way, we decided to fork NOVA's Git repository and maintain our patches in our
|
||||
fork. For each upstream kernel revision that involves kernel ABI changes, we
|
||||
create a separate branch called "r<number>". This branch corresponds to the
|
||||
upstream kernel with our series of custom patches applied (actually rebased) on
|
||||
top. This way, our additions to the upstream kernel are well documented. The
|
||||
'make prepare' mechanism in the base-nova repository automates the task of
|
||||
checking out the right branch. So from the Genode user's point of view, this
|
||||
change is transparent.
|
||||
|
||||
The highly dynamic application scenarios executed on NOVA triggered several
|
||||
synchronization issues in Genode's core process that had not been present on
|
||||
other base platforms. The reason for those issues to occur specifically on NOVA
|
||||
lies in the concurrent page fault handling as employed on this base platform.
|
||||
For all classical L4-like kernels and Fiasco.OC, we use one global pager thread
|
||||
to resolve all page faults that occur in the whole Genode system. In contrast,
|
||||
on NOVA we use one pager thread per user thread. Consequently, proper
|
||||
fine-grained synchronization between those pager threads and the other parts of
|
||||
core is mandated. Even though the immediate beneficiary of these changes is the
|
||||
NOVA platform, many of the improvements refer to generic code. This paves the
|
||||
ground for scaling the page-fault handling on other base platforms (such as
|
||||
Fiasco.OC) to multiple threads. With these improvements in place, we are able
|
||||
to successfully execute the 'noux_tool_chain_nova' scenario on the NOVA kernel
|
||||
and build Genode's core on NOVA. That said, however, not all issues are covered
|
||||
yet. So there is still a way left to go to turn base-nova into a base platform
|
||||
that is suitable for highly dynamic scenarios.
|
||||
|
||||
The second goal was the use of NOVA's IOMMU support on Genode. This topic is
|
||||
covered in detail in section [DMA protection via IOMMU].
|
||||
|
||||
To be able to use and debug Genode on NOVA on modern machines that lack legacy
|
||||
comports, we either use UART PCI cards or the Intel's Active Management
|
||||
Technology (AMT) mechanism. In both cases, the I/O ports to access the serial
|
||||
interfaces differ from the legacy comports. To avoid the need for adjusting the
|
||||
I/O port base addresses per platform, we started using the chain-boot-loader
|
||||
called "bender" developed by the Operating Systems Group of TU Dresden,
|
||||
Germany. This boot loader is started prior the kernel, searches the PCI bus for
|
||||
the first suitable device and registers the corresponding I/O port base address
|
||||
at the bios data area (BDA). Genode's core, in turn, picks the I/O port base
|
||||
address up from the BDA and uses the registered i8250 serial controller for its
|
||||
LOG service.
|
||||
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
The base-hw platform enables the use of Genode on ARM-based hardware without
|
||||
the need for a 3rd-party kernel.
|
||||
|
||||
With the new release, the range of supported ARM-based hardware has been
|
||||
extended to cover the following additional platforms. With the previous
|
||||
release, we introduced the support for Freescale i.MX family of SoC, starting
|
||||
with i.MX31. The current release adds support for the i.MX53 SoC and adds
|
||||
a user-level timer driver for this platform. With the Samsung Exynos 5, the
|
||||
first Cortex-A15-based SoC has entered the list of supported SoCs. Thanks to
|
||||
this addition, Genode has become able to run on the
|
||||
[http://www.arndaleboard.org - Howchip Arndale board]. At the current state,
|
||||
core and multiple instances of init can be executed but drivers for peripherals
|
||||
are largely missing. Those will be covered by our ongoing work with this SoC.
|
||||
The added platforms are readily available via the 'create_builddir' tool.
|
||||
|
||||
To make base-hw practically usable on real hardware (i.e., the Pandaboard),
|
||||
support for caches has been implemented. Furthermore, the implementation of the
|
||||
signalling API underwent a redesign, which leverage the opportunities that
|
||||
arise with tailoring a kernel specifically to the Genode API. As a side-benefit
|
||||
of this endeavour, we could unify the 'base/signal.h' header with the generic
|
||||
version and thereby took another step towards the unification of the Genode
|
||||
headers across different kernels.
|
||||
|
||||
|
||||
Microblaze platform removed
|
||||
===========================
|
||||
|
||||
The 'base-mb' platform has been removed because it is no longer maintained.
|
||||
This platform enabled Genode to run directly on the Xilinx Microblaze softcore
|
||||
CPU. For supporting the Microblaze CPU architecture in the future, we might
|
||||
consider integrating support for this architecture into base-hw. Currently
|
||||
though, there does not seem to be any demand for it.
|
||||
|
||||
|
||||
Fiasco.OC forked, support for Exynos 5 SoC added
|
||||
================================================
|
||||
|
||||
In the last release cycle, we went beyond just using the Fiasco.OC kernel and
|
||||
started to engage with the kernel code more intensively. To avoid that the
|
||||
management of a growing number of kernel patches goes out of hand, we forked
|
||||
the Fiasco.OC kernel and conduct our development in our Fiasco.OC Git
|
||||
repository. When using the 'make prepare' mechanism in the 'base-foc'
|
||||
repository, the new Git repository will be used automatically. There exists a
|
||||
dedicated branch for each upstream SVN revision that we use. We started with
|
||||
updating Fiasco.OC to the current revision 47. Hence, the current branch used
|
||||
by Genode is named "r47". The branch contains the unmodified state of the
|
||||
upstream SVN repository with our modifications appearing as individual commits
|
||||
on top. This makes it easy to keep track of the Genode-specific modifications.
|
||||
Please note that the update to Fiasco.OC requires minor adaptations inside
|
||||
the 'ports-foc' repository. So for using L4Linux, "make prepare" must be
|
||||
issued in both repositories 'base-foc' and 'ports-foc'.
|
||||
|
||||
Speaking of engaging with the kernel code, the most profound improvement is
|
||||
the support for the Samsung Exynos-5-based Arndale board that we added to the
|
||||
kernel. This goes hand in hand with the addition of this platform to Genode.
|
||||
For creating a build directory targeting the Arndale board, just specify
|
||||
"foc_arndale" to the 'create_builddir' tool. At the time of the release,
|
||||
several basic scenarios including the timer driver and the USB driver are
|
||||
working. Also, both Cortex-A15 CPUs of the Exynos 5 SoC are operational.
|
||||
However, drivers for most of the peripherals of the Exynos-5 SoC are missing,
|
||||
which limits the current scope of Genode on this platform.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Since the base-linux platform became used for more than a mere development
|
||||
vehicle, we are revisiting several aspects of this base platform. In the last
|
||||
release, we changed the synchronous inter-process-communication mechanism to
|
||||
the use of SCM rights. For the current release, it was time to have a closer
|
||||
look at the memory management within core. The Linux version of core used a
|
||||
part of the BSS to simulate access to physical memory. All dataspaces would
|
||||
refer to a portion of 'some_mem'. So each time when core would access the
|
||||
dataspace contents, it would access its local BSS. For all processes outside of
|
||||
core, dataspaces were represented as files. We have now removed the distinction
|
||||
between core and non-core processes. Now, core uses the same 'Rm_session_mmap'
|
||||
implementation as regular processes. This way, the 'some_mem' could be
|
||||
abandoned. We still use a BSS variable for allocating core-local meta data
|
||||
though. The major benefit of this change is the removal of the artificial
|
||||
quota restriction that was imposed by the predefined size of the 'some_mem'
|
||||
array. Now, the Linux base platform can use as much memory as it likes. Because
|
||||
the Linux kernel implements virtual memory, we are not bound by the physical
|
||||
memory. Hence, the available quota assigned to the init process is almost
|
||||
without bounds.
|
||||
|
||||
To implement the fault-detection mechanism described in section
|
||||
[New fault-detection mechanism] on Linux, we let core catch SIGCHLD signals of
|
||||
all Genode processes. If such a signal occurs, core determines the process that
|
||||
produced the signal by using 'wait_pid', looks up the CPU session that belongs
|
||||
to the process and delivers an exception signal to the registered exception
|
||||
handler. This way, abnormal terminations of Genode processes are reflected to
|
||||
the Genode API in a clean way and Genode processes become able to respond to
|
||||
terminating Genode child processes.
|
||||
|
||||
|
||||
OKL4
|
||||
====
|
||||
|
||||
The audio stub driver has been removed from OKLinux. Because of the changed
|
||||
'Audio_out::Session' interface, we needed to decide on whether to adapt the
|
||||
OKLinux stub driver to the changed interface or to remove the stub driver.
|
||||
Given the fact that OKLinux is not actively used, we decided for the latter.
|
||||
943
doc/release_notes/13-05.txt
Normal file
943
doc/release_notes/13-05.txt
Normal file
@@ -0,0 +1,943 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 13.05
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
With Genode 13.05, we have diverged quite a bit from the feature-laden plans
|
||||
laid out in our [https://genode.org/about/road-map road map] as we realized
|
||||
that consolidating and optimizing the current feature set will have a more
|
||||
sustainable effect than functional enhancements at this point. In particular,
|
||||
we addressed the problem that the ever growing diversity of platforms imposes
|
||||
on the quality and coverage of testing. We also desired to extend our
|
||||
systematic testing efforts to real hardware platforms, and to have a mechanism
|
||||
for detecting performance regressions. Section
|
||||
[Automated quality-assurance testing] details how we approached these
|
||||
challenges, and how we went on analyzing Genode's network performance in
|
||||
particular.
|
||||
|
||||
That said, we haven't completely restrained ourself from implementing new
|
||||
features. Closely related to test automation but very useful in other
|
||||
situations, we improved the terminal infrastructure in order to enable the
|
||||
interactive use of dynamic system scenarios in headless situations. Section
|
||||
[Terminal infrastructure] introduces a new command-line interface for managing
|
||||
Genode subsystems.
|
||||
|
||||
With regard to platform support, the current release follows up on the
|
||||
hardware support added in the previous releases. For Samsung Exynos-5-based
|
||||
platforms, drivers for USB-3, fast-ethernet networking, gigabit networking,
|
||||
eMMC, and SATA have been added. For Freescale i.MX53-based devices, new
|
||||
drivers for display, touchscreen, and GPIO have become available. The
|
||||
OMAP4 display driver has been enhanced to cover both LCD displays and HDMI.
|
||||
Our custom base-hw kernel has been enabled on the Raspberry Pi
|
||||
board. Finally, Linux/ARM was added to accompany Linux/x86 as a fully usable
|
||||
Genode base platform.
|
||||
|
||||
|
||||
Automated quality-assurance testing
|
||||
###################################
|
||||
|
||||
One of the greatest challenges of the Genode OS Framework is preventing
|
||||
regressions in the face of the growing number of supported platforms.
|
||||
The challenge stems from the fact that the space of Genode scenarios grow
|
||||
two-dimensional. On one axis, the software stack on top of Genode gets more
|
||||
and more complex, which calls for contiguous testing. On the other axis, there
|
||||
is a growing number of kernel and hardware platforms to support.
|
||||
In principle, there are even more dimensions, for example the diversity
|
||||
of tool chains or the diversity of the OS used on the development machine.
|
||||
Luckily, the problem of tool-chain diversity could be mitigated with the
|
||||
introduction of the Genode tool chain since version 11.11, which was a huge
|
||||
relief. However, the mentioned two dimensions cannot be avoided. Because
|
||||
manual testing of manifold scenarios of component compositions on top of many
|
||||
different kernels became infeasible, we automated the task of building and
|
||||
testing years ago.
|
||||
|
||||
The automated builder checks out the staging branch of Genode, prepares
|
||||
the repositories that integrate 3rd-party code, and builds the software
|
||||
for 12 different kernel/platform combinations. Not all 3rd-party software
|
||||
packages are built for each combination though. But we make sure that each
|
||||
piece of software is exposed to different combinations of CPU architectures
|
||||
and kernels.
|
||||
|
||||
The build test is accompanied with automated runtime tests of various
|
||||
run scripts on Qemu. Each run script listed in 'tool/autopilot.lst' is
|
||||
executed on each kernel using the autopilot tool. The tests range from
|
||||
stimulating low-level mechanisms (such as signal, timer, and ldso) to complex
|
||||
scenarios (such as testing networking with L4Linux, or running Noux).
|
||||
|
||||
Both build and runtime tests are executed daily. If any of the
|
||||
tests fail, the Genode developers receive a notification email.
|
||||
Once all tests are passed, the staging branch can be merged into the master
|
||||
branch. This way, we spare the users of Genode to deal with intermediate
|
||||
problems introduced in the staging branch.
|
||||
|
||||
The build and runtime tests have become a fundamental tool for our
|
||||
development work. With the growing variety of real hardware
|
||||
(as opposed to hardware emulated via Qemu), however, our existing solution
|
||||
was falling short. Even though our tests confirm that Genode is running
|
||||
happily on Qemu, they won't help us to detect regressions in our device
|
||||
drivers for non-Qemu hardware such as Pandaboard, Arndale, or modern PC
|
||||
hardware. Furthermore, we are increasingly focussing on performance
|
||||
considerations. In order to be a viable OS platform, Genode does not only need
|
||||
to be able to do networking, but networking performance must be on par with
|
||||
mainstream OSes. This raises the new challenge to extend our
|
||||
continuous-testing tools to become continuous-benchmarking tools. The ultimate
|
||||
goal is to monitor the performance of Genode on real hardware over long
|
||||
periods of development.
|
||||
|
||||
In this release cycle, we attacked this problem in two steps. First, we
|
||||
enabled Genode's run tool to target not only Qemu but real hardware, with the
|
||||
premise that existing run scripts must not be changed. The second step is the
|
||||
creation of new run scripts that perform benchmarks in an automated fashion.
|
||||
By aggregating the results of this automatically executed benchmarks, we can
|
||||
correlate performance effects with commits in our code repository.
|
||||
|
||||
|
||||
Targeting real hardware via the run tool
|
||||
========================================
|
||||
|
||||
In the following, we briefly describe the procedure to execute run scripts
|
||||
on native hardware, for both Intel-based x86 machines and ARM-based platforms.
|
||||
|
||||
|
||||
TFTP boot x86
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The following description uses NOVA as an example to illustrate the usage.
|
||||
Other base platforms are supported as well and can be configured analogously.
|
||||
|
||||
[https://os.inf.tu-dresden.de/~us15/pulsar/ - Pulsar] is a tiny boot loader
|
||||
that uses PXE to fetch boot images via TFTP over the network. On the x86
|
||||
architecture, Genode supports the automatic generation of Pulsar configuration
|
||||
files, which can be placed directly onto a TFTP server. Genode can be booted
|
||||
via Pulsar using the following steps:
|
||||
|
||||
* On the x86 test machine, enable "PXE boot feature" in the BIOS.
|
||||
* When booting, the machine will look for a DHCP server announcing a TFTP server.
|
||||
So you need to make sure to have both the DHCP server and the TFTP server
|
||||
configured such that the 'pulsar' binary will be loaded as PXE binary.
|
||||
* After the PXE BIOS of the test machine has loaded and started the pulsar
|
||||
binary, Pulsar will look on the TFTP server for a file called
|
||||
'config-XX-XX-XX-XX-XX-XX', where the sequence of 'XX' corresponds to the
|
||||
MAC address of the test machine.
|
||||
For example, if the MAC of the network card is 01:02:03:04:05:06, Pulsar
|
||||
would request a file called 'config-01-02-03-04-05-06'.
|
||||
* Using this configuration file, we direct Pulsar to the configuration
|
||||
generated by the run tool. I.e., it should look as follows
|
||||
! root /tftpboot/nova
|
||||
! config config-00-00-00-00-00-00
|
||||
The lines above tell pulsar to load another config file, which contains the
|
||||
actual configuration. To instruct the run script to actually generate the
|
||||
'config-00-00-00-00-00-00' file, set the following environment variables in
|
||||
your shell prior executing the run script:
|
||||
! export PXE_TFTP_DIR_BASE=/tftpboot
|
||||
! export PXE_TFTP_DIR_OFFSET=/nova
|
||||
|
||||
The two-staged configuration of Pulsar may look overly complicated at first
|
||||
sight but has the benefit that the run tool does not need to know the MAC
|
||||
address of the test machine in order to generate the Pulsar configuration
|
||||
file.
|
||||
|
||||
* Create a symbolic link '/tftpboot/nova' pointing to the corresponding
|
||||
Genode build directory.
|
||||
|
||||
* The next time 'make run/printf' is invoked,
|
||||
the run script will generate the 'config-00-00-00-00-00-00' in
|
||||
'/tftpboot/nova'.
|
||||
|
||||
* When rebooting the test machine, it will load and start the printf test.
|
||||
|
||||
|
||||
TFTP boot using U-Boot
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Configure your U-Boot boot loader to load the images via TFTP.
|
||||
|
||||
The remainder of the procedure is similar to the description for x86 above.
|
||||
On ARM platforms, the run tool automatically generates the uBoot image and
|
||||
creates a symbolic link into the TFTP directory.
|
||||
|
||||
* Pandaboard:
|
||||
|
||||
! export PXE_TFTP_DIR_BASE=/tftpboot
|
||||
! export PXE_TFTP_DIR_OFFSET=/panda
|
||||
! ln -s <genode-build-dir> /tftpboot/panda
|
||||
! RUN_OPT="--target uboot" make run/printf
|
||||
|
||||
* Arndale board:
|
||||
|
||||
! export PXE_TFTP_DIR_BASE=/tftpboot
|
||||
! export PXE_TFTP_DIR_OFFSET=/arndale
|
||||
! ln -s <genode-build-dir> /tftpboot/panda
|
||||
! RUN_OPT="--target uboot" make run/printf
|
||||
|
||||
|
||||
|
||||
Output and reset with Intel's AMT
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Most modern x86-based machines lack a COM port, which is normally used for
|
||||
kernel debug messages as well as LOG messages printed by Genode's core.
|
||||
However, Intel's Advanced Management Technology (AMT) can be used to obtain
|
||||
the serial output of the test machine and to reset the test machine. To use
|
||||
AMT with Genode's run tool, install the 'amtterm' package (version 1.3 is
|
||||
known to work well) and set the following environment variables, specifying
|
||||
the IP address of the test machine and the AMT password.
|
||||
|
||||
! export AMT_TEST_MACHINE_IP=XXX.XXX.XXX.XXX
|
||||
! export AMT_TEST_MACHINE_PWD=XXXXXXXXX
|
||||
|
||||
Via setting the RUN_OPT environment variable, we instruct the run tool to use
|
||||
AMT instead of Qemu. The following command will reset the test machine, the test
|
||||
machine will load the binaries of the printf run script via PXE, and we will be
|
||||
able to see the serial output of the test machine through Intel's AMT Serial
|
||||
Over Line (SOL),
|
||||
|
||||
! RUN_OPT="--target amt" make run/printf
|
||||
|
||||
|
||||
Output via a COM port (UART)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If the x86 test machine, Pandaboard or Arndale test board is connected
|
||||
via UART, the run tool can use a specified command to interact with it.
|
||||
|
||||
For example, if the UART interface of the test machine is connected directly
|
||||
to the host machine at /dev/ttyUSB3, and the picocom tool is available,
|
||||
the following command can be used to establish a connection:
|
||||
|
||||
! RUN_OPT="--target serial --serial-cmd \"picocom -b 115200 /dev/ttyUSB3\"" make run/printf
|
||||
|
||||
Alternatively, if the board is connected to some remote machine, which exports
|
||||
the corresponding serial line via TCP/IP, the socat tool can be used for
|
||||
communicating with the remote test machine:
|
||||
|
||||
! RUN_OPT="--target serial --serial-cmd \"socat - tcp:10.0.0.1:2000\"" make run/printf
|
||||
|
||||
|
||||
Reset via a IP power plug NETIO-230B from Koukaam
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
At Genode Labs, we use a NETIO-230B power plug to automate power-cycling ARM
|
||||
boards. This power plug can be controlled over the network. For example, if
|
||||
the Pandaboard is connected to power port 3, the following command will
|
||||
automatically turn on the board when the run script is started:
|
||||
|
||||
! RUN_OPT="--target uboot --target reset --reset-port 2 --reset-ip 10.0.0.1 --reset-user admin --reset-passwd secret" make run/printf
|
||||
|
||||
The '--target reset' option can be combined with '--target uboot' to
|
||||
instruct the run tool to boot via TFTP (as described above) and take care
|
||||
of power cycling. When the run script has finished, the specified port
|
||||
will be automatically switched off by the run tool.
|
||||
|
||||
Of course, the IP address settings, as well as the actual user name and
|
||||
password, to access the NETIO-230B power plug, have to be adjusted accordingly.
|
||||
|
||||
|
||||
Automated benchmarking
|
||||
======================
|
||||
|
||||
With the '--target' features added to the run tool, the road is paved to
|
||||
obtain benchmark results in an automated fashion. Currently, we are most
|
||||
interested in exploring the network-performance characteristics of Genode.
|
||||
|
||||
Network performance can be explored at different levels. We started with
|
||||
looking at raw driver performance, then looked at the overhead of separating
|
||||
the network application from the device driver (and thereby introducing
|
||||
inter-process communication overhead), and finally explored the effects
|
||||
of the TCP/IP stack.
|
||||
|
||||
For pursuing the packet-level performance measurements, we crafted a library
|
||||
called 'net-stat', which contains the application logic of a low-level
|
||||
benchmark operating at network-packet level. This library has been
|
||||
successively incorporated into the 'dde_ipxe' NIC driver and the 'usb_drv'
|
||||
(NIC driver via ethernet-over-USB) to measure the raw driver performance
|
||||
without any microkernel overhead or TCP/IP protocol overhead.
|
||||
|
||||
To see the influence of the inter-process communication, namely the
|
||||
packet-stream interface employed by Genode's NIC-session interface,
|
||||
we implanted the same net-stat library into a NIC-session client. This
|
||||
experiment enables us to compare the operation of the NIC driver
|
||||
with the operation of a NIC driver separated from the NIC
|
||||
application.
|
||||
|
||||
The raw networking tests can be executed automatically using the set
|
||||
of 'network_test_nic*.run' scripts located at 'os/run'.
|
||||
The scenario sends raw ethernet packets from the host machine to the
|
||||
target machine. Three tests are provided:
|
||||
The 'network_test_nic_raw.run' test measures the net-stat-instrumented driver
|
||||
(of usb_drv and net_drv respectively) to observe the raw receive performance.
|
||||
The 'network_test_nic_raw_client.run' test implements the benchmark in a
|
||||
NIC-session client connected to the NIC driver running as a separate
|
||||
component whereas the NIC driver is not instrumented.
|
||||
The 'network_test_nic_raw_bridge_client.run' test further adds a NIC bridge
|
||||
in-between the driver and the NIC-session client.
|
||||
|
||||
In addition to analyzing the performance on a low level, we investigated
|
||||
the effects of TCP/IP for the application performance. This topic is
|
||||
covered in more detail in Section [TCP/IP performance].
|
||||
|
||||
|
||||
Terminal infrastructure
|
||||
#######################
|
||||
|
||||
Closely related to the quality-assurance measures detailed in the previous
|
||||
section, there is the arising need to interact with increasingly complex system
|
||||
scenarios in headless settings. In particular when executing tests remotely on a
|
||||
development board, manual user-interaction via a GUI
|
||||
becomes impractical. We vastly prefer a low-bandwidth textual interface
|
||||
in such situations. But how should a textual user interface for dynamic
|
||||
systems comprised of many components look like? This is particularly difficult
|
||||
because most development boards are equipped with merely a single UART
|
||||
connector.
|
||||
|
||||
On a normal Genode system, the UART connector is typically used
|
||||
by the kernel debugger to print debugging output, or for the interactive
|
||||
use of a debugger. This leaves no interface for interacting with Genode
|
||||
components. So how can we expose complex scenarios, such as concurrently
|
||||
running several instances of Genode subsystems, to the user?
|
||||
Our solution consists of three parts: A pseudo UART driver for Genode
|
||||
that uses the kernel debugger as back end, a terminal-multiplexing
|
||||
facility running on the reference platform, and a command-line based
|
||||
tool for interacting with Genode. By combining those, the user
|
||||
can interact with the kernel debugger, a Genode command line, and the
|
||||
consoles of executed Linux instances over a single serial connection.
|
||||
|
||||
The pseudo UART driver called kdb_uart_drv is a Genode service that
|
||||
implements the 'Uart::Session' interface. Therefore, it can be combined
|
||||
with all components that use the 'Uart::Session' or the 'Terminal::Session'
|
||||
interfaces, for example the Noux runtime environment, the terminal_log
|
||||
service (for displaying LOG messages via the terminal interface), L4Linux, or
|
||||
programs linked against the 'libc_terminal' plugin. The kdb_uart_drv component
|
||||
is located at 'os/src/drivers/uart/kdb'. It does not access a real UART device
|
||||
but rather uses the user-level bindings of the kernel debugger to indirectly
|
||||
read and write data over the UART interface.
|
||||
|
||||
[image kdb_uart_drv 65%]
|
||||
The kdb_uart_drv driver used for sharing one UART among the kernel
|
||||
debugger, core's LOG service, and a terminal client application
|
||||
running on Genode.
|
||||
|
||||
Figure [kdb_uart_drv] illustrates the relationship between the kernel
|
||||
debugger, core's LOG service, and kdb_uart_drv. Because write operations
|
||||
target the kernel debugger directly, core's LOG service gets bypassed. Output
|
||||
written to the kdb_uart_drv will directly appear at the terminal program of
|
||||
the host system. Because kdb_uart_drv has
|
||||
direct access to the host terminal, it can leverage all facilities of the host
|
||||
terminal, in particular various escape sequences for terminal manipulations.
|
||||
For reading from the kernel debugger, there is no way to block for UART input.
|
||||
Hence, the kdb_uart_drv periodically polls for new input with a period of 20
|
||||
milliseconds. If new input is available, the driver reads as many characters as
|
||||
available at once. So the runtime overhead of polling is negligible. To test
|
||||
kdb_uart_drv as individual component, there is a run script provided at
|
||||
'os/run/kdb_uart_drv.run'.
|
||||
|
||||
Thanks to kdb_uart_drv, both the kernel debugger and Genode can
|
||||
share one single UART connection. So we have a principal way to let the user
|
||||
interact with a Genode component that uses the 'Terminal::Session' interface.
|
||||
However, typical system scenarios should accommodate not just a single program
|
||||
but multiple Linux instances and native Genode applications simultaneously,
|
||||
each requiring a dedicated 'Terminal::Session'. Hence, we need a way to
|
||||
multiplex the 'Terminal::Session' interface between those clients. Our
|
||||
multiplexing solution comes in the form of a component called terminal_mux,
|
||||
which we just introduced in the
|
||||
[https://genode.org/documentation/release-notes/13.02#New_terminal_multiplexer - previous release].
|
||||
It uses a single terminal connection to implement a text-based user interface
|
||||
to multiple virtual terminal consoles.
|
||||
|
||||
[image terminal_mux 40%]
|
||||
Operation of the terminal_mux service.
|
||||
|
||||
Figure [terminal_mux] depicts the basic functioning of this component. For
|
||||
terminal_mux clients, the service implements the Linux terminal capabilities.
|
||||
For doing that, it shares large parts of the implementation of the existing
|
||||
Genode terminal program. For each client, terminal_mux renders the client
|
||||
output into a client-specific text-screen buffer. So any number of clients can
|
||||
perform output on terminal_mux concurrently. According to the selection by
|
||||
the user, terminal_mux periodically translates one client buffer (the
|
||||
foreground buffer) to escape sequences as understood by the host terminal. This
|
||||
translation is performed using the ncurses library. The user can pick the
|
||||
foreground buffer using an interactive menu that can be activated via the
|
||||
keyboard shortcut _Control-x_.
|
||||
|
||||
By combining kdb_uart_drv with terminal_mux, we created a flexible way
|
||||
to let the user interact with many Genode applications. The last part
|
||||
missing for a real dynamic system is a text-based command interface to
|
||||
start and stop Genode subsystems. This functionality is provided by the
|
||||
new cli_monitor component located at 'os/src/app/cli_monitor'.
|
||||
It uses the 'Terminal::Session' interface to present a simple interactive
|
||||
command line with commands for starting and stopping Genode subsystems,
|
||||
entering the kernel debugger, and showing status information. It provides
|
||||
tab completion and inline help to make it easily explorable. The cli_monitor
|
||||
component is integrated in the scenario of the 'terminal_mux.run' script
|
||||
mentioned above. Because cli_command is a 'Terminal::Session' client, it can
|
||||
be interfaced with terminal_mux. This composition is illustrated by Figure
|
||||
[uart_overview].
|
||||
|
||||
[image uart_overview 100%]
|
||||
Overview of the terminal infrastructure as employed in the
|
||||
demonstration scenario.
|
||||
|
||||
Note that in some situations, e.g., when killing subsystems, the kernel, core,
|
||||
or the init process may print LOG messages. Because those messages are
|
||||
naturally not routed through terminal_log, they will interfere with the
|
||||
operation of terminal_mux and thereby result in visible inconsistencies.
|
||||
Pressing _Control-x_ will clear such artifacts. This will bring up the
|
||||
terminal_mux menu, which implicitly triggers the redraw of the entire terminal.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
The current release comes with incremental improvements of the MMIO framework
|
||||
API and a new utility to ease the synchronized accesses to otherwise
|
||||
unsynchronized class interfaces.
|
||||
|
||||
:MMIO framework improvements:
|
||||
|
||||
For native Genode device drivers, we consistently use our
|
||||
[https://genode.org/documentation/release-notes/12.02#MMIO_access_framework - MMIO framework API].
|
||||
These utilities help us to safeguard the access to individual bit fields of
|
||||
memory-mapped device registers and cleanly separate the declaration of device
|
||||
registers from the driver logic. During the increased use of the API, we
|
||||
observe that the 'Genode::Mmio' class template operates mostly on addresses
|
||||
that belong to dataspaces provided by core's IO_MEM service. Those dataspaces
|
||||
are typically obtained via the 'Attached_io_mem_dataspace' convenience class,
|
||||
which requests the dataspace and attaches it to the local address
|
||||
space at once. To further reduce repetitive code, we introduced the new
|
||||
'Attached_mmio' class (located at 'os/attached_mmio.h'), which handles the
|
||||
common case of making the content of a IO_MEM dataspace available through
|
||||
register definitions using the 'Mmio' utility. Furthermore, the MMIO framework
|
||||
API has been enhanced with a variant of the 'Mmio::wait_for()' function that
|
||||
waits for whole register values rather than bits.
|
||||
|
||||
:Synchronized interfaces:
|
||||
|
||||
Most Genode programs are multi-threaded, which makes the proper use of locks
|
||||
inevitable. For most data structures, Genode does not implicitly manage the
|
||||
locking but expects the user of the data structures to know what he is doing.
|
||||
This way, we can avoid the locking overhead if a data structure is known to be
|
||||
accessed by a single thread only. If accessed by multiple threads, we usually
|
||||
wrap such data structures within an accessor interface that takes care of the
|
||||
locking. For example, for the 'Allocator' interface, there exists a
|
||||
corresponding 'Synchronized_allocator' interface wrapper. This technique works
|
||||
well as long as the number of interfaces is low -- as is the case for Genode's
|
||||
base API. However, as the wrapper code is for the most part pretty dumb, we'd
|
||||
like to avoid it. Also, when using the Genode API to implement programs on
|
||||
top, we do not anticipate manually creating such accessor wrappers. To ease
|
||||
the creation of synchronized interfaces, we introduced the new
|
||||
'Synced_interface' class template. It takes a pointer to an existing interface
|
||||
and a lock as arguments. An instance of a 'Synced_interface' provides
|
||||
synchronized access to the wrapped interface functions via the 'operator ()'.
|
||||
Because the 'Synced_interface' does not provide any means to obtain the
|
||||
unsynchronized version of the interface, once wrapped, the interface cannot be
|
||||
misused by subsystems that get handed over a reference to a
|
||||
'Synced_interface'. To see how to employ this utility, please have a look of
|
||||
how we realize the synchronization within the Vancouver VMM (in particular,
|
||||
the access to the motherboard).
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
TCP/IP performance
|
||||
==================
|
||||
|
||||
On the course of the automated benchmarking described in Section
|
||||
[Automated quality-assurance testing], we conducted the following steps
|
||||
to enable benchmarks and to improve performance at the TCP/IP level.
|
||||
|
||||
At application level, we desire to compare our network performance with the
|
||||
performance on GNU/Linux using commodity benchmarks. For this reason, netperf
|
||||
has been ported to run as native Genode using the lwIP stack. This benchmark
|
||||
allows us to systematically compare our results with those achieved by Linux.
|
||||
The port of netperf is available in the ports repository.
|
||||
|
||||
In addition to running a commodity benchmark, we pursue synthetic benchmarks
|
||||
that model the behaviour of typical application scenarios, for example, a
|
||||
web server that receive many small requests. This is where the added
|
||||
'test-ping_client' and 'test-ping_server' tests come into play. The test
|
||||
is located at 'libports/src/test/lwip/pingpong'. It is used by the
|
||||
series of 'network_test_*.run' scripts located at 'libports/run'. The
|
||||
run scripts exercise the test in various scenarios and thereby allow us to
|
||||
systematically explore the impact of the libc and NIC bridge on the
|
||||
application performance.
|
||||
|
||||
# Using raw lwIP without the libc
|
||||
# Like the first test, but with an instance of the NIC bridge in between the
|
||||
test program and the driver.
|
||||
# Using lwIP with the libc socket bindings
|
||||
# Like the third test, but with NIC bridge added
|
||||
|
||||
To keep track of the lwIP development more closely, we switched to the
|
||||
Git version of lwIP instead of using a source snapshot.
|
||||
|
||||
Furthermore, we incorporated "window scaling" support (RFC 1323) into our
|
||||
version of lwIP as we identify the TCP window size as a limiting factor
|
||||
of the TCP throughput achieved via lwIP.
|
||||
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
We added support for "resolv" functionality to the libc_lwip_nic_dhcp plugin.
|
||||
Normally, a file called 'resolv.conf' is expected to be located at '/etc'.
|
||||
On Genode, however, we don't have a global file system, which makes this
|
||||
way of configuration cumbersome. To ease the provision of a simple default
|
||||
'resolv.conf' configuration, the plugin hands out the file as a virtual file.
|
||||
The configuration automatically provides the DNS server address acquired by
|
||||
lwIP via DHCP. If, for some reason, this policy is not desired, the feature
|
||||
can be disabled via:
|
||||
|
||||
! <libc resolv="no" />
|
||||
|
||||
*Note that the configuration of the C runtime has changed*
|
||||
|
||||
To foster consistency of the libc configuration, we moved the static
|
||||
network "interface" attributes into the 'libc' XML node. A new configuration
|
||||
of static networking would look as follows:
|
||||
|
||||
! <libc ip_addr="..." netmask="..." gateway="..." />
|
||||
|
||||
|
||||
Terminal
|
||||
========
|
||||
|
||||
Genode's custom terminal implementation has been improved to better handle
|
||||
widely used escape sequences.
|
||||
The new version is able to handle two-argument SGR commands with
|
||||
attribute/color arguments in any order, and supports the ED, EL0, and
|
||||
CUB commands.
|
||||
|
||||
Because the terminal classes do not rely on any 3rd-party code, they
|
||||
have been moved to the os repository at 'os/include/terminal'. This way,
|
||||
we can use those classes by other components of the os repository such
|
||||
as the new CLI monitor.
|
||||
|
||||
|
||||
FS-LOG service
|
||||
==============
|
||||
|
||||
Using the new FS-LOG service residing at 'libports/os/src/server/fs_log', log
|
||||
messages of different processes can be redirected to files on a file-system
|
||||
service. The assignment of processes to files can be expressed in the
|
||||
configuration as follows:
|
||||
|
||||
! <start name="fs_log">
|
||||
! <resource name="RAM" quantum="2M"/>
|
||||
! <provides><service name="LOG"/></provides>
|
||||
! <config>
|
||||
! <policy label="noux" file="/noux.log" />
|
||||
! <policy label="noux ->" file="/noux_process.log" />
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
In this example, all messages originating from the noux process are directed
|
||||
to the file '/noux.log'. All messages originating from children of the noux
|
||||
process end up in the file '/noux_process.log'.
|
||||
|
||||
|
||||
Liquid FB
|
||||
=========
|
||||
|
||||
Liquid FB is a virtual framebuffer service that uses the nitpicker GUI
|
||||
server as back end. The virtual framebuffer is presented as a movable
|
||||
window with a title bar. Until now, we used it primarily for demonstration
|
||||
purposes, i.e., it is part of Genode's default demo scenario.
|
||||
|
||||
Thanks to our forthcoming adaptation of Qt5 to Genode, which requires a
|
||||
very similar solution to interface Qt5's platform-abstraction layer (QPA) to
|
||||
Genode, liquid FB got in the spotlight of this release.
|
||||
|
||||
First, we took the chance to update its configuration parameters to
|
||||
become more consistent with similar services such as nit_fb. As liquid_fb was
|
||||
originally conceived at a time when Genode's XML parser did not support
|
||||
XML attributes, its configuration syntax used to be a bit arcane. This
|
||||
has changed now. Apart from this cosmetic refinement, there are two prominent
|
||||
new features: Support for resizing the framebuffer window with the
|
||||
mouse and support for dynamic reconfiguration of the virtual framebuffer
|
||||
via Genode's configuration mechanism.
|
||||
|
||||
When the liquid FB window gets resized by the user, the virtual framebuffer
|
||||
emits a mode-changed signal to its client, which, in turn can handle the
|
||||
event by re-acquiring the frame-buffer dataspace.
|
||||
|
||||
The added support for dynamic reconfiguration allows for changing the
|
||||
properties of a liquid FB instance via Genode's configuration mechanism.
|
||||
For example, the window position and size can be manipulated this way.
|
||||
|
||||
Furthermore, two new configuration options have been added. The
|
||||
'resize_handle' option shows or hides the resize handle widget at the
|
||||
lower-right window corner (by default, it is hidden). The 'decoration' option
|
||||
defines whether window decorations should be visible (default is yes). Both
|
||||
options can have the values "on" or "off".
|
||||
|
||||
|
||||
3rd-party libraries
|
||||
###################
|
||||
|
||||
The following 3rd-party libraries have been added or updated:
|
||||
|
||||
* To complement libSDL, we have added ports of SDL_ttf, SDL_image,
|
||||
SDL_image, SDL_mixer, and SDL_loadso. Those additions to libSDL
|
||||
are used by popular libSDL-based applications such as Tuxpaint.
|
||||
They are now available at the libports repository.
|
||||
|
||||
* GNU FriBidi 0.19.5 added to the libports repository
|
||||
|
||||
* Qt4 updated to version 4.8.4
|
||||
|
||||
* zlib updated to version 1.2.8
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Unified driver names
|
||||
====================
|
||||
|
||||
The growing diversity of supported hardware platforms calls for improved
|
||||
conventions of how to name device drivers. Otherwise, run scripts that are
|
||||
meant to support a wide range of platforms will eventually become more
|
||||
and more complicated due to platform-dependent conditional configuration
|
||||
snippets. For example, the default framebuffer drivers of the respective
|
||||
platforms used to be called "vesa_drv" (for x86), "omap4_fb_drv", or "pl11x_drv".
|
||||
In order to support the different platforms, run scripts that were otherwise
|
||||
platform-agnostic had to explicitly deal with those differences.
|
||||
|
||||
To solve this issue, we introduced a generic SPEC values for device types, for
|
||||
which a default driver is expected to exist. If a platform features a
|
||||
framebuffer driver, it includes the SPEC value "framebuffer". On each
|
||||
platform, the default driver for the respective device has the same name. So
|
||||
each of "vesa_drv", "pl11x_drv", and "omap4_fb_drv" had been renamed to
|
||||
"fb_drv". This is possible because the use of those drivers is mutually
|
||||
exclusive.
|
||||
|
||||
The same convention has been applied to GPIO drivers as well. The
|
||||
corresponding SPEC value is called "gpio". The driver binaries are called
|
||||
"gpio_drv".
|
||||
|
||||
|
||||
ATAPI
|
||||
=====
|
||||
|
||||
LBA48 support has been added to the ATAPI driver. Thanks to Ivan Loskutov!
|
||||
|
||||
|
||||
KDB UART driver for L4/Fiasco and Fiasco.OC
|
||||
===========================================
|
||||
|
||||
The new KDB UART driver at 'os/src/drivera/uart/kdb' uses the kernel debugger
|
||||
console as backend for input and output. This is useful in the case that only
|
||||
one UART is available as described in Section [Terminal infrastructure].
|
||||
Examples for using the kdb_uart_drv are available in the form of the run scripts
|
||||
'ports-foc/run/l4linux.run' and 'os/run/kdb_uart_drv.run'.
|
||||
|
||||
|
||||
Revised GPIO session interface
|
||||
==============================
|
||||
|
||||
The original design of the GPIO session interface enabled the client of a
|
||||
single session to interact with any number GPIO pins. Each function of the
|
||||
interface took a GPIO number as first argument, which addressed the GPIO pin.
|
||||
|
||||
To simplify the interface and to enable fine-grained GPIO-assignment policies,
|
||||
the interface has been changed to provide access to a single GPIO pin per
|
||||
session only. At session creation time, the client specifies a single GPIO
|
||||
pin, to which the session refers. This information can be evaluated for the
|
||||
session routing. So access-control policies can be easily implemented per GPIO
|
||||
pin. The server stores the pin as part of the session context and implicitly
|
||||
uses the pin for operations on the session interface.
|
||||
|
||||
Furthermore, a generic driver interface for GPIO-class-device drivers
|
||||
has been introduced. The new interface at 'os/include/gpio' alleviates the
|
||||
need to implement the boilerplate code to interface the driver with Genode.
|
||||
The existing GPIO drivers for OMAP4 and i.MX53 are the first beneficiaries of
|
||||
these changes.
|
||||
|
||||
|
||||
Exynos 5 SoC
|
||||
============
|
||||
|
||||
After principally enabling the Exynos 5 SoC platform in the previous
|
||||
release, we moved on with extending the device-driver coverage of this SoC. In
|
||||
particular, we addressed USB networking, XHCI (USB-3), Gigabit networking over
|
||||
USB-3, eMMC, and SATA.
|
||||
|
||||
The development of those device drivers follows our rationale that guided our
|
||||
[https://genode.org/documentation/articles/pandaboard - previous work on the OMAP4 platform].
|
||||
For the USB driver, we employed the device-driver-environment (DDE) approach
|
||||
for reusing the Linux USB stack and the host controller drivers. In contrast,
|
||||
the eMMC and SATA drivers are built as genuine Genode drivers with no
|
||||
3rd-party code used.
|
||||
|
||||
Technically, the addition of Exynos-5 support to our USB driver was
|
||||
an evolutionary step. It required us to add the corresponding EHCI
|
||||
controller and to supply a few additions to the device-driver
|
||||
environment. To simplify the driver, we decided to let the driver
|
||||
rely on the platform initialization as performed by the U-Boot boot
|
||||
loader. Since the initialization is performed during the boot process
|
||||
already, there is no need to do this work twice. Because the platforms
|
||||
supported by the USB driver become more and more diverse, we re-organized the
|
||||
internal structure of the 'dde_linux' repository to keep those platforms well
|
||||
separated. Furthermore, we reworked the memory management of the USB driver to
|
||||
improve the utilization of the available RAM. The new solution employs Genode's
|
||||
concept of managed dataspaces to manage a part of the local address-space
|
||||
layout manually. This helps us to implement a fast translation of driver-local
|
||||
virtual addresses to physical addresses as needed for issuing DMA requests.
|
||||
|
||||
The eMMC driver builds upon our protocol implementation for the SD-card
|
||||
protocol, which was originally developed for the OMAP4 SD-card driver.
|
||||
Because we kept the SD-card protocol implementation well separated
|
||||
from the host-controller driver, it was possible to leverage parts of our
|
||||
existing work for the eMMC driver. Because the eMMC protocol is an extension
|
||||
of the SD-card protocol, however, we needed to enhance the protocol
|
||||
implementation accordingly. The extension comprises support for the
|
||||
MMC_SEND_EXT_CSD, MMC_SEND_OP_COND, and STOP_TRANSMISSION commands as well as
|
||||
the MMC detection. The host controller driver was implemented from scratch
|
||||
with the help of I/O access traces gathered from instrumenting the U-Boot boot
|
||||
loader and the Linux kernel. The driver operates the eMMC in high-speed, 8-bit
|
||||
mode at 52 MHz using DMA. The implementation can be found at
|
||||
'os/src/drivers/sd_card/exynos5'.
|
||||
|
||||
The initial version of our new SATA driver for Exynos 5 has been implemented
|
||||
from the ground up. Even though it is at an early stage, it has been
|
||||
successfully tested with a UDMA-133 disk, e.g., our generic block test
|
||||
is passed and the disk can be attached as a block device to an instance of
|
||||
L4Linux.
|
||||
|
||||
|
||||
Freescale i.MX SoC
|
||||
==================
|
||||
|
||||
The support for the Freescale i.MX53 SoC has been extended by a number of
|
||||
devices. All drivers reside in the os repository under the 'os/src/drivers'
|
||||
subdirectory.
|
||||
|
||||
The general-purpose I/O (GPIO) driver located at 'gpio/imx53' implements the
|
||||
revised GPIO-session interface.
|
||||
|
||||
The i.MX53 input driver provides support for the input devices featured on the
|
||||
i.MX53 SABRE tablet. The tablet uses an Egalaxy touchscreen and Freescale's
|
||||
MPR121 capacitative touch buttons. Both are supported by the new driver. The
|
||||
driver is located at 'input/imx53'.
|
||||
|
||||
The new framebuffer driver for the i.MX53 quick-start board (QSB) as well as
|
||||
the SABRE tablet comes with special support for using the
|
||||
hardware overlay feature provided by the i.MX53 image processing unit (IPU)
|
||||
Access to the overlay is implemented via an IPU-specific extension
|
||||
of the framebuffer-session interface. To combine the driver well with
|
||||
nitpicker using alpha-channels, optional support for double-buffering
|
||||
is provided. The driver is located at 'framebuffer/imx53'.
|
||||
|
||||
As an abstraction of platform features that need to be accessed by
|
||||
multiple drivers, a so-called platform driver has been introduced.
|
||||
The platform driver safeguards the access to global resources such
|
||||
as clocks and system-configuration bits. It can be found at 'platform/imx53'.
|
||||
|
||||
|
||||
OMAP4 SoC
|
||||
=========
|
||||
|
||||
The OMAP4 framebuffer driver used to support HDMI only, which was used
|
||||
for connecting a display to the Pandaboard. To make the driver usable on
|
||||
phones and tablets, the driver has been enhanced to support LCD output. Thanks
|
||||
to Alexander Tarasikov for the patch and the insightful story about
|
||||
[https://allsoftwaresucks.blogspot.com/2013/05/porting-genode-to-commercial-hardware.html - porting Genode to the B&N Nook HD+ tablet]!
|
||||
|
||||
|
||||
USB
|
||||
===
|
||||
|
||||
The USB driver of the 'dde_linux' repository has received substantial
|
||||
improvements both feature-wise and under the hood.
|
||||
|
||||
First and foremost, the Linux device-driver environment, on which the
|
||||
driver is based on, has been updated from kernel version 3.2 to version
|
||||
3.9 as the latter version includes drivers for recent host controllers
|
||||
such as DWC3 out of the box.
|
||||
|
||||
DWC3 is the host controller employed on the Exynos-5-based
|
||||
Arndale platform for USB 3. We added the support needed to operate this
|
||||
controller in XHCI mode and added support for Gigabit networking through
|
||||
the ASIX AX88179 Gigabit-Ethernet Adapter as well as USB storage support.
|
||||
|
||||
Apart from extending the device-driver coverage, we revised the driver
|
||||
internally. The back-end allocators for DMA buffers and normal memory have been
|
||||
rewritten to allocate RAM more sparingly. Furthermore, we enabled the USB
|
||||
driver for 64-bit x86 machines and improved the support for HID keyboards,
|
||||
including the application of quirks to cherry keyboards.
|
||||
|
||||
*Note the change of the USB configuration*
|
||||
|
||||
With the addition of XHCI, the USB driver supports a growing number
|
||||
of host controllers. In some situations, it is desirable to constrain the
|
||||
driver to a subset of controllers only. For example, on the Arndale platform,
|
||||
we desire to use a dedicated USB stack for XHCI, which operates completely
|
||||
independent from the USB stack accessing USB-2. This way, gigabit networking
|
||||
over USB-3 won't interfere with the operation of USB-2. To make this
|
||||
possible, we added new configuration options to the USB driver.
|
||||
With the new scheme, host controllers must be explicitly enabled in the
|
||||
configuration. Supported config attributes are: 'uhci', 'ehci', and 'xhci'.
|
||||
For example, a configuration snippet to enable UHCI and EHCI looks as
|
||||
follows:
|
||||
! <config uhci="yes" ehci="yes">
|
||||
|
||||
|
||||
Updated iPXE device-driver environment
|
||||
======================================
|
||||
|
||||
The iPXE device-driver environment was update to the most recent
|
||||
iPXE upstream Git version in order to benefit from upstream improvements
|
||||
of the Intel E1000 NIC driver.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Vancouver VMM on NOVA
|
||||
=====================
|
||||
|
||||
Vancouver is the user-level virtual-machine monitor that accompanies the
|
||||
NOVA hypervisor for hosting unmodified guest operating systems.
|
||||
|
||||
The most active line of development is led by Julian Stecklina at TU Dresden
|
||||
via a fork called Seoul. In contrast to the original version of Vancouver,
|
||||
this fork is open for outside contributions. Hence, it represents an ideal
|
||||
platform for those parties with a stake in Vancouver to collaborate, i.e.,
|
||||
the NUL userland, the NOVA runtime environment of TUD, and Genode.
|
||||
|
||||
In the current state of the transition, the Hip structure from Genode
|
||||
is reused. String functions, which were formerly taken from NUL are now
|
||||
provided by a stripped-down version of the C library called
|
||||
'seoul_libc_support'. The nul/config.h is replaced by just using a constant
|
||||
value in the one place where the file was needed.
|
||||
|
||||
The Genode-specific back ends of Vancouver, as largely introduced with the
|
||||
previous Genode release, have been improved in several respects:
|
||||
|
||||
* CPUID 0x40000000: This instruction is issued by Linux when the KVM
|
||||
guest support is compiled in. We have to return deterministic values to let
|
||||
the Linux kernel survive.
|
||||
|
||||
* Replaced busy thread startup synchronization by proper locking.
|
||||
|
||||
* New locking scheme: We replaced the error-prone manual locking with the
|
||||
use of the freshly introduced 'Synced_interface' for the motherboard and the
|
||||
VCPU dispatcher. Also, all globally visible locks have been removed. They are
|
||||
explicitly passed to subsystems only when needed.
|
||||
|
||||
* Improved PS/2 mouse back-end:
|
||||
The previous version of the PS/2 mouse back end managed mouse-motion
|
||||
events in a strange way, effectively throwing away most information
|
||||
about the motion vector. Furthermore, the tracking of the mouse-button
|
||||
states were missing. So drag-and-drop in a guest OS won't work. The new
|
||||
version fixes those issues. For the transformation of input events to
|
||||
PS/2 packets, the 'Genode::Register' facility is used, which greatly
|
||||
simplifies the code.
|
||||
|
||||
|
||||
L4Linux on Fiasco.OC
|
||||
====================
|
||||
|
||||
We improved the memory management of L4Linux on Genode in two ways.
|
||||
The first improvement is concerned about the upper limit of memory per Linux
|
||||
instance. The corresponding discussion can be found at
|
||||
[https://github.com/genodelabs/genode/issues/414 - issue #414].
|
||||
We changed our L4Re emulation library to match the semantics of the original
|
||||
L4Re more closely. Furthermore, we removed a heuristic in the L4Linux kernel,
|
||||
which assumed that all kernel-local addresses above 0x8000000 refer to device
|
||||
resources. In our version of L4Linux, there exist no MMIO resources. In
|
||||
contrary, the virtual addresses above this addresses are used for normal
|
||||
memory. By removing this artificial restriction with regard to the virtual
|
||||
memory layout of the L4Linux kernel, we can host a larger kernel memory area.
|
||||
|
||||
The second improvement is concerned with the allocation of L4Linux
|
||||
memory at Genode's core. Until now, L4Linux used to allocate its memory
|
||||
as one contiguous RAM dataspace at core's RAM service. Core tries to
|
||||
naturally align the allocation to improve the likelihood for large-page
|
||||
mappings. So a dataspace is likely to be physically located at a
|
||||
power-of-two boundary larger or equal than the dataspace size. For example,
|
||||
the allocation of a 100 MiB RAM dataspace for a Linux instance will
|
||||
be located at a 128 MiB boundary. If multiple of such allocations happen
|
||||
sub-sequentially, this allocation strategy results in 28 MiB gaps between
|
||||
100 MiB dataspaces. This memory cannot be used for large contiguous
|
||||
allocations anymore. So even if the available memory capacity is far
|
||||
larger than 100 MiB, an allocation of a 100 MiB block may fail.
|
||||
To relieve this problem, we weakened the requirement for contiguous memory
|
||||
by assembling L4Linux memory from multiple chunks of small dataspaces.
|
||||
For example, by using a chunk size of 16 MiB, core's best-fit allocator
|
||||
will have a better chance to find a more suited position for allocation
|
||||
when aligning the block to a 16 MiB boundary compared to the allocation
|
||||
of a larger block. Furthermore, slack memory can be used more efficiently
|
||||
because smaller gaps (such as a 20 MiB gap) remain to be usable for L4Linux.
|
||||
The discussion of this topic and the individual patch can be found at
|
||||
[https://github.com/genodelabs/genode/issues/695 - issue #695].
|
||||
|
||||
Furthermore, the L4Linux block driver has been improved to support large
|
||||
partitions.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Raspberry Pi
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Principal support for the Raspberry Pi platform has been added to the base-hw
|
||||
kernel. The popular Raspberry Pi board is based on an ARMv6 Broadcom BCM2835
|
||||
SoC. The current scope of the platform support comprises:
|
||||
|
||||
* IRQ controller driver: Because the interrupt controller uses a cascade of
|
||||
registers, we settled on the following IRQ enumeration scheme.
|
||||
IRQ numbers 0..7 refer to the basic IRQs.
|
||||
IRQ numbers 8..39 refer to GPU IRQs 0..31.
|
||||
IRQ numbers 40..71 refer to GPU IRQs 32..63.
|
||||
|
||||
* The kernel employs the so-called system timer for the preemptive scheduling.
|
||||
|
||||
* Core's LOG messages are printed over the PL011-based UART.
|
||||
|
||||
* The user-level timer driver uses the so-called ARM timer, which is a
|
||||
slightly modified SP804 timer device.
|
||||
|
||||
Up to this point, a few device driver are missing to use Genode on the
|
||||
Raspberry Pi in practice, most notably USB.
|
||||
|
||||
To build and run Genode on the Raspberry Pi, create a new build directory
|
||||
via the 'create_builddir' tool, specifying 'hw_rpi' as platform.
|
||||
|
||||
|
||||
User-level timer driver for Arndale platform
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By adding our new Exynos 5250 PWM timer driver, the base-hw kernel can now
|
||||
be used for executing meaningful scenarios on the Arndale board including
|
||||
the USB stack and networking.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Until now, Genode on Linux supported x86-based platforms only.
|
||||
The newly added 'linux_arm' platform clears the way to run Genode directly on
|
||||
Linux-based ARM platforms. Genode's entire software stack is supported,
|
||||
including the dynamic linker, graphical applications, and Qt4.
|
||||
|
||||
As a known limitations, the libc 'setjmp()'/'longjmp()' doesn't currently
|
||||
save/restore floating point registers.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
The run tool has been enhanced as detailed in Section
|
||||
[Automated quality-assurance testing].
|
||||
|
||||
995
doc/release_notes/13-08.txt
Normal file
995
doc/release_notes/13-08.txt
Normal file
@@ -0,0 +1,995 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 13.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The release of version 13.08 marks the 5th anniversary of the Genode OS
|
||||
framework. We celebrate this anniversary with the addition of three major
|
||||
features that we have much longed for, namely the port of Qt5 to Genode,
|
||||
profound multi-processor support, and a light-weight event tracing
|
||||
framework. Additionally, the new version comes with new device drivers for
|
||||
SATA 3.0 and power management for the Exynos-5 SoC, improved virtualization
|
||||
support on NOVA on x86, updated kernels, and integrity checks for
|
||||
downloaded 3rd-party source code.
|
||||
|
||||
Over the course of the past five years, Genode's development was primarily
|
||||
motivated by adding and cultivating features to make the framework fit for as
|
||||
many application areas as possible. Now that we have a critical mass of
|
||||
features, the focus on mere functionality does not suffice anymore. The
|
||||
question of what Genode can do ultimately turns into the question of how well
|
||||
Genode can do something: How stable is a certain workload? How does networking
|
||||
perform? How does it scale to multi-processor systems? Because we are lacking
|
||||
concise answers to these kind of questions, we have to investigate.
|
||||
|
||||
When talking about stability, our recently introduced automated testing
|
||||
infrastructure makes us more confident than ever. Each night, over 200
|
||||
automated tests are performed, covering various kernels and several hardware
|
||||
platforms. All those tests are publicly available in the form of so-called run
|
||||
scripts and are under continues development.
|
||||
|
||||
Regarding performance investigations, recently we have begun to benchmark
|
||||
application performance focusing on network throughput. Interestingly, our
|
||||
measurements reveal significant differences between the used kernels, but
|
||||
also shortcomings in our software stack. For example, currently we see that
|
||||
our version of lwIP performs poorly with gigabit networking. To thoroughly
|
||||
investigate such performance issues, the current version adds support
|
||||
for tracing the behaviour of Genode components. This will allow us to get a
|
||||
profound understanding of all inter-component interaction that are on the
|
||||
critical path for the performance of complex application-level workloads.
|
||||
Thanks to the Genode architecture, we could come up with a strikingly simple,
|
||||
yet powerful design for a tracing facility. Section
|
||||
[Light-weight event tracing] explains how it works.
|
||||
|
||||
When it comes to multi-processor scalability, we used to shy away from such
|
||||
inquiries because, honestly, we haven't paid much consideration to it. This
|
||||
view has changed by now. With the current release, we implemented the
|
||||
management of CPU affinities right into the heart of the framework, i.e.,
|
||||
Genode's session concept. Additionally, we cracked a damn hard nut by enabling
|
||||
Genode to use multiple CPUs on the NOVA hypervisor. This kernel is by far the
|
||||
most advanced Open-Source microkernel for the x86 architecture. However,
|
||||
NOVA's MP model seemed to inherently contradict with the API design of Genode.
|
||||
Fortunately, we found a fairly elegant way to go forward and we're able to
|
||||
tame the beast. Section [Enhanced multi-processor support] goes into more
|
||||
detail.
|
||||
|
||||
Functionality-wise, we always considered the availability of Qt on Genode as a
|
||||
big asset. With the current release, we are happy to announce that we finally
|
||||
made the switch from Qt4 to Qt5. Section [Qt5 available on all kernels] gives
|
||||
insights into the challenges that we faced during porting work.
|
||||
|
||||
In addition to those highlights, the new version comes with improvements all
|
||||
over the place. To name a few, there are improved support for POSIX threads,
|
||||
updated device drivers, an updated version of the Fiasco.OC kernel and
|
||||
L4Linux, and new device drivers for Exynos-5. Finally, the problem of
|
||||
verifying the integrity of downloaded 3rd-party source codes has been
|
||||
addressed.
|
||||
|
||||
|
||||
Qt5 available on all kernels
|
||||
############################
|
||||
|
||||
Since its integration with Genode version 9.02, Qt4 is regarded as
|
||||
one of the most prominent features of the framework. For users, combining Qt
|
||||
with Genode makes the world of sophisticated GUI-based end-user applications
|
||||
available on various microkernels. For Genode developers, Qt represents by far
|
||||
the most complex work load natively executed on top of the framework API,
|
||||
thereby stressing the underlying system in any way imaginable. We have been
|
||||
keeping an eye on Qt version 5 for a while and highly anticipate the direction
|
||||
where Qt is heading. We think that the time is right to leave Qt4 behind to
|
||||
embrace Qt5 for Genode.
|
||||
|
||||
For the time being, both Qt4 and Qt5 are available for Genode, but Qt4 is
|
||||
declared as deprecated and will be removed with the upcoming version 13.11.
|
||||
Since Qt5 is almost API compatible to Qt4, the migration path is relatively
|
||||
smooth. So we recommend to move your applications over to Qt5 during the
|
||||
next release cycle.
|
||||
|
||||
In the following, we briefly describe the challenges we faced while adding Qt5
|
||||
support to Genode, point you to the place where to find Qt5 in the source
|
||||
tree, and give quick-start instructions for getting a Qt5 application
|
||||
scenario running.
|
||||
|
||||
We found that the biggest architectural difference between version 4 and
|
||||
version 5 is the use of the so-called Qt Platform Abstraction (QPA) interface,
|
||||
which replaces the former Qt Window System (QWS).
|
||||
|
||||
|
||||
Moving from QWS to QPA
|
||||
======================
|
||||
|
||||
With Qt4, we relied on QWS
|
||||
to perform the window handling. A Qt4 application used to create a session to
|
||||
Genode's GUI server (called nitpicker) and applied its graphical output onto a
|
||||
virtual framebuffer. The virtual framebuffer was not visible per se. To make
|
||||
portions of the virtual framebuffer visible on screen, the application had to
|
||||
create so-called nitpicker views. A view is a rectangular area of the physical
|
||||
screen that displays a (portion of) the virtual framebuffer. The position,
|
||||
size, and stacking order of views is managed by the application. For each Qt
|
||||
window, the application would simply create a corresponding nitpicker view and
|
||||
maintain the consistency of the view with the geometry of the Qt window. Even
|
||||
though each Qt application seemingly operated as a full-screen application
|
||||
with the windows managed by the application-local QWS, the use of nitpicker
|
||||
views still allowed the integration of any number of Qt applications into one
|
||||
windowed environment.
|
||||
|
||||
With the advent of compositing window managers, the typical way of how an
|
||||
application interacts with the window system of the OS changed. Whereas
|
||||
old-generation GUIs relied on a tight interplay of the application with the
|
||||
window server in order to re-generate newly exposed window regions whenever
|
||||
needed (e.g., revealing the window content previously covered by another
|
||||
window), the modern model of a GUI server keeps all pixels of all windows in
|
||||
memory regardless of whether the window is visible or covered by other
|
||||
windows. The use of one pixel buffer per window seems wasteful with respect to
|
||||
memory usage when many large windows are overlapping each other. On the other
|
||||
hand, this technique largely simplifies GUI servers and makes the
|
||||
implementation of fancy effects, like translucent windows, straight forward.
|
||||
Since memory is cheap, the Qt developers abandoned the old method and fully
|
||||
embraced the buffer-per-window approach by the means of QPA.
|
||||
|
||||
For Genode, we faced the challenge that we don't have a window server
|
||||
in the usual sense. With nitpicker, we have a GUI server, but with a more
|
||||
radical design. In particular, nitpicker leaves the management of window
|
||||
geometries and stacking to the client. In contrast, QPA expects the window
|
||||
system to provide both means for a user to interactively change the window
|
||||
layout and a way for an application to define the properties (such as the
|
||||
geometry, title, and visibility) of its windows.
|
||||
The obviously missing piece was the software component that deals with window
|
||||
controls. Fortunately, we already have a bunch of native nitpicker applications
|
||||
that come with client-side window controls, in particular the so-called liquid
|
||||
framebuffer (liquid_fb). This nitpicker client presents a virtual framebuffer
|
||||
in form of a proper window on screen and, in turn, provides a framebuffer and
|
||||
input service. These services can be used by other Genode processes, for
|
||||
example, another nested instance of nitpicker.
|
||||
This way, liquid_fb lends itself to be the interface between the nitpicker
|
||||
GUI server and QPA.
|
||||
|
||||
For each QPA window, the application creates a new liquid_fb instance as a
|
||||
child process. The liquid_fb instance will request a dedicated nitpicker
|
||||
session, which gets routed through the application towards the parent of the
|
||||
application, which eventually routes the request to the nitpicker GUI server.
|
||||
Finally, the liquid_fb instance announces its input and framebuffer services
|
||||
to its parent, which happens to be the application. Now, the application is
|
||||
able to use those services in order to access the window. Because the
|
||||
liquid_fb instances are children of the application, the application can
|
||||
impose control over those. In particular, it can update the liquid_fb
|
||||
configuration including the window geometry and title at any time. Thanks to
|
||||
Genode's dynamic reconfiguration mechanism, the liquid_fb instances are able
|
||||
to promptly respond to such reconfigurations.
|
||||
|
||||
Combined, those mechanisms give the application a way to receive user input
|
||||
(via the input services provided by the liquid_fb instances), perform
|
||||
graphical output (via the virtual framebuffers provided by the liquid_fb
|
||||
instances), and define window properties (by dynamically changing the
|
||||
respective liquid_fb configurations). At the same time, the user can use
|
||||
liquid_fb's window controls to move, stack, and resize application windows as
|
||||
expected.
|
||||
|
||||
[image qt5_screenshot]
|
||||
|
||||
|
||||
Steps of porting Qt5
|
||||
====================
|
||||
|
||||
Besides the switch to QPA, the second major change was related to the build
|
||||
system. For the porting work, we use a Linux host system to obtain the
|
||||
starting point for the build rules. The Qt4 build system would initially
|
||||
generate all Makefiles, which could be inspected and processed at once. In
|
||||
contrast, Qt5 generates Makefiles during the build process whenever needed.
|
||||
When having configured Qt for Genode, however, the build on Linux will
|
||||
ultimately fail. So the much-desired intermediate Makefiles won't be created.
|
||||
The solution was to have 'configure' invoke 'qmake -r' instead of 'qmake'.
|
||||
This way, qmake project files will be processed recursively. A few additional
|
||||
tweaks were needed to avoid qmake from backing out because of missing
|
||||
dependencies (qt5_configuration.patch). To enable the build of the Qt tools
|
||||
out of tree, qmake-specific files had to be slightly adapted
|
||||
(qt5_tools.patch). Furthermore, qtwebkit turned out to use code-generation
|
||||
tools quite extensively during the build process. On Genode, we perform this
|
||||
step during the 'make prepare' phase when downloading and integrating the Qt
|
||||
source code with the Genode source tree.
|
||||
|
||||
For building Qt5 on Genode, we hit two problems. First, qtwebkit depends on
|
||||
the ICU (International Components for Unicode) library, which was promptly
|
||||
ported and can be found in the libports repository. Second, qtwebkit
|
||||
apparently dropped the support of the 'QThread' API in favor of
|
||||
POSIX-thread support only. For this reason, we had to extend the coverage
|
||||
of Genode's pthread library to fulfill the needs of qtwebkit.
|
||||
|
||||
Once built, we entered the territory of debugging problems at runtime.
|
||||
* We hit a memory-corruption problem caused by an assumption of 'QArrayData'
|
||||
with regard to the alignment of memory allocated via malloc. As a
|
||||
work-around, we weakened the assumptions to 4-byte alignment
|
||||
(qt5_qarraydata.patch).
|
||||
* Page faults in QWidgetAnimator caused by
|
||||
use-after-free problems. Those could be alleviated by adding pointer
|
||||
checks (qt5_qwidgetanimator.patch).
|
||||
* Page faults caused by the slot function 'QWidgetWindow::updateObjectName()'
|
||||
with a 'this' pointer of an incompatible type 'QDesktopWidget*'.
|
||||
As a workaround, we avoid this condition by delegating the
|
||||
'QWidgetWindow::event()' that happened to trigger the slot method to
|
||||
'QWindow' (base class of 'QWidgetWindow') rather than to a
|
||||
'QDesktopWidget' member (qt5_qwidgetwindow.patch).
|
||||
* We observed that Arora presented web sites incomplete, or including HTTP
|
||||
headers. During the evaluation of HTTP data, a signal was sent to another
|
||||
thread, which activated a "user provided download buffer" for optimization
|
||||
purposes. On Linux, the receiving thread was immediately scheduled and
|
||||
everything went fine. However, on some kernels used by Genode, scheduling
|
||||
is different, so that the original thread continued to execute a bit longer,
|
||||
ultimately triggering a race condition. As a workaround, we disabled the
|
||||
"user provided download buffer" optimization.
|
||||
* Page faults in the JavaScript engine of Webkit. The JavaScript
|
||||
'RegExp.exec()' function returned invalid string objects. We worked around
|
||||
this issue by deactivating the JIT compiler for the processing of
|
||||
regular expressions (ENABLE_YARR_JIT).
|
||||
|
||||
The current state of the Qt5 port is fairly complete. It covers the core, gui,
|
||||
jscore, network, script, scriptclassic, sql, ui, webcore, webkit, widgets,
|
||||
wtf, and xml modules. That said, there are a few known limitations and
|
||||
differences compared to Qt4. First, the use of one liquid_fb instance per
|
||||
window consumes more memory compared to the use of QWS in Qt4. Furthermore,
|
||||
external window movements are not recognized by our QPA implementation yet.
|
||||
This can cause popup menus to appear at unexpected positions. Key repeat is
|
||||
not yet handled. The 'QNitpickerViewWidget' is not yet adapted to Qt5. For this
|
||||
reason, qt_avplay is not working yet.
|
||||
|
||||
|
||||
Test drive
|
||||
==========
|
||||
|
||||
Unlike Qt4, which was hosted in the dedicated 'qt4' repository, Qt5 is
|
||||
integrated in the libports repository. It can be downloaded and integrated
|
||||
into the Genode build system by issuing 'make prepare' from within the
|
||||
libports repository. The Qt5 versions of the known Qt examples are located at
|
||||
libports/src/app/qt5. Ready-to-use run scripts for those examples are available
|
||||
at libports/run.
|
||||
|
||||
|
||||
Migration away from Qt4 to Qt5
|
||||
==============================
|
||||
|
||||
The support for Qt4 for Genode has been declared as deprecated. By default,
|
||||
it's use is inhibited to avoid name aliasing problems between both versions.
|
||||
Any attempt to build a qt4-based target will result in a message:
|
||||
!Skip target app/qt_launchpad because it requires qt4_deprecated
|
||||
To re-enable the use of Qt4, the SPEC value qt4_deprecated must be defined
|
||||
manually for the build directory:
|
||||
!echo "SPECS += qt4_deprecated" >> etc/specs.conf
|
||||
|
||||
We will keep the qt4 repository in the source tree during the current
|
||||
release cycle. It will be removed with version 13.11.
|
||||
|
||||
|
||||
Light-weight event tracing
|
||||
##########################
|
||||
|
||||
With Genode application scenarios getting increasingly sophisticated,
|
||||
the need for thorough performance analysis has come into spotlight.
|
||||
Such scenarios entail the interaction of many components.
|
||||
For example, with our recent work on optimizing network performance, we
|
||||
have to consider several possible attack points:
|
||||
|
||||
* Device driver: Is the device operating in the proper mode? Are there
|
||||
CPU-intensive operations such as allocations within the critical path?
|
||||
* Interface to the device driver: How frequent are context switches between
|
||||
client and device driver? Is the interface designed appropriately for
|
||||
the access patterns?
|
||||
* TCP/IP stack: How does the data flow from the raw packet level to the
|
||||
socket level? How dominant are synchronization costs between the involved
|
||||
threads? Are there costly in-band operations performed, e.g., dynamic
|
||||
memory allocations per packet?
|
||||
* C runtime: How does integration of the TCP/IP stack with the C runtime
|
||||
work, for example how does the socket API interfere with timeout
|
||||
handling during 'select' calls?
|
||||
* Networking application
|
||||
* Timer server: How often is the timer consulted by the involved components?
|
||||
What is the granularity of timeouts and thereby the associated costs for
|
||||
handling them?
|
||||
* Interaction with core: What is the profile of the component's interaction
|
||||
with core's low-level services?
|
||||
|
||||
This example is just an illustration. Most real-world performance-critical
|
||||
scenarios have a similar or even larger scope. With our traditional
|
||||
tools, it is hardly possible to gather a holistic view of the scenario. Hence,
|
||||
finding performance bottlenecks tends to be a series of hit-and-miss
|
||||
experiments, which is a tiresome and costly endeavour.
|
||||
|
||||
To overcome this situation, we need the ability to gather traces of component
|
||||
interactions. Therefore, we started investigating the design of a tracing
|
||||
facility for Genode one year ago while posing the following requirements:
|
||||
|
||||
* Negligible impact on the performance, no side effects:
|
||||
For example, performing a system call per traced event
|
||||
is out of question because this would severely influence the flow of
|
||||
control (as the system call may trigger the kernel to take a scheduling
|
||||
decision) and the execution time of the traced code, not to speak of
|
||||
the TLB and cache footprint.
|
||||
|
||||
* Kernel independence: We want to use the same tracing facility across
|
||||
all supported base platforms.
|
||||
|
||||
* Accountability of resources: It must be clearly defined where the
|
||||
resources for trace buffers come from. Ideally, the tracing tool should be
|
||||
able to dimension the buffers according to its needs and, in turn, pay for
|
||||
the buffers.
|
||||
|
||||
* Suitable level of abstraction: Only if the trace contains information at
|
||||
the right level of abstraction, it can be interpreted for large scenarios.
|
||||
A counter example is the in-kernel trace buffer of the Fiasco.OC kernel,
|
||||
which logs kernel-internal object names and a few message words when tracing
|
||||
IPC messages, but makes it almost impossible to map this low-level
|
||||
information to the abstraction of the control flow of RPC calls. In
|
||||
contrast, we'd like to capture the names of invoked RPC calls (which is an
|
||||
abstraction level the kernel is not aware of). This requirement implies the
|
||||
need to have useful trace points generated automatically. Ideally those
|
||||
trace points should cover all interactions of a component with the outside
|
||||
world.
|
||||
|
||||
* (Re-)definition of tracing policies at runtime: The
|
||||
question of which information to gather when a trace point is passed
|
||||
should not be solely defined at compile time. Instead of changing static
|
||||
instrumentations in the code, we'd prefer to have a way to configure
|
||||
the level of detail and possible conditions for capturing events at runtime,
|
||||
similar to dtrace. This way, a series of different hypotheses could be
|
||||
tested by just changing the tracing policy instead of re-building and
|
||||
rebooting the entire scenario.
|
||||
|
||||
* Straight-forward implementation: We found that most existing tracing
|
||||
solutions are complicated. For example, dtrace comes with a virtual
|
||||
machine for the sandboxed interpretation of policy code. Another typical
|
||||
source of complexity is the synchronization of trace-buffer accesses.
|
||||
Because for Genode, low TCB complexity is of utmost importance, the
|
||||
simplicity of the implementation is the prerequisite to make it an
|
||||
integral part of the base system.
|
||||
|
||||
* Support for both online and offline analysis of traces.
|
||||
|
||||
We are happy to report to have come up with a design that meets all those
|
||||
requirements thanks to the architecture of Genode. In the following, we
|
||||
present the key aspects of the design.
|
||||
|
||||
The tracing facility comes in the form of a new TRACE service implemented
|
||||
in core. Using this service, a TRACE client can gather information about
|
||||
available tracing subjects (existing or no-longer existing threads),
|
||||
define trace buffers and policies and assign those to tracing subjects,
|
||||
obtain access to trace-buffer contents, and control the tracing state
|
||||
of tracing subjects. When a new thread is created via a CPU session, the
|
||||
thread gets registered at a global registry of potential tracing sources. Each
|
||||
TRACE service manages a session-local registry of so-called trace subjects.
|
||||
When requested by the TRACE client, it queries new tracing sources from the
|
||||
source registry and obtains references to the corresponding threads. This way,
|
||||
the TRACE session becomes able to control the thread's tracing state.
|
||||
|
||||
To keep the tracing overhead as low as possible, we assign a separate trace
|
||||
buffer to each individually traced thread. The trace buffer is a shared memory
|
||||
block mapped to the virtual address space of the thread's process. Capturing
|
||||
an event comes down to a write operation into the thread-local buffer. Because
|
||||
of the use of shared memory for the trace buffer, no system call is needed and
|
||||
because the buffer is local to the traced thread, there is no need for
|
||||
synchronizing the access to the buffer. When no tracing is active, a thread
|
||||
has no trace buffer. The buffer gets installed only when tracing is started.
|
||||
The buffer is not installed magically from the outside of the traced process
|
||||
but from the traced thread itself when passing a trace point. To detect
|
||||
whether to install a new trace buffer, there exists a so-called trace-control
|
||||
dataspace shared between the traced process and its CPU service. This
|
||||
dataspace contains control bits for each thread created via the CPU session.
|
||||
The control bits are evaluated each time a trace point is passed by the
|
||||
thread. When the thread detects a change of the tracing state, it actively
|
||||
requests the new trace buffer from the CPU session and installs it into its
|
||||
address space. The same technique is used for loading the code for tracing
|
||||
policies into the traced process. The traced thread actively checks for
|
||||
policy-version updates by evaluating the trace-control bits. If an update is
|
||||
detected, the new policy code is requested from the CPU session. The policy
|
||||
code comes in the form of position-independent code, which gets mapped into
|
||||
the traced thread's address space by the traced thread itself. Once mapped,
|
||||
a trace point will call the policy code. When called, the policy
|
||||
module code returns the data to be captured into the trace buffer. The
|
||||
relationship between the trace monitor (the client of TRACE service), core's
|
||||
TRACE service, core's CPU service, and the traced process is depicted in
|
||||
Figure [trace_control].
|
||||
|
||||
[image trace_control]
|
||||
|
||||
There is one trace-control dataspace per CPU session, which gets accounted
|
||||
to the CPU session's quota. The resources needed for the
|
||||
trace-buffer dataspaces and the policy dataspaces are paid-for by the
|
||||
TRACE client. On session creation, the TRACE client can specify the amount
|
||||
of its own RAM quota to be donated to the TRACE service in core. This
|
||||
enables the TRACE client to define trace buffers and policies of arbitrary
|
||||
sizes, limited only by its own RAM quota.
|
||||
|
||||
In Genode, the interaction of a process with its outside world is
|
||||
characterized by its use of inter-process communication, namely synchronous
|
||||
RPC, signals, and access to shared memory. For the former two types of
|
||||
inter-process communication, Genode generates trace points automatically. RPC
|
||||
clients generate trace points when an RPC call is issued and when a call
|
||||
returned. RPC servers generate trace points in the RPC dispatcher, capturing
|
||||
incoming RPC requests as well as RPC replies. Thanks to Genode's RPC
|
||||
framework, we are able to capture the names of the RPC functions in the RPC
|
||||
trace points. This information is obtained from the declarations of the RPC
|
||||
interfaces. For signals, trace points are generated for submitting and
|
||||
receiving signals. Those trace points form a useful base line for gathering
|
||||
tracing data. In addition, manual trace points can be inserted into the code.
|
||||
|
||||
|
||||
State of the implementation
|
||||
===========================
|
||||
|
||||
The implementation of Genode's tracing facility is surprisingly low complex.
|
||||
The addition to the base system (core as well as the base library) are
|
||||
merely 1500 lines of code. The mechanism works across all base platforms.
|
||||
|
||||
Because the TRACE client provides the policy code and trace buffer to the
|
||||
traced thread, the TRACE client imposes ultimate control over the traced
|
||||
thread. In contrast to dtrace, which sandboxes the trace policy, we express
|
||||
the policy module in the form of code executed in the context of the traced
|
||||
thread. However, in contrast to dtrace, such code is never loaded into a large
|
||||
monolithic kernel, but solely into the individually traced processes. So the
|
||||
risk of a misbehaving policy is constrained to the traced process.
|
||||
|
||||
In the current form, the TRACE service of core should be considered as a
|
||||
privileged service because the trace-subject namespace of each session
|
||||
contains all threads of the system. Therefore, TRACE sessions should be routed
|
||||
only for trusted processes. In the future, we plan to constrain the
|
||||
namespaces for tracing subjects per TRACE session.
|
||||
|
||||
The TRACE session interface is located at base/include/trace_session/.
|
||||
A simple example for using the service is available at os/src/test/trace/
|
||||
and is accompanied with the run script os/run/trace.run. The test
|
||||
demonstrates the TRACE session interface by gathering a trace of a thread
|
||||
running locally in its address space.
|
||||
|
||||
|
||||
Enhanced multi-processor support
|
||||
################################
|
||||
|
||||
Multi-processor (MP) support is one of those features that most users take for
|
||||
granted. MP systems are so ubiquitous, even on mobile platforms, that a
|
||||
limitation to utilizing a single CPU only is almost a fallacy.
|
||||
That said, MP support in operating systems is hard to get right. For this
|
||||
reason, we successively deferred the topic on the agenda of Genode's
|
||||
road map.
|
||||
|
||||
For some base platforms such as the Linux or Codezero kernels, Genode
|
||||
always used to support SMP because the kernel would manage the affinity
|
||||
of threads to CPU cores transparently to the user-level process. So on
|
||||
these kernels, there was no need to add special support into the framework.
|
||||
|
||||
However, on most microkernels, the situation is vastly different. The
|
||||
developers of such kernels try hard to avoid complexity in the kernel and
|
||||
rightfully argue that in-kernel affinity management would contribute to kernel
|
||||
complexity. Another argument is that, in contrast to monolithic kernels that
|
||||
have a global view on the system and an "understanding" of the concerns of the
|
||||
user processes, a microkernel is pretty clueless when it comes to the roles
|
||||
and behaviours of individual user-level threads. Not knowing whether a thread
|
||||
works as a device driver, an interactive program, or a batch process, the
|
||||
microkernel is not in the position to form a reasonably useful model of the
|
||||
world, onto which it could intelligently apply scheduling and affinity
|
||||
heuristics. In fact, from the perspective of a microkernel, each thread does
|
||||
nothing else than sending and receiving messages, and causing page faults.
|
||||
|
||||
For these reasons, microkernel developers tend to provide the bootstrapping
|
||||
procedure for the physical CPUs and a basic mechanism to assign
|
||||
threads to CPUs but push the rest of the problem to the user space, i.e.,
|
||||
Genode. The most straight-forward way would make all physical CPUs visible
|
||||
to all processes and require the user or system integrator to assign
|
||||
physical CPUs when a thread is created. However, on the recursively
|
||||
structured Genode system, we virtualize resources at each level, which
|
||||
calls for a different approach. Section [Management of CPU affinities]
|
||||
explains our solution.
|
||||
|
||||
When it comes to inter-process communication on MP systems, there is a
|
||||
certain diversity among the kernel designs. Some kernels allow the user land
|
||||
to use synchronous IPC between arbitrary threads, regardless of whether both
|
||||
communication partners reside on the same CPU or on two different CPUs. This
|
||||
convenient model is provided by Fiasco.OC. However, other kernels do not offer
|
||||
any synchronous IPC mechanism across CPU cores at all, NOVA being a poster
|
||||
child of this school of thought. If a user land is specifically designed for
|
||||
a particular kernel, those peculiarities can be just delegated to the
|
||||
application developers. For example, the NOVA user land called NUL is designed
|
||||
such that a recipient of IPC messages spawns a dedicated thread on each
|
||||
physical CPU. In contrast, Genode is meant to provide a unified API that
|
||||
works well across various different kernels. To go forward, we had four
|
||||
options:
|
||||
|
||||
# Not fully supporting the entity of API semantics across all base platforms.
|
||||
For example, we could stick with the RPC API for synchronous communication
|
||||
between threads. Programs just would happen to fail on some base platforms
|
||||
when the called server resides on a different CPU. This would effectively
|
||||
push the problem to the system integrator. The downside would be the
|
||||
sacrifice of Genode's nice feature that a program developed
|
||||
on one kernel usually works well on other kernels without any changes.
|
||||
|
||||
# Impose the semantics provided by the most restrictive kernel onto all
|
||||
users of the Genode API. Whereas this approach would facilitate that
|
||||
programs behave consistently across all base platforms, the restrictions
|
||||
would be artificially imposed onto all Genode users, in particular the
|
||||
users of kernels with less restrictions. Of course, we don't change
|
||||
the Genode API lightheartedly, which attributes to our hesitance to go
|
||||
into this direction.
|
||||
|
||||
# Hiding kernel restrictions behind the Genode API. This approach could come
|
||||
in many different shapes. For example, Genode could transparently spawn a
|
||||
thread on each CPU when a single RPC entrypoint gets created, following
|
||||
the model of NUL. Or Genode could emulate synchronous IPC using the core
|
||||
process as a proxy.
|
||||
|
||||
# Adapting the kernel to the requirements of Genode. That is, persuading
|
||||
kernel developers to implement the features we find convenient, i.e., adding
|
||||
a cross-CPU IPC feature to NOVA. History shows that our track record in
|
||||
doing that is not stellar.
|
||||
|
||||
Because each of those options is like opening a different can of worms, we
|
||||
used to defer the solution of the problem. Fortunately, however, we finally
|
||||
kicked off a series of practical experiments, which led to a fairly elegant
|
||||
solution, which is detailed in Section
|
||||
[Adding multi-processor support to Genode on NOVA].
|
||||
|
||||
|
||||
Management of CPU affinities
|
||||
============================
|
||||
|
||||
In line with our experience of supporting
|
||||
[https://genode.org/documentation/release-notes/10.02#Real-time_priorities - real-time priorities]
|
||||
in version 10.02, we were seeking a way to express CPU affinities such that
|
||||
Genode's recursive nature gets preserved and facilitated. Dealing with
|
||||
physical CPU numbers would contradict with this mission. Our solution
|
||||
is based on the observation that most MP systems have topologies that can
|
||||
be represented on a two-dimensional coordinate system. CPU nodes close
|
||||
to each other are expected to have closer relationship than distant nodes.
|
||||
In a large-scale MP system, it is natural to assign clusters of closely
|
||||
related nodes to a given workload. Genode's architecture is based on the
|
||||
idea to recursively virtualize resources and thereby lends itself to the
|
||||
idea to apply this successive virtualization to the problem of clustering
|
||||
CPU nodes.
|
||||
|
||||
In our solution, each process has a process-local view on a so-called affinity
|
||||
space, which is a two-dimensional coordinate space. If the process creates a
|
||||
new subsystem, it can assign a portion of its own affinity space to the new
|
||||
subsystem by imposing a rectangular affinity location to the subsystem's CPU
|
||||
session. Figure [affinity_space] illustrates the idea.
|
||||
|
||||
[image affinity_space]
|
||||
|
||||
Following from the expression of affinities as a rectangular location within a
|
||||
process-local affinity space, the assignment of subsystems to CPU nodes
|
||||
consists of two parts, the definition of the affinity space dimensions as used
|
||||
for the process and the association of sub systems with affinity locations
|
||||
(relative to the affinity space). For the init process, the affinity space is
|
||||
configured as a sub node of the config node. For example, the following
|
||||
declaration describes an affinity space of 4x2:
|
||||
|
||||
! <config>
|
||||
! ...
|
||||
! <affinity-space width="4" height="2" />
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
Subsystems can be constrained to parts of the affinity space using the
|
||||
'<affinity>' sub node of a '<start>' entry:
|
||||
|
||||
! <config>
|
||||
! ...
|
||||
! <start name="loader">
|
||||
! <affinity xpos="0" ypos="1" width="2" height="1" />
|
||||
! ...
|
||||
! </start>
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
As illustrated by this example, the numbers used in the declarations for this
|
||||
instance of the init process are not directly related to physical CPUs. If
|
||||
the machine has just two cores, init's affinity space would be mapped
|
||||
to the range [0,1] of physical CPUs. However, in a machine
|
||||
with 16x16 CPUs, the loader would obtain 8x8 CPUs with the upper-left
|
||||
CPU at position (4,0). Once a CPU session got created, the CPU client can
|
||||
request the physical affinity space that was assigned to the CPU session
|
||||
via the 'Cpu_session::affinity()' function. Threads of this CPU session
|
||||
can be assigned to those physical CPUs via the 'Cpu_session::affinity()'
|
||||
function, specifying a location relative to the CPU-session's affinity space.
|
||||
|
||||
|
||||
Adding multi-processor support to Genode on NOVA
|
||||
================================================
|
||||
|
||||
The NOVA kernel has been supporting MP systems for a long time. However
|
||||
Genode did not leverage this capability until now. The main reason was that
|
||||
the kernel does not provide - intentionally by the kernel developer - the
|
||||
possibility to perform synchronous IPC between threads residing on different
|
||||
CPUs.
|
||||
|
||||
To cope with this situation, Genode servers and clients would need to make
|
||||
sure to have at least one thread on a common CPU in order to communicate.
|
||||
Additionally, shared memory and semaphores could be used to communicate across
|
||||
CPU cores. Both options would require rather fundamental changes to the Genode
|
||||
base framework and the API. An exploration of this direction should in any
|
||||
case be pursued in evolutionary steps rather than as one big change, also
|
||||
taking into account that other kernels do not impose such hard requirements on
|
||||
inter-CPU communication. To tackle the challenge, we conducted a series of
|
||||
experiments to add some kind of cross-CPU IPC support to Genode/NOVA.
|
||||
|
||||
As a general implication of the missing inter-CPU IPC, messages between
|
||||
communication partners that use disjoint CPUs must take an indirection through
|
||||
a proxy process that has threads running on both CPUs involved. The sender
|
||||
would send the message to a proxy thread on its local CPU, the proxy process
|
||||
would transfer the message locally to the CPU of the receiver by using
|
||||
process-local communication, and the proxy thread on the receiving CPU would
|
||||
deliver the message to the actual destination. We came up with three options
|
||||
to implement this idea prototypically:
|
||||
|
||||
# Core plays the role of the proxy because it naturally has access to all
|
||||
CPUs and emulates cross-CPU IPC using the thread abstractions of the
|
||||
Genode API.
|
||||
# Core plays the role of the proxy but uses NOVA system calls directly
|
||||
rather than Genode's thread abstraction.
|
||||
# The NOVA kernel acts as the proxy and emulates cross-CPU IPC directly
|
||||
in the kernel.
|
||||
|
||||
After having implemented the first prototypes, we reached the following
|
||||
conclusions.
|
||||
|
||||
For options 1 and 2 where core provides this service: If a client can not
|
||||
issue a local CPU IPC, it asks core - actually the pager of the client
|
||||
thread - to perform the IPC request. Core then spawns or reuses a proxy thread
|
||||
on the target CPU and performs the actual IPC on behalf of the client. Option
|
||||
1 and 2 only differ in respect to code size and the question to whom to
|
||||
account the required resources - since a proxy thread needs a stack and some
|
||||
capability selectors.
|
||||
|
||||
As one big issue for option 1 and 2, we found that in order to delegate
|
||||
capabilities during the cross-CPU IPC, core has to receive capability mappings
|
||||
to delegate them to the target thread. However, core has no means to know
|
||||
whether the capabilities must be maintained in core or not. If a capability is
|
||||
already present in the target process, the kernel would just translate the
|
||||
capability to the target's capability name space. So core wouldn't need to
|
||||
keep it. In the other case where the target receives a prior unknown
|
||||
capability, the kernel creates a new mapping. Because the mapping gets
|
||||
established by the proxy in core, core must not free the capability.
|
||||
Otherwise, the mapping would disappear in the target process. This means that
|
||||
the use of core as a proxy ultimately leads to leaking kernel resources
|
||||
because core needs to keep all transferred capabilities, just for the case a
|
||||
new mapping got established.
|
||||
|
||||
For option 3, the same general functionality as for option 1 and 2 is
|
||||
implemented in the kernel instead of core. If a local CPU IPC call
|
||||
fails because of a BAD_CPU kernel error code, the cross-CPU IPC extension
|
||||
will be used. The kernel extension creates - similar as to option 1 and 2 - a
|
||||
semaphore (SM), a thread (EC), and a scheduling context (SC) on the remote
|
||||
CPU and lets it run on behalf of the caller thread. The caller thread
|
||||
gets suspended by blocking on the created semaphore until the remote EC has
|
||||
finished the IPC. The remote proxy EC reuses the UTCB of the suspended caller
|
||||
thread as is and issues the IPC call. When the proxy EC returns, it wakes up
|
||||
the caller via the semaphore. Finally, the proxy EC and SC de-schedule
|
||||
themselves and the resources get to be destroyed later on by the kernel's RCU
|
||||
mechanism. Finally, when the caller thread got woken up, it takes care to
|
||||
initiate the deconstruction of the semaphore.
|
||||
|
||||
The main advantage of option 3 compared to options 1 and 2 is that we don't
|
||||
have to keep and track the capability delegations during a cross-CPU IPC.
|
||||
Furthermore, we do not have potentially up to two additional address space
|
||||
switches per cross-CPU IPC (from client to core and core to the server).
|
||||
Additionally, the UTCB of the caller is reused by the proxy EC and does not
|
||||
need to be allocated separately as for option 1 and 2.
|
||||
|
||||
For these reasons, we decided to go for the third option. From Genode's API
|
||||
point of view, the use of cross-CPU IPC is completely transparent. Combined
|
||||
with the affinity management described in the previous section, Genode/NOVA
|
||||
just works on MP systems.
|
||||
As a simple example for using Genode on MP systems, there is a ready-to-use
|
||||
run script available at base/run/affinity.run.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Affinity propagation in parent, root, and RPC entrypoint interfaces
|
||||
===================================================================
|
||||
|
||||
To support the propagation of CPU affinities with session requests, the
|
||||
parent and root interfaces had to be changed. The 'Parent::Session'
|
||||
and 'Root::Session' take the affinity of the session as a new argument.
|
||||
The affinity argument contains both the dimensions of the affinity space
|
||||
used by the session and the session's designated affinity location within
|
||||
the space. The corresponding type definitions can be found at
|
||||
base/affinity.h.
|
||||
|
||||
Normally, the 'Parent::Session' function is not used directly but indirectly
|
||||
through the construction of a so-called connection object, which represents an
|
||||
open session. For each session type there is a corresponding connection type,
|
||||
which takes care of assembling the session-argument string by using the
|
||||
'Connection::session()' convenience function. To maintain API compatibility,
|
||||
we kept the signature of the existing 'Connection::session()' function using a
|
||||
default affinity and added a new overload that takes the affinity as
|
||||
additional argument. Currently, this overload is used in
|
||||
cpu_session/connection.h.
|
||||
|
||||
For expressing the affinities of RPC entrypoints to CPUs within the affinity
|
||||
space of the server process, the 'Rpc_entrypoint' takes the desired affinity
|
||||
location of the entrypoint as additional argument. For upholding API
|
||||
compatibility, the affinity argument is optional.
|
||||
|
||||
|
||||
CPU session interface
|
||||
=====================
|
||||
|
||||
The CPU session interface underwent changes to accommodate the new event
|
||||
tracing infrastructure and the CPU affinity management.
|
||||
|
||||
Originally the 'Cpu_session::num_cpus()' function could be used to
|
||||
determine the number of CPUs available to the session. This function
|
||||
has been replaced by the new 'affinity_space' function, which returns the
|
||||
bounds of the CPU session's physical affinity space. In the simplest case of
|
||||
an SMP machine, the affinity space is one-dimensional where the width
|
||||
corresponds to the number of CPUs. The 'affinity' function, which is used to
|
||||
bind a thread to a specified CPU, has been changed to take an affinity
|
||||
location as argument. This way, the caller can principally express the
|
||||
affiliation of the thread with multiple CPUs to guide load-balancing in a CPU
|
||||
service.
|
||||
|
||||
|
||||
New TRACE session interface
|
||||
===========================
|
||||
|
||||
The new event tracing mechanism as described in Section
|
||||
[Light-weight event tracing] is exposed to Genode processes in the form
|
||||
of the TRACE service provided by core. The new session interface
|
||||
is located under base/include/trace_session/. In addition to the new session
|
||||
interface, the CPU session interface has been extended with functions for
|
||||
obtaining the trace-control dataspace for the session as well as the trace
|
||||
buffer and trace policy for a given thread.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Event-driven operation of NIC bridge
|
||||
====================================
|
||||
|
||||
The NIC bridge component multiplexes one physical network device among
|
||||
multiple clients. It enables us to multiplex networking on the network-packet
|
||||
level rather than the socket level and thereby take TCP/IP out of the
|
||||
critical software stack for isolating network applications. As it
|
||||
represents an indirection in the flow of all networking packets, its
|
||||
performance is important.
|
||||
|
||||
The original version of NIC bridge was heavily multi-threaded. In addition to
|
||||
the main thread, a timer thread, and a thread for interacting with the NIC
|
||||
driver, it employed one dedicated thread per client. By merging those flows of
|
||||
control into a single thread, we were able to significantly reduce the number
|
||||
of context switches and improve data locality. These changes reduced the
|
||||
impact of the NIC bridge on the packet throughput from 25% to 10%.
|
||||
|
||||
|
||||
Improved POSIX thread support
|
||||
=============================
|
||||
|
||||
To accommodate qtwebkit, we had to extend Genode's pthread library with
|
||||
working implementations of condition variables, mutexes, and thread-local
|
||||
storage. The implemented functions are attr_init, attr_destroy, attr_getstack,
|
||||
attr_get_np, equal, mutex_attr, mutexattr_init, mutexattr_destroy,
|
||||
mutexattr_settype, mutex_init, mutex_destroy, mutex_lock, mutex_unlock,
|
||||
cond_init, cond_timedwait, cond_wait, cond_signal, cond_broadcast, key_create,
|
||||
setspecific, and getspecific.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
SATA 3.0 on Exynos 5
|
||||
====================
|
||||
|
||||
The previous release featured the initial version of our SATA 3.0 driver for
|
||||
the Exynos 5 platform. This driver located at os/src/drivers/ahci/exynos5 has
|
||||
reached a fully functional state by now. It supports UDMA-133 with up to
|
||||
6 GBit/s.
|
||||
|
||||
For driver development, we set the goal to reach a performance equal to
|
||||
the Linux kernel. To achieve that goal, we had to make sure to
|
||||
operate the controller and the disks in the same ways as Linux does.
|
||||
For this reason, we modeled our driver closely after the behaviour of the
|
||||
Linux driver. That is, we gathered traces of I/O transactions to determine the
|
||||
initialization steps and the request patterns that Linux performs to access
|
||||
the device, and used those behavioral traces as a guide for our
|
||||
implementation. Through step-by-step analysis of the traces, we not only
|
||||
succeeded to operate the device in the proper modes, but we also found
|
||||
opportunities for further optimization, in particular regarding the error
|
||||
recovery implementation.
|
||||
|
||||
This approach turned out to be successful. We measured that our driver
|
||||
generally operates as fast (and in some cases even significantly faster)
|
||||
than the Linux driver on solid-state disks as well as on hard disks.
|
||||
|
||||
|
||||
Dynamic CPU frequency scaling for Exynos 5
|
||||
==========================================
|
||||
|
||||
As the Samsung Exynos-5 SoC is primarily targeted at mobile platforms,
|
||||
power management is an inherent concern. Until now, Genode did not pay
|
||||
much attention to power management though. For example, we completely
|
||||
left out the topic from the scope of the OMAP4 support. With the current
|
||||
release, we took the first steps towards proper power management on ARM-based
|
||||
platforms in general, and the Exynos-5-based Arndale platform in particular.
|
||||
|
||||
First, we introduced a general interface to regulate clocks and voltages.
|
||||
Priorly, each driver did its own part of configuring clock and power control
|
||||
registers. The more device drivers were developed, the higher were the chances
|
||||
that they interfere when accessing those clock, or power units.
|
||||
The newly introduced "Regulator" interface provides the possibility to enable
|
||||
or disable, and to set or get the level of a regulator. A regulator might be
|
||||
a clock for a specific device (such as a CPU) or a voltage regulator.
|
||||
For the Arndale board, an exemplary implementation of the regulator interface
|
||||
exists in the form of the platform driver. It can be found at
|
||||
os/src/drivers/platform/arndale. Currently, the driver implements
|
||||
clock regulators for the CPU, the USB 2.0 and USB 3.0 host controller, the
|
||||
eMMC controller, and the SATA controller. Moreover, it provides power
|
||||
regulators for SATA, USB 2.0, and USB 3.0 host controllers. The selection of
|
||||
regulators is dependent on the availability of drivers for the platform.
|
||||
Otherwise it wouldn't be possible to test that clock and power state doesn't
|
||||
affect the device.
|
||||
|
||||
Apart from providing regulators needed by certain device drivers, we
|
||||
implemented a clock regulator for the CPU that allows changing the CPU
|
||||
frequency dynamically and thereby giving the opportunity to scale down
|
||||
voltage and power consumption. The possible values range from 200 MHz to
|
||||
1.7 GHz whereby the last value isn't recommended and might provoke system
|
||||
crashes due to overheating. When using Genode's platform driver for Arndale
|
||||
it sets CPU clock speed to 1.6 GHz by default. When reducing
|
||||
the clock speed to the lowest level, we observed a power consumption
|
||||
reduction of approximately 3 Watt. Besides reducing dynamic power consumption
|
||||
by regulating the CPU clock frequency, we also explored the gating of the clock
|
||||
management and power management to further reduce power consumption.
|
||||
|
||||
With the CPU frequency scaling in place, we started to close all clock gates
|
||||
not currently in use. When the platform driver for the Arndale board gets
|
||||
initialized, it closes everything. If a device driver enables its clock
|
||||
regulator, all necessary clock gates for the device's clock are opened. This
|
||||
action saves about 0.7 Watt. The initial closing of all unnecessary power
|
||||
gates was much more effective. Again, everything not essential for the working
|
||||
of the kernel is disabled on startup. When a driver enables its power
|
||||
regulator, all necessary power gates for the device are opened. Closing all
|
||||
power gates saves about 2.6 Watt.
|
||||
|
||||
If we consider all measures taken to save power, we were able to reduce power
|
||||
consumption to about 59% without performance degradation. When measuring power
|
||||
consumption after boot up, setting the CPU clock to 1.6 GHz, and fully load
|
||||
both CPU cores without the described changes, we measured about 8 Watt. With
|
||||
the described power saving provisions enabled, we measured about 4.7 Watt.
|
||||
When further reducing the CPU clock frequency to 200 MHz, only 1.7 Watt were
|
||||
measured.
|
||||
|
||||
|
||||
VESA driver moved to libports
|
||||
=============================
|
||||
|
||||
The VESA framebuffer driver executes the initialization code located
|
||||
in VESA BIOS of the graphics card. As the BIOS code is for real mode,
|
||||
the driver uses the x86emu library from X11 as emulation environment.
|
||||
We updated x86emu to version 1.20 and moved the driver from the 'os'
|
||||
repository to the 'libports' repository as the library is third-party
|
||||
code. Therefore, if you want to use the driver, the 'libports'
|
||||
repository has to be prepared
|
||||
('make -C <genode-dir>/libports prepare PKG=x86emu') and enabled in
|
||||
your 'etc/build.conf'.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
Seoul (aka Vancouver) VMM on NOVA
|
||||
=================================
|
||||
|
||||
Since we repeatedly received requests for using the Seoul respectively
|
||||
Vancouver VMM on NOVA, we improved the support for this virtualization
|
||||
solution on Genode. Seoul now supports booting from raw hard disk images
|
||||
provided via Genode's block session interface. Whether this image is actually
|
||||
a file located in memory, or it is coming directly from the hard disk, or just
|
||||
from a partition of the hard disk using Genode's part_blk service, is
|
||||
completely transparent thanks to Genode's architecture.
|
||||
|
||||
Additionally, we split up the one large Vancouver run script into several
|
||||
smaller Seoul run scripts for easier usage - e.g. one for disk, one for
|
||||
network testing, one for automated testing, and one we call "fancy". The
|
||||
latter resembles the former vancouver.run script using Genode's GUI to let the
|
||||
user start VMs interactively. The run scripts prefixed with 'seoul-' can be
|
||||
found at ports/run. For the fancy and network scripts, ready-to-use VM images
|
||||
are provided. Those images are downloaded automatically when executing the run
|
||||
script for the first time.
|
||||
|
||||
|
||||
L4Linux on Fiasco.OC
|
||||
====================
|
||||
|
||||
L4Linux has been updated from version 3.5.0 to Linux kernel version 3.9.0 thus
|
||||
providing support for contemporary user lands running on top of L4Linux on both
|
||||
x86 (32bit) and ARM platforms.
|
||||
|
||||
|
||||
Noux runtime for Unix software
|
||||
==============================
|
||||
|
||||
Noux is our way to use the GNU software stack natively on Genode. To improve
|
||||
its performance, we revisited the address-space management of the runtime to
|
||||
avoid redundant revocations of memory mappings when Noux processes are cleaned
|
||||
up.
|
||||
|
||||
Furthermore, we complemented the support for the Genode tool chain to
|
||||
cover GNU sed and GNU grep as well. Both packages are available at the ports
|
||||
repository.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Fiasco.OC updated to revision r56
|
||||
=================================
|
||||
|
||||
Fiasco.OC and the required L4RE parts have been updated to the current SVN
|
||||
revision (r56). For us, the major new feature is the support of Exynos SOCs in
|
||||
the mainline version of Fiasco.OC (www.tudos.org). Therefore Genode's
|
||||
implementation of the Exynos5250 platform could be abandoned leading to less
|
||||
maintenance overhead of Genode on Fiasco.OC.
|
||||
|
||||
Furthermore, Genode's multi-processor support for this kernel has been
|
||||
improved so that Fiasco.OC users benefit from the additions described in
|
||||
Section [Enhanced multi-processor support].
|
||||
|
||||
|
||||
NOVA updated
|
||||
============
|
||||
|
||||
In the process of our work on the multi-processor support on NOVA, we updated
|
||||
the kernel to the current upstream version. Additionally, our customized branch
|
||||
(called r3) comes with the added cross-CPU IPC system call and improvements
|
||||
regarding the release of kernel resources.
|
||||
|
||||
|
||||
Integrity checks for downloaded 3rd-party software
|
||||
##################################################
|
||||
|
||||
Even though Genode supports a large variety of 3rd-party software, its
|
||||
source-code repository contains hardly any 3rd-party source code. Whenever
|
||||
3rd-party source code is needed, Genode provides automated tools for
|
||||
downloading the code and integrating it with the Genode environment. As of
|
||||
now, there exists support for circa 70 software packages, including the
|
||||
tool chain, various kernels, libraries, drivers, and a few applications. Of
|
||||
those packages, the code for 13 packages comes directly from their respective
|
||||
Git repositories. The remaining 57 packages are downloaded in the form of tar
|
||||
archives from public servers via HTTP or FTP. Whereas we are confident with
|
||||
the integrity of the code that comes from Git repositories, we are less so
|
||||
about the archives downloaded from HTTP or FTP servers.
|
||||
|
||||
Fortunately, most Open-Source projects provide signature files that allow
|
||||
the user to verify the origin of the archive. For example, archives of
|
||||
GNU software are signed with the private key of the GNU project. So the
|
||||
integrity of the archive can be tested with the corresponding public key.
|
||||
We used to ignore the signature files for many years but
|
||||
this has changed now. If there is a signature file available for a package,
|
||||
the package gets verified right after downloading. If only a hash-sum file
|
||||
is provided, we check it against a known-good hash sum.
|
||||
|
||||
The solution required three steps, the creation of tools for validating
|
||||
signatures and hashes, the integration of those tools into Genode's
|
||||
infrastructure for downloading the 3rd-party code, and the definition of
|
||||
verification rules for the individual packages.
|
||||
|
||||
First, new tools for downloading and validating hash sums and signatures were
|
||||
added in the form of the shell scripts download_hashver (verify hash sum) and
|
||||
download_sigver (verify signature) found at the tool/ directory. Under the
|
||||
hood, download_sigver uses GNU GPG, and download_hashver uses the tools
|
||||
md5sum, sha1sum, and sha256sum provided by coreutils.
|
||||
|
||||
Second, hooks for invoking the verification tools were added to the
|
||||
tool-chain build script as well as the ports and the libports repositories.
|
||||
|
||||
The third and the most elaborative step, was going through all the packages,
|
||||
looking for publicly available signature files, and adding corresponding
|
||||
package rules. As of now, this manual process has been carried out for 30
|
||||
packages, thereby covering the half of the archives.
|
||||
|
||||
Thanks to Stephan Mueller for pushing us into the right direction, kicking off
|
||||
the work on this valuable feature, and for the manual labour of revisiting all
|
||||
the 3rd-party packages!
|
||||
|
||||
791
doc/release_notes/14-02.txt
Normal file
791
doc/release_notes/14-02.txt
Normal file
@@ -0,0 +1,791 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 14.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
During the release cycle of version 14.02, our development has been focused on
|
||||
storage and virtualization. It goes without saying that proper support for
|
||||
block-device access and file systems is fundamental for the use of
|
||||
Genode as general-purpose OS. Virtualization is relevant as well because
|
||||
it bridges the gap between the functionality we need and the features
|
||||
natively available on Genode today.
|
||||
|
||||
Our work on the storage topic involved changes of the block-driver APIs to an
|
||||
asynchronous mode of operation, overhauling most of the existing block-level
|
||||
components, as well as the creation of new block services, most importantly a
|
||||
block cache. At file-system level, we continued our line of work on FUSE-based
|
||||
file systems, adding support for NTFS-3g. A new highlight, however, is a new
|
||||
file-system service that makes the file systems of the NetBSD kernel available
|
||||
to Genode. This is made possible by using rump kernels as described in Section
|
||||
[NetBSD file systems using rump kernels].
|
||||
|
||||
Virtualization on Genode has a long history, starting with the original
|
||||
support of OKLinux on the OKL4 kernel (OKLinux is no longer supported), over
|
||||
the support of L4Linux on top of the Fiasco.OC kernel, to the support of the
|
||||
Vancouver VMM on top of NOVA. However, whereas each of those variants has
|
||||
different technical merits, all of them were developed in the context of
|
||||
university research projects and were never exposed to real-world scenarios.
|
||||
We were longing for a solution that meets the general expectations from a
|
||||
virtualization product, namely the support for a wide range of guest OSes,
|
||||
guest-host integration features, ease of use, and an active development.
|
||||
VirtualBox is one of the most popular commodity virtualization products as of
|
||||
today. With the current release, we are happy to announce the availability of
|
||||
VirtualBox on top of Genode/NOVA. Section
|
||||
[VirtualBox on top of the NOVA microhypervisor] gives insights into the
|
||||
background of this development, the technical challenges we had to overcome,
|
||||
and the current state of the implementation.
|
||||
|
||||
In addition to addressing storage and virtualization, the current release
|
||||
comes with a new pseudo file system called trace_fs that allows the
|
||||
interactive use of Genode's tracing facilities via Unix commands,
|
||||
a profound unification of the various graphics back ends used throughout
|
||||
the framework, a new facility for propagating status reports, and
|
||||
improvements of the Noux runtime for executing Unix software on Genode.
|
||||
|
||||
|
||||
VirtualBox on top of the NOVA microhypervisor
|
||||
#############################################
|
||||
|
||||
Virtualization is an important topic for Genode for two distinct reasons.
|
||||
It is repeatedly requested by users of the framework who consider
|
||||
Genode as a microkernel-based hosting platform for virtual machines,
|
||||
and it provides a smooth migration path from using Linux-based systems
|
||||
towards using Genode as day-to-day OS.
|
||||
|
||||
Why do people consider Genode as a hosting platform for virtual machines
|
||||
if there is an abundance of mature virtualization solutions on the market?
|
||||
What all existing popular solutions have in common is the staggering complexity
|
||||
of their respective trusted-computing base (TCB). The user of a virtual
|
||||
machine on a commodity hosting platform has to trust millions of lines of
|
||||
code. For example, with Xen, the TCB comprises the hypervisor and the Linux
|
||||
system running as DOM0. For security-sensitive application areas, it is
|
||||
almost painful to trust such a complex foundation. In contrast, the TCB of a
|
||||
hosting platform based on Genode/NOVA is two orders of magnitude less complex.
|
||||
Lowering the complexity reduces the likelihood for vulnerabilities and thereby
|
||||
mitigates the attack surface of the system. It also enables the assessment of
|
||||
security properties by thorough evaluation or even formal verification. In the
|
||||
light of the large-scale privacy issues of today, the desire for systems that
|
||||
are resilient against malware and zero-day exploits has never been higher.
|
||||
Microkernel-based operating systems promise a solution. Virtualization enables
|
||||
compatibility to existing software. Combining both seems natural. This is what
|
||||
Genode/NOVA stands for.
|
||||
|
||||
From the perspective of us Genode developers who are in the process of
|
||||
migrating from Linux-based OSes to Genode as day-to-day OS, we consider
|
||||
virtualization as a stop-gap solution for all those applications that
|
||||
do not exist natively on Genode, yet. Virtualization makes our transition
|
||||
an evolutionary process.
|
||||
|
||||
Until now, NOVA was typically accompanied with a co-developed virtual machine
|
||||
monitor called Seoul (formerly called Vancouver), which is executed as a
|
||||
regular user-level process on top of NOVA. In contrast to conventional wisdom
|
||||
about the performance of microkernel-based systems, the Seoul VMM on top of
|
||||
NOVA is extremely fast, actually faster then most (if not all) commonly used
|
||||
virtualization solutions. However, originating from a research project, Seoul
|
||||
is quite challenging to use and not as mature as commodity VMMs that were
|
||||
developed as real-world products. For example, there is a good chance that an
|
||||
attempt to boot an arbitrary version of a modern Linux distribution might just
|
||||
fail. In our experience, it takes a few days to investigate the issues, modify
|
||||
the guest OS configuration, and tweak the VMM here and there, to run the OS
|
||||
inside the Seoul VMM. That is certainly not a show stopper in appliance-like
|
||||
scenarios, but it rules out Seoul as a general solution. Running Windows
|
||||
OS as guest is not supported at all, which further reduces the application
|
||||
areas of Seoul. With this in mind, it is unrealistic to propose the use
|
||||
of Genode/NOVA as an alternative for popular VM hosting solutions.
|
||||
|
||||
Out of this realization, the idea was born to combine NOVA's virtualization
|
||||
interface with a time-tested and fully-featured commodity VMM. Out of the
|
||||
available Open-Source virtualization solutions, we decided to take a closer
|
||||
look at VirtualBox, which attracted us for several reasons: First, it is
|
||||
portable, supporting various host OSes such as Solaris, Windows OS, Linux,
|
||||
and Mac OS X. Second, it has all the guest-integration features we could
|
||||
wish for. There are extensive so-called guest additions for popular guest
|
||||
OSes that vastly improve the guest-OS performance and allow a tight
|
||||
integration with the host OS using shared folders or a shared clipboard.
|
||||
Third, it comes with sophisticated device models that support all
|
||||
important popular guest OSes. And finally, it is actively developed and
|
||||
commercially supported.
|
||||
|
||||
However, moving VirtualBox over to NOVA presented us with a number of
|
||||
problems. As a precondition, we needed to gain a profound understanding
|
||||
of the VirtualBox architecture and the code base. To illustrate the challenge,
|
||||
the source-code distribution of VirtualBox comprises 2.8 million lines of
|
||||
code. This code contains build tools, the VMM, management tools, several
|
||||
3rd-party libraries, middleware, the guest additions, and tests. The pieces
|
||||
that are relevant for the actual VMM amount to 700 thousand lines. By
|
||||
reviewing the architecture, we found that the part of VirtualBox that
|
||||
implements the hypervisor functionality (the world switch) runs in the
|
||||
kernel of the host OS (it is loaded on demand by the user-level VM process
|
||||
through the _/dev/vboxdrv_ interface into the host OS kernel). It is
|
||||
appropriately named VMMR0. Once installed into the host OS kernel, it
|
||||
takes over the control over the machine. To put it blatantly simple, it runs
|
||||
"underneath" the host OS. The VMMR0 code is kernel agnostic, which explains
|
||||
the good portability of VirtualBox across various host OSes. Porting
|
||||
VirtualBox to a new host OS comes down to finding a hook for installing the
|
||||
VMMR0 code into the host OS kernel and adapting the VirtualBox runtime API
|
||||
to the new host OS.
|
||||
|
||||
In the context of microkernel-based systems, however, it becomes clear that
|
||||
this classical approach of porting VirtualBox would subvert the microkernel
|
||||
architecture. Not only would we need to punch a hole into NOVA for loading
|
||||
additional kernel code, but also the VMMR0 code would inflate the amount of
|
||||
code executed in privileged mode by more than factor 20. Both implications
|
||||
are gross violations of the microkernel principle. Consequently, we needed to
|
||||
find a different way to marry NOVA with VirtualBox.
|
||||
|
||||
Our solution was the creation of a drop-in replacement of the VMMR0 code that
|
||||
runs solely at user level and interacts with NOVA's virtualization
|
||||
interface. Our VMMR0 emulation code is co-located with the VirtualBox
|
||||
VM process. Architecturally, the resulting solution is identical to the
|
||||
use of Seoul on top of NOVA. There is one VM process per virtual machine,
|
||||
and each VM process is isolated from others by the NOVA kernel. In
|
||||
addition to creating the VMMR0 emulation code, we needed to replace some parts
|
||||
of the VirtualBox VMMR3 code with custom implementations because they
|
||||
overlapped with functionality provided by NOVA's virtualization interface,
|
||||
in particular the provisioning of guest-physical memory. Finally, we needed
|
||||
to interface the VM process with Genode's API to let the VM process
|
||||
interact with Genode's input, file-system, and framebuffer services.
|
||||
|
||||
The result of this undertaking is available at the _ports_ repository.
|
||||
VirtualBox can be downloaded and integrated with Genode via the following
|
||||
command issued from within the repository:
|
||||
! make prepare PKG=virtualbox
|
||||
|
||||
To illustrate the integration of VirtualBox into a Genode system, there
|
||||
is run script located at _ports/run/virtualbox.run_. It expects a
|
||||
bootable ISO image containing a guest OS at _<build-dir>/bin/test.iso_.
|
||||
The configuration of the VirtualBox process is as simple as
|
||||
! <config>
|
||||
! <image type="iso" file="/iso/test.iso" />
|
||||
! </config>
|
||||
|
||||
VirtualBox will try to obtain the specified ISO file via a file-system
|
||||
session. Furthermore, it will open a framebuffer session and an input session.
|
||||
The memory assigned to the guest OS depends on the RAM quota assigned to the
|
||||
VirtualBox process. Booting a guest OS stored in a VDI file is supported. The
|
||||
image type must be changed to "vdi" accordingly.
|
||||
|
||||
Please note that this first version of VirtualBox is far from being complete
|
||||
as it lacks many features (SMP, guest-addition support, networking), is not
|
||||
optimized, and must be considered as experimental. However, we could
|
||||
successfully run GNU/Linux, Android, Windows XP, Windows 7, HelenOS, Minix-3,
|
||||
GNU Hurd, and of course Genode inside VirtualBox.
|
||||
|
||||
One point we are pretty excited about is that the porting effort to
|
||||
Genode/NOVA did not require any change of Genode. From Genode's point of
|
||||
view, VirtualBox is just an ordinary leaf node of the process tree, which
|
||||
can happily co-exist with other processes - even if it is the Seoul VMM.
|
||||
|
||||
[image seoul-vbox-win7-tinycore]
|
||||
|
||||
In the screenshot above, VirtualBox is running besides the Seoul VMM on top of
|
||||
Genode/NOVA. Seoul executes Tinycore Linux as guest OS. VirtualBox executes MS
|
||||
Windows 7. Both VMMs are using hardware virtualization (VT-x) but are plain
|
||||
user-level programs with no special privileges.
|
||||
|
||||
|
||||
NetBSD file systems using rump kernels
|
||||
######################################
|
||||
|
||||
In the previous release, we made FUSE-based file systems available to Genode
|
||||
via a custom implementation of the FUSE API. Even though this step made
|
||||
several popular file systems available, we found that the file systems most
|
||||
important to us (such as ext) are actually not well supported by FUSE. For
|
||||
example, write support on ext2 is declared as an experimental feature. In
|
||||
hindsight it is clear why: FUSE is primarily being used for accessing file
|
||||
systems not found in the Linux kernel. So it shines with supporting NTFS
|
||||
but less so with file systems that are well supported by the Linux kernel.
|
||||
Coincidentally, when we came to this realization, we stumbled upon the
|
||||
wonderful work of Antti Kantee on so-called rump kernels:
|
||||
|
||||
:[https://wiki.netbsd.org/rumpkernel/]:
|
||||
Rump kernel Wiki
|
||||
|
||||
The motivation behind the rump kernels was the development of
|
||||
NetBSD kernel subsystems (referred to as "drivers") in the NetBSD user land.
|
||||
Such subsystems like file systems, device drivers, or the TCP/IP stack are
|
||||
linked against a stripped-down version of the NetBSD kernel that can be
|
||||
executed in user mode and uses a fairly small "hypercall" interface to
|
||||
interact with the outside world. A rump kernel contains everything needed to
|
||||
execute NetBSD kernel subsystems but hardly anything else. In particular, it
|
||||
does not support the execution of programs on top. From our perspective,
|
||||
having crafted device-driver environments (DDEs) for Linux, iPXE, and OSS over
|
||||
the years, a rump kernel sounded pretty much like a DDE for NetBSD. So we
|
||||
started exploring rump kernels with the immediate goal of making time-tested
|
||||
NetBSD file systems available to Genode.
|
||||
|
||||
To our delight, the integration of rump kernels into the Genode system went
|
||||
fairly smooth. The most difficult part was the integration of the NetBSD build
|
||||
infrastructure with Genode's build system. The glue between rump kernels and
|
||||
Genode is less than 3,000 lines of code. This code enables us to reuse all
|
||||
NetBSD file systems on Genode. A rump kernel instance that contains several
|
||||
file systems such as ext2, iso9660, msdos, and ffs takes about 8 MiB of memory
|
||||
when executed on Genode.
|
||||
|
||||
The support for rump kernels comes in the form of the dedicated _dde_rump_
|
||||
repository. For downloading and integrating the required NetBSD source code,
|
||||
the repository contains a Makefile providing the usual 'make prepare'
|
||||
mechanism. To build the file-system server, make sure to add the _dde_rump_
|
||||
repository to the 'REPOSITORIES' declaration of your _etc/build.conf_ file
|
||||
within your build directory. The server then can be built via
|
||||
! make server/rump_fs
|
||||
|
||||
There is a run script located at _dde_rump/run/rump_ext2.run_ to execute
|
||||
a simple test scenario:
|
||||
! make run/rump_ext2
|
||||
|
||||
The server can be configured as follows:
|
||||
!<start name="rump_fs">
|
||||
! <resource name="RAM" quantum="8M" />
|
||||
! <provides><service name="File_system"/></provides>
|
||||
! <config fs="ext2fs"><policy label="" root="/" writeable="yes"/></config>
|
||||
!</start>
|
||||
|
||||
On startup, it requests a service that provides a block session. If
|
||||
there is more than one block session in the system, the block session must be
|
||||
routed to the right block-session server. The value of the _fs_ attribute of
|
||||
the '<config>' node can be one of the following: _ext2fs_ for EXT2, _cd9660_ for
|
||||
ISO-9660, or _msdos_ for FAT file-system support. _root_ defines the directory
|
||||
of the file system as seen as root directory by the client. The server hands
|
||||
most of its RAM quota to the rump kernel. This means the larger the quota is,
|
||||
the larger the internal block caches of the rump kernel will be.
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
The base API has not underwent major changes apart from the addition of
|
||||
a few new utilities and minor refinements. Under the hood, however, the inner
|
||||
workings of the framework received much attention, including an extensive
|
||||
unification of the startup code and stack management.
|
||||
|
||||
|
||||
New 'construct_at' utility
|
||||
==========================
|
||||
|
||||
A new utility located at 'base/include/util/construct_at.h' allows for the
|
||||
manual placement of objects without the need to have a global placement new
|
||||
operation nor the need for type-specific new operators.
|
||||
|
||||
|
||||
New utility for managing volatile objects
|
||||
=========================================
|
||||
|
||||
Throughout Genode, we maintain a programming style that largely avoids dynamic
|
||||
memory allocations. For the most part, higher-level objects aggregate
|
||||
lower-level objects as class members. For example, the nitpicker GUI server
|
||||
is actually a compound of such aggregations (see
|
||||
[https://github.com/genodelabs/genode/blob/master/os/src/server/nitpicker/main.cc#L803 - Nitpicker::Main]).
|
||||
This functional programming style leads to robust programs but it poses a
|
||||
problem for programs that are expected to adopt their behaviour at runtime.
|
||||
For the example of nitpicker, the graphics back end of the GUI server takes
|
||||
the size of the screen as constructor argument. If the screen size changes,
|
||||
the once constructed graphics back end becomes inconsistent with the new
|
||||
screen size. We desire a way to selectively replace an aggregated object by a
|
||||
new version with updated constructor arguments. The new utilities found in
|
||||
'os/include/util/volatile_object.h' solve this problem. A so-called
|
||||
'Volatile_object' wraps an object of the type specified as template argument.
|
||||
In contrast of a regular object, a 'Volatile_object' can be re-constructed any
|
||||
number of times by calling 'construct' with the constructor arguments. It is
|
||||
accompanied with a so-called 'Lazy_volatile_object', which remains
|
||||
unconstructed until 'construct' is called the first time.
|
||||
|
||||
|
||||
Changed interface of 'Signal_rpc_member'
|
||||
========================================
|
||||
|
||||
We unified the 'Signal_rpc_member' interface to be more consistent with the
|
||||
'Signal_rpc_dispatcher'. The new version takes an entrypoint as argument and
|
||||
cares for dissolving itself from the entrypoint when destructed.
|
||||
|
||||
|
||||
Filename as default label for ROM connections
|
||||
=============================================
|
||||
|
||||
Since the first version of Genode, ROM services used to rely on a "filename"
|
||||
provided as session argument. In the meanwhile, we established the use of the
|
||||
session label to select routing policies as well as server-side policies.
|
||||
Strictly speaking, the name of a ROM module is used as a key to a server-side
|
||||
policy of ROM services. So why not to use the session label to express the
|
||||
key as we do with other services? By assigning the file name as label for ROM
|
||||
sessions, we may become able to remove the filename argument in the future by
|
||||
just interpreting the last part of the label as filename. By keeping only the
|
||||
label, we won't need to consider conditional routing (via '<if-arg>') based on
|
||||
session arguments other than the label anymore, which would simplify Genode
|
||||
configurations in the long run. This change is transparent at API level but
|
||||
may be taken into consideration when configuring Genode systems.
|
||||
|
||||
|
||||
New 'Genode::Deallocator' interface
|
||||
===================================
|
||||
|
||||
By splitting the new 'Genode::Deallocator' interface from the former
|
||||
'Genode::Allocator' interface, we become able to restrict the accessible
|
||||
operations for code that is only supposed to release memory, but not
|
||||
perform any allocations.
|
||||
|
||||
Closely related to the allocator interface, we introduced variants of the
|
||||
'new' operator that take a reference (as opposed to a pointer) to a
|
||||
'Genode::Allocator' as argument.
|
||||
|
||||
|
||||
Unified main-stack management and startup code among all platforms
|
||||
==================================================================
|
||||
|
||||
In contrast to the stacks of regular threads, which are located within a
|
||||
dedicated virtual-address region called thread-context area, the stack of
|
||||
the main thread of a Genode program used to be located within the BSS
|
||||
segment. If the stack of a normal thread overflows, the program produces
|
||||
an unresolvable page fault, which can be easily debugged. However,
|
||||
an overflowing main stack would silently corrupt the BSS segment. With
|
||||
the current release, we finally resolved this long-standing problem by
|
||||
moving the main stack to the context area, too. The tricky part was that
|
||||
the context area is created by the main thread. So we hit a hen-and-egg
|
||||
problem. We overcame this problem by splitting the process startup
|
||||
into two stages, both called from the crt0 assembly code. The first
|
||||
stage runs on a small stack within the BSS and has the sole purpose
|
||||
of creating the context area and a thread object for the main thread.
|
||||
This code path (and thereby the stack usage) is the same for all programs.
|
||||
So we can safely dimension the stage-1 stack. Once the first stage
|
||||
returns to the crt0 assembly code, the stack pointer is loaded with the
|
||||
stack that is now located within the context area. Equipped with the
|
||||
new stack, the actual startup code ('_main') including the global
|
||||
constructors of the program is executed.
|
||||
|
||||
This change paved the ground for several further code unifications and
|
||||
simplifications, in particular related to the dynamic linker.
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Revised block-driver framework
|
||||
==============================
|
||||
|
||||
Whereas Genode's block-session interface was designed to work asynchronously
|
||||
and supports the out-of-order processing of requests, those capabilities
|
||||
remained unused by the existing block services as those services used to
|
||||
operate synchronously to keep their implementation simple. However, this
|
||||
simplicity came at the prize of two disadvantages: First, it prevented us
|
||||
to fully utilize native command queuing of modern disk controllers. Second,
|
||||
when chaining components such as a block driver, the part_blk server, and
|
||||
a file system, latencies accumulated along the chain of services. This
|
||||
hurts the performance of random access patterns.
|
||||
|
||||
To overcome this limitation, we changed the block-component framework to work
|
||||
asynchronously and to facilitate the recently introduced server API.
|
||||
Consequently, all users of the API underwent an update. The affected
|
||||
components are rom_loopdev, atapi_drv, fb_block_adapter, http_block, usb_drv,
|
||||
and part_blk. For some components, in particular part_blk, this step led to a
|
||||
complete redesign.
|
||||
|
||||
Besides the change of the block-component framework, the block-session
|
||||
interface got extended to support logical block addresses greater than
|
||||
32bit (LBA48). Thereby, the block component framework can now support
|
||||
devices that exceed 2 TiB in size.
|
||||
|
||||
|
||||
Block cache
|
||||
===========
|
||||
|
||||
The provisioning of a block cache was one of the primary motivations behind the
|
||||
[https://genode.org/documentation/release-notes/13.11#Dynamic_resource_balancing - dynamic resource balancing]
|
||||
concept that was introduced in Genode 13.11. We are now introducing the first
|
||||
version of such a cache.
|
||||
|
||||
The new block cache component located at _os/src/server/blk_cache/_ is both
|
||||
a block-session client as well as a block-session server serving a single
|
||||
client. It is meant to sit between a block-device driver and a file-system
|
||||
server. When accessing the block device, it issues requests at a granularity
|
||||
of 4K and thereby implicitly reads ahead whenever a client requests a smaller
|
||||
amount of blocks. Blocks obtained from the device or written by the client
|
||||
are kept in memory. If memory becomes scarce, the block cache first tries
|
||||
to request further memory resources from its parent. If the request
|
||||
gets denied, the cache evicts blocks from memory to the block device following
|
||||
a least-recently-used replacement strategy. As of now, the block cache supports
|
||||
dynamic resource requests to grow on demand but support for handling yield
|
||||
requests is not yet implemented. So memory once handed out to the block cache
|
||||
cannot be regained. Adding support for yielding memory on demand will be
|
||||
complemented in the next version.
|
||||
|
||||
To see how to integrate the block cache in a Genode scenario, there is a
|
||||
ready-to-use run script available at _os/run/blk_cache.run_.
|
||||
|
||||
|
||||
|
||||
File-system infrastructure
|
||||
==========================
|
||||
|
||||
In addition to the integration of NetBSD's file systems, there are
|
||||
file-system-related improvements all over the place.
|
||||
|
||||
First, the 'File_system::Session' interface has been extended with a 'sync'
|
||||
RPC function. This function allows the client of a file system to force
|
||||
the file system to write back its internal caches.
|
||||
|
||||
Second, we extended the FUSE implementation introduced with the previous
|
||||
release.
|
||||
Since file systems tend to have a built-in caching mechanism, we need to
|
||||
sync these caches at the end of a session when using the fuse_fs server.
|
||||
Therefore, each FUSE file system port has to implement a 'Fuse::sync_fs()'
|
||||
function that executes the necessary actions if requested. Further
|
||||
improvements are related to the handling of symbolic links and error
|
||||
handling. Finally, we added a libc plugin for accessing NTFS file systems
|
||||
via the ntfs-3g library.
|
||||
|
||||
Third, we complemented the family of FUSE-based libc plugins with a family of
|
||||
FUSE-based file-system servers. To utilize a FUSE file system, there is a
|
||||
dedicated binary (e.g., _os/src/server/fuse_fs/ext2_) for each FUSE
|
||||
file-system server.
|
||||
Note that write support is possible but considered to be experimental at this
|
||||
point. For now, using it is not recommended.
|
||||
To use the ext2_fuse_fs server in Noux, the following configuration snippet
|
||||
may be used:
|
||||
|
||||
! <start name="ext2_fuse_fs">
|
||||
! <resource name="RAM" quantum="8M"/>
|
||||
! <provides> <service name="File_system"/> </provides>
|
||||
! <config>
|
||||
! <policy label="noux -> fuse" root="/" writeable="no" />
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
Finally, the libc file-system plugin has been extended to support 'unlink'.
|
||||
|
||||
|
||||
Trace file system
|
||||
=================
|
||||
|
||||
The new _trace_fs_ server provides access to a trace session by providing a
|
||||
file-system session as front end. Combined with Noux, it allows for the
|
||||
interactive exploration and tracing of Genode's process tree using
|
||||
traditional Unix tools.
|
||||
|
||||
Each trace subject is represented by a directory ('thread_name.subject') that
|
||||
contains specific files, which are used to control the tracing process of the
|
||||
thread as well as storing the content of its trace buffer:
|
||||
|
||||
:'enable': The tracing of a thread is activated if there is a valid policy
|
||||
installed and the intend to trace the subject was made clear by writing '1'
|
||||
to the 'enable' file. The tracing of a thread may be deactivated by writing a
|
||||
'0' to this file.
|
||||
|
||||
:'policy': A policy may be changed by overwriting the currently used one in the
|
||||
'policy' file. In this case, the old policy is replaced by the new one and
|
||||
automatically used by the framework.
|
||||
|
||||
:'buffer_size': Writing a value to the 'buffer_size' file changes the size of
|
||||
the trace buffer. This value is evaluated only when reactivating the tracing
|
||||
of the thread.
|
||||
|
||||
:'events': The trace-buffer contents may be accessed by reading from the
|
||||
'events' file. New trace events are appended to this file.
|
||||
|
||||
:'active': Reading the file will return whether the tracing is active (1) or
|
||||
not (0).
|
||||
|
||||
:'cleanup': Nodes of untraced subjects are kept as long as they do not change
|
||||
their tracing state to dead. Dead untraced nodes are automatically removed
|
||||
from the file system. Subjects that were traced before and are now untraced
|
||||
can be removed by writing '1' to the 'cleanup' file.
|
||||
|
||||
To use the trace_fs, a configuration similar to the following may be used:
|
||||
|
||||
! <start name="trace_fs">
|
||||
! <resource name="RAM" quantum="128M"/>
|
||||
! <provides><service name="File_system"/></provides>
|
||||
! <config>
|
||||
! <policy label="noux -> trace"
|
||||
! interval="1000"
|
||||
! subject_limit="512"
|
||||
! trace_quota="64M" />
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
:'interval': sets the period the Trace_session is polled. The
|
||||
time is given in milliseconds.
|
||||
|
||||
:'subject_limit': specifies how many trace subjects should by acquired at
|
||||
max when the Trace_session is polled.
|
||||
|
||||
:'trace_quota': is the amount of quota the trace_fs should use for the
|
||||
Trace_session connection. The remaining amount of RAM quota will be used
|
||||
for the actual nodes of the file system and the 'policy' as well as the
|
||||
'events' files.
|
||||
|
||||
In addition, there are 'buffer_size' and 'buffer_size_limit' that define
|
||||
the initial and the upper limit of the size of a trace buffer.
|
||||
|
||||
A ready-to-use run script can by found in 'ports/run/noux_trace_fs.run'.
|
||||
|
||||
|
||||
Unified interfaces for graphics
|
||||
===============================
|
||||
|
||||
Genode comes with several programs that perform software-based graphics
|
||||
operations. A few noteworthy examples are the nitpicker GUI server,
|
||||
the launchpad, the scout tutorial browser, or the terminal. Most of those
|
||||
programs were equipped with their custom graphics back end. In some
|
||||
cases such as the terminal, nitpicker's graphics back end was re-used.
|
||||
But this back end is severely limited because its sole purpose is the
|
||||
accommodation of the minimalistic (almost invisible) nitpicker GUI server.
|
||||
|
||||
The ongoing work on Genode's new user interface involves the creation of
|
||||
new components that rely on a graphics back end. Instead of further
|
||||
diversifying the zoo of graphics back ends, we took the intermediate step
|
||||
to consolidate the existing back ends into one unified concept such that
|
||||
application-specific graphics back ends can be created and extended using
|
||||
modular building blocks. The new versions of nitpicker, scout, launchpad,
|
||||
liquid_fb, nitlog, and terminal have been changed to use the new common
|
||||
interfaces:
|
||||
|
||||
:os/include/util/geometry.h: Basic data structures and operations needed
|
||||
for 2D graphics.
|
||||
|
||||
:os/include/util/color.h: Common color representation and utilities.
|
||||
|
||||
:os/include/os/pixel_rgba.h: Class template for representing a pixel.
|
||||
|
||||
:os/include/os/pixel_rgb565.h: Template specializations for RGB565 pixels.
|
||||
|
||||
:os/include/os/surface.h: Target surface, onto which graphics operations
|
||||
can be applied.
|
||||
|
||||
:os/include/os/texture.h: Source texture for graphics operations that
|
||||
transfer 2D pixel data to a surface.
|
||||
|
||||
The former _os/include/nitpicker_gfx/_ directory is almost deserted. The only
|
||||
remainders are functors for the few graphics operations actually required by
|
||||
nitpicker. For the scout widgets, the corresponding functors have become
|
||||
available at the public headers at _demo/include/scout_gfx/_.
|
||||
|
||||
Because the scout widget set is used by at least three programs and will
|
||||
most certainly play a role in new GUI components, we undertook a major
|
||||
cleanup of the parts worth reusing. The result can be found at
|
||||
_demo/include/scout/_.
|
||||
|
||||
|
||||
New session interface for status reporting
|
||||
==========================================
|
||||
|
||||
Genode has a uniform way of how configuration information is passed from
|
||||
parents to children within the process tree by the means of "config" ROM
|
||||
modules. Using this mechanism, a parent is able to steer the behaviour of
|
||||
its children, not just at their start time but also during runtime.
|
||||
Until now, however, there was no counterpart to the config mechanism, which
|
||||
would allow a child to propagate runtime information to its parent. There
|
||||
are many use cases for such a mechanism. For example, a bus-controller driver
|
||||
might want to propagate a list of devices attached to the bus. When a new
|
||||
device gets plugged in, this list should be updated to let the parent
|
||||
take the new device resource into consideration. Another use case would be the
|
||||
propagation of status information such as the feature set of a plugin.
|
||||
Taken to the extreme, a process might expose its entire internal state to its
|
||||
parent in order to allow the parent to kill and restart the process, and
|
||||
feed the saved state back to the new process instance.
|
||||
|
||||
To cover these use cases, we introduced the new report-session interface. When
|
||||
a client opens a report session, it transfers a part of its RAM quota to the
|
||||
report server. In return, the report server hands out a dataspace dimensioned
|
||||
according to the donated quota. Upon reception of the dataspace, the client
|
||||
can write its status reports into the dataspace and inform the server about
|
||||
the update via the 'submit' function. In addition to the mere reporting of
|
||||
status information, the report-session interface is designed to allow the
|
||||
server to respond to reports. For example, if the report mechanism is used to
|
||||
implement a desktop notification facility, the user may interactively respond
|
||||
to an incoming notification. This response can be reflected to the originator
|
||||
of the notification via the 'response_sigh' and 'obtain_response' functions.
|
||||
|
||||
The new _report_rom_ component is both a report service and a ROM service. It
|
||||
reflects incoming reports as ROM modules. The ROM modules are named
|
||||
after the label of the corresponding report session.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The report-ROM server hands out ROM modules only if explicitly permitted by a
|
||||
configured policy. For example:
|
||||
|
||||
! <config>
|
||||
! <rom>
|
||||
! <policy label="decorator -> pointer" report="nitpicker -> pointer"/>
|
||||
! <policy ... />
|
||||
! ...
|
||||
! </rom>
|
||||
! </config>
|
||||
|
||||
The label of an incoming ROM session is matched against the 'label' attribute
|
||||
of all '<policy>' nodes. If the session label matches a policy label, the
|
||||
client obtains the data from the report client with the label specified in the
|
||||
'report' attribute. In the example above, the nitpicker GUI server sends
|
||||
reports about the pointer position to the report-ROM service. Those reports
|
||||
are handed out to a window decorator (labeled "decorator") as ROM module.
|
||||
|
||||
|
||||
XML generator utility
|
||||
=====================
|
||||
|
||||
With the new report-session interface in place, comes the increased
|
||||
need to produce XML data. The new XML generator utility located at
|
||||
_os/include/util/xml_generator.h_ makes this extremely easy, thanks to
|
||||
C++11 language features. For an example application, refer to
|
||||
_os/src/test/xml_generator/_ and the corresponding run script at
|
||||
_os/run/xml_generator.run_.
|
||||
|
||||
|
||||
Dynamic ROM service for automated testing
|
||||
=========================================
|
||||
|
||||
The new _dynamic_rom_ service provides ROM modules that change during the
|
||||
lifetime of a ROM session according to a timeline. The main purpose of this
|
||||
service is the automated testing of programs that are able to respond to ROM
|
||||
module changes, for example configuration changes.
|
||||
|
||||
The configuration of the dynamic ROM server contains a '<rom>' sub node per
|
||||
ROM module provided by the service. Each '<rom>' node hosts a 'name' attribute
|
||||
and contains a sequence of sub nodes that define the timeline of the ROM
|
||||
module. The possible sub nodes are:
|
||||
|
||||
:'<inline>': The content of the '<inline>' node is assigned to the content
|
||||
of the ROM module.
|
||||
|
||||
:'<sleep>': Sleeps a number of milliseconds as specified via the 'milliseconds'
|
||||
attribute.
|
||||
|
||||
:'<empty>': Removes the ROM module.
|
||||
|
||||
At the end of the timeline, it re-starts at the beginning.
|
||||
|
||||
|
||||
Nitpicker GUI server
|
||||
====================
|
||||
|
||||
The nitpicker GUI server has been enhanced to support dynamic screen
|
||||
resizing. This is needed to let nitpicker respond to screen-resolution
|
||||
changes, or when using a nested version of nitpicker within a resizable
|
||||
virtual framebuffer window.
|
||||
|
||||
To accommodate Genode's upcoming user-interface concept, we introduced the
|
||||
notion of a parent-child relationship between nitpicker views. If an existing
|
||||
view is specified as parent at construction time of a new view, the parent
|
||||
view's position is taken as the origin of the child view's coordinate space.
|
||||
This allows for the grouping of views, which can be atomically repositioned by
|
||||
moving their common parent view. Another use case is the handling of popup
|
||||
menus in Qt5, which can now be positioned relative to their corresponding
|
||||
top-level window. The relative position is maintained transparently to Qt when
|
||||
the top-level window gets repositioned.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Noux runtime for executing Unix software
|
||||
========================================
|
||||
|
||||
Noux plays an increasingly important role for Genode as it allows the use
|
||||
of the GNU software stack. Even though it already supported a variety of
|
||||
packages including bash, gcc, binutils, coreutils, make, and vim, some
|
||||
programs were still limited by Noux' not fully complete POSIX semantics,
|
||||
in particular with regard to signal handling. For example, it was not
|
||||
possible to cancel the execution of a long-running process via Control-C.
|
||||
|
||||
To overcome those limitations, we enhanced Noux by adding the _kill_ syscall,
|
||||
reworking the _wait_ and _execve_ syscalls, as well as adding
|
||||
signal-dispatching code to the Noux libc. Special attention had to be paid to
|
||||
the preservation of pending signals during the process creation via _fork_ and
|
||||
_execve_.
|
||||
|
||||
The current implementation delivers signals each time a Noux syscall
|
||||
returns. Signal handlers are executed as part of the normal control flow. This
|
||||
is in contrast to traditional Unix implementations, which allow the
|
||||
asynchronous invocation of signal handlers out of band with the regular
|
||||
program flow. The obvious downside of our solution is that a program that got
|
||||
stuck in a busy loop (and thereby not issuing any system calls) won't respond
|
||||
to signals. However, as we regard the Unix interface just as a runtime and not
|
||||
as the glue that holds the system together, we think that this compromise is
|
||||
justified to keep the implementation simple and kernel-agnostic. In the worst
|
||||
case, if a Noux process gets stuck because of such a bug, we certainly can
|
||||
live with the inconvenience of restarting the corresponding Noux subsystem.
|
||||
|
||||
To complement our current activities on the block and file-system levels,
|
||||
the e2fsprogs-v1.42.9 package as been ported to Noux. To allow the
|
||||
block-device utilities to operate on Genode's block sessions, we added a new
|
||||
"block" file system to Noux. Such a block file system can be mounted using a
|
||||
'<block>' node within the '<fstab>'. By specifying a label attribute, each
|
||||
block session request can be routed to the proper block session provider:
|
||||
|
||||
! <fstab>
|
||||
! ...
|
||||
! <dir name="dev">
|
||||
! <block name="blkdev0" label="block_session_0" />
|
||||
! </dir>
|
||||
! ...
|
||||
! </fstab>
|
||||
|
||||
In addition to this file system, support for the DIOCGMEDIASIZE ioctl
|
||||
request was added. This request is used by FreeBSD and therefore by our
|
||||
libc to query the size of the block device in bytes.
|
||||
|
||||
|
||||
Qt5 refinements
|
||||
===============
|
||||
|
||||
Our port of Qt5 used to rely on custom versions of synchronization
|
||||
primitives such as 'QWaitCondition' and 'QMutex'. However, since most of the
|
||||
usual pthread synchronization functions as relied on by Qt5's regular POSIX
|
||||
back end have been added to Genode's pthread library by now, we could replace
|
||||
our custom implementations by Qt5's POSIX version.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
The development of our base-hw kernel platform during this release cycle was
|
||||
primarily geared towards adding multi-processor support. However, as we
|
||||
haven't exposed the code to thorough testing yet, we deferred the integration
|
||||
of this feature for the current release.
|
||||
|
||||
We increased the number of usable ARM platforms by adding basic support for
|
||||
the ODROID XU board.
|
||||
|
||||
|
||||
NOVA microhypervisor
|
||||
====================
|
||||
|
||||
The port of VirtualBox to Genode prompted us to improve the NOVA platform in
|
||||
the following respects.
|
||||
|
||||
NOVA used to omit the propagation of the FPU state of the guest OS to the
|
||||
virtual machine monitor (VMM) during the world switch between the guest OS and
|
||||
the VMM. With the Vancouver VMM, which is traditionally used on NOVA, this
|
||||
omission did not pose any problem because Vancouver would never touch the FPU
|
||||
state of the guest. So the FPU context of the guest was always preserved
|
||||
throughout the handling of virtualization events. However, in contrast to the
|
||||
Vancouver VMM, VirtualBox relies on the propagation of the FPU state between
|
||||
the guest running in VT-X non-root mode and the guest running within the
|
||||
VirtualBox recompiler. Without properly propagating the FPU state between both
|
||||
virtualization back ends, both the guest OS in non-root mode and VirtualBox's
|
||||
recompiler would corrupt each other's FPU state. After first implementing an
|
||||
interim solution in our custom version of the kernel, the missing FPU context
|
||||
propagation had been implemented in the upstream version of NOVA as well.
|
||||
|
||||
In contrast to most kernels, NOVA did not allow a thread to yield its current
|
||||
time slice to another thread. The only way to yield CPU time was to block on
|
||||
a semaphore or to perform an RPC call. Unfortunately both of those instruments
|
||||
require the time-receiving threads to explicitly unblock the yielding thread
|
||||
(by releasing the semaphore or replying to the RPC call). However, there are
|
||||
situations where the progress of a thread may depend on an external
|
||||
condition or a side effect produced by another (unknown) thread. One
|
||||
particular example is the spin lock used to protect (an extremely short)
|
||||
critical section of Genode's lock metadata. Apparently VirtualBox presented
|
||||
us with several more use cases for thread-yield semantics. Therefore, we
|
||||
decided to extend NOVA's kernel interface with a new 'YIELD' opcode to the
|
||||
'ec_control' system call.
|
||||
|
||||
1123
doc/release_notes/14-05.txt
Normal file
1123
doc/release_notes/14-05.txt
Normal file
File diff suppressed because it is too large
Load Diff
1136
doc/release_notes/14-08.txt
Normal file
1136
doc/release_notes/14-08.txt
Normal file
File diff suppressed because it is too large
Load Diff
1047
doc/release_notes/14-11.txt
Normal file
1047
doc/release_notes/14-11.txt
Normal file
File diff suppressed because it is too large
Load Diff
899
doc/release_notes/15-02.txt
Normal file
899
doc/release_notes/15-02.txt
Normal file
@@ -0,0 +1,899 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 15.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
Genode's [https://genode.org/about/road-map - roadmap] for this year puts a
|
||||
strong emphasis on the consolidation and cultivation of the existing feature
|
||||
set. With the first release of the year, version 15.02 pays tribute to this
|
||||
mission by stepping up to extensive and systematic automated testing. As
|
||||
a precondition for scaling up Genode's test infrastructure, the release
|
||||
features a highly modular tool kit for exercising system scenarios on a growing zoo
|
||||
of test machines. Section [Modular tool kit for automated testing] explains
|
||||
the new tools in detail. In the spirit of improving the existing feature
|
||||
set, Genode 15.02 vastly improves the performance and stability of our version of
|
||||
VirtualBox running on the NOVA microhypervisor, solves long-standing shortcomings
|
||||
of memory management on machines with a lot of RAM, addresses NOVA-related
|
||||
scalability limitations, stabilizes our Rump-kernel-based file-system server,
|
||||
and refines the configuration interface of the Intel wireless driver.
|
||||
|
||||
As the most significant new feature, the new version introduces virtualization
|
||||
support for ARM to our custom base-hw kernel. Section [Virtualization on ARM]
|
||||
outlines the design and implementation of this feature, which was greatly
|
||||
inspired by NOVA's virtualization architecture and has been developed over the
|
||||
time span of more than a year.
|
||||
|
||||
With respect to platform support, we are happy to accommodate the upcoming
|
||||
USB-Armory board, which is a computer in the form factor of a USB
|
||||
stick especially geared towards security applications. Section
|
||||
[Support for the USB-Armory board] covers the background and the current
|
||||
state of this line of work.
|
||||
|
||||
|
||||
Virtualization on ARM
|
||||
#####################
|
||||
|
||||
The ARMv7 architecture of recent processors like Cortex-A7, Cortex-A15, or
|
||||
Cortex-A17 CPUs support hardware extensions to facilitate virtualization of
|
||||
guest operating systems. With the current release, we enable the use of these
|
||||
virtualization extensions in our custom base-hw kernel when running on the
|
||||
Cortex-A15-based Arndale board.
|
||||
|
||||
While integrating ARM's virtualization extension, we aimed to strictly follow
|
||||
microkernel-construction principles. The primary design is inspired by the
|
||||
[https://hypervisor.org/ - NOVA OS Virtualization Architecture]. It is based on a
|
||||
microhypervisor that provides essential microkernel mechanisms along with
|
||||
basic primitives to switch between virtual machines (VMs). On top of the
|
||||
microhypervisor, classical OS services are implemented as
|
||||
ordinary, unprivileged user-level components. Those services can be used by other
|
||||
applications. Services may be shared between applications or instantiated
|
||||
separately, according to security and safety needs. Correspondingly,
|
||||
following the NOVA principles, each VM has its own associated virtual-machine
|
||||
monitor (VMM) that runs as an unprivileged user-level component. VMM implementations
|
||||
can range from simple ones that just emulate primary device requirements to highly
|
||||
complex monitors including sophisticated device models, like VirtualBox. The
|
||||
NOVA approach allows to decouple the TCB complexity of one VM with respect to
|
||||
another, as well as with respect to all components not related to
|
||||
virtualization at all.
|
||||
|
||||
Along those lines, we extended the base-hw kernel/core conglomerate with API
|
||||
extensions that enable user-level VMM components to create and control virtual
|
||||
machines.
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
The ARM virtualization extensions are based on the so-called security
|
||||
extensions, commonly known as
|
||||
[https://genode.org/documentation/articles/trustzone - TrustZone].
|
||||
The ARM designers did not follow the
|
||||
Intel approach to split the CPU into a "root" and a "guest" world while having all prior
|
||||
existing CPU modes available in both worlds. Instead, ARM added a new privilege level
|
||||
to the non-secure side of TrustZone that sits underneath the ordinary kernel
|
||||
and userland privilege levels. It is subjected to a hypervisor-like kernel. All
|
||||
instructions used to prepare a VM's environment have to be executed in this so
|
||||
called "hyp" mode. In hyp mode, some instructions
|
||||
differ from their regular behaviour on the kernel-privilege level.
|
||||
For this reason, prior-existing kernel code cannot simply be reused in
|
||||
hyp mode without modifications.
|
||||
|
||||
The base-hw kernel is meant to execute Genode's core component on bare hardware.
|
||||
Core, which is an ordinary user-level component, is
|
||||
linked together with a slim kernel library that is executed in privileged kernel
|
||||
mode. To enable ARM hardware virtualization, we pushed this approach
|
||||
even further by executing core in three different privilege levels. Thereby,
|
||||
core shares the same view on hardware resources and virtual memory across all
|
||||
levels. A code path is executed on a higher privilege level only if the code
|
||||
would fail to execute on a lower privilege level.
|
||||
Following this approach, we were able to keep most of the existing kernel code
|
||||
with no modifications.
|
||||
|
||||
[image avirt_overview]
|
||||
Genode's ARM kernel (core) runs across all privilege levels
|
||||
|
||||
The hypervisor part of core is solely responsible to switch between VMs and the
|
||||
host system. Therefore, it needs to load/store additional CPU state that
|
||||
normally remains untouched during context switches of ordinary tasks. It also needs to
|
||||
configure the VM's guest-physical to host-physical memory translations. Moreover, the
|
||||
virtualization extensions of the ARMv7 architecture are not related to the CPU
|
||||
cores only. The interrupt controller and the CPU-local timers are also
|
||||
virtualization-aware. Therefore, the hypervisor has to load/store state specific
|
||||
to those devices, too. Nevertheless, the hypervisor merely reloads those
|
||||
devices. It does not interpret their state.
|
||||
|
||||
In contrast to the low-complexity hypervisor, a user-level VMM can be complex
|
||||
without putting the system's security at risk. It contains potentially complex
|
||||
device-emulation code and assigns hardware resources such as memory and
|
||||
interrupts to the VM. The VMM is an ordinary user-level component running
|
||||
unprivileged. Of course, as a plain user-level component, it is not able to
|
||||
directly access hardware resources. Hence an interface between VMMs and the
|
||||
kernel is needed to share the state of a virtual machine. In the past, we faced a similar
|
||||
problem when building a VMM for our former TrustZone experiments. It was natural
|
||||
to build upon the available solution and to extend it where necessary. Core
|
||||
provides a so-called VM service. Each VM corresponds to a session of this
|
||||
service. The session provides the following extended interface:
|
||||
|
||||
:CPU state:
|
||||
The CPU-state function returns a dataspace containing the virtual machine's
|
||||
state. The state is initialized by the VMM before bootstrapping the VM, gets updated
|
||||
by the hypervisor whenever it switches away from the VM, and can be used by
|
||||
the VMM to interpret the behavior of the guest OS. Moreover, the CPU state can be
|
||||
updated after the virtual machine monitor emulated instructions
|
||||
for the VM.
|
||||
|
||||
:Exception handler:
|
||||
The second function is used to register a signal handler that gets informed
|
||||
whenever the VM produces a virtualization fault.
|
||||
|
||||
:Run:
|
||||
The run function starts or resumes the execution of the VM.
|
||||
|
||||
:Pause:
|
||||
The pause function removes the VM from the kernel's scheduler.
|
||||
|
||||
:Attach:
|
||||
This function attaches a given RAM dataspace to a designated area of the
|
||||
guest-physical address space.
|
||||
|
||||
:Detach:
|
||||
The detach function invalidates a designated area of the guest-physical
|
||||
address space.
|
||||
|
||||
:Attach_pic: Tells the hypervisor to attach the CPU's virtual interface of the
|
||||
virtualization-aware interrupt controller to a designated area of the
|
||||
guest-physical address space.
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
By strictly following the micro-kernel construction principles when integrating the
|
||||
hypervisor into the base-hw kernel, we reached a minimally invasive solution. In
|
||||
doing so, we took the time to separate TrustZone-specific code that was formerly
|
||||
an inherent part of the kernel on ARMv7 platforms. Now, TrustZone- and
|
||||
virtualization-specific aspects are incorporated into the kernel only if
|
||||
actually used. The change in complexity of the whole core component expressed in
|
||||
lines of code is shown in the table below. As can be seen, the additional code in
|
||||
the root of the trusted computing base when using virtualization is about 700-800
|
||||
LOC.
|
||||
|
||||
Platform | with TrustZone, no VT | TrustZone/VT optional
|
||||
-----------------------------------------------------------------
|
||||
hw_arndale | 17970 LOC | 18730 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_imx53_qsb | 17900 LOC | 17760 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_imx53_qsb_tz | 18260 LOC | 18320 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_rpi | 17500 LOC | 17430 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_panda | 18040 LOC | 17880 LOC
|
||||
----------------------------------------------------------------
|
||||
hw_odroid_xu | 17980 LOC | 18050 LOC
|
||||
|
||||
Besides the VM world switch, we enabled support for the so-called "large
|
||||
physical address extension" (LPAE), which is obligatory when using
|
||||
virtualization. It allows for addressing a 40-bit instead of only 32-bit physical
|
||||
address space. Moreover, to execute in hypervisor mode, the bootstrap code of
|
||||
the kernel had to be set up properly. Hence, when booting on the Arndale board,
|
||||
the kernel now prepares the non-secure TrustZone world first, and finally leaves the
|
||||
secure world forever.
|
||||
|
||||
To test and showcase the ARM virtualization features integrated in base-hw, we
|
||||
implemented a minimal, exemplary VMM. It can be found in
|
||||
_repos/os/src/server/vmm_. The VMM emulates a simplified variant of ARM's
|
||||
Versatile Express Cortex-A15 development platform. Currently, it only comprises
|
||||
support for the CPU, the timer, the interrupt controller, and a UART device. It is
|
||||
written in 1100 lines of C++ in addition to the base Genode libraries. The VMM
|
||||
is able to boot a vanilla Linux kernel compiled with a slightly modified
|
||||
standard configuration (no-SMP), and a device tree description stripped down to
|
||||
the devices provided by the VMM. This release includes an automated run test that
|
||||
executes the Linux kernel on top of the VMM on Genode. It can be started via:
|
||||
|
||||
! make run/vmm
|
||||
|
||||
[image avirt_screen]
|
||||
Three Linux serial consoles running in parallel on top of Genode
|
||||
|
||||
|
||||
Modular tool kit for automated testing
|
||||
######################################
|
||||
|
||||
In
|
||||
[https://genode.org/documentation/release-notes/13.05#Automated_quality-assurance_testing - Genode version 13.05],
|
||||
we already introduced comprehensive support for the automated testing of
|
||||
Genode scenarios. Since then, Genode Labs has significantly widened the scope
|
||||
of its internal test infrastructure, both in terms of the coverage of the test
|
||||
scenarios as well as the variety of the used hardware platforms.
|
||||
|
||||
The centerpiece of our test infrastructure is the so-called run tool. Steered
|
||||
by a script (run script), it performs all the steps necessary to test drive
|
||||
a Genode system scenario. Those steps are:
|
||||
|
||||
# *Building* the components of a scenario
|
||||
# *Configuration* of the init component
|
||||
# Assembly of the *boot directory*
|
||||
# Creation of the *boot image*
|
||||
# *Powering-on* the test machine
|
||||
# *Loading* of the boot image
|
||||
# Capturing the *LOG output*
|
||||
# *Validation* of the scenario behavior
|
||||
# *Powering-off* the test machine
|
||||
|
||||
Each of those steps depends on various parameters such as the
|
||||
used kernel, the hardware platform used to run the scenario, the
|
||||
way the test hardware is connected to the test infrastructure
|
||||
(e.g., UART, AMT, JTAG, network), the way the test hardware is powered or
|
||||
reseted, or the way of how the scenario is loaded into the test hardware.
|
||||
Naturally, to accommodate the growing variety of combinations of those
|
||||
parameters, the complexity of the run tool increased over time.
|
||||
This growth of complexity prompted us to eventually turn the run tool into a
|
||||
highly modular and extensible tool kit.
|
||||
|
||||
Originally, the run tool consisted of built-in rules that could be
|
||||
extended and tweaked by a kernel-specific supplement called run environment.
|
||||
The execution of a run script used to depend on the policies built into
|
||||
the run tool, the used run environment, and optional configuration
|
||||
parameters (run opts).
|
||||
|
||||
The new run tool kit replaces most of the formerly built-in policies by the
|
||||
ability to select and configure different modules for the various steps.
|
||||
The selection and configuration of the modules is expressed in the run-tool
|
||||
configuration. There exist the following types of modules:
|
||||
|
||||
:boot-dir modules:
|
||||
These modules contain the functionality to populate the boot directory
|
||||
and are specific to each kernel. It is mandatory to always include the
|
||||
module corresponding to the used kernel.
|
||||
|
||||
_(the available modules are: linux, hw, okl4, fiasco, pistachio, nova,_
|
||||
_codezero, foc)_
|
||||
|
||||
:image modules:
|
||||
These modules are used to wrap up all components used by the run script
|
||||
in a specific format and thereby prepare them for execution.
|
||||
Depending on the used kernel, different formats can be used. With these
|
||||
modules, the creation of ISO and disk images is also handled.
|
||||
|
||||
_(the available modules are: uboot, disk, iso)_
|
||||
|
||||
:load modules:
|
||||
These modules handle the way the components are transfered to the
|
||||
target system. Depending on the used kernel there are various options
|
||||
to pass on the components. For example, loading from TFTP or via JTAG is handled
|
||||
by the modules of this category.
|
||||
|
||||
_(the available modules are: tftp, jtag, fastboot)_
|
||||
|
||||
:log modules:
|
||||
These modules handle how the output of a currently executed run script
|
||||
is captured.
|
||||
|
||||
_(the available modules are: qemu, linux, serial, amt)_
|
||||
|
||||
:power_on modules:
|
||||
These modules are used for bringing the target system into a defined
|
||||
state, e.g., by starting or rebooting the system.
|
||||
|
||||
_(the available modules are: qemu, linux, softreset, powerplug, amt)_
|
||||
|
||||
:power_off modules:
|
||||
These modules are used for turning the target system off after the
|
||||
execution of a run script.
|
||||
|
||||
_(the available modules are: powerplug)_
|
||||
|
||||
When executing a run script, only one module of each category must be used.
|
||||
|
||||
Each module has the form of a script snippet located under the
|
||||
_tool/run/<step>/_
|
||||
directory where _<step>_ is a subdirectory named after the module type.
|
||||
Further instructions about the use of each module (e.g., additional
|
||||
configuration arguments) can be found in the form of comments inside the
|
||||
respective script snippets.
|
||||
Thanks to this modular structure,
|
||||
the extension of the tool kit comes down to adding a file at the corresponding
|
||||
module-type subdirectory. This way, custom work flows (such as tunneling JTAG
|
||||
over SSH) can be accommodated fairly easily.
|
||||
|
||||
|
||||
Usage examples
|
||||
==============
|
||||
|
||||
To execute a run script, a combination of modules may be used. The combination
|
||||
is controlled via the RUN_OPT variable used by the build framework. Here are a
|
||||
few common exemplary combinations:
|
||||
|
||||
Executing NOVA in Qemu:
|
||||
|
||||
!RUN_OPT = --include boot_dir/nova \
|
||||
! --include power_on/qemu --include log/qemu --include image/iso
|
||||
|
||||
Executing NOVA on a real x86 machine using AMT for resetting the target system
|
||||
and for capturing the serial output while loading the files via TFTP:
|
||||
|
||||
!RUN_OPT = --include boot_dir/nova \
|
||||
! --include power_on/amt --power-on-amt-host 10.23.42.13 \
|
||||
! --power-on-amt-password 'foo!' \
|
||||
! --include load/tftp --load-tftp-base-dir /var/lib/tftpboot \
|
||||
! --load-tftp-offset-dir /x86 \
|
||||
! --include log/amt --log-amt-host 10.23.42.13 \
|
||||
! --log-amt-password 'foo!'
|
||||
|
||||
Executing Fiasco.OC on a real x86 machine using AMT for resetting, USB serial
|
||||
for output while loading the files via TFTP:
|
||||
|
||||
!RUN_OPT = --include boot_dir/foc \
|
||||
! --include power_on/amt --amt-host 10.23.42.13 --amt-password 'foo!' \
|
||||
! --include load/tftp --tftp-base-dir /var/lib/tftpboot \
|
||||
! --tftp-offset-dir /x86 \
|
||||
! --include log/serial --log-serial-cmd 'picocom -b 115200 /dev/ttyUSB0'
|
||||
|
||||
Executing base-hw on a Raspberry Pi using powerplug to reset the hardware,
|
||||
JTAG to load the image and USB serial to capture the output:
|
||||
|
||||
!RUN_OPT = --include boot_dir/hw \
|
||||
! --include power_on/powerplug --power-on-powerplug-ip 10.23.42.5 \
|
||||
! --power-on-powerplug-user admin \
|
||||
! --power-on-powerplug-password secret \
|
||||
! --power-on-powerplug-port 1
|
||||
! --include power_off/powerplug --power-off-powerplug-ip 10.23.42.5 \
|
||||
! --power-off-powerplug-user admin \
|
||||
! --power-off-powerplug-password secret \
|
||||
! --power-off-powerplug-port 1
|
||||
! --include load/jtag \
|
||||
! --load-jtag-debugger /usr/share/openocd/scripts/interface/flyswatter2.cfg \
|
||||
! --load-jtag-board /usr/share/openocd/scripts/interface/raspberrypi.cfg \
|
||||
! --include log/serial --log-serial-cmd 'picocom -b 115200 /dev/ttyUSB0'
|
||||
|
||||
After the run script was executed successfully, the run tool will print the
|
||||
string 'Run script execution successful.". This message can be used to check
|
||||
for the successful completion of the run script when doing automated testing.
|
||||
|
||||
|
||||
Meaningful default behaviour
|
||||
============================
|
||||
|
||||
To maintain the ease of use of creating and using a build directory, the
|
||||
'create_builddir' tool equips a freshly created build directory with a meaningful
|
||||
default configuration that depends on the selected platform. For example, if
|
||||
creating a build directory for the Linux base platform, RUN_OPT
|
||||
is initially defined as
|
||||
|
||||
! RUN_OPT = --include boot_dir/linux \
|
||||
! --include power_on/linux --include log/linux
|
||||
|
||||
|
||||
Low-level OS infrastructure
|
||||
###########################
|
||||
|
||||
Improved management of physical memory
|
||||
======================================
|
||||
|
||||
On machines with a lot of memory, there exist constraints with regard to
|
||||
the physical address ranges of memory:
|
||||
|
||||
* On platforms with a non-uniform memory architecture, subsystems should
|
||||
preferably use memory that is local to the CPU cores the subsystem is using.
|
||||
Otherwise the performance is impeded by costly memory accesses to
|
||||
the memory of remote computing nodes.
|
||||
|
||||
* Unless an IOMMU is used, device drivers program physical addresses
|
||||
into device registers to perform DMA operations. Legacy devices such as
|
||||
USB UHCI controllers expect a 32-bit address. Consequently, the memory
|
||||
used as DMA buffers for those devices must not be allocated above 4 GiB.
|
||||
|
||||
* When using an IOMMU on NOVA, Genode represents the address space
|
||||
accessible by devices (by the means of DMA) using a so-called device PD
|
||||
([https://genode.org/documentation/release-notes/13.02#DMA_protection_via_IOMMU]).
|
||||
DMA transactions originating from PCI devices are subjected to the virtual
|
||||
address space of the device PD.
|
||||
All DMA buffers are identity-mapped with their physical addresses within
|
||||
the device PD. On 32-bit systems with more than 3 GiB of memory, this
|
||||
creates a problem. Because the device PD is a regular user-level component, the
|
||||
upper 1 GiB of its virtual address space is preserved for the kernel. Since
|
||||
no user-level memory objects can be attached to this
|
||||
area, the physical address range to be used for DMA buffers is limited
|
||||
to the lower 3 GiB.
|
||||
|
||||
Up to now, Genode components had no way to influence the allocation of
|
||||
memory with respect to physical address ranges. To solve the problems outlined
|
||||
above, we extended core's RAM services to take allocation constraints
|
||||
as session arguments when a RAM session is created. All dataspaces created
|
||||
from such a session are subjected to the specified constraints. In particular,
|
||||
this change enables the AHCI/PCI driver to allocate DMA buffers at suitable
|
||||
physical address ranges.
|
||||
|
||||
This innocent looking feature to constrain RAM allocations raises a problem
|
||||
though: If any component is able to constrain RAM allocations in
|
||||
arbitrary ways, it would become able to scan the physical address space for
|
||||
allocated memory by successively opening RAM sessions with the constraints set
|
||||
to an individual page and observe whether an allocation succeeds or not. Two
|
||||
conspiring components could use this information to construct a covert storage
|
||||
channel.
|
||||
|
||||
To prevent such an abuse, the init component filters out allocations
|
||||
constrains from RAM-session requests unless explicitly permitted. The
|
||||
permission is granted by supplementing the RAM resource assignment of
|
||||
a component with a new 'constrain_phys' attribute. For example:
|
||||
|
||||
! <resource name="RAM" quantum="3M" constrain_phys="yes"/>
|
||||
|
||||
|
||||
Init component
|
||||
==============
|
||||
|
||||
Most of Genode's example scenarios in the form of run scripts support
|
||||
different platforms. However, as the platform details vary, the run scripts
|
||||
have to tweak the configuration of the init component according to the
|
||||
features of the platform.
|
||||
For example, when declaring an explicit route to a framebuffer driver named
|
||||
"fb_drv", the run script won't work on Linux because on this platform, the
|
||||
framebuffer driver is called "fb_sdl".
|
||||
Another example is the role of the USB driver. Depending on the platform, the
|
||||
USB driver is an input driver, a block driver, a networking driver, or a
|
||||
combination of those.
|
||||
Consequently, run scripts with support
|
||||
for a great variety of platforms tend to become convoluted with
|
||||
platform-specific conditionals.
|
||||
|
||||
To counter this problem, we enhanced init to support aliases for component
|
||||
names. By defining the following aliases in the init configuration
|
||||
! <alias name="nic_drv" child="usb_drv"/>
|
||||
! <alias name="input_drv" child="usb_drv"/>
|
||||
! <alias name="block_drv" child="usb_drv"/>
|
||||
the USB driver becomes reachable for session requests routed to either "usb_drv",
|
||||
"nic_drv", "input_drv", and "block_drv". Consequently, the routing
|
||||
configuration of components that use either of those drivers does no longer
|
||||
depend on any platform-intrinsic knowledge.
|
||||
|
||||
|
||||
RTC session interface
|
||||
=====================
|
||||
|
||||
Until now, the RTC session interface used an integer to return the current
|
||||
time. Although this is preferable when performing time-related
|
||||
calculations, a structured representation is more convenient to use, i.e., if
|
||||
the whole purpose is showing the current time. This interface change is only
|
||||
visible to components that use the RTC session directly.
|
||||
|
||||
Since the current OS API of Genode lacks time-related functions, most users
|
||||
end up using the libc, which already converts the structured time stamp
|
||||
internally, or provide their own time related functions.
|
||||
|
||||
|
||||
Update of rump-kernel-based file systems
|
||||
========================================
|
||||
|
||||
We updated the rump-kernel support to a newer rump-kernel version (as of mid of
|
||||
January 2015). This way, Genode is able to benefit from upstream stability
|
||||
improvements related to the memory management. Furthermore, we revised the
|
||||
Genode backend to allow the rump_fs server to cope well with a large amount of
|
||||
memory assigned to it. The latter is useful to utilize the block cache of the
|
||||
NetBSD kernel.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
As a stepping stone in the
|
||||
[https://github.com/genodelabs/genode/issues/1399 - forthcoming community effort]
|
||||
to bring the Nix package manager to Genode, ports of libbz2 and sqlite have
|
||||
been added to the _repos/libports/_ repository.
|
||||
|
||||
|
||||
Runtime environments
|
||||
####################
|
||||
|
||||
VirtualBox on NOVA
|
||||
==================
|
||||
|
||||
Whereas our previous efforts to run VirtualBox on Genode/NOVA were mostly
|
||||
concerned with enabling principal functionality and with the addition of
|
||||
features, we took the release cycle of Genode 15.02 as a chance to focus
|
||||
on performance and stability improvements.
|
||||
|
||||
|
||||
:Performance:
|
||||
|
||||
Our goal with VirtualBox on NOVA is to achieve a user experience
|
||||
comparable to running VirtualBox on Linux. Our initial port of VirtualBox used
|
||||
to cut a lot of corners with regards to performance and timing accuracy
|
||||
because we had to concentrate on more fundamental issues of the porting
|
||||
work first. Now, with the feature set settled, it was time to revisit
|
||||
and solidify our interim solutions.
|
||||
|
||||
The first category of performance improvements is the handling of timing,
|
||||
and virtual guest time in particular. In our original version,
|
||||
we could observe a substantial drift of the guest time compared to the host time.
|
||||
The drift is not merely inconvenient but may even irritate the guest OS
|
||||
because it violates its assumptions about the behaviour of certain virtual devices.
|
||||
The drift was caused by basing the timing on a simple jiffies counter
|
||||
that was incremented by a thread after sleeping for a fixed period. Even
|
||||
though the thread almost never executes, there is still a chance that it gets
|
||||
preempted by the kernel and resumed only after the time slices of
|
||||
concurrently running threads have elapsed. This can take tens of milliseconds.
|
||||
During this time, the jiffies counter remains unchanged. We could
|
||||
significantly reduce the drift by basing the timing on absolute time values
|
||||
requested from the timer driver. Depending on the used guest OS, however,
|
||||
there is still a residual inaccuracy left, which is subject to ongoing
|
||||
investigations.
|
||||
|
||||
The second type of improvements is related to the handling of virtual
|
||||
interrupts. In its original habitat, VirtualBox relies on so-called
|
||||
external-interrupt virtualization events. If a host interrupt occurs while the
|
||||
virtual machine is active, the virtualization event is forwarded by the
|
||||
VirtualBox hypervisor to the virtual machine monitor (VMM).
|
||||
On NOVA, however, the kernel does not propagate this
|
||||
condition to the user-level VMM because the occurrence of host interrupts should
|
||||
be of no matter to the VMM. In the event of a host interrupt, NOVA takes
|
||||
a normal scheduling decision (eventually activating the user-level device driver
|
||||
the interrupt belongs to) and leaves the virtual CPU (vCPU) in a runnable
|
||||
state - to be rescheduled later. Once the interrupt is handled, the vCPU gets
|
||||
resumed. The VMM remains out of the loop. Because the update of the VirtualBox
|
||||
device models ultimately relies on the delivery of external-interrupt
|
||||
virtualization events, the lack of this kind of event introduced huge delays
|
||||
with respect to the update of device models and the injection of virtual
|
||||
interrupts. We solved this problem by exploiting a VirtualBox-internal
|
||||
mechanism called POKE. By setting the so-called POKE flag, an I/O thread is
|
||||
able to express its wish to force the virtual machine into the VMM. We only
|
||||
needed to find the right spots to set the POKE flag.
|
||||
|
||||
Another performance-related optimization is the caching of RTC time
|
||||
information inside VirtualBox. The original version of the gettimeofday
|
||||
function used by VirtualBox contacted the RTC server for obtaining the
|
||||
wall-clock time on each call. After the update to VirtualBox 4.3, the rate of those
|
||||
calls increased significantly. To reduce the costs of these calls, our
|
||||
new version of gettimeofday combines infrequent calls to the RTC driver
|
||||
with a component-local time source based on the jiffies mechanism mentioned above.
|
||||
|
||||
With these optimizations in place,
|
||||
simple benchmarks like measuring the boot time of Window 7 or the time of
|
||||
compiling Genode within a Debian VM suggest that our version of VirtualBox
|
||||
has reached a performance that is roughly on par with the Linux version.
|
||||
|
||||
|
||||
:Stability:
|
||||
|
||||
Since the upgrade to VirtualBox 4.3.16 in release 14.11, we fixed several
|
||||
regression issues caused by the upgrade. Beside that, we completed the
|
||||
support to route serial output of guests to Genode, lifted the restriction
|
||||
to use just one fixed VESA mode, and enabled support for 32-bit Windows 8
|
||||
guests on 64-bit Genode/NOVA. The 64-bit host restriction stems from
|
||||
the fact that Windows 8 requires support for the non-executable bit (NX)
|
||||
feature of page tables. The 32-bit version of the NOVA kernel does not leverage
|
||||
the physical address extension (PAE) feature, which is a pre-requisite for
|
||||
using NX on 32-bit.
|
||||
|
||||
In the course of the adaptation, our port of VirtualBox now evaluates the
|
||||
PAE and HardwareVirtExUX XML tags of .vbox files:
|
||||
|
||||
!<VirtualBox xmlns=...>
|
||||
! <Machine uuid=...>
|
||||
! <Hardware ..>
|
||||
! <CPU ...>
|
||||
! <HardwareVirtExUX enabled="true"/>
|
||||
! <PAE enabled="true"/>
|
||||
! ...
|
||||
|
||||
The PAE tag specifies whether to report PAE capabilities to the guest
|
||||
or not. The HardwareVirtExUx tag is used by our port to decide whether to stay
|
||||
for non-paged x86 modes in Virtualbox's recompiler (REM) or not. Until now, we used REM
|
||||
to emulate execution when the guest was running in real mode and protected mode
|
||||
with paging disabled. However, newer Intel machines support the unrestricted guest
|
||||
feature, which makes the usage of REM in non-paged modes not strictly
|
||||
necessary anymore. Setting the HardwareVirtExUx tag to false accommodates
|
||||
older machines with no support for the unrestricted-guest feature.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
iPXE-based network drivers
|
||||
==========================
|
||||
|
||||
We enabled and tested the driver with Intel I218-LM and I218-V PCI devices.
|
||||
|
||||
|
||||
Intel wireless stack
|
||||
====================
|
||||
|
||||
In this release, several small issues regarding the wireless stack are fixed.
|
||||
From now on, the driver only probes devices on the PCI bus that correspond to
|
||||
the PCI_CLASS_NETWORK_OTHER device class. Prior to that, the driver probed all
|
||||
devices attached to the bus resulting in problems with other devices, e.g.
|
||||
the GPU, when accessing their extended PCI config space.
|
||||
Since the driver uses cooperative scheduling internally, it must never block
|
||||
or, in case it blocks, must schedule another task. Various sleep functions
|
||||
lacked this scheduling call and are now fixed. Furthermore, a bug in the timer
|
||||
implementation has been corrected, which caused the scheduling of wrong timeouts.
|
||||
In addition to these fixes, patches for enabling the support for
|
||||
Intel 7260 cards were incorporated.
|
||||
|
||||
Up to now, the configuration of the wireless driver was rather inconvenient because
|
||||
it did not export any information to the system. The driver now creates two
|
||||
distinct reports to communicate its state and information about the wireless
|
||||
infrastructure to other components. The first one is a list of all available
|
||||
access points. The following exemplary report shows its structure:
|
||||
|
||||
!<wlan_accesspoints>
|
||||
! <accesspoint ssid="skynet" bssid="00:01:02:03:04:05" quality="40"/>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70" protection="WPA-PSK"/>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:07" quality="10" protection="WPA-PSK"/>
|
||||
!</wlan_accesspoints>
|
||||
|
||||
Each '<accesspoint>' node has attributes that contain the SSID and the BSSID
|
||||
of the access point as well as the link quality (signal strength). These
|
||||
attributes are mandatory. If the network is protected, the node will also
|
||||
have an attribute describing the type of protection in addition.
|
||||
|
||||
The second report provides information about the state of the connection
|
||||
with the currently associated access point:
|
||||
|
||||
!<wlan_state>
|
||||
! <accesspoint ssid="foobar" bssid="01:02:03:04:05:06" quality="70"
|
||||
! protection="WPA-PSK" state="connected"/>
|
||||
!</wlan_state>
|
||||
|
||||
Valid state values are 'connected', 'disconnected', 'connecting' and
|
||||
'disconnecting'.
|
||||
|
||||
The driver obtains its configuration via a ROM module. This ROM
|
||||
module contains the selected access point and can be updated during runtime.
|
||||
To connect to an access point, a configuration like the following is used:
|
||||
|
||||
!<selected_accesspoint ssid="foobar" bssid="01:02:03:04:05:06"
|
||||
! protection="WPA-PSK" psk="foobar123!"/>
|
||||
|
||||
To disconnect from an access point, an empty configuration can be set:
|
||||
|
||||
!<selected_accesspoint/>
|
||||
|
||||
For now, the prevalent WPA/WPA2 protection using a pre-shared key is supported.
|
||||
|
||||
|
||||
Improved UART driver for Exynos5
|
||||
================================
|
||||
|
||||
The UART driver for the Exynos5 SoC has been enhanced by enabling the RX
|
||||
channel. This improvement was motivated by automated tests, where a run script
|
||||
needs to interact with some component via a terminal connection.
|
||||
|
||||
|
||||
Touchscreen support
|
||||
===================
|
||||
|
||||
We enabled support of Wacom USB touchscreen devices via dde_linux - a port of
|
||||
Linux USB driver to Genode. In order to make touchscreen coordinates
|
||||
usable by Genode's input services, they must be calibrated
|
||||
to screen-absolute coordinates. The screen resolution is not determined
|
||||
automatically by the USB driver. It can, however, be configured as a sub
|
||||
node of the '<hid>' XML tag of the USB driver's configuration:
|
||||
|
||||
!<start name="usb_drv">
|
||||
! ...
|
||||
! <config uhci=... ohci=... xhci=...>
|
||||
! <hid>
|
||||
! <screen width="1024" height="768"/>
|
||||
! </hid>
|
||||
! ...
|
||||
|
||||
|
||||
USB session interface
|
||||
=====================
|
||||
|
||||
We enhanced our USB driver with the support of remote USB sessions. This
|
||||
feature makes it possible to implement USB-device drivers outside the USB
|
||||
server using a native Genode API. The new USB session can be found under
|
||||
_repos/os/include/usb_session_ and can be used to communicate with the USB
|
||||
server, which merely acts as a host controller and HUB driver in this scenario.
|
||||
Under _repos/os/include/usb_, there are a number of convenience
|
||||
and wrapper functions that operate directly on top of a USB session. These
|
||||
functions are meant to ease the task of USB-device-driver programming by hiding
|
||||
most of the USB session management, like packet-stream handling.
|
||||
|
||||
We also added a USB terminal server, which exposes a Genode terminal session to
|
||||
its clients and drives the popular PL2303 USB to UART adapters using the new
|
||||
USB-session interface.
|
||||
A practical use case for this component is the transmission of logging data on
|
||||
systems where neither UART, AMT, nor JTAG are available. A run script
|
||||
showcasing this feature can be found at _repos/dde_linux/run/usb_terminal.run_.
|
||||
|
||||
|
||||
RTC proxy driver for Linux
|
||||
==========================
|
||||
|
||||
There are a handful of run scripts that depend on the RTC service. So far,
|
||||
it was not possible to run these tests on Linux due to the lack of an RTC
|
||||
driver on this platform. To address this problem, we created a proxy driver
|
||||
that uses the time() system call to provide a
|
||||
reasonable base period on Linux.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Support for the USB-Armory board
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
With [https://www.crowdsupply.com/inverse-path/usb-armory - USB Armory],
|
||||
there is an intriguing hardware platform for Genode on the horizon.
|
||||
In short, USB Armory is a computer in the form factor of a USB
|
||||
stick. It is meant for security applications such as VPNs,
|
||||
authentication tokens, and encrypted storage. It is based on the
|
||||
FreeScale i.MX53 SoC, which is well supported by Genode, i.e.,
|
||||
Genode can be used as secure-world OS besides Linux running in the
|
||||
normal world.
|
||||
Apart from introducing a novel form factor, this project is
|
||||
interesting because it strives to be an 100% open platform, which
|
||||
includes hardware, software, and firmware. This motivated us to
|
||||
bring Genode to this platform.
|
||||
|
||||
The underlying idea is to facilitate
|
||||
[https://genode.org/documentation/articles/trustzone - ARM TrustZone] to
|
||||
use Genode as a companion to a Linux-based OS on the platform.
|
||||
Whereas Linux would run in the normal world of TrustZone, Genode runs
|
||||
in the secure world. With Linux, the normal world will control the
|
||||
communication over USB and provide a familiar environment to implement
|
||||
USB-Armory applications. However, security-critical functions and data like
|
||||
cryptographic keys will reside exclusively in the secure world. Even in
|
||||
the event that Linux gets compromised, the credentials of the user
|
||||
will stay protected.
|
||||
|
||||
The support of the USB Armory platform was added in two steps:
|
||||
First, we enabled our base-hw kernel to run as TrustZone monitor with
|
||||
Genode on the "secure side". Since the USB Armory is based on the
|
||||
FreeScale i.MX53 SoC, which Genode already supported, this step went
|
||||
relatively straight-forward.
|
||||
|
||||
Second, we enabled a recent version of the Linux kernel (3.18) to run in the
|
||||
normal world. The normal world is supervised by a user-level Genode component
|
||||
called tz_vmm (TrustZone Virtual Machine Monitor). The tz_vmm is, among
|
||||
others, responsible for providing startup and hardware information to the
|
||||
non-secure guest. The Linux kernel version we used previously as TrustZone
|
||||
guest on i.MX53 boards expected this information to be communicated via
|
||||
so-called ATAGs. The new version, however, expects this to be done via a
|
||||
device tree blob. As a consequence, the tz_vmm had to be adapted to properly
|
||||
load this blob into the non-secure RAM. The original USB-Armory device tree
|
||||
was modified to blind out the RAM regions that get protected by the TrustZone
|
||||
hardware. This way, Linux won't attempt to access them. Furthermore,
|
||||
to keep basic user interaction simple, our device tree tells Linux to use the
|
||||
same non-secure UART as Genode for console I/O.
|
||||
|
||||
The kernel itself received some modifications, for two reasons. First,
|
||||
we don't want Linux to rely on resources that are protected to keep
|
||||
the secure world secure. This is why the driver for the interrupt controller
|
||||
that originally made use of the TrustZone interrupt configuration, had to be
|
||||
adapted. Second, to prevent Linux from disturbing Genode activities, we
|
||||
disabled most of the dynamic clock and power management as it may sporadically
|
||||
gear down or even disable hardware that Genode relies on. Furthermore, we
|
||||
disabled the Linux drivers for I2C interfaces and the GPIO configuration as
|
||||
these are reserved for Genode.
|
||||
|
||||
|
||||
IPC helping
|
||||
~~~~~~~~~~~
|
||||
|
||||
In traditional L4 microkernels, scheduling parameters (like time-slice
|
||||
length and priority) used to be bound to threads. Usually, those parameters
|
||||
are defined at thread creation time. The initial version
|
||||
of base-hw followed this traditional approach. However, it has a few problems:
|
||||
|
||||
* For most threads, the proper *choice of scheduling parameters* is very
|
||||
difficult if not impossible. For example, the CPU-time demands of a
|
||||
server thread may depend on the usage patterns of its clients. Most
|
||||
theoretical work in the domain of scheduling presumes the knowledge of
|
||||
job lengths in advance of computing a schedule. But in practice and in
|
||||
particular in general-purpose computing, job lengths are hardly known a priori.
|
||||
As a consequence, in most scenarios, scheduling parameters are
|
||||
set to default values.
|
||||
|
||||
* With each thread being represented as an independent schedulable entity,
|
||||
the kernel has to take a scheduling decision each time a thread performs an
|
||||
IPC call because the calling thread gets blocked and the called thread
|
||||
may get unblocked. In a microkernel-based system, those events occur at a
|
||||
much higher rate than the duration of typical time slices, which puts the
|
||||
scheduler in a *performance-critical* position.
|
||||
|
||||
* Regarding IPC calls, a synchronous flow of control along IPC call chains is
|
||||
desired. Ideally, an IPC call should have the same characteristics as
|
||||
a function call with respect to scheduling. When a client thread performs an
|
||||
IPC call, it expects the server to immediately become active to
|
||||
handle the request. But if the kernel treats each thread independently,
|
||||
it may pick any other thread and thereby introduce *high latencies* into
|
||||
IPC operations.
|
||||
|
||||
To counter those problems, the NOVA microhypervisor introduced a new approach
|
||||
that decouples scheduling parameters from threads. Instead of selecting
|
||||
threads for execution, the scheduler selects so-called scheduling contexts.
|
||||
For a selected scheduling context, the kernel dynamically determines a
|
||||
thread to execute by taking IPC relationships into account. When a thread
|
||||
performs an IPC, the thread's scheduling context will be used to execute
|
||||
the called server. In principle, a server does not need CPU time on its own
|
||||
but always works with CPU resources provided by clients.
|
||||
|
||||
The new version of the base-hw kernel adapts NOVA's approach with slight
|
||||
modifications. Each thread owns exactly one scheduling context for its entire
|
||||
lifetime. However, by the means of "helping" during an IPC call, the caller
|
||||
lends its scheduling context to the callee. Even if the callee is still busy
|
||||
and cannot handle the IPC request right away, the caller helps because it
|
||||
wants the callee to become available for its request as soon as
|
||||
possible. Consequently, a thread has potentially many scheduling contexts at
|
||||
its disposal, its own scheduling context plus all scheduling contexts
|
||||
provisioned by helpers. This works transitively.
|
||||
|
||||
|
||||
Purged outdated platforms
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We removed the support for two stale platforms that remained unused for
|
||||
more than a year, namely FreeScale i.MX31 and the TrustZone variant
|
||||
of the Coretile Versatile Express board.
|
||||
|
||||
|
||||
NOVA
|
||||
====
|
||||
|
||||
On Genode/NOVA, we used to employ one pager thread in core for each thread
|
||||
in the system. We were forced to do so because not every page
|
||||
fault can be resolved immediately. In some situations, core asynchronously
|
||||
propagates the fault to an external component for the resolution.
|
||||
In the meantime, the
|
||||
pager thread leaves the page fault unanswered. Unfortunately, the kernel
|
||||
provides no mechanism to support this scenario besides just blocking the
|
||||
pager thread using a semaphore. This, in turn, means that the pager thread is not
|
||||
available for other page-fault requests. Ultimately, we had to setup a
|
||||
dedicated pager per thread.
|
||||
|
||||
This implementation has the downside of "wasting" memory for a lot of
|
||||
pager threads. Moreover, it becomes a denial-of-service vector as soon as more
|
||||
threads get created than core can accommodate. The number of threads is
|
||||
limited per address space - also for core - by the size of Genode's context
|
||||
area, which typically means 256 threads.
|
||||
|
||||
To avoid the downsides mentioned, we extended the NOVA IPC reply syscall to
|
||||
specify an optional semaphore capability. The NOVA kernel validates the
|
||||
capability and blocks the faulting thread in the semaphore. The faulted thread
|
||||
remains blocked even after the pager has replied to the fault message. But
|
||||
the pager immediately becomes available for other
|
||||
page-fault requests. With this change, it suffices to maintain only one pager
|
||||
thread per CPU for all client threads.
|
||||
|
||||
The benefits are manifold. First, the base-nova implementation converges more
|
||||
closely to other Genode base platforms. Second, core can not run out of threads
|
||||
anymore as the number of threads in core is fixed for a given setup. And the
|
||||
third benefit is that the helping mechanism of NOVA can be leveraged for
|
||||
concurrently faulting threads.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
Tools for convenient handling of port contrib directories
|
||||
=========================================================
|
||||
|
||||
We supplemented our tools for the ports mechanism with two convenient
|
||||
scripts:
|
||||
|
||||
:_tool/ports/shortcut_:
|
||||
|
||||
Creates a symbolic link from _contrib/<port-name>-<hash>_ to
|
||||
_contrib/<port-name>_. This is useful when working on the third-party
|
||||
code contained in the _contrib_ directory.
|
||||
|
||||
:_tool/ports/current_:
|
||||
|
||||
Prints the current contrib directory of a port. When switching
|
||||
branches back and forth, the hash of the used port might change.
|
||||
The script provides a shortcut to looking up the hash file for a
|
||||
specific port within the repositories and printing its content.
|
||||
|
||||
1216
doc/release_notes/15-05.txt
Normal file
1216
doc/release_notes/15-05.txt
Normal file
File diff suppressed because it is too large
Load Diff
791
doc/release_notes/15-08.txt
Normal file
791
doc/release_notes/15-08.txt
Normal file
@@ -0,0 +1,791 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 15.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The version 15.08 marks the beginning of Genode as day-to-day OS as one of the
|
||||
project's core developers switched to using Genode/NOVA on his machine,
|
||||
stressing the OS infrastructure we created over the course of the last seven
|
||||
years. Thanks to components like VirtualBox, the Noux runtime for GNU software,
|
||||
the Linux wireless stack and Rump-kernel-based file systems, the transition
|
||||
went actually much smoother than expected. So other members of the team plan
|
||||
to follow soon. Section [Genode as day-to-day operating system] gives an
|
||||
overview of the taken approach. Genode's use as general-purpose OS provided
|
||||
the incentive for most of the improvements featured by the current release,
|
||||
starting with the addressing of the long-standing kernel-memory management
|
||||
deficiencies of the NOVA kernel (Section [NOVA kernel-resource management]),
|
||||
over enhancements of Genode's tracing and file-system facilities, to vast
|
||||
improvements of the guest-host integration of VirtualBox when running on
|
||||
Genode.
|
||||
|
||||
The release is accompanied with a second line of work led by our friends
|
||||
at Codelabs: Enabling Genode to run on top of their Muen separation
|
||||
kernel as described in Section [Genode on top of the Muen Separation Kernel].
|
||||
Muen is a low-complexity kernel for the 64-bit x86 architecture that
|
||||
statically partitions the machine into multiple domains. In contrast to
|
||||
microkernels like the ones already supported by Genode, the assignment
|
||||
of physical resources (such as memory, CPU time, and devices) happens at
|
||||
system-integration time. Since an isolation kernel does not have to deal
|
||||
with dynamic resource management at runtime, it is less complex than
|
||||
a general-purpose microkernel. This makes it relatively easy to reason about
|
||||
its strong isolation properties, which, in turn, makes it attractive for
|
||||
high-assurance computing. With Genode being able to run within a Muen
|
||||
domain, the rich component infrastructure of Genode can be combined with
|
||||
the strong isolation guarantees of Muen.
|
||||
|
||||
|
||||
Genode on top of the Muen Separation Kernel
|
||||
###########################################
|
||||
|
||||
_This section was written by Adrian-Ken Rueegsegger and Reto Buerki who_
|
||||
_conducted the described line of work independent from Genode Labs._
|
||||
|
||||
After completing our x86_64 port of the Genode base-hw kernel, which was
|
||||
featured in the
|
||||
[https://genode.org/documentation/release-notes/15.05#Principal_support_for_the_64-bit_x86_architecture - previous release (15.05)],
|
||||
we immediately started working on our main goal: running a Genode system as
|
||||
guest on the Muen Separation Kernel (SK). This would enable the Muen platform
|
||||
to benefit from the rich ecosystem of Genode.
|
||||
|
||||
For those who have not read the 15.05 Genode release notes, [https://muen.sk - Muen]
|
||||
is an Open-Source microkernel, which uses the [https://spark-2014.org/ - SPARK]
|
||||
programming language to enable light-weight formal methods for high assurance.
|
||||
The 64-bit x86 kernel, currently consisting of a little over 5'000 LOC, makes
|
||||
extensive use of the latest Intel virtualization features and has been formally
|
||||
proven to contain no runtime errors at the source-code level.
|
||||
|
||||
The new 'hw_x86_64_muen' platform, as the name implies, extends the 'hw_x86_64'
|
||||
base-hw kernel by replacing the PIC and timer drivers with paravirtualized
|
||||
variants.
|
||||
|
||||
In contrast to other kernels supported by Genode, the architecture with Muen is
|
||||
different in the sense that the entire 'hw_x86_64_muen' Genode system runs as
|
||||
guest VM in VMX non-root mode on the SK. From the perspective of Muen, Genode
|
||||
is executed on top of the kernel like any other guest OS without special
|
||||
privileges.
|
||||
|
||||
[image muen_system_overview]
|
||||
Genode running on top of the Muen Separation Kernel alongside other subjects
|
||||
|
||||
This loose coupling of Muen and Genode base-hw enables the robust combination
|
||||
of a static, low-complexity SK with a feature-rich and extensive OS framework.
|
||||
The result is a flexible platform for the construction of component-based
|
||||
high-assurance systems.
|
||||
|
||||
People interested in giving the 'hw_x86_64_muen' platform a spin can find a
|
||||
small tutorial at _repos/base-hw/doc/x86_64_muen.txt_.
|
||||
|
||||
|
||||
NOVA kernel-resource management
|
||||
###############################
|
||||
|
||||
For several years, the NOVA kernel has served as Genode's primary base
|
||||
platform on x86. The main reasons for this choice are: the kernel provides -
|
||||
among the supported x86 kernels - the richest feature set like the support of
|
||||
IOMMUs, virtualization, and SMP. It also offers a clean design and a stable
|
||||
kernel interface. The available kernel-interface specification and the
|
||||
readable and modern source base are a pleasure to work with. Hence, Genode
|
||||
Labs is able to fully commit to the maintenance and further evolution of this
|
||||
kernel.
|
||||
|
||||
Nevertheless, since the beginning, the vanilla kernel lacks one essential
|
||||
feature to reliably host Genode as user-land, namely the proper management of
|
||||
the memory used by the kernel itself (in short kernel-memory management). In
|
||||
the past, we already extended the kernel to free up kernel resources when
|
||||
destroying kernel objects, e.g., protection domains and page-tables, threads,
|
||||
semaphores, and portals. Still, on Genode/NOVA, a component may trigger
|
||||
arbitrary kernel-memory consumption during RPC by delegating memory,
|
||||
capabilities, or by creating other components via Genode's core component. If
|
||||
the kernel memory gets depleted, the kernel panics with an "Out of memory"
|
||||
message and the entire Genode scenario stops.
|
||||
|
||||
In principal, the consumption of kernel memory can be deliberately provoked by
|
||||
a misbehaving (greedy) component. But also during the regular day-to-day usage
|
||||
of Genode, can such a situation occur when the system is used in a highly
|
||||
dynamic fashion. For example, compiling and linking source code within the
|
||||
noux environment constantly creates and destroys protection domains, threads,
|
||||
and memory mappings. Our nightly test of compiling Genode within noux triggers
|
||||
this condition every once in a while.
|
||||
|
||||
The main issue here is that the consumption of kernel memory is not accounted
|
||||
by Genode. The kernel interface does not support such a feature. Kernels like
|
||||
seL4 as well as Genode's custom base-hw kernel show how this problem can be
|
||||
solved.
|
||||
|
||||
To improve the current situation - where the overall kernel memory is a fixed
|
||||
amount - we extended NOVA in the following ways: First, the NOVA kernel
|
||||
accounts any kernel memory consumption per protection domain. Second, each
|
||||
process has a limited amount of kernel-memory quota it can use. Last, the
|
||||
kernel detects when the quota limit of a protection domain is reached.
|
||||
|
||||
If the third condition occurs, the kernel stops the offending thread and
|
||||
(optionally) notifies a handler thread. This so called out-of-memory (OOM)
|
||||
handler thread receives information about the current situation and may
|
||||
respond to it in the following ways:
|
||||
|
||||
* Stop the thread of the depleted protection domain, or
|
||||
* Transfer kernel-memory quota between protection domains (upgrading the limit
|
||||
if desired), or
|
||||
* Free up kernel memory if possible, e.g., revoke memory delegations, which
|
||||
can be re-created.
|
||||
|
||||
We implemented the steps above inside the NOVA kernel and extended Genode's
|
||||
core component to handle such OOM situations. All system calls beside the IPC
|
||||
call/reply may now return an error code upon depletion of the quota. Most of
|
||||
these system calls can solely be performed by core and are handled inside
|
||||
core's NOVA-specific platform code.
|
||||
|
||||
In the case of IPC call/reply operations, we desired to handle OOM cases
|
||||
transparently to Genode user-level components. Therefore, each thread in
|
||||
Genode/NOVA now gets constructed with an OOM IPC portal attached. This portal
|
||||
is served by the pager thread in core and is traversed on OOM occurrences
|
||||
during IPC operations. If a pager thread receives such an OOM IPC, it decodes
|
||||
the involved IPC sender and IPC receiver and locates the appropriate
|
||||
core-internal paging objects. The currently implemented out-of-memory policy
|
||||
tries to upgrade the quota. If this is not possible, an attempt to revoke
|
||||
memory mappings from the OOM-causing protection domain is made. This
|
||||
implicitly frees-up some kernel memory (e.g., mapping nodes). If none of the
|
||||
responses suffices, the handler stops the OOM-causing thread and writes a
|
||||
message to the system log.
|
||||
|
||||
The current policy implementation constitutes a rather rough heuristic, which
|
||||
may not suffice under all circumstances. In the future, we would like to
|
||||
specify a distinct policy per component, e.g. depending on prior known memory
|
||||
usage patterns. For example, some components follow well-known usage patterns
|
||||
and therefore a fixed upper quota limit can be specified. Other components are
|
||||
highly dynamic and desire quota upgrades on demand. There are many more
|
||||
combinations imaginable.
|
||||
|
||||
Our current plan is to collect more experience over the next months with this
|
||||
new kernel mechanism. Based on our observations, we may externalize such
|
||||
policy decisions and possibly make them configurable per component.
|
||||
|
||||
The current implementation however, already avoids the situation that the
|
||||
kernel goes out of service if a single component misbehaves
|
||||
kernel-memory-wise.
|
||||
|
||||
|
||||
Genode as day-to-day operating system
|
||||
#####################################
|
||||
|
||||
At the beginning of June, Genode reached the probably most symbolic milestone
|
||||
in the project's history: Norman - one of the core developers - replaced his
|
||||
Linux-based working environment with a Genode-based system. This system is
|
||||
composed of the following ingredients:
|
||||
|
||||
[image turmvilla_scenario]
|
||||
|
||||
The machine used is a Lenovo Thinkpad X201. We settled on this five-year-old
|
||||
machine for several reasons. First, it is a very solid platform with a nice
|
||||
form factor. Second, it features Intel's AMT (Active Management Technology),
|
||||
which is handy to obtain low-level system logs in the case something goes
|
||||
wrong. Third, refurbished machines of this type can be obtained for as little
|
||||
as 200 EUR. Finally, an older machine reinforces the need for good performance
|
||||
of the operating system. So it creates a natural incentive for Norman to find
|
||||
and address performance bottlenecks.
|
||||
|
||||
Our modified version of the NOVA microhypervisor is the used kernel.
|
||||
|
||||
The user interface is based on our custom GUI stack including the nitpicker
|
||||
GUI server as well as the window manager and its companion components
|
||||
(decorator, layouter, pointer) we introduced in
|
||||
[https://genode.org/documentation/release-notes/14.08#New_GUI_architecture - version 14.08].
|
||||
The display is driven by the VESA driver. User input is handled by the PS/2
|
||||
driver for handling the laptop keyboard and trackpoint, and the USB driver for
|
||||
handling an externally connected keyboard and mouse.
|
||||
|
||||
Network connectivity is provided by our port of the Intel Wireless stack that
|
||||
we introduced with the version
|
||||
[https://genode.org/documentation/release-notes/14.11#Intel_wireless_stack - 14.11].
|
||||
|
||||
Our custom AHCI driver provides access to the physical hard disk. File-system
|
||||
access is provided by our
|
||||
[https://genode.org/documentation/release-notes/14.02#NetBSD_file_systems_using_rump_kernels - Rump-kernel-based file-system server].
|
||||
|
||||
A simple Genode shell called CLI monitor allows the user to start and kill
|
||||
subsystems dynamically. Initially, the two most important subsystems are
|
||||
VirtualBox and Noux.
|
||||
|
||||
VirtualBox executes a GNU/Linux-based guest OS that we refer to as "rich OS".
|
||||
The rich OS serves as a migration path from GNU/Linux to Genode. It is used
|
||||
for all tasks that cannot be accomplished directly on Genode yet. At the
|
||||
beginning of the transition, the daily routine still very much depends on the
|
||||
rich OS. By moving more and more functionality over to the Genode world, we
|
||||
will eventually be able to make the rich OS obsolete step by step. Thanks to
|
||||
VirtualBox' excellent host-guest-integration features, the VirtualBox window
|
||||
can be dynamically resized and the guest mouse cursor integrates seamlessly
|
||||
with Genode's pointer. VirtualBox is directly connected to the wireless
|
||||
network driver. So common applications like Firefox can be used.
|
||||
|
||||
The noux runtime allows us to use command-line-based GNU software directly on
|
||||
Genode. Coreutils and Bash are used for managing files. Vim is used for
|
||||
editing files. Unlike the rich OS, the noux environment has access to the
|
||||
Genode partition of the hard disk. In particular, it can be used to update the
|
||||
Genode system. It has access to a number of pseudo files that contain status
|
||||
information of the underlying components, e.g., the list of wireless access
|
||||
points. Furthermore, it has limited access to the configuration interfaces of
|
||||
the base components. For example, it can point the wireless driver to the
|
||||
access point to use, or change the configuration of the nitpicker GUI server
|
||||
at runtime.
|
||||
|
||||
As a bridge between the rich OS and the Genode world, we combine VirtualBox'
|
||||
shared-folder mechanism with Genode's VFS infrastructure. The shared folder is
|
||||
represented by a dedicated instance of a RAM file system, which is mounted in
|
||||
both the VFS of VirtualBox and the VFS of noux.
|
||||
|
||||
As evidenced by Norman's use since June, the described system setup is
|
||||
sufficient to be productive. So other members of the Genode team plan to
|
||||
follow in his footsteps soon. At the same time, the continued use of the
|
||||
system from day to day revealed a number of shortcomings, performance
|
||||
limitations, and rough edges, which we eventually eliminated. It goes without
|
||||
saying that this is an ongoing effort. Eating our own dog food forces us to
|
||||
address the right issues to make the daily life more comfortable.
|
||||
|
||||
Feature-wise the switch to Genode motivated three developments, namely the
|
||||
enhancement of Genode's CLI monitor, the improvement of the window manager,
|
||||
and the creation of a CPU-load monitoring tool.
|
||||
|
||||
|
||||
Interactive management of subsystem configurations
|
||||
==================================================
|
||||
|
||||
The original version of CLI monitor obtained the configuration data of its
|
||||
subsystems at start time via the Genode::config mechanism. But for managing
|
||||
complex scenarios, the config node becomes very complex. Hence, it is
|
||||
preferable to have a distinct file for each subsystem configuration.
|
||||
|
||||
The new version of CLI monitor scans the directory '/subsystems' for files
|
||||
ending with ".subsystem". Each file has the same syntax as the formerly used
|
||||
subsystem nodes. This change has the welcome implication that subsystem
|
||||
configurations can be changed during the runtime of the CLI monitor, e.g., by
|
||||
using a concurrently running instance of noux with access to the _subsystems/_
|
||||
directory. This procedure has become an essential part of the daily work flow
|
||||
as it enables the interactive evolution of the Genode system.
|
||||
|
||||
|
||||
Window-management improvements
|
||||
==============================
|
||||
|
||||
To make the window manager more flexible while reducing its complexity at the
|
||||
same time, we removed the formerly built-in policy hosting the decorator and
|
||||
layout components as children of the window manager. Those components are no
|
||||
longer child components but siblings. The relationship of the components is
|
||||
now solely expressed by the configuration of their common parent, i.e., init.
|
||||
This change clears the way to dynamically replace those components during
|
||||
runtime (e.g., switching between different decorators).
|
||||
|
||||
To improve the usability of the windowed GUI, we enabled the layouter to
|
||||
raise windows on click and to let the keyboard focus follow the pointer.
|
||||
Furthermore, the window manager, the decorator, and the floating window
|
||||
layouter became able to propagate the usage of an alpha channel from the
|
||||
client application to the decorator. This way, the decorator can paint the
|
||||
decoration elements behind the affected windows, which would otherwise be
|
||||
skipped. Consequently, partially transparent windows can be properly displayed.
|
||||
|
||||
|
||||
CPU-load monitoring
|
||||
===================
|
||||
|
||||
During daily system use, we started to wish to know in detail where the CPU
|
||||
cycles are spent. For example, the access of a file by the rich OS involves
|
||||
several components, including the guest OS itself, VirtualBox, rump_fs (file
|
||||
system), part_blk (partition access), ahci_drv (SATA device access), core, and
|
||||
NOVA. Investigating performance issues requires a holistic view of all those
|
||||
components. For this reason, we enhanced our existing tracing infrastructure
|
||||
(Section [Enhanced tracing facilities]) to allow the creation of CPU-load
|
||||
monitoring tools. The first tool in this category is the graphical CPU-load
|
||||
monitor located at _gems/app/cpu_load_display/_, which displays a timeline of
|
||||
the CPU load where each thread is depicted with a different color. Thanks to
|
||||
this tool, we have become able to explore performance issues in an interactive
|
||||
way. In particular, it helped us to identify and resolve a long-standing
|
||||
inaccuracy problem in our low-level timer service.
|
||||
|
||||
|
||||
Base framework and low-level OS infrastructure
|
||||
##############################################
|
||||
|
||||
Improved audio support
|
||||
======================
|
||||
|
||||
In the previous release, we replaced our old audio driver with a new one that
|
||||
provided the same audio-out session interface. Complementing the audio-out
|
||||
session, we are now introducing a new audio-in session interface that can be
|
||||
used to record audio frames. It is modeled after the audio-out interface in
|
||||
the way how it handles the communication between the client and the server. It
|
||||
uses shared memory in the form of the Audio_in::Stream to transport the frames
|
||||
between the components. A server component captures frames and puts them into
|
||||
a packet queue, which is embedded in the Audio_in::Stream. The server
|
||||
allocates packets from this queue to store the recorded audio frames. If the
|
||||
queue is already full, the server will override already allocated packets and
|
||||
will notify the client by submitting an 'overrun' signal. The client has to
|
||||
cope with this situation, e.g., by consuming packets more frequently. A client
|
||||
can install a signal handler to respond to a progress signal, which is sent by
|
||||
the server when a new Audio_in::Packet has been submitted to the packet queue.
|
||||
For now, all audio-in server components only support one channel (left)
|
||||
although the audio-in session interface principally supports multiple
|
||||
channels.
|
||||
|
||||
The _dde_bsd_ audio_drv is the first and currently only audio driver component
|
||||
that was extended to provide the audio-in session. To express this fact, the
|
||||
driver was renamed from _audio_out_drv_ to _audio_drv_. In contrast to its
|
||||
playback functionality, which is enabled by default, recording has to be
|
||||
enabled explicitly by setting the configuration attribute 'recording' to
|
||||
'yes'. If the need arises, playback may be disabled by setting 'playback' to
|
||||
'no'. In addition, it is now possible to configure the driver by adjusting the
|
||||
mixer in the driver's configuration node. For the time being, the interface as
|
||||
employed by the original OpenBSD mixer utility is used.
|
||||
|
||||
The following snippet shows how to enable and configure recording on a
|
||||
Thinkpad X220 where the headset instead of the internal microphone is used as
|
||||
source:
|
||||
|
||||
! <start name="audio_drv">
|
||||
! <resource name="RAM" quantum="8M"/>
|
||||
! <provides>
|
||||
! <service name="Audio_out"/>
|
||||
! <service name="Audio_in"/>
|
||||
! </provides>
|
||||
! <config recording="yes">
|
||||
! <mixer field="outputs.master" value="255"/>
|
||||
! <mixer field="record.adc-0:1_source" value="sel2"/>
|
||||
! <mixer field="record.adc-0:1" value="255"/>
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
In addition to selecting the recording source, the playback as well as the
|
||||
recording volume are raised to the maximum. Information about all available
|
||||
mixers and settings in general may be obtained by specifying the 'verbose'
|
||||
attribute in the config node.
|
||||
|
||||
The enriched driver is accompanied by a simple monitor application, which
|
||||
directly plays back all recorded audio frames and shows how to use the
|
||||
audio-in session. It can be tested by executing the
|
||||
_repos/dde_bsd/run/audio_in.run_ run script.
|
||||
|
||||
There are also changes to the audio-out session itself. The length of a period
|
||||
was reduced from 2048 to 512 samples to accommodate for a lower latency when
|
||||
mixing audio-out packets. A method for invalidating all packets in the queue
|
||||
was also added.
|
||||
|
||||
|
||||
File-system infrastructure
|
||||
==========================
|
||||
|
||||
Unlike traditional operating systems that rely on a global name space for
|
||||
files, each Genode component has a distinct view on files. Many low-level
|
||||
components do not even have the notion of files. Whereas traditional operating
|
||||
systems rely on a virtual file system (VFS) implemented in the OS kernel,
|
||||
Genode's VFS has the form of a library that can optionally be linked to a
|
||||
component. The implementation of this library originated from the noux runtime
|
||||
introduced in version
|
||||
[https://genode.org/documentation/release-notes/11.02#Noux_-_an_execution_environment_for_the_GNU_userland - 11.02],
|
||||
and was later integrated into our C runtime in version
|
||||
[https://genode.org/documentation/release-notes/14.05#Per-process_virtual_file_systems - 14.05].
|
||||
With the current release, we take the VFS a step further by making it
|
||||
available to components without a C runtime. Thereby, low-complexity
|
||||
security-sensitive components such as CLI monitor become able to benefit from
|
||||
the powerful VFS infrastructure.
|
||||
|
||||
The VFS itself received a welcome improvement in the form of private RAM file
|
||||
systems. A need for process-local storage motivated a conversion of the
|
||||
existing ram_fs server component to an embeddable VFS file system. This
|
||||
addition to the set of VFS plugins enables components to use temporary file
|
||||
systems without relying on the resources of an external component.
|
||||
|
||||
|
||||
Unified networking components
|
||||
=============================
|
||||
|
||||
Having had a good experience with our Block::Driver implementation, which
|
||||
wraps the block-session interface and takes care of the packet-stream
|
||||
handling, thus easing the implementation of driver and other block components,
|
||||
we observed that this approach did not provide enough flexibility for
|
||||
NIC-session servers. For example, NIC servers are bi-directional and when a
|
||||
network packet arrives the server has to make sure that there are enough
|
||||
resources available to dispatch the network packet to the client. This has to
|
||||
be done because the server must never block, e.g., by waiting for allocations
|
||||
to succeed or for an empty spot in the packet queue of a client. Therefore,
|
||||
such a non-blocking NIC server needs to validate all preconditions for
|
||||
dispatching the packet in advance and, if they cannot be met, drop the network
|
||||
packet.
|
||||
|
||||
In order to implement this kind of behavior, NIC-session servers must have
|
||||
direct access to the actual NIC session. For this reason, we removed the
|
||||
Nic::Driver interface from Genode and added a Nic::Session_component that
|
||||
offers common basic packet-stream-signal dispatch functionality. Servers may
|
||||
now inherit from this component and implement their own policy.
|
||||
|
||||
We adjusted all servers that implement NIC sessions to the new interface
|
||||
(dde_ipxe, wifi, usb, nic_bridge, OpenVPN, ...), and thereby unified all
|
||||
networking components within Genode.
|
||||
|
||||
|
||||
Enhanced tracing facilities
|
||||
===========================
|
||||
|
||||
Recent Genode-based system scenarios like the one described in Section
|
||||
[Genode as day-to-day operating system] consist of dozens of components that
|
||||
interact with each other. For reasoning about the behaviour of such scenarios
|
||||
and identifying effective optimization vectors, tools for gathering a holistic
|
||||
view of the system are highly desired.
|
||||
|
||||
With the introduction of our light-weight
|
||||
[https://genode.org/documentation/release-notes/13.08#Light-weight_event_tracing - event-tracing facility]
|
||||
in version 13.08, we laid the foundation for such tools. The current release
|
||||
extends core's TRACE service with the ability to obtain statistics about CPU
|
||||
utilization. More specifically, it enables clients of core's TRACE service to
|
||||
obtain the execution times of trace subjects (i.e., threads). The execution
|
||||
time is delivered as part of the 'Subject_info' structure. In addition to the
|
||||
execution time, the structure delivers the information about the affinity of
|
||||
the subject with a physical CPU.
|
||||
|
||||
At the current stage, the feature is available solely on NOVA since this is
|
||||
our kernel of choice for using Genode as our day-to-day OS. On all other base
|
||||
platforms, the returned execution times are 0. To give a complete picture of
|
||||
the system's threads, the kernel's idle threads (one per CPU) are featured as
|
||||
trace subjects as well. Of course, idle threads cannot be traced but their
|
||||
corresponding trace subjects allow TRACE clients to obtain the idle time of
|
||||
each CPU.
|
||||
|
||||
By obtaining the trace-subject information in periodic intervals, a TRACE
|
||||
client is able to gather statistics about the CPU utilization attributed to
|
||||
the individual threads present (or no longer present) in the system. One
|
||||
instance of such a tool is the new trace-subject reporter located at
|
||||
_os/src/app/trace_subject_reporter_. It acts as a TRACE client, which delivers
|
||||
the gathered trace-subject information in the form of XML-formatted data to a
|
||||
report session. This information, in turn, can be consumed by a separate
|
||||
component that analyses the data. In contrast to the low-complexity
|
||||
trace-subject reporter, which requires access to the privileged TRACE services
|
||||
of core, the (potentially complex) analysing component does not require access
|
||||
to core's TRACE service. So it isn't as critical as the trace-subject monitor.
|
||||
The first representative of a consumer of trace-subject reports is the
|
||||
CPU-load display mentioned in Section [CPU-load monitoring] and depicted in
|
||||
Figure [nano3d].
|
||||
|
||||
In addition to the CPU-monitoring additions, the tracing facilities received
|
||||
minor refinements. Up to now, it was not possible to trace threads that use a
|
||||
CPU session other than the component's initial one. A specific example is
|
||||
VirtualBox, which employs several CPU sessions, one for each priority. This
|
||||
problem has been solved by associating the event logger of each thread with
|
||||
its actual CPU session. Consequently, the tracing mechanism has become able to
|
||||
trace VirtualBox, which is pivotal for our further optimizations.
|
||||
|
||||
|
||||
Low-complexity software rendering functions
|
||||
===========================================
|
||||
|
||||
Our ambition to use Genode as our day-to-day OS raises the need for custom
|
||||
graphical applications. Granted, it is principally possible to base such
|
||||
applications on Qt5, which is readily available to native Genode components.
|
||||
However, for certain applications like status displays, we prefer to avoid the
|
||||
dependency on an overly complex GUI tool kit. To accommodate such
|
||||
applications, Genode hosts a small collection of low-complexity graphics
|
||||
functions called painters. All of Genode's low-complexity graphical components
|
||||
such as nitpicker, launchpad, window decorator, or the terminal are based on
|
||||
this infrastructure.
|
||||
|
||||
With the current release, we extend the collection with two new painters
|
||||
located at _gems/include/polygon_gfx_. Both draw convex polygons with an
|
||||
arbitrary number of points. The shaded-polygon painter interpolates the color
|
||||
and alpha values whereas the textured-polygon painter applies a texture to the
|
||||
polygon. The painters are accompanied by simplistic 3D routines located at
|
||||
_gems/include/nano3d/_ and a corresponding example (_gems/run/nano3d.run_).
|
||||
|
||||
[image nano3d]
|
||||
|
||||
With the nano3d demo and our new CPU load display, the screenshot above shows
|
||||
two applications that make use of the new graphics operations.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Completing the transition to the new platform driver
|
||||
====================================================
|
||||
|
||||
Until now, the platform driver on x86-based machines was formed by the ACPI
|
||||
and PCI drivers. The ACPI driver originally executed the PCI driver as a slave
|
||||
(child) service. The ACPI driver parsed the ACPI tables and provided the
|
||||
relevant information as configuration during the PCI-driver startup. We
|
||||
changed this close coupling to the more modern and commonly used
|
||||
[https://genode.org/documentation/release-notes/14.02#New_session_interface_for_status_reporting - report_rom mechanism].
|
||||
|
||||
When the new ACPI driver finishes the ACPI table parsing, it provides the
|
||||
information via a report to any interested and registered components. The
|
||||
report contains among other the IRQ re-routing information. The PCI driver is
|
||||
a component, which - according to its session routing configuration - plays
|
||||
the role of a consumer of the ACPI report.
|
||||
|
||||
With this change of interaction of ACPI and PCI driver, the policy for devices
|
||||
must be configured solely at the PCI driver and not at the ACPI driver. The
|
||||
syntax, however, stayed the same as introduced with release 15.05.
|
||||
|
||||
Finally, the PCI driver 'pci_drv' got renamed to 'platform_drv' as already
|
||||
used on most ARM platforms. All files and session interfaces containing
|
||||
PCI/pci in the names were renamed to Platform/platform. The x86 platform
|
||||
interfaces moved to _repos/os/include/platform/x86/_ and the implementation of
|
||||
the platform driver to _repos/os/src/drivers/platform/x86/_.
|
||||
|
||||
An example x86 platform configuration snippet looks like this:
|
||||
|
||||
!<start name="acpi_drv" >
|
||||
! <resource .../>
|
||||
! <route>
|
||||
! ...
|
||||
! <service name="Report"> <child name="acpi_report_rom"/> </service>
|
||||
! </route>
|
||||
!</start>
|
||||
!
|
||||
!<start name="acpi_report_rom" >
|
||||
! <binary name="report_rom"/>
|
||||
! <resource .../>
|
||||
! <provides> <service name="ROM" /> <service name="Report" /> </provides>
|
||||
! <config>
|
||||
! <rom> <policy label="platform_drv -> acpi" report="acpi_drv -> acpi"/> </rom>
|
||||
! </config>
|
||||
! <route> ... </route>
|
||||
!</start>
|
||||
!
|
||||
!<start name="platform_drv" >
|
||||
! <resource name="RAM" quantum="3M" constrain_phys="yes"/>
|
||||
! <provides> <service name="Platform"/> </provides>
|
||||
! <route>
|
||||
! <service name="ROM">
|
||||
! <if-arg key="label" value="acpi"/> <child name="acpi_report_rom"/>
|
||||
! </service>
|
||||
! ...
|
||||
! </route>
|
||||
! <config>
|
||||
! <policy label="ps2_drv"> <device name="PS2"/> </policy>
|
||||
! <policy label="nic_drv"> <pci class="ETHERNET"/> </policy>
|
||||
! <policy label="fb_drv"> <pci class="VGA"/> </policy>
|
||||
! <policy label="wifi_drv"> <pci class="WIFI"/> </policy>
|
||||
! <policy label="usb_drv"> <pci class="USB"/> </policy>
|
||||
! <policy label="ahci_drv"> <pci class="AHCI"/> </policy>
|
||||
! <policy label="audio_drv"> <pci class="AUDIO"/> <pci class="HDAUDIO"/> </policy>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
In order to unify and simplify the writing of run scripts, we added the
|
||||
commonly used platform configuration to the file
|
||||
_repos/base/run/platform_drv.inc_. This file may be included by any test run
|
||||
script in order to setup a default platform driver configuration.
|
||||
|
||||
In addition, the snippet provides the following functions:
|
||||
'append_platform_drv_build_components', 'append_platform_drv_config' and
|
||||
'append_platform_drv_boot_modules'. The functions add necessary information to
|
||||
the 'build_components', 'config' and 'boot_modules' run variables. The
|
||||
_platform_drv.inc_ also contains the distinction between various ARM/x86
|
||||
platforms and includes the necessary pieces. Hence, run scripts are largely
|
||||
relieved from platform-specific peculiarities.
|
||||
|
||||
The body of an example run script looks like this:
|
||||
|
||||
! set build_components { ... }
|
||||
!
|
||||
! source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
! append_platform_drv_build_components
|
||||
!
|
||||
! build $build_components
|
||||
!
|
||||
! create_boot_directory
|
||||
!
|
||||
! set config { ... }
|
||||
!
|
||||
! append_platform_drv_config
|
||||
!
|
||||
! append config { ... }
|
||||
!
|
||||
! install_config $config
|
||||
!
|
||||
! append_platform_drv_boot_modules
|
||||
!
|
||||
! build_boot_image $boot_modules
|
||||
!
|
||||
! run_genode_until ...
|
||||
|
||||
|
||||
BCM57cxx network cards
|
||||
======================
|
||||
|
||||
During Hack'n Hike 2015, we had access to a server that featured a Broadcom
|
||||
network card. Therefore Guido Witmond performed the first steps to enable
|
||||
Broadcom's BCM 57cxx cards. With this preliminary work in place, we were
|
||||
quickly able to perform the additional steps required to add BCM 57cxx support
|
||||
to Genode.
|
||||
|
||||
|
||||
VESA driver refinements
|
||||
=======================
|
||||
|
||||
The VESA driver now reports the frame buffer's line width instead of the
|
||||
visible width to the client. This fixes a possible distortion if these widths
|
||||
differ, at the cost that content in the right-most area might be invisible in
|
||||
such cases.
|
||||
|
||||
|
||||
VirtualBox
|
||||
##########
|
||||
|
||||
Policy-based mouse pointer
|
||||
==========================
|
||||
|
||||
In the previous release, we implemented support for the transparent
|
||||
integration of the guest mouse pointer with nitpicker via the VirtualBox guest
|
||||
additions and the vbox_pointer component, which is capable of rendering
|
||||
guest-provided mouse-pointer shapes. Now, we extended vbox_pointer by a
|
||||
policy-based configuration that allows the selection of ROMs containing the
|
||||
actual mouse shape based on the nitpicker session label or domain. With this
|
||||
feature in place, it is possible to integrate several VirtualBox instances as
|
||||
well as dedicated pointer shapes for specific components. To see the improved
|
||||
vbox_pointer in action give _run/vbox_pointer_ a shot.
|
||||
|
||||
|
||||
Dynamic adaptation to screen size changes
|
||||
=========================================
|
||||
|
||||
VirtualBox now notifies the guest operating system about screen-size changes
|
||||
(for example if the user resizes a window, which shows the guest frame
|
||||
buffer). The VirtualBox guest additions can use this information to adapt the
|
||||
guest frame buffer to the new size.
|
||||
|
||||
|
||||
SMP support
|
||||
===========
|
||||
|
||||
Guest operating systems can now use multiple virtual CPUs, which are mapped to
|
||||
multiple host CPUs. The number of virtual CPUs can be configured in the
|
||||
'.vbox' file.
|
||||
|
||||
|
||||
Preliminary audio support
|
||||
=========================
|
||||
|
||||
At some point, the use of VirtualBox as a stop-gap solution for using Genode
|
||||
as everyday OS raises the need to handle audio. With this release, we address
|
||||
this matter by enabling preliminary audio support in our VirtualBox port. A
|
||||
back end that uses the audio-out and audio-in sessions to playback and record
|
||||
sound samples has been added. It disguises itself as the OSS back end that is
|
||||
already used by vanilla VirtualBox. Since Genode pretends to be FreeBSD in the
|
||||
eyes of VirtualBox (because Genode's libc is based on FreeBSD's libc), the
|
||||
provisioning of an implementation of the OSS back end as used on FreeBSD host
|
||||
systems is the most natural approach. The audio support is complemented by
|
||||
adding the necessary device models for the virtual HDA as well as the AC97
|
||||
devices to our VirtualBox port.
|
||||
|
||||
For now, it is vital to have the guest OS configure the virtual device in a
|
||||
way that considers the current implementation. For example, we cannot
|
||||
guarantee distortion-free playback or recording if the guest OS uses a period
|
||||
that is too short, typically 10ms or less. There are also remaining issues
|
||||
with the mixing/filtering code in VirtualBox. Therefore, we bypass it to
|
||||
achieve better audio quality. As a consequence, the device model of the VM has
|
||||
to use the same sample rate as is used by the audio-out and audio-in sessions
|
||||
(44.1kHz).
|
||||
|
||||
Enabling audio support is done be adding
|
||||
! <AudioAdapter controller="HDA" driver="OSS" enabled="true"/>
|
||||
to the .vbox file manually or configuring the VM accordingly by using the GUI.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Bender chain loader on base-hw x86_64
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On Intel platforms, we use the Bender chain loader from the
|
||||
[https://github.com/alex-ab/morbo - Morbo multiboot suite] to detect available
|
||||
COM ports of PCI plug-in cards, the AMT SOL device, or as fall back the
|
||||
default comport 1. The loader stores the I/O port information of the detected
|
||||
cards into the BIOS data area (BDA), from where it is retrieved by core on
|
||||
boot and subsequently used for logging. With this release, we added the BDA
|
||||
parsing to base-hw on x86-64 and enabled the feature in the run tool. As a
|
||||
prerequisite, we had to fix an issue in bender triggered by the loading of
|
||||
only one (large) multi-boot kernel. Consequently, its binary in
|
||||
_tool/boot/bender_ was updated.
|
||||
|
||||
|
||||
Revised page-table handling
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
One of the main advantages of the base-hw platform is that the memory trading
|
||||
concept of Genode is universally applied even with regard to kernel objects.
|
||||
For instance, whenever a component wants to create a thread, it pays for the
|
||||
thread's stack, UTCB, and for the corresponding kernel object. The same
|
||||
applies to objects needed to manage the virtual address space of a component
|
||||
with the single exception of page tables.
|
||||
|
||||
Normally, when the quota, which was donated by a component to a specific
|
||||
service, runs out, the component receives an exception the next time it tries
|
||||
to invoke the service. The component can respond by upgrading the respective
|
||||
session quota. However, in the context of page-fault resolution, this is
|
||||
particularly difficult to do. The allocation and thereby the shortage of
|
||||
memory becomes evident only when the client produces a page fault. Therefore,
|
||||
there is no way to inform the component to upgrade its session quota before
|
||||
resolving the fault.
|
||||
|
||||
Instead of designing a sophisticated protocol between core and the other
|
||||
components to solve this problem, we decided to simplify the current
|
||||
page-fault resolution by using a static set of page-tables per component.
|
||||
Formerly, page tables were dynamically allocated from core's memory allocator.
|
||||
Now, an array of page tables gets allocated during construction of a
|
||||
protection domain. When a component runs out of page tables, all of its
|
||||
mappings get flushed, and the page tables are populated from scratch. This
|
||||
change greatly simplifies the page-table handling inside of base-hw.
|
||||
|
||||
|
||||
Dynamic interrupt mode setting on x86_64
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On x86-based hardware, user-level device drivers have become able to specify
|
||||
the trigger mode and polarity of the interrupts when requesting an IRQ
|
||||
session. On ARM, those session parameters are ignored. This change enables the
|
||||
x86_64 platform to support devices, which use arbitrary trigger modes and
|
||||
polarity settings, e.g., AHCI on QEMU and real hardware.
|
||||
|
||||
|
||||
Fiasco.OC
|
||||
=========
|
||||
|
||||
Genode's device-driver support when using the Fiasco.OC kernel as base
|
||||
platform received an upgrade.
|
||||
|
||||
First, principle support for the Raspberry Pi was added. To make this platform
|
||||
useful in practice, a working USB driver is important. I.e., the network
|
||||
interface is connected via USB. Hence the USB driver got enabled for
|
||||
Fiasco.OC, too. As a result, Genode's software stack can now be used on the
|
||||
Raspberry Pi by using either our custom base-hw kernel or Fiasco.OC.
|
||||
|
||||
Second, support for the Odroid-X2 platform using the Exynos4412 SoC was added,
|
||||
which includes the drivers for clock management (CMU), power management
|
||||
(PMU) as well as USB.
|
||||
|
||||
Thanks to Reinier Millo Sánchez and Alexy Gallardo Segura for having
|
||||
contributed this line of work.
|
||||
|
||||
|
||||
Removal of deprecated features
|
||||
##############################
|
||||
|
||||
We dropped the support for the *ARM Versatile Express* board from the Genode
|
||||
source tree to relieve our automated testing infrastructure from supporting a
|
||||
platform that remained unused for more than two years.
|
||||
|
||||
The device driver environment kit (DDE Kit) was originally intended as a
|
||||
common API among the execution environments of ported user-level device
|
||||
drivers. However, over the course of the past years, we found that this
|
||||
approach could not fulfill its promise while introducing a number of new
|
||||
problems. We reported our experiences in the release notes of versions
|
||||
[https://genode.org/documentation/release-notes/12.05#Re-approaching_the_Linux_device-driver_environment - 12.05] and
|
||||
[https://genode.org/documentation/release-notes/14.11#Roundup - 14.11].
|
||||
To be able to remove the DDE-Kit API, we reworked the USB driver, our port of
|
||||
the Linux TCP/IP stack, and the wireless driver accordingly.
|
||||
|
||||
1429
doc/release_notes/15-11.txt
Normal file
1429
doc/release_notes/15-11.txt
Normal file
File diff suppressed because it is too large
Load Diff
652
doc/release_notes/16-02.txt
Normal file
652
doc/release_notes/16-02.txt
Normal file
@@ -0,0 +1,652 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 16.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
With version 16.02, we add RISC-V to Genode's supported CPU architectures,
|
||||
enable the secure pass-through of individual USB devices to virtual machines,
|
||||
and update the support for the Muen and seL4 kernels.
|
||||
|
||||
Trustworthy hardware becomes an increasingly pressing problem. With each new
|
||||
generation of today's commodity hardware comes a dramatic increase of
|
||||
complexity, the addition of proprietary companion processors, and opaque
|
||||
firmware blobs. Even with a perfectly secure operating system, the user's
|
||||
privacy and security remains at risk as there is no way to assess the
|
||||
trustworthiness of our underlying hardware. RISC-V is a new hardware
|
||||
architecture that tries to overcome this problem by the means of open source
|
||||
and transparency. It is designed to scale from micro controllers to
|
||||
general-purpose computers, and to be both synthesizable as FPGA softcores and
|
||||
implementable in ASICs. The prospect of a scalable and trustworthy open-source
|
||||
hardware platform motivated us to add RISC-V to Genode's supported CPU
|
||||
architectures. Section [New support for the RISC-V CPU architecture] gives a
|
||||
brief overview of this line of work.
|
||||
|
||||
Thanks to the growing number of our regular developers using Genode as day to
|
||||
day OS, we create a natural incentive to address typical desktop-OS work
|
||||
flows. In particular, the new version comes with the ability to assign
|
||||
individual USB devices to VirtualBox instances. Conceptually, this looks like
|
||||
a relatively straight-forward feature. But as discussed in Section
|
||||
[Assignment of USB devices to virtual machines], we had to overcome a number of
|
||||
challenging problems caused by the inherently dynamic nature of USB-device
|
||||
hot-plugging. Also on the account of day-to-day computing, the GUI stack
|
||||
received welcomed usability improvements like keyboard shortcuts for certain
|
||||
window-management operations.
|
||||
|
||||
With respect to Genode's underlying base platforms, we are happy to announce
|
||||
the updates of the Muen and seL4 kernels. The Muen separation kernel received
|
||||
an update to version 0.7, which accommodates Genode's regular work flows (via
|
||||
run scripts) much better than the previous version. As described in Section
|
||||
[Muen separation kernel], this change clears the way to subject Muen to
|
||||
Genode's regular automated tests. The seL4 kernel represents an exciting
|
||||
playground as a future base platform for Genode. We have updated the kernel to
|
||||
version 2.1, which prompted us to fundamentally revisit the low-level resource
|
||||
management of Genode on this kernel. A summary of this undertaking is presented
|
||||
in Section [seL4 version 2.1].
|
||||
|
||||
According to the [https://genode.org/about/road-map - road map], we originally planned to
|
||||
revise the framework API in this release. Even though this topic is
|
||||
[https://github.com/genodelabs/genode/issues/1832 - very actively pursued], we
|
||||
decided to not rush it. We find it important to provide a smooth migration path
|
||||
from the old API to the new one. Determining the best path is actually trickier
|
||||
than revising the API, though. To let our decisions settle a bit, we postpone
|
||||
the transition to the upcoming release.
|
||||
|
||||
|
||||
Assignment of USB devices to virtual machines
|
||||
#############################################
|
||||
|
||||
As a migration strategy for running Genode on a daily basis, using VirtualBox
|
||||
to execute a feature-rich OS is vital. In release
|
||||
[https://genode.org/documentation/release-notes/15.05#USB-device_pass-through_support - 15.05],
|
||||
we added USB pass-through support to VirtualBox by enabling its integrated USB
|
||||
proxy service. Since we use the open-source edition of VirtualBox, we were
|
||||
merely able to use the OHCI device model and were therefore limited to using
|
||||
USB 1.x devices in low and full speed mode only. To make matters worse, when
|
||||
using the OHCI controller model, it is difficult if not impossible to access
|
||||
USB mass-storage devices. Usually, VirtualBox facilitates the EHCI or xHCI
|
||||
device models for the pass-through of storage devices. Unfortunately, those
|
||||
models are only available as a proprietary extension, which cannot be used by
|
||||
our VirtualBox port.
|
||||
|
||||
Having support for the pass-through of high-speed and super-speed USB devices
|
||||
is a must in such controller models. Therefore, we either have to implement
|
||||
these models ourselves or port existing ones from another VMM or emulator to
|
||||
fill the gap. We went for porting existing models first because device-model
|
||||
development from scratch could end up being time consuming if we want to
|
||||
guarantee them to work with a variety of different OS drivers.
|
||||
|
||||
|
||||
QEMU xHCI device model
|
||||
----------------------
|
||||
|
||||
QEMU features a NEC xHCI (UPD720200) device model that works well with Windows
|
||||
guests. For this reason, we decided to give porting this device model a shot.
|
||||
We applied the DDE approach and started by creating a QEMU emulation
|
||||
environment so that only the bare minimum amount of source code needed to be
|
||||
taken from the QEMU sources. It came down to a handful of source files, mainly
|
||||
the USB core and the xHCI device model files. We iteratively extended the
|
||||
emulation environment until the QEMU sources compiled and linked fine. One
|
||||
particular cumbersome issue we had to overcome was the emulation of the QEMU
|
||||
Object Model. Since QEMU is written in C, it uses its own object model to
|
||||
implement inheritance. This object model is used throughout QEMU. We took the
|
||||
easy way out and just used a C++ wrapper class that contains all QEMU objects
|
||||
that are used in the USB subsystem.
|
||||
|
||||
The next step was to develop a USB host device model. This model connects a
|
||||
USB device attached to Genode's USB host-controller driver to the xHCI device
|
||||
model. Lucky for us, QEMU already contains a USB host device model that uses
|
||||
libusb, which we could use as blueprint. We implemented a USB host device that
|
||||
leverages Genode's custom USB session interface. This host device reacts to a
|
||||
USB device report coming from another component such as the host-controller
|
||||
driver. It tries to claim all devices it finds in that report and then creates
|
||||
a QEMU USB device for each of them that is attached to the xHCI device model.
|
||||
|
||||
The xHCI device model needs infrastructure that normally is provided by QEMU
|
||||
itself such as a timer queue and PCI device handling. We introduced a QEMU
|
||||
USB controller interface _repos/libports/include/qemu/usb.h_ whose back-end
|
||||
library interface has to be implemented by a component, i.e. the VMM, that
|
||||
wants to use the library.
|
||||
|
||||
In the end, this work resulted in a small library that contains the xHCI
|
||||
device model and works in a standalone way. All required resources have to be
|
||||
provided by the component using the library. This makes it easy to integrate
|
||||
the library in different VMMs because the user of the library is not forced to
|
||||
employ the library in a certain way but free to use it any way he chooses.
|
||||
|
||||
|
||||
xHCI device model wrapper in VirtualBox
|
||||
---------------------------------------
|
||||
|
||||
We implemented an xHCI device model _repos/port/src/virtualbox/devxhci.cc_ in
|
||||
VirtualBox that merely wraps the QEMU USB library and provides the back-end
|
||||
functionality required by the library to glue QEMU's xHCI device model to
|
||||
VirtualBox. For now, this device is always part of a VM because there is
|
||||
currently no way to disable it from within the VirtualBox configuration
|
||||
front end. Therefore, it is necessary to always give VirtualBox access to a
|
||||
_usb_devices_ ROM module.
|
||||
|
||||
We removed the afore mentioned USB proxy service from our VirtualBox port
|
||||
because it became redundant with the advent of our xHCI device model.
|
||||
|
||||
|
||||
USB device report filter
|
||||
------------------------
|
||||
|
||||
With the xHCI support in VirtualBox in place, we had to come up with a
|
||||
mechanism to select, which USB devices it may access. Since USB devices are
|
||||
usually hot-plugged by the user of the system, we need to be able to configure
|
||||
the access permissions dynamically at run-time. On this account, we created a
|
||||
component that intercepts the report from the USB host-controller driver. On
|
||||
the one hand, this USB device report-filter component screens the device
|
||||
report coming from the USB host-controller driver by checking each reported
|
||||
device against a given white list of devices. Only approved devices are
|
||||
reported to a consumer of the report, i.e. VirtualBox. On the other hand, this
|
||||
component generates a new configuration for the USB host-controller driver.
|
||||
The configuration has to be changed each time the filter component finds a
|
||||
suitable device because the driver will hand out access to a given device to a
|
||||
client only if there is a valid policy. As we do not know in advance, which
|
||||
devices might be plugged in, this policy must be maintained dynamically. The
|
||||
report filter will send the device report only if the host-controller driver
|
||||
has changed its configuration. This ensures that a matching policy will be in
|
||||
effect at the time when the client component tries to access the device.
|
||||
|
||||
The configuration of the report-filter component can also be changed at run
|
||||
time.
|
||||
|
||||
See _repos/os/src/app/usb_report_filter/README_ for more details on how the
|
||||
USB device report filter may be configured.
|
||||
|
||||
|
||||
Example configuration
|
||||
---------------------
|
||||
|
||||
The following figure illustrates the interplay and configuration of the
|
||||
involved components:
|
||||
|
||||
[image qemu_xhci]
|
||||
|
||||
When the user plugs in a USB device, the USB host-controller driver generates
|
||||
a device report that is consumed by the USB device report-filter component
|
||||
(1). The filter component then examines the report and checks if it contains a
|
||||
device it should report to its report consumer. It then reconfigures the
|
||||
host-controller driver (2). Afterwards it sends a report to its consumer (3).
|
||||
The consumer, in this case a VMM, then accesses the USB device (4).
|
||||
|
||||
|
||||
New support for the RISC-V CPU architecture
|
||||
###########################################
|
||||
|
||||
We became aware of [https://riscv.org - RISC-V] when attending several talks
|
||||
about the project at [https://fosdem.org - FOSDEM] in 2015. RISC-V aims to be
|
||||
an open-source hardware architecture and is now complemented by many projects
|
||||
that target the release of real hardware or ASICs (for example,
|
||||
[https://www.lowrisc.org - the LowRISC project]). We have experience with various
|
||||
major CPU architectures and many systems on a chip and, therefore, embrace a
|
||||
sharp eye on certain platform properties. Intel's ME and ARM's Trustzone
|
||||
practically lock out operating systems of certain hardware and firmware
|
||||
features. The true nature of these mechanisms becomes increasingly dubious,
|
||||
especially when trying to build a secure open-source operating system. Intel's
|
||||
AMT technology for instance comes with a complete TCP/IP stack that intercepts
|
||||
packets from the integrated NIC and a VNC server that can magically expose a
|
||||
mouse and a keyboard at the USB controller. If you are interested in more
|
||||
details about this topic
|
||||
[https://blog.invisiblethings.org/papers/2015/x86_harmful.pdf - Intel x86 considered harmful]
|
||||
by Joanna Rutkowska is a very good read. We decided to have a deeper look at
|
||||
the RISC-V architecture as an alternative open hardware platform. Especially,
|
||||
since the LowRISC project promises a completely open system on chip, including
|
||||
the peripherals.
|
||||
|
||||
RISC-V comes with a lot of optional features, so it can cover a large field of
|
||||
applications reaching from simple I/O processors to general-purpose computing.
|
||||
For example, there are 64 and 32 bit ISA (instruction set architecture)
|
||||
versions, three page table formats with the option to omit paging at all, up
|
||||
to four privilege modes, and a minimal integer core ISA (I). Everything else,
|
||||
like multiplication and division (M), atomic instructions (A), and floating
|
||||
point support (F) are subject to ISA extensions and are completely optional
|
||||
for a specific hardware implementation.
|
||||
|
||||
For Genode, we chose to add the RISC-V support to our custom _base-hw_ kernel.
|
||||
Since Genode may be used as a general purpose OS, we implemented the kernel
|
||||
using the 64 bit RISC-V version, the Sv39 three-level page table format, and
|
||||
the so-called general-purpose extension (G), which is the abbreviation for the
|
||||
IAMF extensions. The current implementation provides the kernel and the
|
||||
necessary adaptations of the user level part of core.
|
||||
|
||||
For testing, we used the RISC-V instruction emulator called
|
||||
[https://github.com/riscv/riscv-isa-sim - Spike]. There also exists a RISC-V
|
||||
implementation for various Zynq FPGAs. Genode's Zynq board support has kindly
|
||||
been added and contributed by Mark Vels.
|
||||
|
||||
In the current state, basic Genode applications including core, init, and
|
||||
components that use shared libraries can be executed on top of our RISC-V
|
||||
port. We did not enable the libc and postponed further activity as the
|
||||
platform currently does not specify the interaction with peripherals.
|
||||
|
||||
|
||||
Steps to test Genode on RISC-V
|
||||
------------------------------
|
||||
|
||||
# Building the instruction emulator
|
||||
|
||||
! # download the front end server
|
||||
! git clone https://github.com/ssumpf/riscv-fesvr.git
|
||||
!
|
||||
! # build the front end server
|
||||
! cd riscv-fesvr
|
||||
! mkdir build
|
||||
! cd build
|
||||
! export RISCV=<installation path>
|
||||
! ../configure --prefix=$RISCV
|
||||
! (sudo) make install
|
||||
!
|
||||
! # download the instruction emulator
|
||||
! cd ../../
|
||||
! git clone https://github.com/ssumpf/riscv-isa-sim.git
|
||||
! cd riscv-isa-sim
|
||||
!
|
||||
! # build the emulator
|
||||
! mkdir build
|
||||
! cd build
|
||||
! ../configure --prefix=$RISCV --with-fesvr=$RISCV
|
||||
! (sudo) make install
|
||||
!
|
||||
! # add $RISCV/bin to path
|
||||
! export PATH=$RISCV/bin:$PATH
|
||||
|
||||
# Building Genode and running a test scenario
|
||||
|
||||
! # download Genode
|
||||
! cd ../../
|
||||
! git clone https://github.com/genodelabs/genode.git
|
||||
!
|
||||
! # build the Genode tool chain
|
||||
! cd genode
|
||||
! ./tool/tool_chain riscv
|
||||
!
|
||||
! # create RISC-V build directory
|
||||
! ./tool/create_builddir hw_riscv
|
||||
! cd build/hw_riscv
|
||||
!
|
||||
! # build and execute the printf run script
|
||||
! make run/printf
|
||||
|
||||
|
||||
GUI stack usability improvements
|
||||
################################
|
||||
|
||||
Motivated by the daily use of Genode as desktop OS by an increasingly number
|
||||
of developers, the window-layouter component of the
|
||||
[https://genode.org/documentation/release-notes/15.11#GUI_stack - GUI stack]
|
||||
received welcomed usability improvements.
|
||||
|
||||
|
||||
Configurable window placement
|
||||
-----------------------------
|
||||
|
||||
The policy of the window layouter can be adjusted via its configuration. For
|
||||
a given window label, the window's initial position and its maximized state
|
||||
can be defined as follows:
|
||||
|
||||
! <config>
|
||||
! <policy label="mupdf" maximized="yes"/>
|
||||
! <policy label="nit_fb" xpos="50" ypos="50"/>
|
||||
! </config>
|
||||
|
||||
|
||||
Keyboard shortcuts
|
||||
------------------
|
||||
|
||||
The window layouter has become able to respond to key sequences. However,
|
||||
normally, the layouter is not a regular nitpicker client but receives only
|
||||
those input events that refer to the window decorations. It never owns the
|
||||
keyboard focus. In order to propagate global key sequences to the layouter,
|
||||
nitpicker must be explicitly configured to direct key sequences initiated with
|
||||
certain keys to the decorator. For example, the following nitpicker
|
||||
configuration routes key sequences starting with the left windows key to the
|
||||
decorator. The window manager, in turn, forwards those events to the layouter.
|
||||
|
||||
! <start name="nitpicker">
|
||||
! ...
|
||||
! <config>
|
||||
! ...
|
||||
! <global-key name="KEY_LEFTMETA" label="wm -> decorator" />
|
||||
! ...
|
||||
! </config>
|
||||
! ...
|
||||
! </start>
|
||||
|
||||
The response of the window layouter to key sequences can be expressed in the
|
||||
layouter configuration as follows:
|
||||
|
||||
! <config>
|
||||
! <press key="KEY_LEFTMETA">
|
||||
! <press key="KEY_TAB" action="next_window">
|
||||
! <release key="KEY_TAB">
|
||||
! <release key="KEY_LEFTMETA" action="raise_window"/>
|
||||
! </release>
|
||||
! </press>
|
||||
! <press key="KEY_LEFTSHIFT">
|
||||
! <press key="KEY_TAB" action="prev_window">
|
||||
! <release key="KEY_TAB">
|
||||
! <release key="KEY_LEFTMETA" action="raise_window"/>
|
||||
! </release>
|
||||
! </press>
|
||||
! </press>
|
||||
! <press key="KEY_ENTER" action="toggle_fullscreen"/>
|
||||
! </press>
|
||||
! </config>
|
||||
|
||||
Each '<press>' node defines the policy when the specified 'key' is pressed.
|
||||
It can be equipped with an 'action' attribute that triggers a window action.
|
||||
The supported window actions are:
|
||||
|
||||
:next_window: Focus the next window in the focus history.
|
||||
:prev_window: Focus the previous window in the focus history.
|
||||
:raise_window: Bring the focused window to the front.
|
||||
:toggle_fullscreen: Maximize/unmaximize the focused window.
|
||||
|
||||
By nesting '<press>' nodes, actions can be tied to key sequences. In the
|
||||
example above, the 'next_window' action is executed only if TAB is pressed
|
||||
while the left windows-key is kept pressed. Furthermore, key sequences can
|
||||
contain specific release events. In the example above, the release of the left
|
||||
windows key brings the focused window to front, but only if TAB was pressed
|
||||
before.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
USB host-controller driver enhancements
|
||||
=======================================
|
||||
|
||||
The _usb_drv_ component now solely uses a policy to grant other components
|
||||
access to USB devices exposed by its raw interface (USB session). On the basis
|
||||
of the 'label' attribute, it will choose a pre-configured device that is
|
||||
identified by either the 'bus' and 'dev' or the 'vendor' and 'product'
|
||||
attribute tuple. To accommodate policy decisions made at run time, the USB
|
||||
driver is now able to reload its configuration on demand. The USB device
|
||||
report now contains a 'bus' and a 'dev' attribute as well in order to identify
|
||||
a USB device more precisely. In addition to that, there is also a generated
|
||||
'label' attribute in form of 'usb-<bus>-<dev>' that may be used to form
|
||||
policies while configuring the system dynamically, e.g., when using the
|
||||
_usb_report_filter_ component.
|
||||
|
||||
|
||||
USB mass-storage driver
|
||||
=======================
|
||||
|
||||
Up to now, access to USB storage devices was provided by the USB
|
||||
host-controller driver only. However, its ability to do so is limited. E.g.,
|
||||
it only supports one storage device and the storage device cannot be changed
|
||||
at run-time. With this release we add a USB mass-storage driver that supports
|
||||
UMS bulk-only devices that use the SCSI Block Commands set (direct-access).
|
||||
This is still most common for USB sticks. Devices using different command
|
||||
sets, e.g SD/HC devices or some external disc drives, will not work properly
|
||||
if at all. The driver uses the USB session interface to access the USB device
|
||||
and provides its service as block session to its client.
|
||||
|
||||
This component is part of the first step providing the ability to mount and
|
||||
use USB sticks dynamically when using Genode as a general purpose OS. In the
|
||||
future, the _usb_drv_ component should solely be the host-controller driver
|
||||
while other tasks are handled by dedicated USB driver components such as this
|
||||
one.
|
||||
|
||||
|
||||
Audio output on Linux
|
||||
=====================
|
||||
|
||||
The audio-out driver for Linux was modernized by replacing its multi-threaded
|
||||
architecture by an event-driven architecture using Genode's server API. In
|
||||
addition, the playback is now driven by a timer. For now it is a periodic
|
||||
timer that triggers every 11 ms which is roughly the current audio-out period.
|
||||
|
||||
The driver now also behaves like the other BSD-based audio-out driver, i.e.,
|
||||
it always advances the play pointer. That is vital for the audio-out stack
|
||||
above the driver to work properly (e.g., the mixer).
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New Genode-world repository
|
||||
===========================
|
||||
|
||||
With a growing number of users and contributors comes the desire to bring more
|
||||
and more existing software to Genode. Most of such libraries and applications,
|
||||
however, are outside of the scope of Genode as an OS framework. In contrast to
|
||||
device drivers, protocol stacks, and low-level OS services, which we subject
|
||||
to our regular automated tests, most 3rd-party software is pretty independent
|
||||
from Genode. The attempt to integrate the growing pool of such diverse
|
||||
software into the main repository does not scale.
|
||||
|
||||
For this reason, we introduce the new
|
||||
[https://github.com/genodelabs/genode-world - Genode World] repository, which
|
||||
is the designated place for hosting ported applications, libraries, and games.
|
||||
|
||||
To use it, you first need to obtain a clone of Genode:
|
||||
|
||||
! git clone https://github.com/genodelabs/genode.git genode
|
||||
|
||||
Now, clone the _genode-world.git_ repository to _genode/repos/world:_
|
||||
|
||||
! git clone https://github.com/genodelabs/genode-world.git genode/repos/world
|
||||
|
||||
By placing the _world_ repository under the _repos/_ directory, Genode's tools
|
||||
will automatically incorporate the ports provided by the _world_ repository.
|
||||
|
||||
For building software of the _world_ repository, the build-directory
|
||||
configuration _etc/build.conf_ must be extended with the following line:
|
||||
|
||||
! REPOSITORIES += $(GENODE_DIR)/repos/world
|
||||
|
||||
*Word of caution*
|
||||
|
||||
In contrast to the components found in the mainline Genode repository, the
|
||||
components within the _world_ repository are not subjected to the regular
|
||||
quality-assurance measures of Genode Labs. Hence, problems are to be expected.
|
||||
If you encounter bugs, build problems, or stability issues, please report them
|
||||
to the [https://github.com/genodelabs/genode-world/issues - issue tracker] or
|
||||
the [https://genode.org/community/mailing-lists - mailing list].
|
||||
|
||||
|
||||
Updated 3rd-party software
|
||||
==========================
|
||||
|
||||
The following 3rd-party code packages of the _ports_ and _libports_
|
||||
repositories have been ported or updated:
|
||||
|
||||
* Lynx 2.8.8rel.2 (noux package)
|
||||
* OpenSSH 7.1p1 (noux package)
|
||||
* tar-1.27 (noux package)
|
||||
* libssh 0.7.2
|
||||
* Lighttpd 1.4.38
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Within the last months, the initialization code of our custom kernel got
|
||||
re-arranged to simplify the addition of new architectures, e.g., the RISC-V
|
||||
port (Section [New support for the RISC-V CPU architecture]) while also making
|
||||
its implementation leaner. A positive side effect of this work was the
|
||||
generalization of multi-processor and L2-cache support for ARM's Cortex-A9
|
||||
CPUs. For instance, the Wandboard (Freescale i.MX6 SoC) is now driven with all
|
||||
four cores, and its memory can be accessed with full speed.
|
||||
|
||||
Besides those feature additions, we fixed an extremely rare and tricky race
|
||||
condition in the implementation of the kernel-protected capabilities,
|
||||
introduced in release 15.05. A capability's lifetime within a component is
|
||||
tracked by a reference-counting like mechanism that is under control of the
|
||||
component itself. When the kernel transfered a capability to a component, and
|
||||
the very same capability was deleted within the component simultaneously, the
|
||||
received capability was marked as invalid, which led to diverse, sporadic
|
||||
faults. This deficit in the capabilities reference-counting is solved with the
|
||||
current release.
|
||||
|
||||
|
||||
Muen separation kernel
|
||||
======================
|
||||
|
||||
Build integration
|
||||
-----------------
|
||||
|
||||
Building Genode scenarios running on top of the
|
||||
[https://muen.sk - Muen separation kernel] has been greatly simplified by
|
||||
properly integrating the Muen system build process into the Genode build system.
|
||||
As described in the
|
||||
[https://genode.org/documentation/release-notes/15.08#Genode_on_top_of_the_Muen_Separation_Kernel - 15.08 release notes],
|
||||
the architecture with Muen is different since the entire hw_x86_64_muen Genode
|
||||
system runs as a guest VM on top of the separation kernel. This means that the
|
||||
Genode base-hw image must itself be packaged into the final Muen system image
|
||||
as an additional step after the Genode system build.
|
||||
|
||||
The packaging process of a Muen system image is performed by the new
|
||||
_image/muen_ run-tool plugin, which processes the following RUN_OPT parameters.
|
||||
|
||||
:--image-muen-external-build:
|
||||
Muen system is built automatically or externally
|
||||
|
||||
:--image-muen-system:
|
||||
Muen system policy
|
||||
|
||||
:--image-muen-components:
|
||||
Muen system components required for the given system policy
|
||||
|
||||
:--image-muen-hardware:
|
||||
Muen target hardware platform
|
||||
|
||||
:--image-muen-gnat-path:
|
||||
Path to GNAT toolchain
|
||||
|
||||
:--image-muen-spark-path:
|
||||
Path to SPARK toolchain
|
||||
|
||||
The options are automatically added to the _etc/build.conf_ file for the
|
||||
hw_x86_64_muen base-hw platform. The
|
||||
[https://genode.org/documentation/platforms/muen - documentation] has been
|
||||
updated to reflect the new, simplified build process.
|
||||
|
||||
A port file was added to facilitate the download of the Muen sources v0.7 and
|
||||
to check the required dependencies.
|
||||
|
||||
Using the new _image/muen_ script in combination with iPXE allows to run the
|
||||
Genode test suite via the autopilot tool.
|
||||
|
||||
|
||||
MSI support
|
||||
-----------
|
||||
|
||||
Muen employs Intel VT-d interrupt remapping (IR) besides DMA remapping for
|
||||
secure device assignment. As a consequence, PCI devices using Message Signaled
|
||||
Interrupts (MSI) must be programmed to trigger requests in remappable format
|
||||
(see Intel VT-d specification, Section 5.1.2.2 for further details).
|
||||
|
||||
To enable the use of MSIs with the base-hw kernel, a platform-specific
|
||||
function has been introduced that returns the necessary MSI parameters for a
|
||||
given PCI device. If either the platform or the specific device does not
|
||||
support MSI, the function returns false.
|
||||
|
||||
On hw_x86_64_muen, the function consults the Muen subject info page to supply
|
||||
the appropriate information to the IRQ session. This allows Genode device
|
||||
drivers to transparently use MSIs for passed-through PCI devices.
|
||||
|
||||
|
||||
seL4 version 2.1
|
||||
================
|
||||
|
||||
By the end of 2015, the [https://sel4.systems/ - seL4 kernel] version 2.0 was
|
||||
published. With the current release, we update Genode's preliminary support
|
||||
for this kernel from the experimental branch of one year ago to the master
|
||||
branch of version 2.1. Note that this line of work is still considered as an
|
||||
exploration. As of now, there is still a way to go until we can leverage seL4
|
||||
as a fully featured base platform. Under the hood of Genode, the transition to
|
||||
the version 2.1 master branch had the following implications.
|
||||
|
||||
In contrast to the experimental branch, the seL4 master branch has no way to
|
||||
manually define the allocation of kernel objects within untyped memory ranges.
|
||||
Instead, the kernel maintains a built-in allocation policy. This policy rules
|
||||
out the deallocation of once-used parts of untyped memory. The only way to
|
||||
reuse memory is to revoke the entire untyped memory range. Consequently, we
|
||||
cannot share a large untyped memory range for kernel objects of different
|
||||
protection domains. In order to reuse memory at a reasonably fine granularity,
|
||||
we need to split the initial untyped memory ranges into small chunks that can
|
||||
be individually revoked. Those chunks are called "untyped pages". An untyped
|
||||
page is a 4 KiB untyped memory region.
|
||||
|
||||
The bootstrapping of core has to employ a two-stage allocation approach now.
|
||||
For creating the initial kernel objects for core, which remain static during
|
||||
the entire lifetime of the system, kernel objects are created directly out of
|
||||
the initial untyped memory regions as reported by the kernel. The so-called
|
||||
"initial untyped pool" keeps track of the consumption of those untyped memory
|
||||
ranges by mimicking the kernel's internal allocation policy. Kernel objects
|
||||
created this way can be of any size. For example the CNode, which is used to
|
||||
store page-frame capabilities is 16 MiB in size. Also, core's CSpace uses a
|
||||
relatively large CNode.
|
||||
|
||||
After the initial setup phase, all remaining untyped memory is turned into
|
||||
untyped pages. From this point on, newly created kernel objects cannot exceed
|
||||
4 KiB in size because one kernel object cannot span multiple untyped memory
|
||||
regions. The capability selectors for untyped pages are organized similarly to
|
||||
those of page-frame capabilities. There is a new 2nd-level CNode
|
||||
(UNTYPED_CORE_CNODE) that is dimensioned according to the maximum amount of
|
||||
physical memory (1M entries, each entry representing 4 KiB). The CNode is
|
||||
organized such that an index into the CNode directly corresponds to the
|
||||
physical frame number of the underlying memory. This way, we can easily
|
||||
determine an untyped page selector for any physical addresses, i.e., for
|
||||
revoking the kernel objects allocated at a specific physical page. The
|
||||
downside is the need for another 16 MiB chunk of meta data. Also, we need to
|
||||
keep in mind that this approach won't scale to 64-bit systems. We will
|
||||
eventually need to replace the PHYS_CORE_CNODE and UNTYPED_CORE_CNODE by CNode
|
||||
hierarchies to model a sparsely populated CNode. The following figure
|
||||
illustrates the layout of core's capability space.
|
||||
|
||||
[image sel4_core_cspace_master]
|
||||
Organization of core's capability space on seL4
|
||||
|
||||
For each protection domain, core maintains a so-called VM CSpace that holds
|
||||
capability selectors for page frames and page tables. The size constraint of
|
||||
kernel objects has the immediate implication that the VM CSpaces of protection
|
||||
domains must be organized via several levels of CNodes. I.e., as the top-level
|
||||
CNode of core has a size of 2^12, the remaining 20 PD-specific CSpace address
|
||||
bits are organized as a 2nd-level 2^4 padding CNode, a 3rd-level 2^8 CNode,
|
||||
and several 4th-level 2^8 leaf CNodes. The latter contain the actual selectors
|
||||
for the page tables and page-table entries of the respective PD.
|
||||
|
||||
As another slight difference from the experimental branch, the master branch
|
||||
requires the explicit assignment of page directories to an ASID pool.
|
||||
|
||||
Functionality-wise the update to version 2.1 brings no changes. The
|
||||
preliminary support is still limited to Genode's most fundamental mechanisms
|
||||
like the bootstrapping, the creation of protection domains, the execution of
|
||||
threads, and inter-component communication. User-level device drivers are not
|
||||
supported yet. Such functional improvements are scheduled for Genode 16.08.
|
||||
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
We started to experience crashes of our dynamic linker (ldso) when using
|
||||
Genode's _base-linux_ platform on recent Linux kernels. Ldso is primarily a
|
||||
shared object, which is linked to dynamic binaries. But ldso is also an
|
||||
executable, which, once started loads the dynamically-linked binary along with
|
||||
all shared libraries required by the binary. Up to now, ldso had to be loaded
|
||||
at a link address defined at compilation time, which we enforced through
|
||||
linker-script magic. Unfortunately, this does not work any longer on recent
|
||||
Linux versions. The kernel notices that ldso is a shared object and loads it
|
||||
at an arbitrary (randomized) address, which ultimately results in a
|
||||
segmentation fault during ldso initialization. We found a fix for this issue
|
||||
by marking ldso as an executable in the ELF header. But since ldso is linked
|
||||
to all dynamic binaries (it contains Genode's base libraries) the GNU linker
|
||||
then refused to link because ldso was not marked as a shared object.
|
||||
Therefore, we decided to implement true self relocation within ldso. This
|
||||
feature only works on Genode's base-linux platform as it requires some
|
||||
symbol-address magic.
|
||||
|
||||
1315
doc/release_notes/16-05.txt
Normal file
1315
doc/release_notes/16-05.txt
Normal file
File diff suppressed because it is too large
Load Diff
1126
doc/release_notes/16-08.txt
Normal file
1126
doc/release_notes/16-08.txt
Normal file
File diff suppressed because it is too large
Load Diff
729
doc/release_notes/16-11.txt
Normal file
729
doc/release_notes/16-11.txt
Normal file
@@ -0,0 +1,729 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 16.11
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
In contrast to most parts of the framework, the fundamental low-level
|
||||
protocols, which define the interaction between parent and child components
|
||||
have remained unchanged since the very first Genode version. From this
|
||||
interplay, the entire architecture follows. That said, certain initial design
|
||||
choices were not perfect. They partially resulted from limitations of the
|
||||
kernels we used during Genode's early years and from our pre-occupation with a
|
||||
certain style of programming. Over the years, the drawbacks inherent in our
|
||||
original design became more and more clear and we drafted rough plans to
|
||||
overcome them. However, reworking the fundamental protocols of a system that
|
||||
already accommodates hundreds of component implementations cannot be taken
|
||||
lightly. Because of this discomfort, we repeatedly deferred the topic -
|
||||
until now. With the rapidly growing workloads carried by Genode, we
|
||||
deliberately decided to address long-standing deficiencies rather than adding
|
||||
the features we originally planned according to the
|
||||
[https://genode.org/about/road-map - road map].
|
||||
|
||||
Section [Asynchronous parent-child interactions] presents the reworking of
|
||||
Genode's component interplay at the lowest level. With this change in place,
|
||||
we feel much more comfortable to scale up our workloads in the upcoming
|
||||
releases.
|
||||
|
||||
Functionality-wise, the most prominent topic of the current release is the
|
||||
vastly improved NIC-routing component. Since we introduced the first version
|
||||
of the NIC router in the previous release, we took an iterative approach to
|
||||
shape the component according to its most prominent use cases. Section
|
||||
[Further improved virtual networking] summarizes the changes and the
|
||||
motivation behind them.
|
||||
|
||||
Even though we added support for seL4 in the previous release, the NOVA
|
||||
hypervisor is still our go-to kernel for x86-based hardware because of its
|
||||
feature set. For this reason, we continuously improve this kernel and the
|
||||
NOVA-specific components like VirtualBox. Section [NOVA hypervisor] covers
|
||||
the introduction of an asynchronous map operation to NOVA.
|
||||
|
||||
Further topics of the current release range from added smart-card support,
|
||||
over a new timeout API, to a VFS-based time-based password generator. With
|
||||
respect to the road map, we postponed most topics originally planned. In
|
||||
particular, we intended to enable the use of Genode on top of Xen by following
|
||||
the footsteps of the existing Muen support - using our custom
|
||||
base-hw kernel within a Xen DomU domain. However, before proceeding this
|
||||
route, we decided to modernize the kernel design, in particular with respect
|
||||
to bootstrapping and address-space management. Some parts of this line of work
|
||||
are already present in the current release, for example the unification of the
|
||||
boot-module handling as explained in Section
|
||||
[Unified handling of boot modules].
|
||||
|
||||
|
||||
Asynchronous parent-child interactions
|
||||
######################################
|
||||
|
||||
When Genode was born in 2006, the L4 microkernels of the time universally
|
||||
lacked an asynchronous inter-process-communication (IPC) mechanism.
|
||||
Consequently, we designed the first version of Genode with the presumption
|
||||
that components had to interact solely synchronously. To us, this seemed to be
|
||||
the "right" way because the synchronous low-footprint IPC was presumably the
|
||||
key for L4's good performance. It felt natural to leverage this benefit to the
|
||||
maximum extent possible.
|
||||
|
||||
To illustrate the implications of this line of thinking for Genode, let's take
|
||||
a look at a simple scenario where a parent component hosts two children and one
|
||||
child provides a service to the other child.
|
||||
|
||||
[image simple_scenario]
|
||||
|
||||
During the creation of a session, the kernel's IPC mechanism serves three
|
||||
purposes. First, it is used to communicate information between different
|
||||
protection domains, in this case the parent, the client, and the server.
|
||||
Second, it implicitly dictates the flow of control between the involved
|
||||
parties because the caller blocks until the callee replies to the IPC call.
|
||||
Third, the IPC is the mechanism to delegate authority (like the authority to
|
||||
access the server's session object) between protection domains. The latter is
|
||||
realized with the kernel's ability to carry capabilities as IPC message
|
||||
payload. If this sounds a bit too abstract, please consider reviewing Section
|
||||
3.1. "Capability-based security" of the
|
||||
[https://genode.org/documentation/genode-foundations-16-05.pdf - Genode Foundations].
|
||||
Using solely a synchronous IPC mechanism, the sequence of establishing a
|
||||
session in the given scenario is as follows. In the context of Genode,
|
||||
we usually refer to synchronous IPC as RPC (remote procedure call).
|
||||
|
||||
[image sync_session_seq]
|
||||
|
||||
The sequence looks straightforward:
|
||||
|
||||
# The client issues an RPC call to its parent, requesting a session for a
|
||||
service of the given type while also passing a number of session-construction
|
||||
arguments along with the request.
|
||||
# Given the service name as provided with the session request, the parent
|
||||
determines the server to ask for a new session. It requests a session
|
||||
on behalf of the client by performing an RPC call to the server's prior
|
||||
registered "root" capability. This capability refers to an interface for
|
||||
creating and closing sessions.
|
||||
# The server responds to the invocation of its root interface by creating
|
||||
a new session object along with a session capability.
|
||||
Whereas the session object is local to the server, the corresponding
|
||||
session capability can be passed (delegated) to other components.
|
||||
Each component in possession of the session capability is able to interact
|
||||
with the server's corresponding session object via RPC calls.
|
||||
The server returns the session capability to the parent as the result of the
|
||||
parent's RPC call.
|
||||
# The parent forwards the session capability to the client as the result of
|
||||
the client's original RPC call.
|
||||
|
||||
Even though the simplicity of this protocol seems nice, it has inherent
|
||||
limitations:
|
||||
|
||||
First, as the parent performs a synchronous RPC call to the server on behalf
|
||||
of the client, it must trust the server to eventually respond to the RPC call.
|
||||
If the server doesn't, the parent may block forever. In contrast to the client
|
||||
that actually uses the service and thereby relies on the liveliness of the
|
||||
server, the parent should not need to trust the server to be responsive. To
|
||||
deal with the risk of an unresponsive server, Genode's existing runtime
|
||||
environments (like the init component), maintain a dedicated thread for each
|
||||
child. The session requests originating from a child are handled by the
|
||||
corresponding parent-local child thread. In the worst case - if the server
|
||||
fails to respond - only a single child thread stays blocked but the other
|
||||
parts of the runtime environment remain unaffected. Consequently, runtime
|
||||
environments have to be multi-threaded components. This, in turn, comes at the
|
||||
cost of added complexity, in particular the need for error-prone inter-thread
|
||||
synchronization.
|
||||
|
||||
Second, the approach keeps the parent's state implicitly stored in the stacks
|
||||
of the parent's threads. This becomes a problem in dynamic runtime
|
||||
environments that need to kill subsystems at arbitrary times. E.g., imagine
|
||||
the situation where the client component is to be destroyed while the parent's
|
||||
call to the server's root interface is still pending. The safe destruction of
|
||||
the child - including its associated parent-local child thread - requires the
|
||||
parent to abort the RPC call, which is a complex and - again - error-prone
|
||||
operation.
|
||||
|
||||
Third, even though not inherent to synchronous RPC, Genode's original design
|
||||
facilitated the use of a session capability as argument for requesting the
|
||||
parent to close a specific session. However, the use of capabilities as
|
||||
re-identifiable tokens is not well supported by most kernels, including seL4
|
||||
([https://sel4.systems/pipermail/devel/2014-November/000114.html - discussion]
|
||||
on the seL4 mailing list).
|
||||
|
||||
|
||||
Asynchronous communication throughout Genode
|
||||
--------------------------------------------
|
||||
|
||||
In 2008, we acknowledged the sole reliance on synchronous RPC as too limiting
|
||||
and introduced an
|
||||
[https://genode.org/documentation/release-notes/8.11#Asynchronous_notifications - API for asynchronous notifications].
|
||||
On the traditional L4 kernels, we implemented the API by using Genode's
|
||||
core component as a proxy for signal delivery. The use of asynchronous
|
||||
notifications soon became natural and wide-spread throughout Genode. Today,
|
||||
most session interfaces combine three forms of inter-component communication,
|
||||
namely synchronous RPC calls, asynchronous notifications, and shared memory.
|
||||
The new Genode API introduced in
|
||||
[https://genode.org/documentation/release-notes/16.05#The_great_API_renovation - version 16.05]
|
||||
further cultivated the modeling of Genode components as single-threaded state
|
||||
machines instead of multi-threaded programs.
|
||||
|
||||
Still, until now, the most fundamental mechanism of Genode - the protocol
|
||||
between parent and child components - has remained synchronous. The reasons
|
||||
are twofold. First, our workaround for realizing runtime environments in a
|
||||
multi-threaded way worked too well. So we were not constantly bothered by this
|
||||
design problem. Second and more importantly, redesigning the fundamental
|
||||
mechanism of the framework while not breaking the more than 300 existing
|
||||
components is quite scary. But in anticipation of the rapidly scaling
|
||||
workloads imposed on Genode, we had to take on the problem sooner or later.
|
||||
We figured that now - with the modernized framework API in place - it's the
|
||||
right time. From redesigning the interplay of parent and child components, we
|
||||
will become able to create single-threaded runtime environments that behave
|
||||
completely deterministically while consuming less resources than
|
||||
multi-threaded programs. By the explicit enumeration of possible states, we
|
||||
greatly ease the validation/evaluation of such crucial components.
|
||||
|
||||
|
||||
New session-creation procedure
|
||||
------------------------------
|
||||
|
||||
Following the asynchronous approach, the sequence of creating a session now
|
||||
looks as follows:
|
||||
|
||||
[image async_session_seq]
|
||||
|
||||
The dotted lines are asynchronous notifications, which have fire-and-forget
|
||||
semantics. A component that triggers a signal does not block.
|
||||
|
||||
The following points are worth noting:
|
||||
|
||||
* Sessions are identified via IDs, which are plain numbers as opposed to
|
||||
capabilities. The IDs as seen by the client and server belong to different
|
||||
ID name spaces.
|
||||
IDs of sessions requested by the client are allocated by the client. IDs
|
||||
of sessions requested at the server are allocated by the parent.
|
||||
* The parent does no longer need to perform RPC calls to any of its children.
|
||||
Hence, the need for multiple threads in runtime environments disappears.
|
||||
* Each activation of the parent merely applies a state change of the session's
|
||||
meta data structures maintained at the parent, which capture the entire
|
||||
state of session requests. There is no hidden state stored on the parent's
|
||||
stack.
|
||||
* The information about pending session requests is communicated from the
|
||||
parent to the server via a ROM session. At startup, the server requests
|
||||
a ROM session for the ROM module "session_requests" from its parent. The
|
||||
parent implements this ROM session locally. Since ROM sessions support
|
||||
versions, the parent can post version updates of the "session_requests"
|
||||
ROM with the regular mechanisms already present in Genode.
|
||||
* The involved parties can potentially run in parallel.
|
||||
|
||||
|
||||
Outcome and current state
|
||||
-------------------------
|
||||
|
||||
Intuitively, the sequence of steps required to establish a session has
|
||||
become more complicated. However, for the users of the framework, the entire
|
||||
procedure is completely transparent. With a few tricks, we were actually able
|
||||
to implement this fundamental change while keeping almost all existing
|
||||
components untouched. One trick is the introduction of a server-local proxy
|
||||
mechanism, which translates the requests obtained from the "session_requests"
|
||||
ROM to component-local RPC calls on the server's root interface. So from the
|
||||
perspective of an existing server component, a session request still looks
|
||||
like a synchronous RPC request from the outside. Of course, the proxy is meant
|
||||
as an intermediate solution until we have crafted a convenient front-end API
|
||||
for the asynchronous mode of operation.
|
||||
|
||||
Even though the biggest share of components remains unaffected by the change,
|
||||
this is not true for all components. In particular, runtime environments had
|
||||
to be reworked, in some cases quite fundamentally. These include core, init,
|
||||
noux, the loader, GDB monitor, launcher, CLI monitor, and the platform driver.
|
||||
The change does not only affect the interplay between components but also
|
||||
required a reconsideration of the child-creation procedure.
|
||||
|
||||
Besides the architectural improvement, this line of work had two welcome
|
||||
effects.
|
||||
|
||||
First, in contrast to the original design, which relied on capabilities as
|
||||
re-identifiable tokens, the new version greatly alleviates the need for
|
||||
re-identifying capabilities on seL4. So we are able to eliminate a
|
||||
long-standing problem with Genode on this kernel.
|
||||
|
||||
Second, the work called for new data structures for the safe interaction with
|
||||
ID spaces (_base/id_space.h_) and object registries (_base/registry.h_). Those
|
||||
data structures will possibly be useful in a lot of places that currently use
|
||||
plain (and fairly unsafe) AVL trees or lists.
|
||||
|
||||
At the API level, the change is almost transparent to regular components,
|
||||
except for two details. The upgrading of session quota is no longer
|
||||
possible by a mere RPC call to the parent. Instead, 'Connection' objects
|
||||
received a new 'upgrade_ram' method that must be used instead. Speaking
|
||||
of 'Connection' objects, we had to remove the (fairly obscure) 'KEEP_OPEN'
|
||||
feature, which is conceptually incompatible with the new design.
|
||||
|
||||
|
||||
Further improved virtual networking
|
||||
###################################
|
||||
|
||||
The
|
||||
[https://genode.org/documentation/release-notes/16.08#Virtual_networking_and_support_for_TOR - previous release]
|
||||
introduced the NIC router - a component that individually routes IP
|
||||
packets between multiple NIC sessions, translates between different IP
|
||||
subnets, and also supports port forwarding and NAT. For the first version of
|
||||
the NIC router, we focused on the technical realization. Now, besides
|
||||
some optimization and restructuring, we took the chance to polish the
|
||||
configuration interface of the component. The goal was to make the interface
|
||||
more intuitive and reduce pitfalls to a minimum. Roughly speaking, the
|
||||
handling of the NIC router became more tailored to its/our typical use cases.
|
||||
|
||||
Let's create a practical setup to explain the changes in detail. Assume that
|
||||
there are two virtual subnets 192.168.1.0/24 and 192.168.2.0/24 within our
|
||||
Genode system. They connect as Virtnet A and B to the router. The standard
|
||||
gateway of the virtual networks is the NIC router with IP 192.168.*.1 . The
|
||||
router's uplink, on the other hand, is connected to the NIC driver. It
|
||||
interfaces the machine with our real-world home network 10.0.2.0/24. The home
|
||||
network is connected to the internet through its standard gateway 10.0.2.1.
|
||||
|
||||
[image nic_router_basic]
|
||||
|
||||
The basic router configuration for this setup without any routing rules would
|
||||
be as follows:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" />
|
||||
|
||||
The first thing to notice is the changed usage of the policy tag. Previously,
|
||||
the policy label - normally solely designated to correlate sessions with
|
||||
configuration domains - was misused also as unique peer identifier in the
|
||||
routing rules. This approach disregarded advanced label-matching techniques
|
||||
such as the 'label_prefix' used above. Now, the whole NIC-router-specific
|
||||
enhancement of the policy tag moved to the new '<domain>' tag, leaving the
|
||||
policy tag only with its original purpose to select policies. Note that even
|
||||
if this modification gives the impression, the router is not yet capable of
|
||||
handling multiple NIC sessions at one domain at a time.
|
||||
|
||||
In the domain tag, the 'interface' attribute replaces the old policy attribute
|
||||
named 'src'. That means, it tells the router which IP identity to use when
|
||||
talking as itself to the domain. But in addition to that, the 'interface'
|
||||
attribute also defines which subnet this identity and the domain belong to.
|
||||
This reflects a basic decision we made during the reworking process: The new
|
||||
NIC router is aware of subnets. Sessions of the same subnet have the same
|
||||
configuration domain. We came to this conclusion as it solves some fundamental
|
||||
problems with the old version. First, the equivalence of domain and subnet
|
||||
enables us to link a default gateway to a subnet by adding the 'gateway'
|
||||
attribute to the domain tag. In our example, this is done in the uplink
|
||||
domain. The 'gateway' attribute is optional for a domain and replaces the
|
||||
former 'via' attributes of the different routing rules. It is more efficient
|
||||
and natural to have this value set only once at the corresponding subnet than
|
||||
having it scattered all over the routing rules of the remote domains as done
|
||||
before. If a domain has no default gateway, it drops all packets with a
|
||||
foreign recipient.
|
||||
|
||||
The second advantage of a domain being equivalent to a subnet is that handling
|
||||
ARP broadcasts becomes easy. It can be excluded that such ARP broadcasts
|
||||
concern sessions outside the source domain anymore. And as sessions in the
|
||||
same domain are not distinguishable to the routing, the broadcast can be sent
|
||||
to all of them without breaking any rules.
|
||||
|
||||
Now, let's enhance our example by some routing rules. One pretty complicated
|
||||
thing to do with the old NIC router was port forwarding. You had to combine
|
||||
different routing rules, explicitly enable the back routing at the remote
|
||||
side, and take care that NAT was applied - a lot of opportunities for
|
||||
mistakes. With the new version, it became easier. Let's assume we have an HTTP
|
||||
server in Virtnet A and an NTP server in Virtnet B. We want the NIC router to
|
||||
act as proxy for their services in our home network.
|
||||
|
||||
[image nic_router_servers]
|
||||
|
||||
In order to achieve this, the uplink domain must be enhanced by two rules:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <tcp-forward port="443" domain="virtnet_a" to="192.168.1.2" />
|
||||
! <udp-forward port="123" domain="virtnet_b" to="192.168.2.2" />
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" />
|
||||
|
||||
The TCP forwarding rule for port 443 (HTTP+TLS/SSL) redirects to IP address
|
||||
192.168.1.2 in Virtnet A and the UDP forwarding rule for port 123 (NTP)
|
||||
redirects to IP address 192.168.2.2 in Virtnet B. The Virtnet domains remain
|
||||
empty as the router keeps track of the redirected transfers and routes back
|
||||
reply packets automatically. Also automatically, the router applies NAT for the
|
||||
server as it is in the nature of port forwarding.
|
||||
|
||||
Next, we add some clients to Virtnet B that like to talk to our home network
|
||||
and the internet. We want them to be hidden via NAT when they do so. For
|
||||
internet communication, they shall furthermore be limited to HTTP+TLS/SSL and
|
||||
IMAP+TLS/SSL.
|
||||
|
||||
[image nic_router_client]
|
||||
|
||||
This is what the router configuration looks now:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <tcp-forward port="443" domain="virtnet_a" to="192.168.1.2" />
|
||||
! <udp-forward port="123" domain="virtnet_b" to="192.168.2.2" />
|
||||
! <nat domain="virtnet_b" tcp-ports="1000" udp-ports="1000">
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" >
|
||||
! <tcp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </tcp>
|
||||
! <udp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </udp>
|
||||
! <tcp dst="0.0.0.0/0">
|
||||
! <permit port="443" domain="uplink" />
|
||||
! <permit port="993" domain="uplink" />
|
||||
! </tcp>
|
||||
! </domain>
|
||||
|
||||
There are several new tag types. One of them is the NAT configuration for
|
||||
Virtnet B in the uplink domain. In contrast to the former NIC-router version
|
||||
where NAT settings were part of the source domain, NAT is now configured in
|
||||
the target domain with a sub-tag for each source. This has the advantage
|
||||
of supporting heterogeneous NAT configurations for a packet source depending
|
||||
on which domain it talks to. Besides, it is more intuitive to read. Apart from
|
||||
that, the NAT settings haven't changed.
|
||||
|
||||
Furthermore, there are the new TCP and UDP tags in the Virtnet-B domain. The
|
||||
first two of them have a 'permit-any' sub-tag. With this combination, we open
|
||||
all ports to IP addresses of the 10.0.2.0/24 subnet, our home network, and
|
||||
route them to the uplink domain. TCP packets that don't match these first two
|
||||
rules may fall back to the third. This TCP rule doesn't have all ports opened
|
||||
but only 443 (HTTP+TLS/SSL) and 993 (IMAP+TLS/SSL). Both ports are again bound
|
||||
to the uplink domain. As the IP filter 0.0.0.0/0 of the surrounding rule isn't
|
||||
restrictive, we now also route packets to a foreign destination. The NIC
|
||||
router redirects such packets to the default gateway of our home network.
|
||||
|
||||
Compared to the old router version where IP and UDP/TCP routing had to be
|
||||
combined for this purpose, the new TCP and UDP rules with their
|
||||
port-permission sub-rules have some notable advantages. Like port-forwarding
|
||||
rules, TCP and UDP rules always imply link-state tracking in order to route
|
||||
back reply packets automatically. This can be seen also in our example as no
|
||||
further routing rules had to be added to the uplink domain. This aspect is
|
||||
clear from the outermost rule and not dependent on sub-rules anymore.
|
||||
Furthermore, the strict separation of UDP and TCP routing prevents
|
||||
configuration faults and increases readability. Last but not least, the
|
||||
'permit-any' rule allows something new. Opening all ports for an address range
|
||||
was previously only possible without link-state tracking as it could be
|
||||
expressed only on the IP level.
|
||||
|
||||
At this point, we have thoroughly discussed the layer-3 routing abilities of
|
||||
the new NIC router and our focus has indeed moved more into this direction.
|
||||
Even though IP routing is still available, we found that it should be more
|
||||
clearly separated from the rest. To illustrate this feature, we enhance our
|
||||
example again. We want the Virtnets to be allowed to communicate to each other
|
||||
without any restrictions. For that purpose, we add two more rules to the
|
||||
router configuration:
|
||||
|
||||
! <policy label_prefix="virtnet_a" domain="virtnet_a" />
|
||||
! <policy label_prefix="virtnet_b" domain="virtnet_b" />
|
||||
!
|
||||
! <domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" />
|
||||
! <tcp-forward port="443" domain="virtnet_a" to="192.168.1.2" />
|
||||
! <udp-forward port="123" domain="virtnet_b" to="192.168.2.2" />
|
||||
! <nat domain="virtnet_b" tcp-ports="1000" udp-ports="1000">
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_a" interface="192.168.1.1/24" />
|
||||
! <ip dst="192.168.2.0/24" domain="virtnet_b"/>
|
||||
! </domain>
|
||||
!
|
||||
! <domain name="virtnet_b" interface="192.168.2.1/24" >
|
||||
! <tcp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </tcp>
|
||||
! <udp dst="10.0.2.0/24"> <permit-any domain="uplink" /> </udp>
|
||||
! <tcp dst="0.0.0.0/0">
|
||||
! <permit port="443" domain="uplink" />
|
||||
! <permit port="993" domain="uplink" />
|
||||
! </tcp>
|
||||
! <ip dst="192.168.1.0/24" domain="virtnet_a"/>
|
||||
! </domain>
|
||||
|
||||
As you can see, each of the new IP rules in the Virtnet domains match the
|
||||
addresses of the opposite subnet and route to the corresponding domain. As
|
||||
mentioned, the new IP rules and UDP/TCP rules are not combined anymore to
|
||||
clearly distinguish IP routing from layer-3 routing because this decision has
|
||||
far-reaching effects. First, in contrast to UDP and TCP routing, IP routing is
|
||||
stateless. Thus, for each IP routing rule one has to be sure to have a
|
||||
back-routing rule at the remote domain or else bidirectional communication
|
||||
won't happen. And second, NAT does not apply to IP-routed packets. So, if
|
||||
you're not aware of such packets, you may unintentionally reveal information
|
||||
about a private network.
|
||||
|
||||
For more details on the new NIC router, you may refer to the comprehensive
|
||||
documentation in the _repos/os/src/server/nic_router/README_ file and the
|
||||
basic NIC-router test at _libports/run/nic_router.run_ .
|
||||
|
||||
|
||||
Base framework
|
||||
##############
|
||||
|
||||
Improved RPC mechanism
|
||||
======================
|
||||
|
||||
Since we introduced Genode's current API for synchronous RPCs in
|
||||
[https://genode.org/documentation/release-notes/11.05#New_API_for_type-safe_inter-process_communication - version 11.05],
|
||||
inter-component communication within Genode has become almost a child's play.
|
||||
The RPC framework leverages the C++ type system and templates to a great
|
||||
effect. In contrast to the traditional use of IDL compilers, the interaction
|
||||
with RPC objects provided by other components is robust and natural because
|
||||
no language boundaries need to be crossed.
|
||||
|
||||
Still, a few differences between RPC calls and regular function calls remain.
|
||||
In particular, there exist a few restrictions with regard to the types of
|
||||
RPC function arguments. Those types did not just need to be POD (plain old
|
||||
data) types but they had to be default-constructible, too. Whereas the former
|
||||
restriction still applies (non-POD objects that include references or
|
||||
vtables cannot be used as arguments), the latter limitation has been lifted
|
||||
now. Generally, non-default-constructible types are a way to attain
|
||||
simpler code because the special case of an "invalid" object does not need
|
||||
to be considered. I.e., values of such types can be kept as constants as
|
||||
opposed to variables. If an object exists (as equivalent to successful
|
||||
instantiation), it is valid. With the improved RPC mechanism, the RPC
|
||||
framework does no longer stay in the way in this respect.
|
||||
|
||||
Thanks to Edgard Schmidt for this welcome contribution!
|
||||
|
||||
|
||||
Unification and tightening of session labels
|
||||
============================================
|
||||
|
||||
In Genode, each session requested by a client component is labeled according
|
||||
to the components that intermediate the session request. The client can
|
||||
optionally specify a label of choice along with the session request. Its
|
||||
parent prefixes the client-provided label by a label of its own. If the
|
||||
session request is further passed to the parent's parent, the grandparent
|
||||
prepends its own label. This works recursively. Consequently, the final label
|
||||
as seen by the server is the product of the labeling policies of all
|
||||
components on the route of the session request.
|
||||
|
||||
The label is used for two purposes. First, the server uses the label as
|
||||
a key for a server-side policy selection. E.g., depending on the session label
|
||||
received by the disk-partition server, the server decides which partition to
|
||||
hand out to the client. Second, the label is used by intermediate components
|
||||
to take session-routing decisions. E.g., based on the label of a file-system
|
||||
session request, a parent component may route the request to one of several
|
||||
file-system servers.
|
||||
|
||||
Originally, Genode did not impose a specific way of how labels are formed.
|
||||
It was up to each intermediate component to filter the label of a session
|
||||
request in any way desired. However, in practice, this freedom remained unused
|
||||
and the very simple successive prefixing of labels prevails in all our use
|
||||
cases. Each intermediate node concatenates its own label in front of the label
|
||||
supplied by the originator of the session request. The different parts of the
|
||||
label are separated with the character sequence '" -> "'. Some corner cases
|
||||
were handles specially for aesthetic reasons. For example, if a client
|
||||
provided no label, the parent would skip the pending separator. That said,
|
||||
since each intermediate component had to provide the labeling policy, not all
|
||||
components were consistent in these respects. Since we found no use for
|
||||
arbitrary labeling policies, we decided to make the only prominent way of
|
||||
session labeling mandatory for all intermediate components. We thereby removed
|
||||
the aesthetically motivated corner cases and possible ambiguities. I.e., with
|
||||
the original policy, it was not possible to distinguish a unlabeled session
|
||||
requested by a client from a labeled session requested by the client's parent.
|
||||
|
||||
As a consequence, the stricter labeling must now be considered wherever
|
||||
a precise label was specified as a key for a session route or a server-side
|
||||
policy selection. The simplest way to adapt those cases is to use a
|
||||
'label_prefix' instead of the 'label' attribute. Alternatively, the
|
||||
'label' attribute may used by appending '" -> "' (note the whitespace).
|
||||
|
||||
|
||||
Transition to new framework API
|
||||
===============================
|
||||
|
||||
Since we fundamentally revised Genode's API in
|
||||
[https://genode.org/documentation/release-notes/16.05#The_great_API_renovation - version 16.05],
|
||||
we gradually adapt our existing components. Given that Genode comes with
|
||||
over 300 components, this is no small feat. But with 30 percent of the
|
||||
components converted, we already made substantial progress.
|
||||
|
||||
In some respects, the conversion is actually nearly complete. In particular,
|
||||
the move away from format-string-based text output to our new type-safe output
|
||||
facility has been applied to almost all components now. The former 'PDBG'
|
||||
macro that is quite useful for temporary debug messages has been replaced with
|
||||
a new version that must be manually included via the _base/debug.h_ header
|
||||
file. Like the regular log functions, the new PDBG facility uses the type-safe
|
||||
text-output facility.
|
||||
|
||||
|
||||
Minor API adjustments
|
||||
---------------------
|
||||
|
||||
While applying Genode's new API, we refined the API in the following respects:
|
||||
|
||||
We added a dedicated 'String' constructor overload to better accommodate
|
||||
string literals. This overload covers the common case for initializing a
|
||||
string from a literal without employing the 'Output' mechanism. This way, such
|
||||
strings can by constructed without calling virtual functions, which in turn
|
||||
makes the 'String' usable during the self-relocation phase of the dynamic
|
||||
linker.
|
||||
|
||||
Up till now, several Genode components still rely on the use of 'snprintf'
|
||||
whenever strings must be assembled out of smaller pieces. As we like to shun
|
||||
format strings from Genode altogether, we needed an alternative mechanism.
|
||||
Since we introduced the new type-safe text-output facilities in Genode 16.05,
|
||||
there is an obvious solution: Let the 'String' constructor accept an arbitrary
|
||||
list of arguments, which are turned into their respective textual
|
||||
representation and appear concatenated in the resulting string. Consequently,
|
||||
strings can be assembled with the same flexibility as log output. For the
|
||||
construction of 'String' objects from character buffers of a known size, the
|
||||
'Cstring' utility can be used, which takes a 'char const *' and an optional
|
||||
length as arguments.
|
||||
|
||||
Several low-level types received support for the new output facilities, e.g.,
|
||||
'Xml_node' or the network-related headers in _os/net/_.
|
||||
|
||||
In anticipation of the forthcoming package-management infrastructure, we try
|
||||
to unify Genode's executable binaries across kernels and architectures
|
||||
wherever reasonable. Of course, the latter is not possible with respect to the
|
||||
used instructions. But unifying symbol information is deemed worthwhile. For
|
||||
this reason, we changed the 'Genode::size_t' type to be always defined as an
|
||||
'unsigned' 'long'. This is in contrast to GCC's built-in '__SIZE_TYPE__',
|
||||
which is defined as 'unsigned int' on 32-bit architectures but 'unsigned long'
|
||||
on 64-bit architectures.
|
||||
|
||||
|
||||
OS-level infrastructure and device drivers
|
||||
##########################################
|
||||
|
||||
New timeout-handing API
|
||||
=======================
|
||||
|
||||
The new timeout API offers tools for easily multiplexing a single time
|
||||
source among different timeouts. In general, the time source can be
|
||||
implemented individually but we expect that the most prominent use case will
|
||||
be the multiplexing of timer sessions. Thus, the timeout library also provides
|
||||
a convenience tool for this use case. A library-usage example can be found
|
||||
under _os/src/test/timeout_. If you're interested in implementing
|
||||
your own time source, you can find an example at _os/include/os/timer.h_ .
|
||||
|
||||
|
||||
Support for smart cards
|
||||
=======================
|
||||
|
||||
We ported the [https://pcsclite.alioth.debian.org/pcsclite.html - PC/SC Lite]
|
||||
library to Genode, which provides a commonly used API for communicating with
|
||||
smart cards. It supports USB smart card readers, using the
|
||||
[https://pcsclite.alioth.debian.org/ccid.html - CCID] library as driver.
|
||||
The CCID driver itself requires [https://libusb.info - libusb] to access the
|
||||
USB device.
|
||||
|
||||
Vanilla PC/SC Lite is structured as a client-server architecture, consisting
|
||||
of the 'pcscd' daemon, which runs on a privileged user account and manages all
|
||||
card reader devices, and one or more non-privileged client applications, which
|
||||
communicate with pcscd to access the card readers. On Genode, pcscd's role as
|
||||
privileged device manager is not really needed, since the devices can also be
|
||||
managed using Genode's configuration mechanisms. For this reason, we merged
|
||||
the part of pcscd which implements the API with the pcsc-lite client library.
|
||||
|
||||
In the current state, a Genode application using PC/SC Lite can access a single
|
||||
card reader device, which is selected using its USB product ID and vendor ID in
|
||||
the application's configuration and in the policy of the USB driver.
|
||||
|
||||
More configuration details can be found in the README files of the PC/SC Lite,
|
||||
CCID, and libusb libraries in the libports repository and in the accompanying
|
||||
_smartcard.run_ script.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Time-based password generation
|
||||
==============================
|
||||
|
||||
A time-based one-time password authentication client that adheres to the
|
||||
Google Authenticator standard has been introduced into the
|
||||
[https://github.com/genodelabs/genode-world - world repository].
|
||||
|
||||
Single use, time-based passwords are commonly used as an additional
|
||||
authentication step for web-based services. In this scheme, a user generates
|
||||
and presents a six digit passcode to a service generated using a shared secret
|
||||
and a timestamp. This short passcode length makes manual entry convenient so
|
||||
that the shared secret may be stored on a separate device than the service
|
||||
client, such as a smartphone, layering the security properties of both
|
||||
devices.
|
||||
|
||||
The 'gtotp' VFS plugin provides these passcodes by embedding the generator as
|
||||
a special file in the file-system layer of a component. This approach provides
|
||||
readily available passcodes for programmatic and manual use without enlarging
|
||||
the code base to encompass a GUI, command-line, or networked interface.
|
||||
|
||||
At the time of this release, the common use case is to manually retrieve codes
|
||||
for clients running in VirtualBox by reading special files with an isolated
|
||||
instance of the Noux runtime. Storing the shared secret on the same device
|
||||
contradicts the recommendations of the standard but the trade-off is that the
|
||||
software stack required to host the shared secret is significantly smaller
|
||||
than that found on a mobile device.
|
||||
|
||||
|
||||
Random number generator testing
|
||||
===============================
|
||||
|
||||
No random number generator can be proved to be good, but empirical statistical
|
||||
tests can prove that some are bad. A port of the TestU01 RNG test suite is
|
||||
provided in the world repository. The TestU01 batteries give independent
|
||||
assurance of the fitness of Genode's CPU jitter based RNG and are available
|
||||
for testing future physical and non-phyical RNGs.
|
||||
|
||||
|
||||
VirtualBox on top on the NOVA hypervisor
|
||||
########################################
|
||||
|
||||
Both VirtualBox-based virtual machine monitors on Genode got updated to the
|
||||
latest revision as provided by Oracle, namely 4.3.40 and 5.1.10 - mainly to
|
||||
stay close to the upstream versions.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Unified handling of boot modules
|
||||
================================
|
||||
|
||||
Until now, the way of passing boot modules from the boot procedure to the core
|
||||
component, which core provides as ROM modules, varied from platform to
|
||||
platform. Either we used a multiboot-compliant bootloader that accepts
|
||||
multiple modules, or the platform provided some specific way of linking binary
|
||||
modules together with the kernel, e.g., the Elfweaver tool of OKL4.
|
||||
By unifying the boot-module handover, we further reduce platform specific core
|
||||
code. Thereby, maintenance costs are decreased, and code analysis becomes
|
||||
easier. With this new solution, when issuing to build the core component:
|
||||
|
||||
! make core
|
||||
|
||||
within the build system, only a core library gets built. Not until all
|
||||
binaries needed by a run-script are available, a final image is linked
|
||||
together using the core library and all additional binaries. The core
|
||||
component now can access its ROM modules directly via addresses contained in
|
||||
its binary. As a side effect of this change, there is no core binary in the
|
||||
'bin' or 'core' directory of the corresponding build directory available
|
||||
anymore. Instead, you will find the core binary with no ROM modules, but
|
||||
including debug information under 'var/run/*.core' within your build
|
||||
directory. The concrete name depends on the name of the run-script.
|
||||
|
||||
The new approach is used on all platforms except Linux where the ROM modules
|
||||
still need to be accessed via the file-system.
|
||||
|
||||
|
||||
NOVA hypervisor
|
||||
===============
|
||||
|
||||
We extended the kernel to support the asynchronous delegation of kernel
|
||||
resources. Up to now, resources could only be delegated during RPC or during
|
||||
the initial protection-domain construction. With this extension, the
|
||||
construction and setup of new protection domains, threads, and especially
|
||||
virtual CPUs for the VirtualBox VMM became more straightforward and several
|
||||
quirks inside the 'core' component could be dropped. The added kernel syscall
|
||||
expects the NOVA-kernel capabilities of the source and target protection
|
||||
domains, which effectively renders the operation solely available to 'core' -
|
||||
as only holder of the NOVA protection domain capabilities.
|
||||
|
||||
Additionally, we changed the CPU ID enumeration in Genode/NOVA to a
|
||||
predictable order. The lower CPU IDs used via the Genode 'Cpu_session'
|
||||
interface now correspond to the first hyper-thread of all physical CPU cores.
|
||||
For example, on a quad-core machine with hyper-threading enabled Genode's CPU
|
||||
IDs 0-3 refer to the first hyper-threads of all physical cores and IDs 4-7 to
|
||||
the second hyper-threads.
|
||||
|
||||
1033
doc/release_notes/17-05.txt
Normal file
1033
doc/release_notes/17-05.txt
Normal file
File diff suppressed because it is too large
Load Diff
651
doc/release_notes/17-08.txt
Normal file
651
doc/release_notes/17-08.txt
Normal file
@@ -0,0 +1,651 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 17.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The flagship feature of Genode 17.08 has been in the works for more than a
|
||||
year: The support for hardware-accelerated graphics on Intel Gen-8 GPUs. This
|
||||
is an especially challenging topic because it is riddled with terminology,
|
||||
involves highly complex software stacks, carries a twisted history with it,
|
||||
and remains to be a moving target. It took up a lot of patience to build up a
|
||||
profound understanding of the existing driver architectures and the mechanisms
|
||||
offered by modern graphics hardware. On the other hand, with the proliferation
|
||||
of hardware-based sandboxing features like virtual GPU memory and hardware
|
||||
contexts, we found that now is the perfect time for a clean-slate design of a
|
||||
microkernelized GPU driver.
|
||||
Section [Hardware-accelerated graphics for Intel Gen-8 GPUs] introduces this
|
||||
work, which includes our new GPU multiplexer as well as the integration with
|
||||
the client-side Mesa protocol stack.
|
||||
|
||||
The second focus of the current release is the extension of Genode's supported
|
||||
base platforms. Most prominently, we upgrade the seL4 kernel to version 6.0
|
||||
while extending the architecture support from 32-bit x86 to ARM and 64-bit
|
||||
x86 (Section [The seL4 kernel on ARM and 64-bit x86 hardware]). To bring
|
||||
Genode closer to cloud-computing scenarios, we added basic support for
|
||||
executing Genode scenarios as Xen DomU domains (Section [Genode as Xen DomU]).
|
||||
Furthermore, the Muen separation kernel has been updated to a current version.
|
||||
As a cross-kernel effort, there is work under way to boot Genode-based
|
||||
systems via UEFI, currently addressing the NOVA, base-hw, and seL4 kernels.
|
||||
|
||||
Among the many other functional additions are a new VFS plugin for accessing
|
||||
FAT file systems, new components like _sequence_ and _fs_report_ that aid new
|
||||
system compositions, and our evolving custom package-management
|
||||
infrastructure.
|
||||
|
||||
|
||||
Hardware-accelerated graphics for Intel Gen-8 GPUs
|
||||
##################################################
|
||||
|
||||
The ability to leverage hardware-accelerated graphics is generally taken for
|
||||
granted in modern commodity operating systems. The user experience of
|
||||
modern desktop environments, web-browser performance, and obviously games
|
||||
depend on it. On the other hand, the benefit of hardware-accelerated graphics
|
||||
comes at the expense of tremendous added complexity in the lower software
|
||||
stack, in particular in system components that need to be ultimately trusted.
|
||||
For example, with circa 100 thousand lines of code, the Intel GPU driver in
|
||||
the Linux kernel is an order of magnitude more complex than a complete modern
|
||||
microkernel. In a monolithic-kernel-based system, this complexity is
|
||||
generally neglected because the kernel is complex anyway. But in
|
||||
microkernel-based scenarios optimized for a trusted computing base in the
|
||||
order of a few ten thousand lines of code, it becomes unacceptable.
|
||||
Fortunately, recent generations of graphics hardware provide a number of
|
||||
hardware features that promise to solve this conflict, which prompted us to
|
||||
investigate the use of these features for Genode.
|
||||
|
||||
During this year's Hack'n'Hike event, we ported the ioquake3 engine to Genode.
|
||||
As preliminary requirement, we had to resurrect OpenGL support in our aging
|
||||
graphics stack and enable support for current Intel HD Graphics devices (IGD).
|
||||
We started by updating Mesa from the old 7.8.x to a more recent 11.2.2 release.
|
||||
Since we focused mainly on supporting Intel devices, we dropped support for the
|
||||
Gallium back end as Intel still uses the old DRI infrastructure. This decision,
|
||||
however, also influenced the choice of the software rendering back end. Rather
|
||||
than retaining the softpipe implementation, we now use swrast. In addition, we
|
||||
changed the available OpenGL implementation from OpenGL ES 2.x to the fully
|
||||
fledged OpenGL 4.5 profile, including the corresponding shader language
|
||||
version. As with the previous Mesa port, EGL serves as front end API for
|
||||
system integration and loads a DRI back-end driver (i965 or swrast). EGL
|
||||
always requests the back-end driver 'egl_drv.lib.so' in form of a shared
|
||||
object. Genode's relabeling features are used to select the proper back end
|
||||
via a route configuration. The following snippet illustrates such a
|
||||
configuration for software rendering:
|
||||
|
||||
! <start name="gears" caps="200">
|
||||
! <resource name="RAM" quantum="32M"/>"
|
||||
! <route>
|
||||
! <service name="ROM" label="egl_drv.lib.so">
|
||||
! <parent label="egl_swrast.lib.so"/>
|
||||
! </service>
|
||||
! <any-service> <parent/> <any-child/> </any-service>
|
||||
! </route>
|
||||
! </start>
|
||||
|
||||
With the graphics-stack front end in place, it was time to take care of the
|
||||
GPU driver. In our case this meant implementing the DRM interface in our
|
||||
ported version of the Intel i915 DRM driver. Up to now, this driver was solely
|
||||
used for mode setting while we completely omitted supporting the render
|
||||
engine.
|
||||
|
||||
[image mesa_genode]
|
||||
|
||||
With this new and adapted software stack, we successfully could play ioquake3
|
||||
on top of Genode with a reasonable performance in 1080p on a Thinkpad X250.
|
||||
|
||||
During this work, we gathered valuable insights into the architecture of a
|
||||
modern 3D-graphics software stack as well as into recent Intel HD Graphics
|
||||
hardware. We found that the Intel-specific Mesa driver itself is far more
|
||||
complex than its kernel counter part. The DRM driver is mainly concerned with
|
||||
resource and execution management whereas the Mesa driver programs the GPU.
|
||||
For example, amongst others, Mesa compiles the OpenGL shaders into a
|
||||
GPU-specific machine code that is passed on to the kernel for execution.
|
||||
|
||||
While inspecting the DRM driver, it became obvious that one of the reasons for
|
||||
its complexity is the need to support a variety of different HD Graphics
|
||||
generations as well as different features driven by software-usage patterns.
|
||||
For our security related use cases, it is important to offer a clear isolation
|
||||
and separation mechanism per client. Hardware features provided by modern
|
||||
Intel GPUs like per-process graphics translation tables (PPGTT) and hardware
|
||||
contexts that are unique for each client make it possible to fulfill these
|
||||
requirements.
|
||||
|
||||
By focusing on this particular feature set and thus limiting the supported
|
||||
hardware generations, the development of a maintainable GPU multiplexer for
|
||||
Genode became feasible. After all, we strive to keep all Genode components as
|
||||
low complex as possible, especially resource multiplexers like such a GPU
|
||||
multiplexer.
|
||||
|
||||
[image intel_gpu_drv]
|
||||
This image shows multiple GPU-session clients and the resources they are
|
||||
using. The fence registers as well as the aperture is partitioned between
|
||||
them, the PPGTT is backed by the system memory, and the contexts are located
|
||||
in disjoint GGTT regions.
|
||||
|
||||
Within four months, we implemented an experimental GPU multiplexer for Intel
|
||||
HD Graphics Gen8 (Broadwell class) devices. We started out defining a GPU
|
||||
session interface that is sufficient to implement the API used by the DRM
|
||||
library. For each session, the driver creates a context consisting of a
|
||||
hardware context, a set of page tables (PPGTT), and a part of the aperture.
|
||||
The client may use the session to allocate and map memory buffers used by the
|
||||
GPU. Each buffer is always eagerly mapped 1:1 into the PPGTT by using the
|
||||
local virtual address of the client. Special memory buffers like an image
|
||||
buffer are additionally mapped through the aperture to make use of the
|
||||
hardware-provided de-tiling mechanism. As is essential in Genode components,
|
||||
the client must donate all resources that the driver might need to fulfill the
|
||||
request, i.e., quota for memory and capability allocations. Clients may
|
||||
request the execution of their workload by submitting an execution buffer. The
|
||||
GPU multiplexer will then enqueue the request and schedule all pending
|
||||
requests sequentially. Once the request is completed, the client is notified
|
||||
via a completion signal.
|
||||
|
||||
[image multi_gl]
|
||||
Example scenario of multiple OpenGL programs that use the new GPU multiplexer
|
||||
for hardware-accelerated rendering.
|
||||
|
||||
We consider this first version of the GPU driver as experimental. As of now,
|
||||
it only manages the render engine of the GPU. Mode-setting or rather display
|
||||
handling must be performed by another component. Currently, the VESA driver is
|
||||
used for this purpose. It also lacks any power-management functionality and
|
||||
permanently keeps the GPU awake. Both limitations will be addressed in future
|
||||
releases and support for Gen9+ (Skylake) and newer devices might be added.
|
||||
|
||||
In its current incarnation, the GPU multiplexer component consists of about
|
||||
4,200 lines of code whereas the Mesa DRI i965 driver complements the driver at
|
||||
the client side with about 78,000 lines of code.
|
||||
|
||||
|
||||
The seL4 kernel on ARM and 64-bit x86 hardware
|
||||
##############################################
|
||||
|
||||
With the 16.08 release, we brought the seL4 support to a level to be
|
||||
considered being on par with the other supported kernels. At the time,
|
||||
Genode's use of seL4 was limited to 32-bit x86 platforms.
|
||||
|
||||
In the current release, we extend the platform support to ARM and 64-bit x86.
|
||||
We started this line of work with an incremental kernel upgrade from version
|
||||
3.2.0 to 5.2.0 and finally to seL4 6.0. Through these upgrades, we were able
|
||||
to drop several Genode-specific seL4 patches, which were required in the 16.08
|
||||
release. One major improvement of version 6.0 compared to earlier versions is
|
||||
the handling of device-memory announcements by the kernel to Genode's roottask
|
||||
_core_.
|
||||
|
||||
With the kernel update in place, we inspected the x86-specific part thoroughly
|
||||
while splitting and separating it properly into architecture-agnostic and
|
||||
architecture-dependent parts. Upon this work, we added the
|
||||
architecture-specific counterparts for x86_64 and ARM. One major work item was
|
||||
to make the page-table handling in Genode's core aware and generic enough to
|
||||
handle the different page-table sizes of the three architectures.
|
||||
|
||||
For the ARM support, we decided to enable the i.MX6 FreeScale based SoC,
|
||||
namely the Wandboard Quad board. Since the seL4 kernel interface provides no
|
||||
timeout support, we revived a user-level timer driver that we originally
|
||||
developed for our custom base-hw kernel: The so-called EPIT timer, which is
|
||||
part of most i.MX SoCs.
|
||||
|
||||
We finished the essential work for the mentioned three platforms in
|
||||
less time than expected and, thereby, had spare time to address additional
|
||||
features.
|
||||
|
||||
First, we enabled multiprocessor support for Genode/seL4 on x86 and
|
||||
thread-priority support for all seL4 platforms. Additionally, we were able to
|
||||
utilize the seL4 benchmark interface for Genode's trace infrastructure in
|
||||
order to obtain utilization information about threads and CPUs. The Genode
|
||||
components _top_ (text-based) and _cpu_load_monitor_ (graphical) are now
|
||||
usable on Genode/seL4.
|
||||
Finally, as we are currently exploring the support for booting various kernels
|
||||
via UEFI on x86, we took the chance to investigate the steps needed to boot
|
||||
seL4 via UEFI. UEFI firmware does not always provide a compatibility support
|
||||
module (CSM) for legacy BIOS boot support. Hence, we extended the seL4 kernel
|
||||
for Genode according to the Multiboot2 specification, which enables us to
|
||||
start Genode/seL4 together with GRUB2 - as an UEFI capable bootloader - on
|
||||
machines missing CSM support.
|
||||
|
||||
|
||||
Base framework and OS-level infrastructure
|
||||
##########################################
|
||||
|
||||
Simplified IOMMU handling
|
||||
=========================
|
||||
|
||||
When IOMMUs are used on x86, all host memory targeted via direct memory
|
||||
accesses (DMA) by devices must eagerly be registered in the respective I/O
|
||||
page table of the device. Up to now, Genode supports IOMMUs on NOVA only. On
|
||||
this kernel, a device protection domain is represented as a regular protection
|
||||
domain with its virtual memory layout being used for both the CPU's MMU and
|
||||
the device. Traditionally, mappings into such virtual memory spaces are
|
||||
inserted on demand as responses to page faults. However, as there are no page
|
||||
faults for DMA transactions, DMA buffers must always be eagerly mapped. The
|
||||
so-called device PD hid this gap for NOVA. In anticipation of adding IOMMU
|
||||
support for more kernels, we desired to generalize the device-PD mechanism by
|
||||
introducing an explicit way to trigger the insertion of DMA memory into the
|
||||
proper page tables.
|
||||
|
||||
We extended the PD-session interface by a 'map' function, which takes a
|
||||
virtual memory region of the PD's virtual address space as argument. The page
|
||||
frames of the previously attached dataspaces are added eagerly by core to the
|
||||
IOMMU page-tables. With this explicit 'map' support, we were able to replace
|
||||
the Genode/NOVA-specific device-PD implementation with a generic one, which
|
||||
will easily accommodate other kernels in the future.
|
||||
|
||||
|
||||
New report server for capturing reports to files
|
||||
================================================
|
||||
|
||||
The report session is a simple mechanism for components to publish structured
|
||||
data without the complexity of a file-system layer. In the simplest case, a
|
||||
client component will produce a report and communicate it directly to a
|
||||
component acting as a server. The disadvantage is that the report client
|
||||
becomes reliant on the liveliness and presence of the consumer component. So
|
||||
in the more robust case, the _report_rom_ component acts as the server hosting
|
||||
the report service as well as a ROM service for components consuming reports.
|
||||
|
||||
The _report_rom_ server permits ROM access only to clients matching an
|
||||
explicit configuration policy. This is good for security but opaque to a user.
|
||||
Reports can only be read where an explicit policy is in place and only a
|
||||
single report session can report to an active ROM session.
|
||||
|
||||
The new _fs_report_ component is a friendlier and more flexible report server.
|
||||
Reports are written to a file system using a file and directory hierarchy that
|
||||
expresses session routing. This allows for intuitive report inspection and
|
||||
injection via a file system. When used with the _ram_fs_ and _fs_rom_ servers,
|
||||
it can also replicate the functionality of _report_rom_.
|
||||
|
||||
|
||||
New runtime environment for starting components sequentially
|
||||
============================================================
|
||||
|
||||
The _init_ component is a prime example of software with an emphasis on
|
||||
function over features. It is the fundamental building block for combining
|
||||
components yet its behavior is simple and without heuristics. Like other
|
||||
contemporary init managers, it starts components in parallel, but to a more
|
||||
extreme degree in that it has no concept of "runlevels" or "targets", all
|
||||
components are started as soon as possible. The concrete sequence of execution
|
||||
is instead determined by when server components make service announcements and
|
||||
how quickly they respond to client requests.
|
||||
|
||||
In some cases, the execution of one component must not occur until the
|
||||
execution of another component ends, be it that the first produces output that
|
||||
is consumed by the second, or that the two contend for a service that cannot
|
||||
be multiplexed. Init contains no provisions to enforce ordering. But we are
|
||||
free to define new behaviors in other management components.
|
||||
|
||||
The solution to the problem of ordering is the _sequence_ component. Sequence
|
||||
walks a list of children and executes them in order, one at a time. With only
|
||||
one child active, there is no need for any local resource or routing
|
||||
management. By applying the same session label transformations as init,
|
||||
external routing and policy handling are unchanged.
|
||||
|
||||
An example of ordering a producer and consumer within an init configuration
|
||||
follows:
|
||||
! <start name="sequence">
|
||||
! <resource name="RAM" quantum="128M"/>
|
||||
! <config>
|
||||
! <start name="producer">
|
||||
! <config .. />
|
||||
! </start>
|
||||
! <start name="consumer">
|
||||
! <config .. />
|
||||
! </start>
|
||||
! </config>
|
||||
! <route>
|
||||
! <service name="LOG" label_prefix="producer">
|
||||
! <child name="log_a"/> </service>
|
||||
! <service name="LOG" label_prefix="consumer">
|
||||
! <child name="log_b"/> </service>
|
||||
! <any-service> <parent/> <any-child/> </any-service>
|
||||
! </route>
|
||||
! </start>
|
||||
|
||||
|
||||
Support for boot-time initialized frame buffer
|
||||
==============================================
|
||||
|
||||
UEFI-based systems do not carry along legacy BIOS infrastructure, on which
|
||||
our generic VESA driver depends. Hence, when booting via UEFI, one has to use
|
||||
either a hardware-specific driver like our Intel-FB driver or - alternatively -
|
||||
facilitate generic UEFI mechanisms.
|
||||
|
||||
Instead of booting in VGA text mode and leaving the switch to a graphics mode
|
||||
(via real-mode SVGA BIOS subroutines) to the booted OS, UEFI employs the
|
||||
so-called graphics output protocol as a means to setup a reasonable default
|
||||
graphics mode prior booting the operating system. In order to produce
|
||||
graphical output, the operating system merely has to know the physical address
|
||||
and layout of the frame buffer. Genode's core exposes this information as the
|
||||
_platform_info_ ROM module. The new _fb_boot_drv_ driver picks up this
|
||||
information to provide a Genode framebuffer session interface. Hence, on
|
||||
UEFI-based systems, it can be used as a drop-in replacement for the VESA
|
||||
driver. In contrast to the VESA driver, however, it is not able to switch
|
||||
graphics modes at runtime.
|
||||
|
||||
The new component is located at _os/src/drivers/framebuffer/boot/_. Thanks
|
||||
to Johannes Kliemann for this contribution.
|
||||
|
||||
|
||||
Extended non-blocking operation of the VFS
|
||||
==========================================
|
||||
|
||||
In
|
||||
[https://genode.org/documentation/release-notes/17.02#VFS_support_for_asynchronous_I_O_and_reconfiguration - version 17.02],
|
||||
we added support for non-blocking reads from the VFS in the form of the
|
||||
'read_ready()', 'queue_read()', and 'complete_read()' functions. Since then,
|
||||
it has become obvious that blocking within the VFS is not only problematic in
|
||||
the VFS server itself when multiple clients are connected, but also when the
|
||||
VFS is deployed in a multi-threaded environment and a VFS plugin needs to
|
||||
reliably wait for I/O-completion signals.
|
||||
|
||||
For this reason, we reworked the interface of the VFS even more towards
|
||||
non-blocking operation and adapted the existing users of the VFS accordingly.
|
||||
|
||||
The most important changes are:
|
||||
|
||||
* Directories are now created and opened with the 'opendir()' function and
|
||||
the directory entries are read with the 'queue_read()' and 'complete_read()'
|
||||
functions.
|
||||
|
||||
* Symbolic links are now created and opened with the 'openlink()' function and
|
||||
the link target is read with the 'queue_read()' and 'complete_read()'
|
||||
functions and written with the 'write()' function.
|
||||
|
||||
* The 'write()' function does not wait for signals anymore. This can have the
|
||||
effect that data written by a VFS library user has not been processed by a
|
||||
file-system server when the library user asks for the size of the file or
|
||||
closes it (both done with RPC functions at the file-system server). For this
|
||||
reason, a user of the VFS library should request synchronization before
|
||||
calling 'stat()' or 'close()'. To make sure that a file-system server has
|
||||
processed all write request packets that a client submitted prior the
|
||||
synchronization request, synchronization is now requested at the file-system
|
||||
server with a synchronization packet instead of an RPC function. Because of
|
||||
this change, the synchronization interface of the VFS library has been split
|
||||
into the 'queue_sync()' and 'complete_sync()' functions.
|
||||
|
||||
|
||||
Making block sessions read-only by default
|
||||
==========================================
|
||||
|
||||
Genode server components are expected to apply the safest and strictest
|
||||
behavior when exposing cross-component state or persistent data. In practice
|
||||
block and file-system servers only allow access to clients with explicitly
|
||||
configured local policies. The file-system servers enforce an additional
|
||||
provision that sessions are implicitly read-only unless overridden by policy.
|
||||
This release introduces a similar restriction to the AHCI driver and partition
|
||||
multiplexer. Clients of these servers require an affirmative 'writeable'
|
||||
attribute on policies to permit the writing of blocks. Write permission at
|
||||
these servers may also be revoked by components that forward block-session
|
||||
requests by placing 'writeable="no"' into session-request arguments.
|
||||
|
||||
All users of _ahci_drv_ and _part_blk_ are advised that this change may break
|
||||
existing configurations without explicit 'writeable' policies.
|
||||
|
||||
|
||||
Refined time handling
|
||||
=====================
|
||||
|
||||
Release 17.05 introduced a
|
||||
[https://genode.org/documentation/release-notes/17.05#New_API_for_user-level_timing - new API for user-level timing]
|
||||
named _timeout framework_. Together with this new framework came a
|
||||
comprehensive test that stresses all aspects of the interface. During the past
|
||||
few months, this test has turned out to be an enrichment for Genode far beyond
|
||||
its original scope. As the test significantly raised the standards in
|
||||
user-level timing, it also sharpened our view on the measurement precision of
|
||||
various timer drivers and timestamps, which act as input for the framework.
|
||||
This revealed several problems previously unidentified. For instance, we
|
||||
improved the accuracy and stability of the time values provided by the drivers
|
||||
for the Raspberry-Pi timer, the Cortex-A9 timer, the PIT, and the LAPIC. We
|
||||
also were able to further optimize the calibration of the TSC in the NOVA
|
||||
kernel.
|
||||
|
||||
Additionally, the test also helped us to refine the timeout framework itself.
|
||||
The initial calibration of the framework - that previously took about 1.5
|
||||
seconds - is now performed much quicker. This makes microseconds-precise time
|
||||
available immediately after the timer connection switched to the modern
|
||||
fine-grained mode of operation, which is a prerequisite for hardware drivers
|
||||
that need such precision during their early initialization phase. The
|
||||
calculations inside the framework also became more flexible to better fit the
|
||||
characteristics of all the hardware and kernels Genode supports.
|
||||
|
||||
Finally, we were able to extend the application of the timeout framework. Most
|
||||
notably, our C runtime uses it as timing source to the benefit of all
|
||||
libc-using components. Another noteworthy case is the USB driver on the
|
||||
Raspberry Pi. It previously couldn't rely on the default Genode timing but
|
||||
required a local hardware timer to reach the precision that the host
|
||||
controller expected from software. With the timeout framework, this workaround
|
||||
could be removed from the driver.
|
||||
|
||||
|
||||
FatFS-based VFS plugin
|
||||
======================
|
||||
|
||||
Genode has supported VFAT file-systems since the 9.11 release when the
|
||||
[http://elm-chan.org/fsw/ff/00index_e.html - FatFS] library was first ported.
|
||||
The 11.08 release fit the library into the libc plugin architecture and
|
||||
in 12.08 FatFS was used in the _ffat_fs_ file-system server. Now, the 17.08
|
||||
release revisits FatFS to mold the library into the newer and more flexible
|
||||
VFS plugin system. The _vfs_fatfs_ plugin may be fitted into the VFS server or
|
||||
used directly by arbitrary components linked to the VFS library. As the
|
||||
collection of VFS plugins in combination with the VFS file-system server has a
|
||||
lower net maintenance cost than multiple file-system servers, the _ffat_fs_
|
||||
server will be retired in a future release.
|
||||
|
||||
|
||||
Enhanced GUI primitives
|
||||
=======================
|
||||
|
||||
Even though we consider Qt5 as the go-to solution for creating advanced
|
||||
graphical user interfaces on top of Genode, we also continue to explore an
|
||||
alternative approach that facilitates Genode's component architecture to an
|
||||
extreme degree. The so-called menu-view component takes an XML description of
|
||||
a dialog as input and produces rendered pixels as output. It also gives
|
||||
feedback to user input such as the hovered widget at a given pointer position.
|
||||
The menu view does not implement any application logic but is meant to be
|
||||
embedded as a child component into the actual application. This approach
|
||||
relieves the application from the complexity (and potential bugs) of widget
|
||||
rendering. It also reinforces a rigid separation of a view and its underlying
|
||||
data model.
|
||||
|
||||
The menu view was first introduced in
|
||||
[https://genode.org/documentation/release-notes/14.11#New_menu_view_application - version 14.11].
|
||||
The current release improves it in the following ways:
|
||||
|
||||
* The new '<float>' widget aligns a child widget within a
|
||||
larger parent widget by specifying the boolean attributes 'north', 'south',
|
||||
'east', and 'west'. If none is specified, the child is centered. If opposite
|
||||
attributes are specified, the child is stretched.
|
||||
|
||||
* A new '<depgraph>' widget arranges child widgets in the form of a
|
||||
dependency graph, which will be the cornerstone for Genode's upcoming
|
||||
interactive component-composition feature. As a prerequisite for
|
||||
implementing the depgraph widget, Genode's set of basic graphical primitives
|
||||
received new operations for drawing sub-pixel-accurate anti-aliased lines
|
||||
and bezier curves.
|
||||
|
||||
* All geometric changes of the widget layout are animated now. This includes
|
||||
structural changes of the new '<depgraph>' widget.
|
||||
|
||||
[image depgraph]
|
||||
|
||||
The menu-view component is illustrated by the run script at
|
||||
_gems/run/menu_view.run_.
|
||||
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
The growing number of ported applications used on Genode is accompanied by the
|
||||
requirement of extensive POSIX compatibility of our C runtime. Therefore, we
|
||||
enhanced our implementation by half a dozen features (e.g., O_ACCMODE
|
||||
tracking) during the past release cycle. We thank the contributors of patches
|
||||
and test cases and will continue our efforts to accommodate more ported
|
||||
open-source components in the future.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Mesa adjustments
|
||||
================
|
||||
|
||||
The Mesa update required the adaption of all components that use OpenGL.
|
||||
In particular that means the Qt5 framework. Furthermore, we also enabled
|
||||
OpenGL support in our SDL1 port.
|
||||
|
||||
As playground, there are a few OpenGL examples. The demos are located under
|
||||
_repos/libports/src/test/mesa_demos_, which use the EGLUT bindings. There
|
||||
are also some SDL based examples in the world repository under
|
||||
_repos/world/src/test/sdl_opengl_.
|
||||
|
||||
|
||||
Package management
|
||||
==================
|
||||
|
||||
The previous release featured the initial version of Genode's
|
||||
[https://genode.org/documentation/release-notes/17.05#Package_management - custom package-management tools].
|
||||
Since then, we continued this line of work in three directions.
|
||||
|
||||
First, we refined the depot tools and the integration of the depot with our
|
||||
custom work-flow ("run") tool. One important refinement is a simplification of
|
||||
the depot's directory layout for library binaries. We found that the initial
|
||||
version implied unwelcome complexities down the road. Instead of placing
|
||||
library binaries in a directory named after their API, they are now placed
|
||||
directly in the architecture directory along with regular binaries.
|
||||
|
||||
Second, driven by the proliferated use of the depot by more and more run
|
||||
scripts, we enhanced the depot with new depot recipes as needed.
|
||||
|
||||
Third, we took the first steps to use the depot on-target. The experimentation
|
||||
with on-target depots is eased by the new 'create_tar_from_depot_binaries'
|
||||
function of the run tool, which allows one to assemble a new depot in the form
|
||||
of a tar archive out of a subset of packages. Furthermore, the new
|
||||
_depot_query_ component is able to scan an on-target depot for runtime
|
||||
descriptions and returns all the information needed to start a subsystem based
|
||||
on the depot content. The concept is exemplified by the new
|
||||
_gems/run/depot_deploy.run_ script, which executes the "fs_report" test case
|
||||
supplied via a depot package.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Genode as Xen DomU
|
||||
==================
|
||||
|
||||
We want to widen the application scope of Genode by enabling users to easily
|
||||
deploy Genode scenarios on Xen-based cloud platforms.
|
||||
|
||||
As a first step towards this goal, we enhanced our run tool to support running
|
||||
Genode scenarios as a local Xen DomU, managed from within the Genode build
|
||||
system on Linux running as Xen Dom0.
|
||||
|
||||
The Xen DomU runs in HVM mode (full virtualization) and loads Genode from an
|
||||
ISO image. Serial log output is printed to the text console and graphical
|
||||
output is shown in an SDL window.
|
||||
|
||||
To use this new target platform, the following run options should be defined in
|
||||
the 'build/x86_*/etc/build.conf' file:
|
||||
|
||||
! RUN_OPT = --include boot_dir/$(KERNEL)
|
||||
! RUN_OPT += --include image/iso
|
||||
! RUN_OPT += --include power_on/xen
|
||||
! RUN_OPT += --include log/xen
|
||||
! RUN_OPT += --include power_off/xen
|
||||
|
||||
The Xen DomU is managed using the 'xl' command line tool and it is possible to
|
||||
add configuration options in the 'xen_args' variable of a run script. Common
|
||||
options are:
|
||||
|
||||
* Disabling the graphical output:
|
||||
|
||||
! append xen_args { sdl="0" }
|
||||
|
||||
* Configuring a network device:
|
||||
|
||||
! append xen_args { vif=\["model=e1000,mac=02:00:00:00:01:01,bridge=xenbr0"\] }
|
||||
|
||||
* Configuring USB input devices:
|
||||
|
||||
! append xen_args { usbdevice=\["mouse","keyboard"\] }
|
||||
|
||||
Note that the 'xl' tool requires super-user permissions. Interactive
|
||||
password input can be complicated in combination with 'expect' and is not
|
||||
practical for automated tests. For this reason, the current implementation
|
||||
assumes that no password input is needed when running 'sudo xl', which can
|
||||
be achieved by creating a file '/etc/sudoers.d/xl' with the content
|
||||
|
||||
! user ALL=(root) NOPASSWD: /usr/sbin/xl
|
||||
|
||||
where 'user' is the Linux user name.
|
||||
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
UEFI support
|
||||
------------
|
||||
|
||||
Analogously to our work on the seL4 and NOVA kernels in this release, we
|
||||
extended our base-hw kernel to become a Multiboot2 compliant kernel. When used
|
||||
together with GRUB2, it can be started on x86 UEFI machines missing legacy
|
||||
BIOS support (i.e., CSM).
|
||||
|
||||
|
||||
RISC-V
|
||||
------
|
||||
|
||||
With Genode version 17.05, we updated base-hw's RISC-V support to privileged
|
||||
ISA revision 1.9.1. Unfortunately, this implied that dynamic linking was not
|
||||
supported on the RISC-V architecture anymore. Since dynamic linking is now
|
||||
required for almost all Genode applications by default, this became a severe
|
||||
limitation. Therefore, we revisited our RISC-V implementation - in particular
|
||||
the kernel entry code - to lift the limitation of being able to execute only
|
||||
statically linked binaries.
|
||||
|
||||
Additionally, we integrated the Berkeley Boot Loader (BBL), which bootstraps
|
||||
the system and implements the machine mode, more closely into our build
|
||||
infrastructure. We also added a new timer implementation to base-hw by using
|
||||
the _set timeout SBI_ call of BBL.
|
||||
|
||||
What still remains missing is proper FPU support. While we are building the
|
||||
Genode tool chain with soft float support, we still encounter occasions where
|
||||
FPU code is generated, which in turn triggers compile time errors. We will
|
||||
have to investigate this behavior more thoroughly, but ultimately we want to
|
||||
add FPU support for RISC-V to our kernel and enable hardware floating point in
|
||||
the tool chain.
|
||||
|
||||
|
||||
Muen separation kernel
|
||||
======================
|
||||
|
||||
Besides updating the Muen port to the latest kernel version as of end of June,
|
||||
Muen has been added to Genode's automated testing infrastructure. This
|
||||
includes the revived support for VirtualBox 4 on top of this kernel.
|
||||
|
||||
|
||||
NOVA microhypervisor
|
||||
====================
|
||||
|
||||
The current release extends NOVA to become a Multiboot2 compliant kernel. Used
|
||||
together with GRUB2, NOVA can now be started on x86 UEFI machines missing
|
||||
legacy BIOS support (called CSM).
|
||||
|
||||
GRUB2 provides the initial ACPI RSDP (Root System Description Pointer) to a
|
||||
Multiboot2 kernel. The RSDP contains vital information required to bootstrap
|
||||
the kernel and the operating system in general on today's x86 machines. To
|
||||
make this information available to the user-level ACPI and ACPICA drivers, the
|
||||
kernel propagates the RSDP to Genode's core, which - in turn - exposes it to
|
||||
the user land as part of the _platform_info_ ROM module.
|
||||
|
||||
In order to ease the setup of an UEFI bootable image, we added a new image
|
||||
module to our run-tool infrastructure. The run option 'image/uefi' can be used
|
||||
instead of 'image/iso' in order to create a raw image that contains a EFI
|
||||
system partition in a GUID partition table (GPT). The image is equipped by the
|
||||
new 'image/uefi' module with the GRUB2 boot loader, a GRUB2 configuration, and
|
||||
the corresponding Genode run scenario. The final image can be copied with 'dd'
|
||||
to a bootable USB stick. Additionally, we added support to boot such an image
|
||||
on Qemu leveraging [https://www.tianocore.org - TianoCore's] UEFI firmware.
|
||||
|
||||
As a side project, minor virtualization support for AMD has been added to
|
||||
Virtualbox 4 and to the NOVA kernel on Genode. This enables us to run a 32-bit
|
||||
Windows 7 VM on a 32-bit Genode/NOVA host on an (oldish) AMD Phenom II X4 test
|
||||
machine.
|
||||
703
doc/release_notes/17-11.txt
Normal file
703
doc/release_notes/17-11.txt
Normal file
@@ -0,0 +1,703 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 17.11
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
In contrast to most releases, which are focused on one or two major themes,
|
||||
the development during the release cycle of version 17.11 was almost entirely
|
||||
driven by the practical use of Genode as a day-to-day OS by the entire staff
|
||||
of Genode Labs. The basis of this endeavor is an evolving general-purpose
|
||||
system scenario - dubbed "sculpt" - that is planned as an official feature
|
||||
for the next release 18.02. The name "sculpt" hints at the approach to start
|
||||
with a minimalistic generic live system that can be interactively shaped
|
||||
into a desktop scenario by the user without any reboot. This is made possible
|
||||
by combining Genode's unique dynamic reconfiguration concept with the
|
||||
recently introduced package management, our custom GUI stack, and the many
|
||||
ready-to-use device-driver components that we developed over the past years.
|
||||
|
||||
By stressing Genode in such a dynamic and interactive fashion, we identified
|
||||
and smoothened many rough edges and usability shortcomings, ranging from the
|
||||
use of client-provided pointer shapes, the proper handling of keyboard
|
||||
modifiers, mouse acceleration, over the configuration of the user-level
|
||||
networking facilities, to improvements of the file-system support. Since the
|
||||
sculpt scenario is based on Genode's custom package-management concept
|
||||
introduced in
|
||||
[https://genode.org/documentation/release-notes/17.05#Package_management - version 17.05],
|
||||
it motivated the packaging of all components required by this system scenario.
|
||||
Altogether, there are now over 150 ready-to-use depot archives available.
|
||||
|
||||
At the platform level, the release unifies the boot concept across all
|
||||
supported x86 microkernels and offers the option to boot 64-bit kernels via
|
||||
UEFI. For both UEFI and legacy boot, Genode consistently uses GRUB2 now.
|
||||
|
||||
Feature-wise, the most prominent topics are the native support of game-console
|
||||
emulators based on libretro, the ability to resize libSDL-based applications
|
||||
like avplay, and the further cultivation of Nim as implementation language
|
||||
for native Genode components.
|
||||
|
||||
|
||||
Base framework and OS-level infrastructure
|
||||
##########################################
|
||||
|
||||
Virtual file system and C runtime
|
||||
=================================
|
||||
|
||||
The VFS and C runtime received improvements in several respects. First, we
|
||||
reintegrated the resolver library back into the libc library as it is an
|
||||
essential feature for network applications. The former split was an ancient
|
||||
artifact we implemented when integrating the lxip network stack as an optional
|
||||
alternative to lwip. Speaking of ancient features, we also remove the rcmd
|
||||
code from libc. This feature for remote-shell access is not used in modern
|
||||
environments. The VFS server was adjusted to handle incomplete calls to
|
||||
'stat()' correctly.
|
||||
|
||||
|
||||
NIC-router improvements
|
||||
=======================
|
||||
|
||||
Genode's user-level network-routing component was originally introduced in
|
||||
[https://genode.org/documentation/release-notes/16.08#Virtual_networking_and_support_for_TOR - version 16.08]
|
||||
and refined in
|
||||
[https://genode.org/documentation/release-notes/16.11#Further_improved_virtual_networking - version 16.11].
|
||||
In the current release, the NIC router has received two minor improvements
|
||||
regarding MAC addresses and ARP handling. In addition, it now has the ability
|
||||
to act as DHCP server or client for each configured domain.
|
||||
|
||||
Let's first have a look at the minor changes. The MAC addresses that the NIC
|
||||
router allocates on behalf of its NIC clients are now of the proper type:
|
||||
"local" and "individual" and this way, conform to the ARP protocol. The NIC
|
||||
router now also considers ARP requests for foreign IP addresses coming from a
|
||||
domain. If there is no gateway configured for the domain, the NIC router
|
||||
itself jumps in as gateway and answers those requests with its IP address.
|
||||
Thus, if you have an individual gateway in a subnet behind the NIC router,
|
||||
make sure to have the gateway attribute in the according '<domain>' tag set.
|
||||
|
||||
The new DHCP server functionality is activated for a domain by the new
|
||||
'<dhcp-server>' sub-tag of the '<domain>' tag:
|
||||
|
||||
! <domain name="vbox" interface="10.0.1.1/24">
|
||||
! <dhcp-server ip_first="10.0.1.80"
|
||||
! ip_last="10.0.1.100"
|
||||
! ip_lease_time_sec="3600"
|
||||
! dns_server="10.0.0.2"/>
|
||||
! ...
|
||||
! </domain>
|
||||
|
||||
The attributes 'ip_first' and 'ip_last' define the available IPv4 address
|
||||
range whereas the lifetime of an IPv4 address assignment is defined by the
|
||||
'ip_lease_time_sec' attribute in seconds. The 'dns_server' attribute is
|
||||
optional and declares the IPv4 address the NIC router shall state in the
|
||||
DNS-server option of DHCP. The DNS server may be located within a foreign
|
||||
subnet.
|
||||
|
||||
When used as a DHCP server, the NIC router provides the following DHCP options
|
||||
to its clients: message type, server IP (set to the NIC routers IP), subnet
|
||||
mask, IP lease time, router IP (set to the NIC routers IP), DNS server (if
|
||||
configured), and broadcast address.
|
||||
|
||||
If you want the NIC router to act as DHCP client at a domain, simply omit the
|
||||
interface attribute in the '<domain>' tag. In this case, the router tries to
|
||||
dynamically receive and maintain an IP configuration for the affected domain.
|
||||
Make sure that your DHCP server provides the following DHCP option fields to
|
||||
the NIC router: message type, server IP, subnet mask, IP lease time, and
|
||||
router IP.
|
||||
|
||||
Also note that the NIC router drops all packets not related to its DHCP client
|
||||
functionality at a domain that (currently) has no IP configuration. As soon as
|
||||
the domain achieves to get a valid IP configuration, the router switches to
|
||||
the normal behavior.
|
||||
|
||||
|
||||
New driver-manager subsystem
|
||||
============================
|
||||
|
||||
In traditional Genode system scenarios, the selection and configuration of the
|
||||
used device drivers are defined at system-integration time. This approach
|
||||
works fine whenever the hardware platform targeted by a given scenario and the
|
||||
use case of the scenario is well known in advance. But it does not scale up to
|
||||
general-purpose computing where one system image must be usable on diverse
|
||||
machines, and the concrete use cases are up to the end user.
|
||||
|
||||
The new _driver-manager_ subsystem composes existing Genode components within
|
||||
a dynamic subsystem. It spawns and configures device drivers that are
|
||||
fundamental for an interactive system on demand. When integrated as a
|
||||
building block in a Genode system, it provides the following feature set:
|
||||
|
||||
* It contains the ACPI-discovery component and the platform driver.
|
||||
|
||||
* It hosts and automatically configures the USB driver such that USB storage
|
||||
and vendor-specific devices become available to user-specific driver
|
||||
components residing outside the drivers subsystem (e.g., a VirtualBox
|
||||
instance that drives an individual USB stick). The list of present USB
|
||||
devices and the current USB-driver configuration are provided as a
|
||||
'usb_devices' and 'usb_drv.config' report respectively. Furthermore, the USB
|
||||
driver is configured to drive human input devices (HID) and provides the
|
||||
event stream as an input service.
|
||||
|
||||
* It spawns the AHCI driver and produces a list of present devices as a
|
||||
'block_devices' report.
|
||||
|
||||
* It hosts a PS/2 driver as well as an input-filter that incorporates the
|
||||
input-event streams originating from the PS/2 and USB HID drivers. The
|
||||
default configuration generates character events based on a configurable
|
||||
keyboard layout and key repeat, and includes scroll-wheel emulation and
|
||||
pointer acceleration for a PS/2 mouse (or, more importantly, the trackpoint
|
||||
of Lenovo laptops).
|
||||
|
||||
* It responds to changes of the 'capslock' and 'numlock' states, which are
|
||||
managed outside of the driver subsystem. Both states are consumed by the USB
|
||||
and PS/2 drivers to drive the keyboard-indicator LEDs. The 'numlock' state
|
||||
is furthermore used to toggle key re-mappings performed by the input filter.
|
||||
The 'capslock' state is incorporated into the modifier state as processed by
|
||||
the input-filter's character generator.
|
||||
|
||||
The new subsystem comes in the form of a depot package, which depends on all
|
||||
required components. Internally, it employs a dynamic init instance as a tool
|
||||
to start and manage driver components on demand. The actual management
|
||||
component is a simple program of about 500 lines of code that merely consumes
|
||||
reports and produces configurations. It is so simple that it does not even
|
||||
perform any dynamic memory allocation.
|
||||
|
||||
The new subsystem is present in the _gems_ repository and illustrated by the
|
||||
_gems/run/driver_manager.run_ script. It is also used as one cornerstone of
|
||||
the forthcoming general-purpose "sculpt" scenario mentioned in the
|
||||
introduction.
|
||||
|
||||
|
||||
Configuration changes of acpica and platform driver
|
||||
===================================================
|
||||
|
||||
Up to now, the acpica application was started up-front in most scenarios to
|
||||
get exclusive access to all PCI devices during initialization. Afterwards
|
||||
the platform driver took over the device access and announced the platform
|
||||
service. With the upcoming "sculpt" scenario, the desire arose to start the
|
||||
acpica application at a later stage, when the platform driver is already
|
||||
running. We adjusted the acpica and platform driver configuration slightly to
|
||||
cover this use case also.
|
||||
|
||||
|
||||
New ROM-filter abilities
|
||||
========================
|
||||
|
||||
The ROM-filter component is able to transform XML data from multiple ROM
|
||||
modules into a new ROM module. It is prominently used to generate component
|
||||
configurations depending on global system state. The current release makes
|
||||
this tool more flexible by allowing verbatim copies of input content into
|
||||
the output XML node as well as the use of input content as attribute values.
|
||||
|
||||
|
||||
New user-input processing capabilities
|
||||
======================================
|
||||
|
||||
In [https://genode.org/documentation/release-notes/17.02#Input-event_filter - version 17.02],
|
||||
we introduced a modular input-processing component called _input-filter_.
|
||||
The current release adds the following features to this component:
|
||||
|
||||
:incorporating modifier state from external ROMs:
|
||||
|
||||
By adding a '<rom name="...">' node into '<modN>' node of a chargen-filter,
|
||||
it is now possible to incorporate the content of the given ROM module into
|
||||
the modifier state. If the ROM module contains a top-level node with the
|
||||
attribute 'enabled' set to "yes", the modifier is enabled. This is useful
|
||||
for handling a system-global capslock state.
|
||||
|
||||
:scroll-wheel emulation:
|
||||
|
||||
The new '<button-scroll>' filter turns relative motion events into wheel
|
||||
events while a special button (i.e., the middle mouse button) is pressed.
|
||||
The button and rate of generated wheel events can be configured per axis via
|
||||
the sub nodes '<vertical>' and '<horizontal>'. The button of each axis can
|
||||
be specified via the 'button' attribute. By default, "BTN_MIDDLE" is used.
|
||||
The rate of generated wheel events can be defined by the 'speed_percent'
|
||||
attribute. A value of "100" uses relative motion vectors directly as wheel
|
||||
motion vectors. In practice, this results in overly fast wheel motion. By
|
||||
lowering the value, the rate can be reduced to practical levels. By
|
||||
specifying a negative value, the direction of the generated wheel motion can
|
||||
be inverted.
|
||||
|
||||
The consumed relative motion events are filtered out from the event stream
|
||||
such that pointer movements are inhibited while the wheel emulation is
|
||||
active. All other events are passed along unmodified.
|
||||
|
||||
:pointer acceleration:
|
||||
|
||||
The new '<accelerate>' filter applies acceleration to relative motion
|
||||
values. The 'max' attribute defines the maximum value added to the incoming
|
||||
motion values. The 'sensitivity_percent' attribute scales incoming motion
|
||||
values before applying the (potentially non-linear) acceleration function.
|
||||
The 'curve' attribute defines the degree of non-linearity of the
|
||||
acceleration. The value "0" corresponds to a linear function whereas the
|
||||
maximum value "255" applies a curved function. The default value is "127".
|
||||
|
||||
|
||||
Keyboard-LED support for PS/2 and USB HID
|
||||
=========================================
|
||||
|
||||
Both the PS/2 and the USB drivers have gained the new '<config>' attributes
|
||||
'capslock_led="no"', 'numlock_led="no"', and 'scrlock_led="no"' (with their
|
||||
default values shown). The attributes can have the values "no" (LED is turned
|
||||
off), "yes" (LED is turned on), or "rom". In the latter case, the driver reads
|
||||
the LED state from a dedicated ROM module called "capslock", "numlock", or
|
||||
"scrlock" respectively. The ROM module is expected to have a top-level XML
|
||||
node with the attribute 'enabled' set to "yes" or "no". The drivers reflect
|
||||
this state information by driving the corresponding keyboard-mode indicator
|
||||
LEDs.
|
||||
|
||||
|
||||
Revised Nitpicker GUI server
|
||||
============================
|
||||
|
||||
Driven by use cases like the "sculpt" scenario mentioned in the introduction,
|
||||
the Nitpicker GUI server and its helper components received an overhaul.
|
||||
|
||||
Besides modernizing the implementation according to our today's best
|
||||
practices, we succeeded in removing the focus handling as the last remaining
|
||||
builtin policy from the GUI server to an external component, thereby making
|
||||
the GUI server much more flexible. This line of work is complemented with
|
||||
an improved way of supporting client-provided pointer shapes, and a new
|
||||
general component for handling global keys.
|
||||
|
||||
|
||||
Supplementing user-activity information to the hover report
|
||||
-----------------------------------------------------------
|
||||
|
||||
Nitpicker's existing "hover" report features the information of the currently
|
||||
hovered client (e.g., the client's label and domain). In the new version, the
|
||||
report also features the information whether or not the user has actively
|
||||
moved the pointer during the last half second. This is analogous to how the
|
||||
"focus" report features user-activity information about recent key
|
||||
press/release activity. When combined, the "hover" and "focus" reports provide
|
||||
a way to detect the absence of user activity, e.g., to implement a lock screen
|
||||
or screen saver. If both reports have no 'active' attribute, such a component
|
||||
can schedule a timer. Whenever either of both reports shows an 'active'
|
||||
attribute, the timer is reset. The lock screen becomes active once the timeout
|
||||
triggers.
|
||||
|
||||
|
||||
Key-state reporting
|
||||
-------------------
|
||||
|
||||
For debugging purposes or for implementing global key combinations, Nitpicker
|
||||
now offers "keystate" reports. The report is updated each time, the user
|
||||
presses or releases a key. It lists all currently pressed keys along with the
|
||||
key count as observed by Nitpicker.
|
||||
|
||||
|
||||
Report last clicked-on client
|
||||
-----------------------------
|
||||
|
||||
The new 'clicked' report features the information about the client, on which
|
||||
the user actively clicked most recently. It is useful to implement a
|
||||
click-to-focus policy outside of Nitpicker.
|
||||
|
||||
|
||||
Externalizing Nitpicker's focus policy
|
||||
--------------------------------------
|
||||
|
||||
Traditionally, Nitpicker had a builtin policy about the input focus, which
|
||||
ensured that only the user can change the focus. The input focus is changed
|
||||
whenever the user clicks on an unfocused view. If permitted by the policy of
|
||||
the domain, the clicked-on client receives the focus. The policy configuration
|
||||
allows one to define domains that never receive any focus, domains that
|
||||
receive the focus only temporarily while the button is kept pressed (the
|
||||
so-called "transient focus"), or domains that can receive the regular input
|
||||
focus.
|
||||
|
||||
However, there are situations where this builtin policy stands in the way. For
|
||||
example, in a scenario based on virtual consoles, the user wants to be able to
|
||||
switch virtual consoles via keyboard shortcuts and expects the input focus to
|
||||
match the currently visible console regardless of any mouse clicks. Another
|
||||
example is the change of the input focus via key combinations like alt-tab.
|
||||
|
||||
As an alternative to the builtin policy, the new version of Nitpicker is able
|
||||
to respond to an externally provided "focus" state in the form of a ROM
|
||||
session. This state is driven by a dedicated component, like the new
|
||||
_nit_focus_ component that implements the traditional click-to-focus policy.
|
||||
By supplying the focus as a ROM session to Nitpicker, it becomes easy to
|
||||
globally overwrite the focus if needed. One particular example is a lock
|
||||
screen that should capture the focus when becoming active, and yield the focus
|
||||
to the original owner when becoming inactive.
|
||||
|
||||
The new explicit focus handling can be activated by setting the '<config>'
|
||||
attribute 'focus' to the value "rom". Further down the road, we plan to make
|
||||
this option the default, with the ultimate goal to remove the original builtin
|
||||
policy.
|
||||
|
||||
|
||||
Generalized global-key handling
|
||||
-------------------------------
|
||||
|
||||
The new _global_keys_handler_ component replaces the former _xray-trigger_
|
||||
component. It transforms a stream of Nitpicker input events to state reports.
|
||||
The states and the ways of how the user input affects these states is
|
||||
configurable. Examples for such states are the system-global capslock and
|
||||
numlock states, or the Nitpicker X-ray mode activated by a global
|
||||
secure-attention key. The configuration looks as follows:
|
||||
|
||||
! <config>
|
||||
! <bool name="xray" initial="no"/>
|
||||
!
|
||||
! <press name="KEY_F1" bool="xray" change="on"/>
|
||||
! <release name="KEY_F1" bool="xray" change="off"/>
|
||||
! <press name="KEY_F2" bool="xray" change="toggle"/>
|
||||
!
|
||||
! <report name="xray" delay_ms="125">
|
||||
! <hovered domain="panel"/>
|
||||
! <bool name="xray"/>
|
||||
! </report>
|
||||
! </config>
|
||||
|
||||
A '<bool>' node declares a boolean state variable with the given name and its
|
||||
initial value (default is "no"). There may be any number of such variables.
|
||||
|
||||
The '<press>' and '<release>' nodes define how key events affect the state
|
||||
variables. Each of those nodes refers to a specific state variable via the
|
||||
'bool' attribute, and the operation as the 'change' attribute. Possible
|
||||
'change' attribute values are "on", "off", and "toggle".
|
||||
|
||||
The '<report>' node defines a state-dependent report with the name as
|
||||
specified in the 'name' attribute. The report-generation rate can be
|
||||
artificially limited by the 'delay_ms' attribute. If specified, the report is
|
||||
not issued immediately on a state change but after the specified amount of
|
||||
milliseconds. The '<report>' node contains a number of conditions. Whenever
|
||||
one of those conditions is true, a report of the following form is generated:
|
||||
|
||||
! <xray enabled="yes"/>
|
||||
|
||||
Otherwise, the report's 'enabled' attribute has the value "no". Possible
|
||||
conditions are '<bool>' and '<hovered>'. The '<bool>' condition is true if the
|
||||
named boolean state variable has the value true. The '<hovered>' condition is
|
||||
true if the currently hovered Nitpicker client belongs to the domain as
|
||||
specified in the 'domain' attribute. The latter information is obtained from a
|
||||
ROM module named "hover", which corresponds to Nitpicker's hover reports.
|
||||
|
||||
To use the global-keys-handler in practice, one needs to configure the
|
||||
Nitpicker GUI server such that the press/release events of the global keys of
|
||||
interest are routed to the global-keys-handler. This can be achieved by
|
||||
Nitpicker's '<global-key>' configuration nodes. For example:
|
||||
|
||||
! <global-key name="KEY_F1" label="global_keys_handler -> input" />
|
||||
! <global-key name="KEY_F2" label="global_keys_handler -> input" />
|
||||
|
||||
|
||||
More flexible geometry definitions of nit_fb instances
|
||||
------------------------------------------------------
|
||||
|
||||
The _nit_fb_ component translates the Nitpicker session interface into the
|
||||
low-level input and framebuffer session interfaces such that raw framebuffer
|
||||
clients can be hosted as Nitpicker applications. The position and size of such
|
||||
an application is configurable.
|
||||
|
||||
The new 'origin' attribute denotes the coordinate origin of the values
|
||||
specified in the 'xpos' and 'ypos' attributes. Supported origins are
|
||||
"top_left", "top_right", "bottom_left", and "bottom_right". This attribute
|
||||
allows one to align a Nitpicker view at any of the four screen corners.
|
||||
|
||||
The 'width' and 'height' attribute values can now be negative. If so, they are
|
||||
relative to the physical screen size. E.g., when using a screen size of
|
||||
640x480, the effective width for a 'width' attribute value of "-100" would be
|
||||
640 - 100 = 540.
|
||||
|
||||
|
||||
Simplified handling of client-provided pointer shapes
|
||||
-----------------------------------------------------
|
||||
|
||||
The _pointer_ component that accompanies Nitpicker by default shows a static
|
||||
pointer shape only. In advanced scenarios, for example when multiple instances
|
||||
of VirtualBox are present on one screen, it is desired to show the shape
|
||||
provided by the currently hovered guest OS. This was accomplished by a
|
||||
special _vbox_pointer_ component with access to both the client-provided
|
||||
shape and Nitpicker's hover report. Whereas this component sufficed for
|
||||
relatively static scenarios, the pointer's policy configuration became rather
|
||||
difficult in dynamic scenarios where the labels of the displayed VMs or
|
||||
applications are unknown at system-integration time.
|
||||
|
||||
The new version simplifies the shape handling by letting the pointer component
|
||||
play the role of a "Report" service that consumes "shape" reports. This way,
|
||||
the pointer implicitly knowns the label of the shape-providing client. It
|
||||
matches the labels of its report clients against the currently hovered client
|
||||
as obtained from Nitpicker's hover report. If there is a match, the pointer
|
||||
displays the matching client-provided shape. Since the new component is
|
||||
generically applicable, e.g., not only for VirtualBox-provided shapes but also
|
||||
for Qt5-provided shapes (Section [Displaying of Qt5's custom pointer shapes]),
|
||||
it has become Nitpicker's default pointer component.
|
||||
|
||||
|
||||
USB-driver support for RNDIS
|
||||
============================
|
||||
|
||||
In this release, support for Microsoft's proprietary RNDIS protocol was
|
||||
enabled in our Linux-based USB network driver. Thereby it is possible to use
|
||||
the network sharing ("tethering") features provided by many Android devices.
|
||||
The driver was tested using devices from different vendors.
|
||||
|
||||
Since the RNDIS driver is based on the 'cdc_ether' driver (the open protocol
|
||||
alternative phone vendors should be using), it had to be enabled as well.
|
||||
Due to lack of any devices supporting CDC, while enabled, the driver could not
|
||||
be tested and must be considered experimental for now.
|
||||
|
||||
The porting and enabling of the driver was done by Alexander Senier from
|
||||
[https://componolit.com - Componolit]. Thanks for this welcome contribution!
|
||||
|
||||
|
||||
Refined Rump-kernel-based file-system support
|
||||
=============================================
|
||||
|
||||
We extended the 'rump_fs' file-system server with the ability to mount and
|
||||
unmount the underlying file system on demand. The server will mount the file
|
||||
system on the first established session request and in return will unmount the
|
||||
file system when the last session is closed. In case all clients are shut down
|
||||
before the server is stopped, this prevents leaving the file system marked as
|
||||
dirty. Even if the file system itself is in a clean state, the dirty bit might
|
||||
otherwise trigger a false negative result when performing a file-system check.
|
||||
|
||||
In release [https://genode.org/documentation/release-notes/14.02 - 14.02], we
|
||||
added a e2fsprogs Noux port. Since the use of the VFS library within libc,
|
||||
Noux is not strictly needed anymore for running tools like the e2fsprogs
|
||||
utilities. On the contrary, it increases the complexity of a file-system
|
||||
management mechanism needlessly. With this release, we introduce a port of the
|
||||
'e2fsck' tool from e2fsprogs to Genode that does not depend on Noux. It can be
|
||||
used by a management component to check an ext2 file-system prior to starting
|
||||
'rump_fs' and in case of errors to attempt to fix them automatically.
|
||||
|
||||
Additionally, we significantly stripped down Genode's version of the Rump
|
||||
kernel. By integrating Rump directly into Genode's build system, compiling and
|
||||
checking out required Rump sources only, we were able to reduce the compile
|
||||
time of 'rump_fs' and the source archive size (from about 700 MiB to about 10
|
||||
MiB).
|
||||
|
||||
Runtime environments and programming languages
|
||||
##############################################
|
||||
|
||||
Genode components based on the Nim language
|
||||
===========================================
|
||||
|
||||
Support for the [https://nim-lang.org/ - Nim] programming language was
|
||||
introduced in the [https://genode.org/documentation/release-notes/17.05 - 17.05]
|
||||
release and during this release period, our understanding of Nim, its idiom,
|
||||
and its interaction with the Genode framework progressed to a point where
|
||||
native components can be reasonably implemented using the language.
|
||||
|
||||
The 'hotkey_edit' component in the world repository toggles XML sections in
|
||||
and out of a file managed by 'xml_editor' when triggered by key input events.
|
||||
The component is written in Nim, acts as a "Nitpicker", "Input", "Report",
|
||||
and "ROM" client, and follows the Genode paradigm of a state-machine driven by
|
||||
asynchronous signalling. The application specific source is also less than one
|
||||
hundred lines of code.
|
||||
|
||||
To enable client usage of Genode services the respective 'Client' or
|
||||
'Connection' C++ classes are wrapped as Nim objects by taking advantage of the
|
||||
Genode 'Constructible' class to be able to manually invoke constructors during
|
||||
object initialization. Wrapping service classes and their methods is currently
|
||||
done by hand, but changes to service interfaces are so gradual that it is more
|
||||
effective than automated code generation. Signal handling is achieved using
|
||||
anonymous procedures and happens when the thread of execution winds back to
|
||||
the initial entrypoint. This approach is just the same as for components that
|
||||
are linked to the 'libc' library, and contrasted with components linked to the
|
||||
'posix' library. The Nim language has no conventions for a special "main"
|
||||
procedure like C or Go, so signals handlers are dispatched by default after
|
||||
all top-level statements have been executed.
|
||||
|
||||
The language has experimentally proven to be flexible enough to implement RPC
|
||||
servers, but more experience is required to determine if a garbage-collected
|
||||
language can manage to abide by transient RAM resource quotas, as any
|
||||
multi-session server must do to reliably serve an indefinite number of
|
||||
clients. The standard language runtime also depends on the 'libc' library,
|
||||
which is relatively expensive and complicated for typical native components.
|
||||
This dependency also prevents the implementation of VFS plugins in Nim, which
|
||||
must be available as the C runtime is initialized. Removing the dependency is
|
||||
certainly possible, but it remains an open question of whether it is practical
|
||||
to maintain such radical changes.
|
||||
|
||||
To experiment with the Nim language, a recent release or development version
|
||||
of the compiler is required. To this end, the Genode toolchain uses a custom
|
||||
compiler by default. A script is provided to build the recommended version at
|
||||
_tool/tool_chain_nim_.
|
||||
|
||||
|
||||
GDB-based debugging of server components
|
||||
========================================
|
||||
|
||||
We adapted the 'gdb_monitor' component to the asynchronous session-creation
|
||||
procedure introduced in Genode release
|
||||
[https://genode.org/documentation/release-notes/16.11#New_session-creation_procedure - 16.11].
|
||||
The current release makes it possible to debug components that implement
|
||||
Genode services.
|
||||
|
||||
|
||||
Applications and libraries
|
||||
##########################
|
||||
|
||||
Displaying of Qt5's custom pointer shapes
|
||||
=========================================
|
||||
|
||||
Qt applications often make use of custom mouse-pointer shapes, for example
|
||||
when a text input field is hovered. We enabled this feature for our Qt5 port
|
||||
by letting Qt report its custom pointer shapes to the newly enhanced pointer
|
||||
component described in Section
|
||||
[Simplified handling of client-provided pointer shapes]. The use of the new
|
||||
feature is illustrated in the _qt5_calculatorform.run_ script. Note the
|
||||
rewriting of the 'shape' session label.
|
||||
|
||||
|
||||
Qt5-based virtual keyboard
|
||||
==========================
|
||||
|
||||
Genode supports user input with keyboard and mouse attached via PS/2 and USB
|
||||
as well as USB touch panels. The current release brings an option for Qt5
|
||||
applications to support textual-information input in situations where a
|
||||
hardware keyboard is missing. The Qt5 input stack was extended for platform
|
||||
input contexts and the accompanied example _run/qt5_virtualkeyboard.run_
|
||||
showcases the feature.
|
||||
|
||||
[image virtual_keyboard]
|
||||
|
||||
Thanks to Johannes Kliemann for his contribution!
|
||||
|
||||
|
||||
Resizable libSDL-based applications like avplay
|
||||
===============================================
|
||||
|
||||
There are quite a few ports of SDL-based software available on Genode that
|
||||
work well when executed in isolation, e.g., a game running in full screen
|
||||
directly in the frame buffer. However, when running in a common desktop
|
||||
scenario, the fixed size of the frame buffer used in Genode's SDL video back
|
||||
end is a noticeable limitation. So, in addition to removing the usage of
|
||||
deprecated APIs in the SDL back ends, we lifted this limitation as well.
|
||||
|
||||
Removing the usage of the deprecated APIs, which rely on a global environment,
|
||||
led to the addition of the Genode-specific initialization function
|
||||
'sdl_init_genode' that has to be called prior to 'SDL_Init'. For that purpose,
|
||||
we introduce a stub library 'sdlmain'. In accordance to the posix library, it
|
||||
handles command-line argument parsing, proper SDL initializing, and the call
|
||||
to SDL's 'main' function. For interacting with the Genode API, we might have
|
||||
to execute signal handlers, e.g., whenever a framebuffer mode change signal is
|
||||
received. This is complicated from within a thread that is running libc code,
|
||||
which is true for most if not all SDL-based components. Therefor and because
|
||||
those components come with their own event loop, that polls SDL for events, we
|
||||
start the 'main' function in its own thread. The main entrypoint of the
|
||||
component does all the signal handling and the dispatcher flag signals in a
|
||||
way that SDL can transform them into SDL_Events and inject them into the event
|
||||
loop.
|
||||
|
||||
This changes enable the seamless resizing of a running avplay instance.
|
||||
|
||||
|
||||
Front end for the Libretro API
|
||||
==============================
|
||||
|
||||
A component that has been in the world repository for almost a year has been
|
||||
refactored and is ready for mention. The 'retro_frontend' is a native front
|
||||
end to games implemented as "Libretro cores".
|
||||
[https://libretro.com - Libretro] is an API that exposes generic
|
||||
audio/video/input callbacks from a dynamic library to a front end. The front
|
||||
end handles video output, audio output, input, and the application's life
|
||||
cycle. This novel arrangement is intended to minimize the effort of porting
|
||||
games to different platforms and to increase future backwards compatibility.
|
||||
On Genode, these cores are executed frame-by-frame as compelled by the front
|
||||
end rather than by a main loop within the game. Game assets are loaded as
|
||||
configured in a general manner at the front end and multiple input devices can
|
||||
be managed and mapped into cores. This in effect moves the platform
|
||||
abstraction layer tighter around the game engine and relinquished more control
|
||||
and configuration to a native layer provided by the user. Documentation on
|
||||
using the front end can be found in the world repository along with examples
|
||||
for emulating a few game consoles.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
UEFI boot, consistent use of GRUB2 on x86
|
||||
=========================================
|
||||
|
||||
With the previous release, we already added support for GRUB2 when booting in
|
||||
UEFI mode. However, for non-UEFI boots, we still relied on GRUB-0.97 and
|
||||
ISOLINUX from the Syslinux Project as boot loaders.
|
||||
|
||||
With the experiences gained from GRUB2, we decided to modernize our bootloader
|
||||
chain for x86. With this release, we solely use GRUB2 during all x86 boots.
|
||||
|
||||
For ISO creation, we now leverage the images - shipped by GRUB2 -
|
||||
'embedded.img' and 'eltorito.img', together with the 'xorriso' tool. Due to
|
||||
this change, we were able to remove the ISOLINUX binaries and eltorito files
|
||||
of ancient GRUB1.
|
||||
|
||||
The final GRUB2 binaries are now integrated as external Genode port, which
|
||||
can be installed by invoking:
|
||||
|
||||
! tool/ports/prepare_port grub2
|
||||
|
||||
The 'grub2' port contains the GRUB2 binaries. Additionally, the port contains
|
||||
the instructions and the references to the git source code of GRUB2 used to
|
||||
generate the bootloader binaries. With the information provided within the
|
||||
port, one can easily reproduce the GRUB2 builds if desired.
|
||||
|
||||
|
||||
Enabling MMU-based threat mitigations by default
|
||||
================================================
|
||||
|
||||
With this release, we enabled support to leverage non-executable memory on
|
||||
Genode. On hardware and kernels supporting this feature, it is now enabled by
|
||||
default.
|
||||
|
||||
On ARM this feature is available to all supported kernels, namely our own
|
||||
hw kernel, seL4, and Fiasco.OC.
|
||||
|
||||
On x86 the 64bit kernels hw, NOVA, and Fiasco.OC support this feature.
|
||||
|
||||
SeL4 currently misses support on x86. The remaining x86 32bit kernels (i.e.,
|
||||
OKL4, Pistachio and Fiasco) don't offer non-executable memory support, since
|
||||
they do not configure the page-tables in the PAE (physical address extension)
|
||||
format, which is required by non-executable memory.
|
||||
|
||||
|
||||
Updated seL4 to kernel branch 7.0
|
||||
=================================
|
||||
|
||||
In the previous releases, we extended our seL4 support and thereby collected a
|
||||
patch series for the seL4 kernel, e.g. UEFI boot support. We submitted the
|
||||
patches to the seL4 developers who integrated most of our changes into the
|
||||
seL4 7.0 kernel release.
|
||||
|
||||
Additionally to the update, we extended the UEFI framebuffer support for the
|
||||
seL4 kernel so that our simple boot framebuffer driver may now utilize the
|
||||
graphics device if setup by GRUB2 during UEFI boot. The patches to the kernel
|
||||
got submitted to the seL4 maintainers for review and for inclusion.
|
||||
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
During the previous releases, several preparation steps were made to enable
|
||||
the execution of Genode's core as privileged code inside the protection domain
|
||||
of each component. With this release, we pushed the genesis of the base-hw
|
||||
core component and its kernel library to finally achieve that goal. Now, the
|
||||
virtual address space of each component is split into a privileged and an
|
||||
unprivileged part. The privileged part is shared between all components and
|
||||
does not vary when switching between different protection domains.
|
||||
Nonetheless, it is accessible by the privileged threads of core and the kernel
|
||||
library's context only. The advantages of this approach are less context
|
||||
switch overhead and less complex assembler code with respect to the
|
||||
platform-specific exception and system call entry path.
|
||||
|
||||
|
||||
Improved offline validation of Genode configurations
|
||||
====================================================
|
||||
|
||||
Genode's configuration is based on XML and gets validated by xmllint during
|
||||
each run tool invocation. Up to now, we used xmllint to check for a valid XML
|
||||
syntax.
|
||||
|
||||
With this release, we added an additional semantic check for Genode's 'init'
|
||||
component. The check determines whether the XML nodes and attributes are known
|
||||
and understood by 'init'. This check is performed on each run tool invocation
|
||||
at integration time. The XML schema file is located in
|
||||
|
||||
! tool/run/genode.xsd
|
||||
|
||||
and gets applied by xmllint.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user