mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-22 04:52:56 +01:00
Compare commits
5566 Commits
sculpt-19.
...
feature/ha
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95fb98d280 | ||
|
|
17befa5c44 | ||
|
|
2a6cb2a97f | ||
|
|
b8079ed15a | ||
|
|
dd0c8b10dc | ||
|
|
9943716d9b | ||
|
|
1dd70b3e3e | ||
|
|
e3fff92481 | ||
|
|
8845be160a | ||
|
|
0da523ce73 | ||
|
|
98b545d136 | ||
|
|
12a844ad90 | ||
|
|
04bf2ed28c | ||
|
|
865eded4aa | ||
|
|
9c13ceb3cc | ||
|
|
cf8c0ee7c7 | ||
|
|
c74ce6083c | ||
|
|
b6a36278a9 | ||
|
|
052026e86a | ||
|
|
8cdefc4c68 | ||
|
|
21b8726a59 | ||
|
|
05c3cc93d1 | ||
|
|
2dda557313 | ||
|
|
e35c1596a6 | ||
|
|
e6261ce31d | ||
|
|
7910439f37 | ||
|
|
3303295a81 | ||
|
|
95e5585752 | ||
|
|
90761ae232 | ||
|
|
4a3b85f667 | ||
|
|
cedb65027d | ||
|
|
44bdf5fcc4 | ||
|
|
7539dca746 | ||
|
|
3fd592a0b3 | ||
|
|
b5657ab546 | ||
|
|
07a2adefe4 | ||
|
|
82382d2f98 | ||
|
|
b62a6c4c02 | ||
|
|
716c44b8d6 | ||
|
|
e0f9540c9c | ||
|
|
ddce0c8ce2 | ||
|
|
2449980a7f | ||
|
|
8bb99791b8 | ||
|
|
e5f4f66e3b | ||
|
|
a2462c6386 | ||
|
|
c3e8e0d89c | ||
|
|
6c9dee3f71 | ||
|
|
d3886052d8 | ||
|
|
e9d6bb7782 | ||
|
|
56d5e1d46b | ||
|
|
94d8c31c79 | ||
|
|
33a3f44cd5 | ||
|
|
4308a3091b | ||
|
|
a69c53bfc9 | ||
|
|
548ff291c2 | ||
|
|
c28c6a3339 | ||
|
|
f468ad9ba7 | ||
|
|
3b1fa40de3 | ||
|
|
89239e2b43 | ||
|
|
dcf5bb924d | ||
|
|
9da9182aba | ||
|
|
83058c8ca4 | ||
|
|
afa3375696 | ||
|
|
8eaf2e533d | ||
|
|
2c2c7a2120 | ||
|
|
6c7283b711 | ||
|
|
c296076d7d | ||
|
|
dccd1ddfc3 | ||
|
|
92ed8c926b | ||
|
|
93c1268b91 | ||
|
|
bb48a4c616 | ||
|
|
663d33e936 | ||
|
|
78b4afb218 | ||
|
|
48832c32b5 | ||
|
|
284ed952f5 | ||
|
|
e20a605709 | ||
|
|
b0e46febfb | ||
|
|
225396c805 | ||
|
|
d9d02c9024 | ||
|
|
795b22afeb | ||
|
|
9d3fe9b93d | ||
|
|
2f18953440 | ||
|
|
f8223c0626 | ||
|
|
bba40b9423 | ||
|
|
dc51de546b | ||
|
|
16bec7c880 | ||
|
|
229b9dba01 | ||
|
|
d2cd009a00 | ||
|
|
f46bd8755e | ||
|
|
2ea40b1884 | ||
|
|
1d23971196 | ||
|
|
8cc04bf343 | ||
|
|
3d20264caa | ||
|
|
a900e6fb78 | ||
|
|
ef1f314876 | ||
|
|
df4316af25 | ||
|
|
ba23ca5386 | ||
|
|
3f4024e7d5 | ||
|
|
35a4a0d2e0 | ||
|
|
3c4a1c4d8d | ||
|
|
069460901d | ||
|
|
7b3400b261 | ||
|
|
f279097716 | ||
|
|
6f7cc95def | ||
|
|
ea10dfb143 | ||
|
|
e91f8b5044 | ||
|
|
e9e6c03b6b | ||
|
|
ea3648e2e4 | ||
|
|
25fcb81d46 | ||
|
|
24ddf24f78 | ||
|
|
1b76283593 | ||
|
|
baa37c03d4 | ||
|
|
d83c382a6c | ||
|
|
7736c41cc3 | ||
|
|
766ea4679e | ||
|
|
45079145aa | ||
|
|
cbdbdf16ba | ||
|
|
920bd07488 | ||
|
|
ebfd0e9f65 | ||
|
|
c02da6f448 | ||
|
|
31983ae81c | ||
|
|
bbfc9ffcd1 | ||
|
|
ffb2295496 | ||
|
|
c4e83c816a | ||
|
|
5c7d959ab7 | ||
|
|
2d69361890 | ||
|
|
a6e880e267 | ||
|
|
058b190a81 | ||
|
|
701be9aab6 | ||
|
|
71b84f75f6 | ||
|
|
39e4801726 | ||
|
|
11d3f3737a | ||
|
|
b4d69e547f | ||
|
|
de8728f250 | ||
|
|
8d50dd703e | ||
|
|
50c81933a0 | ||
|
|
5d801d7e10 | ||
|
|
feee3bd6dc | ||
|
|
e9bfa0e16c | ||
|
|
61a3cca20e | ||
|
|
f96331d59e | ||
|
|
ff30866207 | ||
|
|
1ce8cd22e0 | ||
|
|
2e7cf6c58e | ||
|
|
0b7dd68ca5 | ||
|
|
26bc8c6a7d | ||
|
|
6447d12c15 | ||
|
|
3441df3578 | ||
|
|
afbe7e1c3e | ||
|
|
9d0b5493f4 | ||
|
|
229d395b73 | ||
|
|
da184d07a1 | ||
|
|
1ea0f6ad52 | ||
|
|
9135630c00 | ||
|
|
ab060aad6b | ||
|
|
c15bf4cc11 | ||
|
|
f35f6f65b9 | ||
|
|
372ca18156 | ||
|
|
7aeca3aceb | ||
|
|
854bab4769 | ||
|
|
d80716ed56 | ||
|
|
05a1e9bec8 | ||
|
|
b3991be657 | ||
|
|
1b4f291be8 | ||
|
|
860396477b | ||
|
|
bfd8f99f92 | ||
|
|
a682e20b7a | ||
|
|
1970c59077 | ||
|
|
9e986181b6 | ||
|
|
9ccf7d1264 | ||
|
|
9ea62b25a0 | ||
|
|
6e3b1839ea | ||
|
|
775f92d1a9 | ||
|
|
4338d503c3 | ||
|
|
2ed44d458c | ||
|
|
e2d7465c06 | ||
|
|
c1017645b7 | ||
|
|
086e9ac5be | ||
|
|
caa59f84b8 | ||
|
|
c27e19c310 | ||
|
|
77da41768c | ||
|
|
b11450dbba | ||
|
|
99ca48ca25 | ||
|
|
fe2ac905de | ||
|
|
8517ed7236 | ||
|
|
e7473337cb | ||
|
|
ddb8720728 | ||
|
|
c159cd6022 | ||
|
|
a461e0886f | ||
|
|
ddc3e9b38d | ||
|
|
3ec2bfd92d | ||
|
|
a57ec384ff | ||
|
|
c8b883215d | ||
|
|
2c6c95202a | ||
|
|
b4e45b87e9 | ||
|
|
359dd71dd2 | ||
|
|
73c5472c67 | ||
|
|
11f332d382 | ||
|
|
00bad9bee5 | ||
|
|
ca7bcc2d80 | ||
|
|
8e0fe39248 | ||
|
|
a376ebafa7 | ||
|
|
f9f874d7e4 | ||
|
|
9b61f00187 | ||
|
|
8730657e08 | ||
|
|
35e0a2b144 | ||
|
|
d12b491a5c | ||
|
|
130efed0cb | ||
|
|
004aaf0235 | ||
|
|
27c2064a3c | ||
|
|
be7df4fa82 | ||
|
|
6793143d31 | ||
|
|
28ecbbbb71 | ||
|
|
8bdddbd46a | ||
|
|
103d03b590 | ||
|
|
5def882001 | ||
|
|
da65626cdd | ||
|
|
cdbc31add8 | ||
|
|
b455139e8c | ||
|
|
b4f4a6db09 | ||
|
|
d3d901886f | ||
|
|
0d4d23a161 | ||
|
|
827401ee2d | ||
|
|
fa9373cbd3 | ||
|
|
bfaacb1ada | ||
|
|
8eae6501b7 | ||
|
|
e840a3f8f9 | ||
|
|
7c5f879b91 | ||
|
|
2b566042ad | ||
|
|
6e82520165 | ||
|
|
1677a36225 | ||
|
|
c564013a5d | ||
|
|
d033e4c153 | ||
|
|
c5e6d071e5 | ||
|
|
68613c8265 | ||
|
|
67985e2ba9 | ||
|
|
673c97b3e6 | ||
|
|
3bdfb078bf | ||
|
|
84cabaf9b7 | ||
|
|
f2d91fd56a | ||
|
|
a5664ba5c0 | ||
|
|
7e4decfacc | ||
|
|
d9ca56e1ed | ||
|
|
7010dbbbbb | ||
|
|
b7d3d8237b | ||
|
|
f4c255955f | ||
|
|
13abc33ec9 | ||
|
|
2e3e57f50a | ||
|
|
b451f4c45c | ||
|
|
5e2ba4d859 | ||
|
|
896e652b4c | ||
|
|
0d641600a4 | ||
|
|
42c78b946b | ||
|
|
2743e625f6 | ||
|
|
0ebf11f143 | ||
|
|
d25a9a0e21 | ||
|
|
e3cc8274ba | ||
|
|
c1eafc39ab | ||
|
|
a392b93187 | ||
|
|
de7e11c122 | ||
|
|
54b036d61c | ||
|
|
a392e258cd | ||
|
|
54153be983 | ||
|
|
811e51a24e | ||
|
|
64e0c5413f | ||
|
|
1d315bc355 | ||
|
|
cc7501cee7 | ||
|
|
311c7a8cd0 | ||
|
|
891cc5bf5f | ||
|
|
19163e44b4 | ||
|
|
94ece697e1 | ||
|
|
40b00e2bcd | ||
|
|
bd79ee0805 | ||
|
|
cea5a16abb | ||
|
|
142ddd4d3b | ||
|
|
5a2b6ee101 | ||
|
|
9950fecf49 | ||
|
|
65e78497cb | ||
|
|
9f6a6b33db | ||
|
|
d3f5015c3a | ||
|
|
3f8d9e5953 | ||
|
|
2d8efcec1e | ||
|
|
4a2aa95099 | ||
|
|
a3c05bd793 | ||
|
|
7fce3b0767 | ||
|
|
03f18e1dfe | ||
|
|
68f3e54738 | ||
|
|
b84d6b95ae | ||
|
|
3531bfc4c7 | ||
|
|
e72915c13e | ||
|
|
5eba0d68e0 | ||
|
|
38d99c6dd1 | ||
|
|
5d2b57118d | ||
|
|
6578639bb9 | ||
|
|
44860e89be | ||
|
|
4aabe39e36 | ||
|
|
404e21017a | ||
|
|
f9e6c3aa0e | ||
|
|
c156c6012c | ||
|
|
3f2a867a49 | ||
|
|
7fcfa4ede5 | ||
|
|
294ba9d30a | ||
|
|
ccdbefd158 | ||
|
|
dd64164ed6 | ||
|
|
d3002b26ac | ||
|
|
ebb159d32d | ||
|
|
cd6701c483 | ||
|
|
60d009e6c6 | ||
|
|
d0522706ba | ||
|
|
7f8db06284 | ||
|
|
0749f8cbdf | ||
|
|
1ddbb3444c | ||
|
|
4da68e11b6 | ||
|
|
5665e8059a | ||
|
|
3067a2c51d | ||
|
|
1d73cf2003 | ||
|
|
010847b69c | ||
|
|
96d9f5d317 | ||
|
|
97e638a2ac | ||
|
|
ba013af1a3 | ||
|
|
e520dbbb7e | ||
|
|
7928597249 | ||
|
|
979aaed52b | ||
|
|
f2c25383af | ||
|
|
e384381942 | ||
|
|
b529b1eac6 | ||
|
|
b21c8729ea | ||
|
|
d5f3cc6ec2 | ||
|
|
4730312c1e | ||
|
|
cc2bcee417 | ||
|
|
2c2fb6b70e | ||
|
|
b50bbef303 | ||
|
|
35a679d861 | ||
|
|
37842757ac | ||
|
|
fa9473ce58 | ||
|
|
873386f8a1 | ||
|
|
2b18913782 | ||
|
|
fb7fa915c6 | ||
|
|
011b44c282 | ||
|
|
a3193b919c | ||
|
|
798b49fcc3 | ||
|
|
d095945d6c | ||
|
|
9e4b27a829 | ||
|
|
4d7a5b6829 | ||
|
|
7019b795a6 | ||
|
|
3bb894370a | ||
|
|
9e5e648073 | ||
|
|
14e3339ce6 | ||
|
|
b05b7f17f3 | ||
|
|
f6a1956a30 | ||
|
|
59d951ed6a | ||
|
|
fe008e0884 | ||
|
|
f72fdf77ed | ||
|
|
0f70cbd704 | ||
|
|
6e2a7e979e | ||
|
|
0eefe2d872 | ||
|
|
052dd903a4 | ||
|
|
591aadea54 | ||
|
|
28542e66ab | ||
|
|
ed2d9fef47 | ||
|
|
7dbc9129db | ||
|
|
9a7fe5e775 | ||
|
|
79ab0cf98e | ||
|
|
dfd373fa0c | ||
|
|
b510394a6d | ||
|
|
4a5f80ddbf | ||
|
|
7fb702a0d9 | ||
|
|
1f225b4b6f | ||
|
|
d104ca0561 | ||
|
|
728ea95857 | ||
|
|
188080e15f | ||
|
|
6f5bcd4446 | ||
|
|
7fe7ca1968 | ||
|
|
dffa32a72c | ||
|
|
f886acdcc6 | ||
|
|
0794d99eff | ||
|
|
fdd2b4edb0 | ||
|
|
8d50d320e2 | ||
|
|
ec1316e1cb | ||
|
|
cb5eb740c0 | ||
|
|
05fd121975 | ||
|
|
30f3ef25ad | ||
|
|
e9fb2d89fb | ||
|
|
7f1a6e55f3 | ||
|
|
cf84787c09 | ||
|
|
324245d029 | ||
|
|
2d3170124d | ||
|
|
aafd03ee74 | ||
|
|
baedd79f62 | ||
|
|
e1909da501 | ||
|
|
1660dc0635 | ||
|
|
c9015d6076 | ||
|
|
da6124c087 | ||
|
|
732f310b26 | ||
|
|
9ad7111634 | ||
|
|
71a3e228ae | ||
|
|
01c96cf537 | ||
|
|
8ed87dae71 | ||
|
|
f94e0a3464 | ||
|
|
45fc49b4f1 | ||
|
|
8c43f8aa33 | ||
|
|
8d76eebf93 | ||
|
|
fa267ecbb3 | ||
|
|
3ab9173b20 | ||
|
|
515bd3263f | ||
|
|
c609e76cec | ||
|
|
845dc80df9 | ||
|
|
b48ae5550a | ||
|
|
db02e04d0c | ||
|
|
08bf219b28 | ||
|
|
5e3b6ee08f | ||
|
|
8985d8200e | ||
|
|
6715f074ff | ||
|
|
f30bbb1472 | ||
|
|
7e9c1ca3ca | ||
|
|
a25d19169b | ||
|
|
5c75f1efa7 | ||
|
|
73991e62ec | ||
|
|
13e8013334 | ||
|
|
679d68d470 | ||
|
|
2d7cd1c736 | ||
|
|
5f4e1db576 | ||
|
|
135a866ec0 | ||
|
|
e1be17b56d | ||
|
|
986bec20a9 | ||
|
|
6d78712454 | ||
|
|
7961ff50a2 | ||
|
|
5497829608 | ||
|
|
b908999def | ||
|
|
fe93df27d1 | ||
|
|
8094b1ee01 | ||
|
|
8ec2d6a36b | ||
|
|
77471cc10e | ||
|
|
f3b94a3b21 | ||
|
|
44c23ca472 | ||
|
|
f7689a473c | ||
|
|
71f3e5f82a | ||
|
|
1a5f3a2210 | ||
|
|
6c2c830f66 | ||
|
|
6a5473b478 | ||
|
|
a0ef5b5a36 | ||
|
|
d87a235abb | ||
|
|
4f084d1f9e | ||
|
|
77d53f13ca | ||
|
|
a148dc5cb4 | ||
|
|
700b248749 | ||
|
|
225adf3681 | ||
|
|
4084df6360 | ||
|
|
be70fddbb8 | ||
|
|
7cf39188ef | ||
|
|
3142554343 | ||
|
|
56199240ec | ||
|
|
7b23227e7f | ||
|
|
d68977fa12 | ||
|
|
bc8932e46a | ||
|
|
12fb925555 | ||
|
|
686c5ac007 | ||
|
|
7760116478 | ||
|
|
95c439e758 | ||
|
|
5d33ea7242 | ||
|
|
e344fa8c23 | ||
|
|
ca77669181 | ||
|
|
b2859b89ce | ||
|
|
e0874baa8f | ||
|
|
e4d2a4df42 | ||
|
|
40f2b58098 | ||
|
|
31f9d414a3 | ||
|
|
0b9d3c3dcc | ||
|
|
61c9706353 | ||
|
|
c296795089 | ||
|
|
57b10b9611 | ||
|
|
4a6c506f37 | ||
|
|
ca47280ce9 | ||
|
|
92227df624 | ||
|
|
996d9b300c | ||
|
|
75b04b38f6 | ||
|
|
03a23ad987 | ||
|
|
4dd5c6ff8a | ||
|
|
b1d5a5f7b8 | ||
|
|
d7830a0ce6 | ||
|
|
318d641266 | ||
|
|
d29cb0a15d | ||
|
|
bfce470690 | ||
|
|
f324aa902b | ||
|
|
88dc4c878f | ||
|
|
7579fe5749 | ||
|
|
e528ebc374 | ||
|
|
458458b65f | ||
|
|
50cc52a091 | ||
|
|
e69c01aad3 | ||
|
|
5b4e1915d8 | ||
|
|
388218a3f9 | ||
|
|
bf064874db | ||
|
|
5c20de212a | ||
|
|
e738162bde | ||
|
|
336d481726 | ||
|
|
b303fe1098 | ||
|
|
6522158caa | ||
|
|
4565cd0143 | ||
|
|
db2f1e542c | ||
|
|
8082aa980e | ||
|
|
0e33830d1f | ||
|
|
e1b24d1ebd | ||
|
|
b3ac8c5bd8 | ||
|
|
4d559c2907 | ||
|
|
c27e25b5ca | ||
|
|
8530aa7540 | ||
|
|
c0a0c0ae71 | ||
|
|
a16ca36eb6 | ||
|
|
66689fa799 | ||
|
|
fc4b026b62 | ||
|
|
e69ade5299 | ||
|
|
58d20c7751 | ||
|
|
ffcd08b5c7 | ||
|
|
0e55119b36 | ||
|
|
4554ec42da | ||
|
|
09461c51bd | ||
|
|
c527a4e0e4 | ||
|
|
2d3c2fc258 | ||
|
|
3f1759a4d1 | ||
|
|
6d68d3297d | ||
|
|
6d79a44c46 | ||
|
|
d4e4b8bf60 | ||
|
|
6b474e059c | ||
|
|
42dae6e570 | ||
|
|
e5df8da1bd | ||
|
|
d565598489 | ||
|
|
75266e467d | ||
|
|
a07b5937d9 | ||
|
|
ff506b0375 | ||
|
|
5993fa9c7f | ||
|
|
e5437563e2 | ||
|
|
b4ff720ea4 | ||
|
|
9cd87a8495 | ||
|
|
e83ace4242 | ||
|
|
f147a1220e | ||
|
|
0414e4929f | ||
|
|
3ba8ddc85c | ||
|
|
ec50c008bb | ||
|
|
cf507a0b86 | ||
|
|
a9b2d9bdc6 | ||
|
|
034de3b1b1 | ||
|
|
240b631512 | ||
|
|
e8e499ae9e | ||
|
|
e4af726056 | ||
|
|
61c0be82f9 | ||
|
|
eb7aea82b8 | ||
|
|
cdc45e15f1 | ||
|
|
45cee6e951 | ||
|
|
899893cd17 | ||
|
|
e076a8a99c | ||
|
|
65bd5f5ca3 | ||
|
|
425182e3db | ||
|
|
fd4c9e5b04 | ||
|
|
2b75de292f | ||
|
|
aae70d74d7 | ||
|
|
67be2ec786 | ||
|
|
1419b25736 | ||
|
|
131f8015f1 | ||
|
|
505cd5e338 | ||
|
|
ce4f0cdd18 | ||
|
|
f650f2e91b | ||
|
|
dd13a976af | ||
|
|
cc2b628d1c | ||
|
|
e2dd009256 | ||
|
|
fc3bd14da0 | ||
|
|
0a178dc625 | ||
|
|
30e57b9f24 | ||
|
|
9cf24c9f78 | ||
|
|
3e82422d17 | ||
|
|
8b06d7ff42 | ||
|
|
b8292124b9 | ||
|
|
d7724e9d6a | ||
|
|
975b550432 | ||
|
|
e199d937e2 | ||
|
|
2e584f2f86 | ||
|
|
996ebbcbe8 | ||
|
|
d00117e7aa | ||
|
|
0b55d9fa88 | ||
|
|
90a4922592 | ||
|
|
02c8d6ab48 | ||
|
|
26002a5482 | ||
|
|
395c3d901c | ||
|
|
dd1da81898 | ||
|
|
6dfe05b5bf | ||
|
|
f7a4d92c2f | ||
|
|
c426929979 | ||
|
|
7f52089eae | ||
|
|
1446da8aec | ||
|
|
61e2c630b1 | ||
|
|
0ca2fdb2de | ||
|
|
1e933cc490 | ||
|
|
9b01ca3086 | ||
|
|
d1f1a16e89 | ||
|
|
e363af476b | ||
|
|
19bb265539 | ||
|
|
44ec8ec7db | ||
|
|
dd0140f82e | ||
|
|
653dfed0c5 | ||
|
|
189fb008b3 | ||
|
|
056c755708 | ||
|
|
dbb51786fc | ||
|
|
2014046f77 | ||
|
|
92b34837cb | ||
|
|
bb214af3eb | ||
|
|
40009986ee | ||
|
|
4a7a4cfac5 | ||
|
|
3211a10573 | ||
|
|
995208585b | ||
|
|
18869199ca | ||
|
|
451ea47dd8 | ||
|
|
b3bf9fc9ab | ||
|
|
d86d8b542f | ||
|
|
95d7e57d62 | ||
|
|
b443375cde | ||
|
|
15a69113fa | ||
|
|
5537a26c25 | ||
|
|
730f9ea437 | ||
|
|
7e95d5701f | ||
|
|
d762da8659 | ||
|
|
faf90f259c | ||
|
|
f98c356efd | ||
|
|
805e3552fd | ||
|
|
24378ac873 | ||
|
|
d02a3d25d0 | ||
|
|
4e711d4738 | ||
|
|
f274ed549e | ||
|
|
b0803eabdb | ||
|
|
9823b7dbd0 | ||
|
|
1c148c7984 | ||
|
|
83ddc41d63 | ||
|
|
3b5ea97e8f | ||
|
|
f3217f6ab3 | ||
|
|
32b7a91c19 | ||
|
|
2e92b7ae32 | ||
|
|
79506e4494 | ||
|
|
666a66e327 | ||
|
|
2b3a2b875b | ||
|
|
572d406d66 | ||
|
|
978e82e893 | ||
|
|
bc64d53a77 | ||
|
|
672179c3b8 | ||
|
|
89446084f3 | ||
|
|
d40f9b712e | ||
|
|
91e81591fe | ||
|
|
e64b07d7a4 | ||
|
|
e5c0d5247e | ||
|
|
f283c2e7b2 | ||
|
|
af78376627 | ||
|
|
a7b4add27c | ||
|
|
9258004cc7 | ||
|
|
6afe4f79a2 | ||
|
|
7770285aed | ||
|
|
6889959f59 | ||
|
|
99667de35b | ||
|
|
eaadc6aad6 | ||
|
|
044d8bca44 | ||
|
|
56ee01bc8c | ||
|
|
f552b26fb9 | ||
|
|
a441bdf59a | ||
|
|
a798f70284 | ||
|
|
0c5df0036c | ||
|
|
992b412be2 | ||
|
|
110a24f650 | ||
|
|
86848d2868 | ||
|
|
62061c5596 | ||
|
|
c0f6d9ba7e | ||
|
|
ae8eb37ca2 | ||
|
|
6acfe8a41e | ||
|
|
8ef88ae084 | ||
|
|
5bc6c9f2d0 | ||
|
|
7b8a2e77e4 | ||
|
|
96ef527436 | ||
|
|
09c40688e1 | ||
|
|
a83d7d515d | ||
|
|
33bcd7c02e | ||
|
|
190d49527c | ||
|
|
eb656bf40c | ||
|
|
cfe27e07de | ||
|
|
458cb25d6c | ||
|
|
ddcfe51ef5 | ||
|
|
943dfa10e7 | ||
|
|
0288cffaee | ||
|
|
19c13877ca | ||
|
|
361557e1f0 | ||
|
|
a2b0553c51 | ||
|
|
b5c9107465 | ||
|
|
d44ec53cd3 | ||
|
|
c18f7c7594 | ||
|
|
462718bcf0 | ||
|
|
969a0583ee | ||
|
|
f1f2d759af | ||
|
|
73b65084e2 | ||
|
|
37e0d20bf2 | ||
|
|
5a6c4d6ff2 | ||
|
|
d9d2a7584e | ||
|
|
0105494223 | ||
|
|
d866b6b053 | ||
|
|
e7f564cd3b | ||
|
|
7d576b4f15 | ||
|
|
31a438edf6 | ||
|
|
682dedb2e1 | ||
|
|
e93f5fe8e0 | ||
|
|
0c8abf9b50 | ||
|
|
d1123ebe4c | ||
|
|
86386548c0 | ||
|
|
6162eae9e0 | ||
|
|
5a8d149fe3 | ||
|
|
ed522d51c8 | ||
|
|
32c5ef32e9 | ||
|
|
299951ced5 | ||
|
|
65957e024d | ||
|
|
f0e9ce7422 | ||
|
|
e153f44ce8 | ||
|
|
9d42890fbf | ||
|
|
258c06df03 | ||
|
|
14d3c4cb5e | ||
|
|
16b863fc6e | ||
|
|
5181d08d05 | ||
|
|
0d7d60a1f4 | ||
|
|
08066269ba | ||
|
|
a450110b97 | ||
|
|
a935a733ab | ||
|
|
24342db476 | ||
|
|
dcddeccccc | ||
|
|
8a0689d832 | ||
|
|
a52c2ce141 | ||
|
|
7de2f57ef2 | ||
|
|
84bbde2879 | ||
|
|
09b3fa389d | ||
|
|
20371d0445 | ||
|
|
58726a6707 | ||
|
|
0a33168733 | ||
|
|
93c3f6371b | ||
|
|
f7f171e457 | ||
|
|
c96150bc70 | ||
|
|
ac42ade48c | ||
|
|
0faec6afaa | ||
|
|
25717df15f | ||
|
|
0aafec038d | ||
|
|
6912dd62fa | ||
|
|
ba473134da | ||
|
|
a12ff58674 | ||
|
|
0062a3e784 | ||
|
|
ef385696f6 | ||
|
|
8b0a16d750 | ||
|
|
3216733a05 | ||
|
|
0c97c13562 | ||
|
|
7f152ea9ba | ||
|
|
dd4b19cda7 | ||
|
|
7c91596922 | ||
|
|
73d18261dc | ||
|
|
a70354cb18 | ||
|
|
b9594c2ae8 | ||
|
|
06d098052f | ||
|
|
4969c7cdb0 | ||
|
|
b11116088a | ||
|
|
c629c54153 | ||
|
|
bb06d879aa | ||
|
|
791dd38160 | ||
|
|
2580045a83 | ||
|
|
ac4aaa208f | ||
|
|
c85e53cb2a | ||
|
|
7c32af9d99 | ||
|
|
af8b13e88c | ||
|
|
138f5fe61a | ||
|
|
102baab7d7 | ||
|
|
09ef478838 | ||
|
|
193b19fb78 | ||
|
|
3bd04d1253 | ||
|
|
fe613fa9a3 | ||
|
|
7c19e2bc38 | ||
|
|
9eeeb4e36c | ||
|
|
191306531c | ||
|
|
8943a3e949 | ||
|
|
cb88c2c3e2 | ||
|
|
0a181240c8 | ||
|
|
940a1912fa | ||
|
|
6ba0574950 | ||
|
|
00844efd2f | ||
|
|
996b2fe79f | ||
|
|
a5c7b20196 | ||
|
|
eca864175c | ||
|
|
a3a84b25e8 | ||
|
|
78a6d2bd0c | ||
|
|
dc5990ce4a | ||
|
|
649653eb1c | ||
|
|
86895d6a5c | ||
|
|
c1297e15d1 | ||
|
|
d5f7c3ab49 | ||
|
|
5c91504b49 | ||
|
|
4b9f4d8c38 | ||
|
|
7c0d8acd8f | ||
|
|
b6aa021d76 | ||
|
|
95a7e7a840 | ||
|
|
20a7918b41 | ||
|
|
8610eecb2b | ||
|
|
98ecde5b7b | ||
|
|
99c9909508 | ||
|
|
4ac5fde7c2 | ||
|
|
4801cbf47c | ||
|
|
f171bc5050 | ||
|
|
179b3eb7e4 | ||
|
|
f79ff59619 | ||
|
|
16e088a34e | ||
|
|
65ca9ee906 | ||
|
|
889f1f5488 | ||
|
|
e90f6988d8 | ||
|
|
b793802333 | ||
|
|
cfd013a01a | ||
|
|
5e862b2cd3 | ||
|
|
48d6f0220c | ||
|
|
3c24715d16 | ||
|
|
d71b6ca305 | ||
|
|
dca3b12109 | ||
|
|
b83b53d3b2 | ||
|
|
221d0c6c48 | ||
|
|
4fc94deccb | ||
|
|
30b39d5fa3 | ||
|
|
58e9856eb8 | ||
|
|
c31adb77e7 | ||
|
|
97544ed7a9 | ||
|
|
b33afb24d7 | ||
|
|
d9086833ed | ||
|
|
801fe272ca | ||
|
|
32bc1b14d4 | ||
|
|
aad80e81da | ||
|
|
f0ec1adcd3 | ||
|
|
dbd070b815 | ||
|
|
5049f03f5b | ||
|
|
b4fe9154b9 | ||
|
|
0d1716b07d | ||
|
|
3a88d133ed | ||
|
|
e82859444e | ||
|
|
59c42ffb46 | ||
|
|
6c9d3326ec | ||
|
|
a59f73f7d3 | ||
|
|
bfddf08f75 | ||
|
|
dc4dad4608 | ||
|
|
79e391ba8d | ||
|
|
f0f66f8ccc | ||
|
|
4bda9d9136 | ||
|
|
8a019c9bb9 | ||
|
|
25b918052b | ||
|
|
4b9d02fe31 | ||
|
|
101e9f5733 | ||
|
|
50b87957db | ||
|
|
b1df5d890e | ||
|
|
18511770bc | ||
|
|
6710092bb4 | ||
|
|
c25841691f | ||
|
|
1146f27c59 | ||
|
|
593a9aefca | ||
|
|
b2eca7cea2 | ||
|
|
1534ba21ce | ||
|
|
72bb960c2a | ||
|
|
e350dc27e9 | ||
|
|
3a0ded3bdd | ||
|
|
fc27469b97 | ||
|
|
00c776c3dd | ||
|
|
8c7e90f7f2 | ||
|
|
e31273a410 | ||
|
|
59b85cc672 | ||
|
|
f6aa053737 | ||
|
|
820a144f6d | ||
|
|
88f050963e | ||
|
|
c5acfd027b | ||
|
|
d9420c618c | ||
|
|
68de550090 | ||
|
|
6dd87a6ce0 | ||
|
|
54cf1334e1 | ||
|
|
c4b5f11a38 | ||
|
|
10f8da4a13 | ||
|
|
b085550a0c | ||
|
|
f9e9835449 | ||
|
|
48a5c12526 | ||
|
|
ac3202e554 | ||
|
|
1379661a85 | ||
|
|
50fc5c6d42 | ||
|
|
d5e3f73884 | ||
|
|
2bcc85b5f5 | ||
|
|
969469edef | ||
|
|
a7ef2319f6 | ||
|
|
483fe18c4d | ||
|
|
9d78356885 | ||
|
|
b75b40049d | ||
|
|
d3d1e701a4 | ||
|
|
a029b85d62 | ||
|
|
60d97fab7e | ||
|
|
b939358c36 | ||
|
|
0f0fa5b2a2 | ||
|
|
f925680035 | ||
|
|
274a733e1a | ||
|
|
9337c178c1 | ||
|
|
2a4502b0de | ||
|
|
5f67073aad | ||
|
|
3b83292205 | ||
|
|
47c1e45f28 | ||
|
|
39ccd5ab79 | ||
|
|
ad722f1450 | ||
|
|
02efe59cdd | ||
|
|
766060ece6 | ||
|
|
53230d39f4 | ||
|
|
0b3cc37258 | ||
|
|
10d7427490 | ||
|
|
084a14b114 | ||
|
|
85c99c238d | ||
|
|
e3d4f202c4 | ||
|
|
d90ec3775b | ||
|
|
9e69c7301a | ||
|
|
f2b921f380 | ||
|
|
87ea807136 | ||
|
|
7e23b704f0 | ||
|
|
0a5e174d78 | ||
|
|
c6aa50ec56 | ||
|
|
f8c420a78b | ||
|
|
4a6ab846e5 | ||
|
|
f34bf0d19e | ||
|
|
29e21bff7f | ||
|
|
7441aba6d5 | ||
|
|
8cd206a050 | ||
|
|
def630c3db | ||
|
|
b97e549dc4 | ||
|
|
d52af2ac94 | ||
|
|
7c7c4e80e1 | ||
|
|
dcd4578585 | ||
|
|
e1ebcd8019 | ||
|
|
e0f5a2ddc5 | ||
|
|
c822dc0f18 | ||
|
|
08ecddf5ca | ||
|
|
f86bba3059 | ||
|
|
2be57e4156 | ||
|
|
344831ec06 | ||
|
|
1bdff41544 | ||
|
|
fe144a6c5f | ||
|
|
aefbc47c56 | ||
|
|
4e78e91bc2 | ||
|
|
e1ab69491c | ||
|
|
8319f047d2 | ||
|
|
49f3eca476 | ||
|
|
14b3a0c794 | ||
|
|
4c79f948ab | ||
|
|
94b3e30f90 | ||
|
|
3471fce672 | ||
|
|
75e1f1797d | ||
|
|
d858a600f7 | ||
|
|
5dce61563e | ||
|
|
b086996438 | ||
|
|
694eb3f40d | ||
|
|
4c4adec5ad | ||
|
|
22f0ab926b | ||
|
|
29960db32c | ||
|
|
22a731b671 | ||
|
|
7df19173af | ||
|
|
c4f75f49e5 | ||
|
|
a5dcb8494e | ||
|
|
3af3773c60 | ||
|
|
c551b4dfb3 | ||
|
|
dcf5b5052a | ||
|
|
0ad6faeeaa | ||
|
|
dc0e78cdf8 | ||
|
|
7fca026b48 | ||
|
|
24d0c18193 | ||
|
|
49548fea07 | ||
|
|
d0aa8362db | ||
|
|
33735d0af8 | ||
|
|
4a9e6a001f | ||
|
|
798087c5ad | ||
|
|
e27fad7c9a | ||
|
|
76176a196d | ||
|
|
8b43554a27 | ||
|
|
7a042925fc | ||
|
|
edaff9fb96 | ||
|
|
a1e3f9a73e | ||
|
|
5d56340568 | ||
|
|
309a281b14 | ||
|
|
536048592b | ||
|
|
039a851003 | ||
|
|
fd60e5a8b2 | ||
|
|
f83487869d | ||
|
|
f59883427f | ||
|
|
8875e3b879 | ||
|
|
e04336d087 | ||
|
|
fd5f8c0ee1 | ||
|
|
3f66bf25aa | ||
|
|
594da536c7 | ||
|
|
e5fce868fb | ||
|
|
cc41a06c89 | ||
|
|
1f24eb2401 | ||
|
|
4775dad26c | ||
|
|
047f130005 | ||
|
|
b7049b5321 | ||
|
|
0404cc6907 | ||
|
|
ac2d708205 | ||
|
|
9ce7c72c7c | ||
|
|
d6cb9cf854 | ||
|
|
550dea7279 | ||
|
|
881f443bbe | ||
|
|
96acb3412f | ||
|
|
a3f04d2b4d | ||
|
|
b2a68211a4 | ||
|
|
bda86b8f15 | ||
|
|
5f88562263 | ||
|
|
e61b804252 | ||
|
|
c9d70552a4 | ||
|
|
600e5424a5 | ||
|
|
489d87c4b0 | ||
|
|
b9c8c8c2a5 | ||
|
|
a6b8d382a9 | ||
|
|
22281c18ec | ||
|
|
2da94bb702 | ||
|
|
268a77add1 | ||
|
|
9ea99a896a | ||
|
|
fbec6ae030 | ||
|
|
a7ff30d5a4 | ||
|
|
0ef92baf9d | ||
|
|
5cb5610906 | ||
|
|
4a1a29b3d0 | ||
|
|
508e0bdfbf | ||
|
|
2f0fe562ec | ||
|
|
84285881f3 | ||
|
|
65dfd2f9a8 | ||
|
|
1056c759fd | ||
|
|
b30bacf86e | ||
|
|
b78b2c7ac9 | ||
|
|
f96cea8151 | ||
|
|
0cf12c6778 | ||
|
|
4dc1014bfb | ||
|
|
6cabc85ac8 | ||
|
|
b7bbf8f7e4 | ||
|
|
d8acc3a9f4 | ||
|
|
d13b8e1937 | ||
|
|
85e020b8e1 | ||
|
|
99da68183f | ||
|
|
fe596f2219 | ||
|
|
206bf856bb | ||
|
|
e3803fb861 | ||
|
|
556a7b8b17 | ||
|
|
3580bb6e17 | ||
|
|
06c4b0248b | ||
|
|
e53b00aafb | ||
|
|
5907307af6 | ||
|
|
f3610dc3a8 | ||
|
|
9971f41f8c | ||
|
|
c54e8ec3e2 | ||
|
|
e691af4e97 | ||
|
|
38d2b8d46a | ||
|
|
66286d6f17 | ||
|
|
5ff1ef82d1 | ||
|
|
68925a6d33 | ||
|
|
b903ddeea7 | ||
|
|
067a8a35cd | ||
|
|
81b17ba1e4 | ||
|
|
4a68f6bf75 | ||
|
|
518c32e1af | ||
|
|
016a769605 | ||
|
|
d2af024349 | ||
|
|
b4c4681733 | ||
|
|
14f4aa6e05 | ||
|
|
ef0c3f9d2c | ||
|
|
02ef158748 | ||
|
|
fb2d153c92 | ||
|
|
cf72499919 | ||
|
|
bcd82b7e75 | ||
|
|
d8a71e5978 | ||
|
|
82388f4389 | ||
|
|
801a779a88 | ||
|
|
417fb4e108 | ||
|
|
f8332ce587 | ||
|
|
b44ffc9361 | ||
|
|
3eb5302ab0 | ||
|
|
9605a60eac | ||
|
|
b49f052051 | ||
|
|
a187f15d8c | ||
|
|
7248c5cc23 | ||
|
|
90239c0787 | ||
|
|
2eae70d3cd | ||
|
|
7f1adbea46 | ||
|
|
e0fe046ad3 | ||
|
|
c27d04e338 | ||
|
|
960670b16c | ||
|
|
219eecf8d7 | ||
|
|
6b50f993bc | ||
|
|
1866520d6c | ||
|
|
bc44104522 | ||
|
|
891f933863 | ||
|
|
d813a12f20 | ||
|
|
b439924bf9 | ||
|
|
ff728eb6ce | ||
|
|
229f01b153 | ||
|
|
5e5fe7291a | ||
|
|
31e8b50b7c | ||
|
|
feba5a138e | ||
|
|
d0d9cb6a73 | ||
|
|
23078154cd | ||
|
|
e1e87657c7 | ||
|
|
b36a49dfc2 | ||
|
|
27e0500452 | ||
|
|
b67df08c9d | ||
|
|
609a065503 | ||
|
|
a452390f0b | ||
|
|
72a575a5f9 | ||
|
|
1b313df419 | ||
|
|
6315a09369 | ||
|
|
598dfff601 | ||
|
|
5b4e1d22d9 | ||
|
|
956ec2f84c | ||
|
|
3052260249 | ||
|
|
2f1520b4c1 | ||
|
|
abb2045e17 | ||
|
|
7ec08af6d9 | ||
|
|
6e437674f7 | ||
|
|
f3313b6603 | ||
|
|
5a79cb9150 | ||
|
|
dea6609612 | ||
|
|
33d4134f49 | ||
|
|
a0290f8c51 | ||
|
|
7ae7b8481a | ||
|
|
913196e2dc | ||
|
|
6407f8667f | ||
|
|
bc0b6be6a9 | ||
|
|
44e0d7003a | ||
|
|
3e46cf5664 | ||
|
|
3dbe398252 | ||
|
|
d1a750c528 | ||
|
|
011a521968 | ||
|
|
32cb245cb8 | ||
|
|
34674ac49f | ||
|
|
62b3f24d1c | ||
|
|
40fd3d8c62 | ||
|
|
b99d91b96e | ||
|
|
83afc6e438 | ||
|
|
706e341d3a | ||
|
|
449a72d8a2 | ||
|
|
4025ca8ae1 | ||
|
|
36a52c6886 | ||
|
|
95affade5d | ||
|
|
54a07dd3d6 | ||
|
|
1e8c36f682 | ||
|
|
9c7a303caf | ||
|
|
0d1e4bf8d5 | ||
|
|
88c347ee00 | ||
|
|
32e7ec7b9b | ||
|
|
9a65e4f607 | ||
|
|
b370591e64 | ||
|
|
ea51f1ffda | ||
|
|
aa6f99b0a4 | ||
|
|
12df9bf450 | ||
|
|
77f5ef3bcd | ||
|
|
9d15735bc6 | ||
|
|
cde4d4aee0 | ||
|
|
8b3a339817 | ||
|
|
bf6c484c13 | ||
|
|
0684101ff0 | ||
|
|
4ce4d4120a | ||
|
|
35638568c5 | ||
|
|
cda48b4a49 | ||
|
|
5073cba536 | ||
|
|
18c4393106 | ||
|
|
ff1e4b1bfb | ||
|
|
7cbce1f47c | ||
|
|
0b63bb91b6 | ||
|
|
07669ac991 | ||
|
|
914508bf7a | ||
|
|
080d3b6b63 | ||
|
|
a529fffb7b | ||
|
|
fb2e0b50c8 | ||
|
|
7651c94bf5 | ||
|
|
edba179497 | ||
|
|
394801c998 | ||
|
|
79167d8f5c | ||
|
|
c8380c1447 | ||
|
|
1c4078f23a | ||
|
|
9d72c21894 | ||
|
|
2f727fb5c6 | ||
|
|
8e2c95e5e4 | ||
|
|
0055438257 | ||
|
|
776c2a6046 | ||
|
|
ecd7b0568b | ||
|
|
c12224ffd3 | ||
|
|
97f8179f90 | ||
|
|
8aa3967201 | ||
|
|
8755993123 | ||
|
|
b6baf3fe1e | ||
|
|
f86cd6899c | ||
|
|
4a1a162c09 | ||
|
|
1dcc6fda6b | ||
|
|
a0e0000108 | ||
|
|
5f2691a65b | ||
|
|
7304a019e7 | ||
|
|
17724c5f1c | ||
|
|
ca9b5e3f56 | ||
|
|
fccf025d2f | ||
|
|
c57b841556 | ||
|
|
a1b5ebeb09 | ||
|
|
0bc2e240bf | ||
|
|
d23e1a87dd | ||
|
|
6a94b8d153 | ||
|
|
37736016fb | ||
|
|
5f1b0a5945 | ||
|
|
a5f72ec095 | ||
|
|
7e8661f8bf | ||
|
|
651eb9d4f2 | ||
|
|
8c9b23ef56 | ||
|
|
05283ac247 | ||
|
|
240819b708 | ||
|
|
61115c3776 | ||
|
|
fb4ac714b2 | ||
|
|
561a9e7a72 | ||
|
|
93b3e7d12f | ||
|
|
701856b06a | ||
|
|
27b1017fe9 | ||
|
|
42d9640443 | ||
|
|
c2080ecc03 | ||
|
|
bcb4b231af | ||
|
|
364e58097d | ||
|
|
a0840d7a06 | ||
|
|
1006e9d987 | ||
|
|
8c26a142c6 | ||
|
|
c2a2ed67bb | ||
|
|
7abe07e2cf | ||
|
|
df459c46ef | ||
|
|
5dc4ee6524 | ||
|
|
7395f24423 | ||
|
|
7d62b891f8 | ||
|
|
e21e32a793 | ||
|
|
c2650cd1e7 | ||
|
|
360d38c36d | ||
|
|
f19cd8416e | ||
|
|
1336b0a751 | ||
|
|
ee6f5f3b1b | ||
|
|
7ea020d471 | ||
|
|
d191c376f7 | ||
|
|
7bfc8f2fde | ||
|
|
55007f5bd9 | ||
|
|
40c8e76f49 | ||
|
|
8540b4c9d1 | ||
|
|
69b76ba9ed | ||
|
|
cec7847502 | ||
|
|
de6048f517 | ||
|
|
684de7a57b | ||
|
|
491ab232bf | ||
|
|
1b4f7ae0d3 | ||
|
|
f9bff3bc7c | ||
|
|
dea712ab72 | ||
|
|
8851b64825 | ||
|
|
b73765cf9b | ||
|
|
01369546d2 | ||
|
|
a67bc59686 | ||
|
|
bb06e8451a | ||
|
|
6aba9b1b9a | ||
|
|
94ebdc9269 | ||
|
|
0d34988929 | ||
|
|
443008777b | ||
|
|
6855b27553 | ||
|
|
e440ab40ef | ||
|
|
2584c104e0 | ||
|
|
092e4a001f | ||
|
|
d6d1b8e025 | ||
|
|
4535a27dfc | ||
|
|
00d3f61961 | ||
|
|
43274fbf5f | ||
|
|
fb58e46672 | ||
|
|
840bb5f90d | ||
|
|
8a94dd2cb1 | ||
|
|
ac790cd6fb | ||
|
|
b19d8a50d5 | ||
|
|
83e3178e9b | ||
|
|
f3cf4a7d7b | ||
|
|
96ea73c3fe | ||
|
|
7c76ec897c | ||
|
|
c2cd4102d8 | ||
|
|
d02f4866ea | ||
|
|
c5a1e3daa3 | ||
|
|
3062b7d780 | ||
|
|
27c9825bf0 | ||
|
|
25c7204b2a | ||
|
|
41731a2439 | ||
|
|
8b5aa538e7 | ||
|
|
fc15a164ce | ||
|
|
c2e1013ad4 | ||
|
|
980793970d | ||
|
|
30e37d90dd | ||
|
|
a6b30d58df | ||
|
|
a5b8090e14 | ||
|
|
87993a864c | ||
|
|
d9e4d32374 | ||
|
|
602f9b5670 | ||
|
|
c167e86d87 | ||
|
|
4a2319a4d6 | ||
|
|
d5188161f5 | ||
|
|
36ea3cc5a4 | ||
|
|
68ac1347b9 | ||
|
|
c4679e7af6 | ||
|
|
89270f69e0 | ||
|
|
32d1e5b4a7 | ||
|
|
77b0e10e88 | ||
|
|
cb74956d06 | ||
|
|
54c5b7d712 | ||
|
|
713659cea5 | ||
|
|
3aa2119290 | ||
|
|
63dd5efa72 | ||
|
|
74abf8132e | ||
|
|
636f5dda29 | ||
|
|
ad92d799cd | ||
|
|
8f9056d738 | ||
|
|
c1bc9f8557 | ||
|
|
b80fd10a70 | ||
|
|
1e7116fcc1 | ||
|
|
73bf682b62 | ||
|
|
dec1869e2c | ||
|
|
ce66e12699 | ||
|
|
342e48115e | ||
|
|
58dba227ce | ||
|
|
0046edf761 | ||
|
|
ff5a474e74 | ||
|
|
9a049789de | ||
|
|
f57da7e645 | ||
|
|
12b89852e0 | ||
|
|
f66ce025d3 | ||
|
|
bfe88307de | ||
|
|
610ba6e3b6 | ||
|
|
66160e6bd3 | ||
|
|
e2d1888f52 | ||
|
|
2aeea45c30 | ||
|
|
82a9582dd7 | ||
|
|
4e4b95bfe3 | ||
|
|
9d989b1557 | ||
|
|
4685ba394e | ||
|
|
5734ea736c | ||
|
|
5fdea3a595 | ||
|
|
efccd9c961 | ||
|
|
87c5fa1279 | ||
|
|
8baf19022c | ||
|
|
518a57d8e5 | ||
|
|
039ade7ad0 | ||
|
|
1f1437747c | ||
|
|
3f1e1323f0 | ||
|
|
bc09ff7498 | ||
|
|
4163367b53 | ||
|
|
c06b53e52e | ||
|
|
196133c582 | ||
|
|
d018cb62f3 | ||
|
|
350a3d9ae4 | ||
|
|
3a62676da8 | ||
|
|
44617b8c9d | ||
|
|
855147a021 | ||
|
|
70b1ae3d1b | ||
|
|
f55d06fd5c | ||
|
|
eefaa07024 | ||
|
|
a80464299a | ||
|
|
0182e81b51 | ||
|
|
ae7e461452 | ||
|
|
d7b9cd0654 | ||
|
|
022762605b | ||
|
|
7c5b59556a | ||
|
|
e816020346 | ||
|
|
7b99a43c9e | ||
|
|
a90e0e249e | ||
|
|
3b7124bb37 | ||
|
|
49dd55313a | ||
|
|
801c4aa72f | ||
|
|
ee8c76b42e | ||
|
|
67741655d1 | ||
|
|
1e166c7236 | ||
|
|
ff740e300a | ||
|
|
cb10fe1d77 | ||
|
|
5ae0dab6c5 | ||
|
|
c02aa759e6 | ||
|
|
5410ecf9ad | ||
|
|
2d48e209f4 | ||
|
|
5a75a2f930 | ||
|
|
b843dbf045 | ||
|
|
5af3ffd6a8 | ||
|
|
727d307089 | ||
|
|
ab0058a454 | ||
|
|
b27bd256dd | ||
|
|
db72301eb0 | ||
|
|
aa7058a3b4 | ||
|
|
769a6ce987 | ||
|
|
9144d47fe2 | ||
|
|
4a5632ab6d | ||
|
|
789ae1ea8d | ||
|
|
0f54ad8e26 | ||
|
|
e326371762 | ||
|
|
40c0db2e8d | ||
|
|
9fae8a7532 | ||
|
|
767ea7f5b1 | ||
|
|
00ede822c6 | ||
|
|
cd34effd64 | ||
|
|
e9f3101105 | ||
|
|
2bacd2bf62 | ||
|
|
0a71c8f3e1 | ||
|
|
1490c58f8b | ||
|
|
fa6c7204cd | ||
|
|
133cbd272e | ||
|
|
ec60011852 | ||
|
|
1aba8182a4 | ||
|
|
e3881163c4 | ||
|
|
040cf2eb2a | ||
|
|
5d9d3bff11 | ||
|
|
536277ec55 | ||
|
|
7cefeac8ed | ||
|
|
963b8b0607 | ||
|
|
e337f2cb0f | ||
|
|
62492f3cd2 | ||
|
|
4ecae91fc3 | ||
|
|
ad28da66b0 | ||
|
|
3264a22c1e | ||
|
|
c7956aa41b | ||
|
|
7fb0c9ba30 | ||
|
|
f663168ffd | ||
|
|
98f7227ed0 | ||
|
|
e309c38263 | ||
|
|
4962340985 | ||
|
|
48865337b1 | ||
|
|
c05d4e5b49 | ||
|
|
65b619e7b4 | ||
|
|
4d1e75ce3b | ||
|
|
394a495b55 | ||
|
|
fec1765cc4 | ||
|
|
a942efd92b | ||
|
|
e56437ff0a | ||
|
|
0f8dd3a7a0 | ||
|
|
445ecba9b5 | ||
|
|
f13463325a | ||
|
|
a482bb8a89 | ||
|
|
6eaf333f10 | ||
|
|
d7ee460704 | ||
|
|
0f686a774d | ||
|
|
b9b2a7de34 | ||
|
|
b7b74e62a0 | ||
|
|
6e0d44397f | ||
|
|
58f7ed268d | ||
|
|
47ac55e9c5 | ||
|
|
c9938e424b | ||
|
|
3e24a86b87 | ||
|
|
b249d9f66d | ||
|
|
b41df1fb7a | ||
|
|
d8b87b2593 | ||
|
|
784d4e39d5 | ||
|
|
50d0a1b8f9 | ||
|
|
672b03f553 | ||
|
|
df71cecc66 | ||
|
|
1895931918 | ||
|
|
0d344de496 | ||
|
|
b53a630592 | ||
|
|
37a7119eb3 | ||
|
|
f66a7db87f | ||
|
|
9aa0de24af | ||
|
|
94bbdbb71d | ||
|
|
ebea6fb23f | ||
|
|
002eb6f649 | ||
|
|
02753b3c2c | ||
|
|
6402182815 | ||
|
|
132e027c69 | ||
|
|
58a420511c | ||
|
|
392ed76344 | ||
|
|
25ad0ad530 | ||
|
|
b7855cc517 | ||
|
|
c738f4b029 | ||
|
|
686b9d44f4 | ||
|
|
0cf2b1be89 | ||
|
|
579a5e7845 | ||
|
|
b634549722 | ||
|
|
49aecc20b7 | ||
|
|
c188f792b2 | ||
|
|
70737c034b | ||
|
|
b50a88a95d | ||
|
|
20239dc27f | ||
|
|
ca85cb936b | ||
|
|
5471ef7e1e | ||
|
|
26be862e08 | ||
|
|
e88e3680aa | ||
|
|
0a001443e9 | ||
|
|
94d04b724a | ||
|
|
b3a9a2eb4e | ||
|
|
7b15cce099 | ||
|
|
19ec0b2dd4 | ||
|
|
83d4fcdf27 | ||
|
|
5261fe626d | ||
|
|
cf43e0c3da | ||
|
|
d49700f562 | ||
|
|
1224162072 | ||
|
|
87b7dfed5d | ||
|
|
1b23d3b8cb | ||
|
|
82705cfc0f | ||
|
|
c4677042e1 | ||
|
|
d3e5e5c286 | ||
|
|
eb2843de33 | ||
|
|
3f80249204 | ||
|
|
9b312054f5 | ||
|
|
ab91750869 | ||
|
|
64b3ab59b0 | ||
|
|
66c2c74147 | ||
|
|
794b178032 | ||
|
|
0db4116ba6 | ||
|
|
accfc4145a | ||
|
|
e36170c997 | ||
|
|
fe3a958dbf | ||
|
|
16ba978025 | ||
|
|
07c4b92335 | ||
|
|
aea90dc7da | ||
|
|
ae899b9bc7 | ||
|
|
471e61f0e4 | ||
|
|
51875b89fd | ||
|
|
1bb1ebe2ae | ||
|
|
7731e02a20 | ||
|
|
529cdc949b | ||
|
|
aff17cb177 | ||
|
|
558a00138c | ||
|
|
0e49149a46 | ||
|
|
149a0183ec | ||
|
|
72a3c2fe97 | ||
|
|
9ab593e1b5 | ||
|
|
916bd88e5e | ||
|
|
ffc25fde53 | ||
|
|
0c40d52010 | ||
|
|
9d5af71c3d | ||
|
|
37d5bdbae5 | ||
|
|
f90058488f | ||
|
|
4fdc999087 | ||
|
|
6895175764 | ||
|
|
391c261199 | ||
|
|
76adfff091 | ||
|
|
4bef85d7bc | ||
|
|
abc3c5f0df | ||
|
|
ef0c859b7a | ||
|
|
264160797d | ||
|
|
0d868515a5 | ||
|
|
63c5ec7390 | ||
|
|
385b37dca7 | ||
|
|
9c32d53914 | ||
|
|
3cb567d0b1 | ||
|
|
f0b734886e | ||
|
|
d77cb2b1fc | ||
|
|
c6881a8126 | ||
|
|
a7a7c56ad6 | ||
|
|
9db4293d7a | ||
|
|
15d1beca1b | ||
|
|
cc1a6041a7 | ||
|
|
d3d822cd9d | ||
|
|
3e68b07db0 | ||
|
|
9799adda79 | ||
|
|
5abd2dddb8 | ||
|
|
3a566262fe | ||
|
|
12fc9a0fbb | ||
|
|
484bde4b4b | ||
|
|
17a140db3d | ||
|
|
cfab4e74a9 | ||
|
|
7e79128c03 | ||
|
|
9f054635bd | ||
|
|
1515a0a51e | ||
|
|
5136883ded | ||
|
|
85012d5edd | ||
|
|
9489bf41a5 | ||
|
|
daafe3f4e2 | ||
|
|
5c27993884 | ||
|
|
37a6669e71 | ||
|
|
aa5751b7fc | ||
|
|
159c3d0606 | ||
|
|
02c8d73426 | ||
|
|
ab4c36c834 | ||
|
|
2bb901e1e3 | ||
|
|
3ebb715c5c | ||
|
|
e8059ccba5 | ||
|
|
458206b11a | ||
|
|
d7bbb27671 | ||
|
|
8009e9ca59 | ||
|
|
0489f3673c | ||
|
|
b15fb2bbaf | ||
|
|
b025ddcc8f | ||
|
|
bb51c113ca | ||
|
|
798fb709a2 | ||
|
|
7e823f7c19 | ||
|
|
cd2910eb2c | ||
|
|
d5cf77539a | ||
|
|
f668aea42a | ||
|
|
e1b463082a | ||
|
|
f4d7455a9f | ||
|
|
5bce4dac81 | ||
|
|
c835993ac3 | ||
|
|
6ac68494db | ||
|
|
c4ec847680 | ||
|
|
3925c7ec60 | ||
|
|
5eff895f9d | ||
|
|
d27e0a8fe6 | ||
|
|
22231c0604 | ||
|
|
71c32f2923 | ||
|
|
57d2b7235d | ||
|
|
f9e70b0300 | ||
|
|
c5a55e5af4 | ||
|
|
f896fcfadb | ||
|
|
9f8ccc030b | ||
|
|
5c1b9399b0 | ||
|
|
9a6423b4ef | ||
|
|
8f34c27ca5 | ||
|
|
41adf8d196 | ||
|
|
119f679278 | ||
|
|
6881a71a87 | ||
|
|
3f661a75e4 | ||
|
|
0622446f09 | ||
|
|
e78a84196d | ||
|
|
4f8d8b760c | ||
|
|
7541c357ca | ||
|
|
8cba87420b | ||
|
|
134a785fe0 | ||
|
|
9f7e47368f | ||
|
|
0a85964f91 | ||
|
|
da53a11508 | ||
|
|
bd0c680ec8 | ||
|
|
8a279855ff | ||
|
|
efae71dac7 | ||
|
|
7000fb8642 | ||
|
|
8b7f959451 | ||
|
|
f3b03fa01b | ||
|
|
7a6d9f8530 | ||
|
|
65d9607ece | ||
|
|
9e41848927 | ||
|
|
48e6468df1 | ||
|
|
419e5e46f6 | ||
|
|
c88e6bb81d | ||
|
|
c3c7a01df5 | ||
|
|
280ca8982b | ||
|
|
53018515a9 | ||
|
|
8bad3d08d7 | ||
|
|
9a94fbb1ec | ||
|
|
d8c51656d7 | ||
|
|
987dea5f7f | ||
|
|
c47a6b0830 | ||
|
|
b587134a8d | ||
|
|
4277bdd3cd | ||
|
|
8f4903ca86 | ||
|
|
68fd016746 | ||
|
|
c23491ef3c | ||
|
|
4c4962b306 | ||
|
|
7aa301361d | ||
|
|
7c77a98118 | ||
|
|
ec60ad3a80 | ||
|
|
175ec07c06 | ||
|
|
2f6864a487 | ||
|
|
f30c49c0c3 | ||
|
|
ca1a94d74c | ||
|
|
5ca6dd10f8 | ||
|
|
4918035258 | ||
|
|
7ce734d886 | ||
|
|
93d6d71a1d | ||
|
|
0f70cafb91 | ||
|
|
d6da06913e | ||
|
|
647631af09 | ||
|
|
e18c02991e | ||
|
|
dd1b8a106f | ||
|
|
fc24ffcdb8 | ||
|
|
90ba794e8e | ||
|
|
9d98e8ac01 | ||
|
|
cccb763737 | ||
|
|
62a0605cf0 | ||
|
|
7ba00f3692 | ||
|
|
f33ff21ab2 | ||
|
|
3af5a0ca4e | ||
|
|
38152d6c72 | ||
|
|
5ffdda783b | ||
|
|
fb1d66b254 | ||
|
|
2fb0bfdf85 | ||
|
|
c05a0eca86 | ||
|
|
852bc3fc62 | ||
|
|
75bfc37b18 | ||
|
|
8463f4910a | ||
|
|
ba67b535f8 | ||
|
|
1cac134030 | ||
|
|
caac994da8 | ||
|
|
1f1fafb0cf | ||
|
|
70c57a3be3 | ||
|
|
02209e5455 | ||
|
|
7b7851abfb | ||
|
|
6e7b66cb8a | ||
|
|
18c00e58cc | ||
|
|
c84bbea1ca | ||
|
|
f6dcc3ca74 | ||
|
|
317c5429d2 | ||
|
|
ff0ba89e91 | ||
|
|
fa3f5edcc2 | ||
|
|
f9bb7246ef | ||
|
|
4193279560 | ||
|
|
13e0710d20 | ||
|
|
3d5ec9ea3f | ||
|
|
5e7e6514be | ||
|
|
edcd44d9a7 | ||
|
|
b15fd68b60 | ||
|
|
720d2847b6 | ||
|
|
7563cf5c55 | ||
|
|
15b30f3547 | ||
|
|
2dd1365af3 | ||
|
|
5a2d4c3437 | ||
|
|
6e03d731a2 | ||
|
|
1a7ff195d9 | ||
|
|
e2ddcee440 | ||
|
|
1139492c4f | ||
|
|
1fd1786122 | ||
|
|
e2836bf68a | ||
|
|
1d82a049bf | ||
|
|
7e1a2ac684 | ||
|
|
de99945af0 | ||
|
|
415d4ab23d | ||
|
|
7093258649 | ||
|
|
3f9698a292 | ||
|
|
3a8c3dcc2d | ||
|
|
54cc70f9b1 | ||
|
|
59ce64b638 | ||
|
|
8264b63e0b | ||
|
|
ea294fff0c | ||
|
|
afaabb3121 | ||
|
|
1996041dcc | ||
|
|
18c23ddb0c | ||
|
|
2232b33b8e | ||
|
|
0ab69a2bb8 | ||
|
|
6e30d00eef | ||
|
|
ee564125df | ||
|
|
8ecbc48211 | ||
|
|
48cc8fb657 | ||
|
|
d258422c34 | ||
|
|
8de0d8d4e0 | ||
|
|
36c1dc16d4 | ||
|
|
3489672bc0 | ||
|
|
adf0b893e8 | ||
|
|
943c9809ed | ||
|
|
c888fcbdd9 | ||
|
|
7109b80bbd | ||
|
|
098bc66fc9 | ||
|
|
0a28df8805 | ||
|
|
abe163c335 | ||
|
|
434a4db637 | ||
|
|
bf18ffbbdd | ||
|
|
c907e44a02 | ||
|
|
79e262921e | ||
|
|
0a81bd5d5a | ||
|
|
c09b4ba46b | ||
|
|
6e607349e1 | ||
|
|
fb0e8fffa2 | ||
|
|
40338f9acb | ||
|
|
21d4b8aba0 | ||
|
|
62db70e2ea | ||
|
|
563f55e57b | ||
|
|
45e5a33b26 | ||
|
|
cc99646b23 | ||
|
|
e8ee2cc227 | ||
|
|
f789c8152c | ||
|
|
70cf9fe3dd | ||
|
|
98cbfa3561 | ||
|
|
29b441c6fa | ||
|
|
a27e46989f | ||
|
|
57b66987dd | ||
|
|
d7440a8b1c | ||
|
|
3c5d27506f | ||
|
|
a4c59c03e3 | ||
|
|
65d3b3a32f | ||
|
|
47fa54992f | ||
|
|
6af42c9fb5 | ||
|
|
54a549d808 | ||
|
|
6a57683e52 | ||
|
|
65f65073e6 | ||
|
|
add6dbac4e | ||
|
|
0d5571a820 | ||
|
|
734fc252e8 | ||
|
|
f2153f9b2f | ||
|
|
30b70da6c1 | ||
|
|
f47c64e246 | ||
|
|
3e0e86f720 | ||
|
|
e3c2fdf414 | ||
|
|
b599f4e106 | ||
|
|
530ec3115f | ||
|
|
dea53f635f | ||
|
|
5800ab4961 | ||
|
|
03d7258d33 | ||
|
|
7c5c92351e | ||
|
|
80b729703b | ||
|
|
194af03fe9 | ||
|
|
c40205e93f | ||
|
|
d9dd518a20 | ||
|
|
ceaa02230e | ||
|
|
e0dc544aa5 | ||
|
|
6cb697e6d8 | ||
|
|
250c16ddcf | ||
|
|
4a15621dc8 | ||
|
|
7441548458 | ||
|
|
11764ed755 | ||
|
|
b349dd9c0a | ||
|
|
97bf616b5b | ||
|
|
6f4242f03b | ||
|
|
716579b12f | ||
|
|
df25d23eb9 | ||
|
|
66c3463749 | ||
|
|
dfc1b97fa2 | ||
|
|
d6f65901f9 | ||
|
|
5253d4ddd7 | ||
|
|
2dbf3322d8 | ||
|
|
798e3ee306 | ||
|
|
583f2d6a36 | ||
|
|
c1104ccbc7 | ||
|
|
e882ca748d | ||
|
|
b277b84e19 | ||
|
|
1e3836f8b5 | ||
|
|
312b638220 | ||
|
|
c75b07e0fd | ||
|
|
cb69c59fa3 | ||
|
|
fa6e819f9a | ||
|
|
0a819d5e19 | ||
|
|
e11ed069bf | ||
|
|
7477f99d05 | ||
|
|
6ca7119267 | ||
|
|
256a989550 | ||
|
|
34c7085ada | ||
|
|
30e0452faf | ||
|
|
435c9719a7 | ||
|
|
d92bd3afee | ||
|
|
7351aa1670 | ||
|
|
22bee79534 | ||
|
|
5a97297282 | ||
|
|
80c8775d77 | ||
|
|
1c790b2776 | ||
|
|
0aef0959d5 | ||
|
|
6b2338257d | ||
|
|
823349fffb | ||
|
|
e1e26c4439 | ||
|
|
b1be660c7b | ||
|
|
8992dadb15 | ||
|
|
497c8b0922 | ||
|
|
cfd3be675f | ||
|
|
dc178e0ab2 | ||
|
|
0e82322605 | ||
|
|
22c9157231 | ||
|
|
6b406469f6 | ||
|
|
080b0fb9b3 | ||
|
|
ea0a692879 | ||
|
|
3ba070e5e4 | ||
|
|
d5710d9de3 | ||
|
|
6727b5ea49 | ||
|
|
aeb65d6b1b | ||
|
|
d3d3351b99 | ||
|
|
cb0546aa9b | ||
|
|
b558cd18d4 | ||
|
|
9b5944b90c | ||
|
|
d3357b4c53 | ||
|
|
b2e4f95f27 | ||
|
|
f2e63bdd64 | ||
|
|
f98466430f | ||
|
|
3520492f09 | ||
|
|
475bcfc2b9 | ||
|
|
11f3df6e72 | ||
|
|
a4fd743973 | ||
|
|
9b4cd59d09 | ||
|
|
44046a82d4 | ||
|
|
8cb9d19079 | ||
|
|
46c8267fa9 | ||
|
|
4903487f21 | ||
|
|
40f31a9050 | ||
|
|
4c98be54eb | ||
|
|
86ebbc2191 | ||
|
|
60b44f071b | ||
|
|
75d43555c8 | ||
|
|
61d1226805 | ||
|
|
d69113643f | ||
|
|
ccc04a7082 | ||
|
|
f8bcb1999e | ||
|
|
c35714dc81 | ||
|
|
97b015b8c7 | ||
|
|
b60190a73c | ||
|
|
f5477dc53b | ||
|
|
4961ee293d | ||
|
|
c3b53bc2ec | ||
|
|
9e3233f13f | ||
|
|
44bed3495d | ||
|
|
d2b12b5c79 | ||
|
|
90690d96d4 | ||
|
|
87bed28ef8 | ||
|
|
0285e5f217 | ||
|
|
49f835db86 | ||
|
|
7eb0b6928a | ||
|
|
da6b384e3a | ||
|
|
7f170e492e | ||
|
|
c4810c5db4 | ||
|
|
e88a84e2ab | ||
|
|
de986c5f0b | ||
|
|
cb531e4cf9 | ||
|
|
6355b48eee | ||
|
|
37735d84d9 | ||
|
|
bfecea9001 | ||
|
|
058990de48 | ||
|
|
cfca9899b2 | ||
|
|
e1b6855352 | ||
|
|
9713fa505f | ||
|
|
ee9281b458 | ||
|
|
c4b8fae563 | ||
|
|
b696439a67 | ||
|
|
74734b7dd9 | ||
|
|
1f2dc78feb | ||
|
|
ae19ab0cff | ||
|
|
e64f2eaff9 | ||
|
|
a12fcfea0d | ||
|
|
8e32e7a14e | ||
|
|
29079b2ac8 | ||
|
|
604d6bf567 | ||
|
|
f679864c23 | ||
|
|
1dac048413 | ||
|
|
81e85bf1b5 | ||
|
|
2383d802ba | ||
|
|
11de03fedc | ||
|
|
1e1df21a94 | ||
|
|
502f5b8a59 | ||
|
|
03c23d299a | ||
|
|
590cf78c0f | ||
|
|
978f86ba60 | ||
|
|
5e0a9052d2 | ||
|
|
37d1855907 | ||
|
|
d59a2b4b38 | ||
|
|
d35e6f1aa2 | ||
|
|
8f5fe6dfe1 | ||
|
|
cc5d476fb1 | ||
|
|
ff497bc710 | ||
|
|
69d3d83930 | ||
|
|
9cb9060794 | ||
|
|
369af8d8c3 | ||
|
|
02a8c279dc | ||
|
|
2e754da822 | ||
|
|
78b8b2785c | ||
|
|
07c089e860 | ||
|
|
bab90d4837 | ||
|
|
3fa275354d | ||
|
|
d0578700bc | ||
|
|
e4ac393de4 | ||
|
|
417547c7d9 | ||
|
|
9e021422c7 | ||
|
|
106e322f82 | ||
|
|
b8c80c9570 | ||
|
|
8920e5fbea | ||
|
|
de70f17ee4 | ||
|
|
b12ebae6cd | ||
|
|
8602837fd4 | ||
|
|
f18a12a592 | ||
|
|
8c9ca0e7a9 | ||
|
|
29238498b6 | ||
|
|
70644186c1 | ||
|
|
0c70e9e8df | ||
|
|
b2bc5912c8 | ||
|
|
a2832995d0 | ||
|
|
dab7c64762 | ||
|
|
1cb4b4e2d8 | ||
|
|
71bda7db24 | ||
|
|
f119d9ee8b | ||
|
|
fc71f1848f | ||
|
|
03ed5fc3f4 | ||
|
|
05e5ecca86 | ||
|
|
2a0e45d0f7 | ||
|
|
d9643b61af | ||
|
|
2a49eee50f | ||
|
|
901cbf0af3 | ||
|
|
1742eb16b2 | ||
|
|
5c501997ca | ||
|
|
b96004fd71 | ||
|
|
4dc5426a45 | ||
|
|
db69104f1a | ||
|
|
1edde7c1bc | ||
|
|
c2aacfa9c4 | ||
|
|
aa44ada2d4 | ||
|
|
0eda98b03e | ||
|
|
ed5cbbfa1b | ||
|
|
36a1428c55 | ||
|
|
c74c8d12cf | ||
|
|
920e240f67 | ||
|
|
b29db99f1c | ||
|
|
acfeda15a7 | ||
|
|
eab8db228b | ||
|
|
98bf2dadb8 | ||
|
|
97e3572844 | ||
|
|
f079d1f7c3 | ||
|
|
19e2b5b8b2 | ||
|
|
3c3e45746a | ||
|
|
cad11093f1 | ||
|
|
5080e88a7a | ||
|
|
b7d1d8d091 | ||
|
|
bcc454aa89 | ||
|
|
280724e6b5 | ||
|
|
4a5d31e248 | ||
|
|
eb93b5f863 | ||
|
|
f712d97763 | ||
|
|
0e3a9bfe1f | ||
|
|
2e76374a35 | ||
|
|
db8fb0e168 | ||
|
|
ab0fe21ac7 | ||
|
|
22d8c4059e | ||
|
|
97070620af | ||
|
|
de106608a0 | ||
|
|
01b198657d | ||
|
|
43d51c4499 | ||
|
|
937ddd012b | ||
|
|
280fc45c5f | ||
|
|
091db48843 | ||
|
|
6717494c5b | ||
|
|
6d91b5d51b | ||
|
|
8f0a191c2a | ||
|
|
bdbfa532cd | ||
|
|
98a31bbfdb | ||
|
|
7deee978c5 | ||
|
|
d68f5446b1 | ||
|
|
d8ff3f655a | ||
|
|
4edd45dd8f | ||
|
|
ddc3b88cd2 | ||
|
|
e9a497abe4 | ||
|
|
83d0214099 | ||
|
|
105b3cd21d | ||
|
|
5687dc06fd | ||
|
|
1dbad87139 | ||
|
|
bd58bd8279 | ||
|
|
75917f6595 | ||
|
|
67c1ca1e61 | ||
|
|
114a199321 | ||
|
|
38f4b15df1 | ||
|
|
83f78e7fe6 | ||
|
|
7e06aa13c1 | ||
|
|
8752d8d677 | ||
|
|
5f469589eb | ||
|
|
c7c9542262 | ||
|
|
8893b800e0 | ||
|
|
a289eff741 | ||
|
|
cec8a401ae | ||
|
|
1c160d2366 | ||
|
|
bb6a189589 | ||
|
|
9e42c94e30 | ||
|
|
5cb06b5f1c | ||
|
|
c705bdd6a9 | ||
|
|
a5eb198549 | ||
|
|
aab9227365 | ||
|
|
014066f15b | ||
|
|
54d7a48c9b | ||
|
|
1d376717c1 | ||
|
|
8f91f119b8 | ||
|
|
2b4246c59b | ||
|
|
6c36a58bb7 | ||
|
|
0b28c9ae6f | ||
|
|
e6ee7d3d4a | ||
|
|
eaaedb6ae8 | ||
|
|
0b08ae09c4 | ||
|
|
8ae5ae76fb | ||
|
|
56d366995c | ||
|
|
e0d6e2e5a7 | ||
|
|
7b146e0563 | ||
|
|
997e60d52a | ||
|
|
bba9254172 | ||
|
|
b5f79756b3 | ||
|
|
f91aba873e | ||
|
|
364ff0e65c | ||
|
|
2b194d47cc | ||
|
|
effe17c852 | ||
|
|
4b54520579 | ||
|
|
684388e737 | ||
|
|
1041ed8773 | ||
|
|
595660fb84 | ||
|
|
22836e3e0f | ||
|
|
f8fd202a1c | ||
|
|
b6bb338011 | ||
|
|
a351b0c164 | ||
|
|
3a99deef5a | ||
|
|
daf53df670 | ||
|
|
b91e5353ba | ||
|
|
9be7ce54c2 | ||
|
|
fb1865eb91 | ||
|
|
9834849e95 | ||
|
|
0bec935ccb | ||
|
|
9ef6ed52c4 | ||
|
|
ed8e8b9473 | ||
|
|
123df93741 | ||
|
|
7927c0b540 | ||
|
|
118fff0472 | ||
|
|
e27737a0a5 | ||
|
|
7be915a185 | ||
|
|
0bc5bcce4a | ||
|
|
2269f42e17 | ||
|
|
80038ad936 | ||
|
|
7c84d73d67 | ||
|
|
6a80b4bd17 | ||
|
|
807e2a1eb4 | ||
|
|
f4f292d22f | ||
|
|
3a9ef48721 | ||
|
|
4016c799f2 | ||
|
|
ef5e211fa0 | ||
|
|
3c45f5c7ab | ||
|
|
217d59ce68 | ||
|
|
21d9854a81 | ||
|
|
a2e29c0226 | ||
|
|
6884e6b1ec | ||
|
|
6ab06f417d | ||
|
|
25c8c0f9e9 | ||
|
|
34db8f5360 | ||
|
|
927d71ad59 | ||
|
|
082d1780cf | ||
|
|
f7b910b298 | ||
|
|
bd3936c7ed | ||
|
|
2c1b51be65 | ||
|
|
fd7001d020 | ||
|
|
40333a8ee2 | ||
|
|
61926ebc07 | ||
|
|
9e0ef550a8 | ||
|
|
d5051c439d | ||
|
|
61454178c0 | ||
|
|
cb3b6c4b88 | ||
|
|
441186468c | ||
|
|
223e185b83 | ||
|
|
73771669f1 | ||
|
|
dc8fcc254d | ||
|
|
b609411e76 | ||
|
|
188a214a29 | ||
|
|
f2485f624b | ||
|
|
805fae5bab | ||
|
|
9b9d1f4e12 | ||
|
|
d0f4791413 | ||
|
|
2c32e9ee18 | ||
|
|
c14007f559 | ||
|
|
ae0e0c118e | ||
|
|
239d4864e9 | ||
|
|
c99fb2b69b | ||
|
|
ec700e88f7 | ||
|
|
8698e693d5 | ||
|
|
d4047e9af7 | ||
|
|
d727d18871 | ||
|
|
e9b249b709 | ||
|
|
9ef0f1b6cb | ||
|
|
50ee8dfaf8 | ||
|
|
94b8c61e32 | ||
|
|
8b44f49d75 | ||
|
|
36c00cc294 | ||
|
|
ecd0066e80 | ||
|
|
915adcd0dd | ||
|
|
9debad4e91 | ||
|
|
fb66e733b5 | ||
|
|
bed084c17c | ||
|
|
9ae4fc2371 | ||
|
|
6a7a30ceaa | ||
|
|
50541c68ec | ||
|
|
7e2c546d8e | ||
|
|
c90b61f571 | ||
|
|
eba2c8cf2f | ||
|
|
2c1724d7f2 | ||
|
|
b9b18c92d0 | ||
|
|
ea2584e2fb | ||
|
|
182ba3a931 | ||
|
|
23cc96e661 | ||
|
|
2e6dd010ae | ||
|
|
487aad6db1 | ||
|
|
98fa0a1ad2 | ||
|
|
caef7d642a | ||
|
|
57fcc7a25f | ||
|
|
f4cd47fa48 | ||
|
|
89e198204f | ||
|
|
e265cf6d49 | ||
|
|
470f07d462 | ||
|
|
a4d45921c6 | ||
|
|
8145ff6303 | ||
|
|
e2c334d6e4 | ||
|
|
df27cc87b5 | ||
|
|
30c6feb86e | ||
|
|
1ea6708d84 | ||
|
|
faf54244c4 | ||
|
|
32b1aa605a | ||
|
|
dc1996d289 | ||
|
|
1da71afbf3 | ||
|
|
5587476b4e | ||
|
|
1b5bfec8f9 | ||
|
|
a20a26b41b | ||
|
|
80453236c4 | ||
|
|
c5b9cabd89 | ||
|
|
adc594a7e6 | ||
|
|
ac69189e23 | ||
|
|
b044520344 | ||
|
|
78b85339b0 | ||
|
|
6d25ffc70b | ||
|
|
356506a67a | ||
|
|
32f9d1fceb | ||
|
|
b0e52ba7d4 | ||
|
|
e09941f310 | ||
|
|
bdf47785b8 | ||
|
|
6e1517ca3c | ||
|
|
89f99df44d | ||
|
|
66fedecf34 | ||
|
|
46fc41ba50 | ||
|
|
909b25db57 | ||
|
|
da32849ac2 | ||
|
|
401da72a86 | ||
|
|
b8d8ff6d4d | ||
|
|
c0e98f4481 | ||
|
|
e6c64290fa | ||
|
|
b88951345f | ||
|
|
07e3e09652 | ||
|
|
73f7f8aef6 | ||
|
|
0a8ac9fe4d | ||
|
|
34b2a83b84 | ||
|
|
f1bc791c22 | ||
|
|
d10c7c31a4 | ||
|
|
8279038da2 | ||
|
|
56e7e2ad53 | ||
|
|
47f1eaac2a | ||
|
|
f72cb2b69b | ||
|
|
23b87929f5 | ||
|
|
3260c86d15 | ||
|
|
13453e3c68 | ||
|
|
da0dbd901c | ||
|
|
0212f94809 | ||
|
|
1d5fc3ef60 | ||
|
|
c10904967b | ||
|
|
5bdc88bf57 | ||
|
|
c8cf33a251 | ||
|
|
d089e80906 | ||
|
|
79d389d812 | ||
|
|
76828f25c5 | ||
|
|
62af32270b | ||
|
|
291beb1145 | ||
|
|
dbf02ac3c1 | ||
|
|
6e20ffb990 | ||
|
|
fa167bcdc4 | ||
|
|
d26770eb40 | ||
|
|
4653e2eb3b | ||
|
|
611efd9921 | ||
|
|
791c389923 | ||
|
|
6b3c7c9a6c | ||
|
|
60a089d795 | ||
|
|
1f11e4b8db | ||
|
|
46eb175b17 | ||
|
|
677c8e828c | ||
|
|
b3bcab6c13 | ||
|
|
866e84ec49 | ||
|
|
06a53abe68 | ||
|
|
3355d14b65 | ||
|
|
4de71549d4 | ||
|
|
2986d46fd3 | ||
|
|
7ada79b5ca | ||
|
|
61a7671de1 | ||
|
|
345b77cfc9 | ||
|
|
3447d0ccb9 | ||
|
|
11ff774f72 | ||
|
|
21a9527686 | ||
|
|
de9ea43616 | ||
|
|
52fb4eee5f | ||
|
|
208547e3af | ||
|
|
c3843cd0d6 | ||
|
|
eb354be20d | ||
|
|
264ee999a1 | ||
|
|
3403a91213 | ||
|
|
e8424e19fa | ||
|
|
f1b048c595 | ||
|
|
e17d104c0a | ||
|
|
9dbaa150d6 | ||
|
|
0724db2d80 | ||
|
|
d2f27a34f7 | ||
|
|
93e26cae35 | ||
|
|
84c5a7b0cd | ||
|
|
7858c00539 | ||
|
|
297947bec7 | ||
|
|
4d0cb175da | ||
|
|
777b093cad | ||
|
|
578a8c9918 | ||
|
|
e826095e71 | ||
|
|
25d0dc19d5 | ||
|
|
00a6d1306c | ||
|
|
9f9bed7aa8 | ||
|
|
76a99015c1 | ||
|
|
faf37b51e7 | ||
|
|
1f8438a6ae | ||
|
|
bfa90ab3e8 | ||
|
|
80687e702c | ||
|
|
85c8bd7d7e | ||
|
|
f2188bd397 | ||
|
|
9de81369a7 | ||
|
|
da673cfad7 | ||
|
|
07d02f8d46 | ||
|
|
4ab52aaf12 | ||
|
|
2353082bda | ||
|
|
53c2cff331 | ||
|
|
661330a97a | ||
|
|
dca71dbad9 | ||
|
|
25eac6b9e6 | ||
|
|
3561ff90e9 | ||
|
|
ffb8321e57 | ||
|
|
ff8f7875f3 | ||
|
|
14483f64fd | ||
|
|
437fd21ba0 | ||
|
|
d33139c40a | ||
|
|
114238c248 | ||
|
|
88becbe29d | ||
|
|
a7a5c5ce54 | ||
|
|
c06f5e2661 | ||
|
|
41865e6c30 | ||
|
|
5f0ba7d722 | ||
|
|
41ebf3bd94 | ||
|
|
eba22b7551 | ||
|
|
845694bc44 | ||
|
|
17e4e2497f | ||
|
|
515854a19f | ||
|
|
d86309957e | ||
|
|
641fadb3e9 | ||
|
|
79d8d1d557 | ||
|
|
bf231f7fca | ||
|
|
39ca06114b | ||
|
|
be7022dadc | ||
|
|
0e311845bf | ||
|
|
c665f4e51d | ||
|
|
68afbbc0f0 | ||
|
|
f60a004cff | ||
|
|
20fea7fdd2 | ||
|
|
615dd377dd | ||
|
|
0467b4aaf3 | ||
|
|
f74962bdad | ||
|
|
ab298b6337 | ||
|
|
1151706243 | ||
|
|
fd3c70ec5b | ||
|
|
fc690f1c47 | ||
|
|
5a558a64e1 | ||
|
|
ddeaccf728 | ||
|
|
09c1a9cfc0 | ||
|
|
25e4bcefbf | ||
|
|
74e6370187 | ||
|
|
53b67810ba | ||
|
|
909c3571e3 | ||
|
|
6c79e95052 | ||
|
|
f56883e238 | ||
|
|
f4da21252b | ||
|
|
bb904b9166 | ||
|
|
767632e1af | ||
|
|
782fad0b41 | ||
|
|
9a2c03d2c6 | ||
|
|
ba78cf72ae | ||
|
|
1aba073e32 | ||
|
|
a1fb51e050 | ||
|
|
e483fc2525 | ||
|
|
89b0eca383 | ||
|
|
bccc57bb29 | ||
|
|
0c465fbb4d | ||
|
|
b4f6f796d6 | ||
|
|
0fefee804c | ||
|
|
08c56e61e1 | ||
|
|
66fd027b96 | ||
|
|
e8f748cfed | ||
|
|
8fe7fa5532 | ||
|
|
b59ec55d50 | ||
|
|
6d14f5442e | ||
|
|
0fa683f244 | ||
|
|
ca0d3757cc | ||
|
|
1b1a9ca95c | ||
|
|
7a7cac57d9 | ||
|
|
68ba648897 | ||
|
|
16ce6b7acc | ||
|
|
2c92fc4b6f | ||
|
|
41d0c89a52 | ||
|
|
e5272b65a1 | ||
|
|
8384d7b5ed | ||
|
|
794b019a8a | ||
|
|
aed3b6c6be | ||
|
|
14d0b72f52 | ||
|
|
03165c96cc | ||
|
|
a96c7ebd8d | ||
|
|
916d45b450 | ||
|
|
a16eeeec5d | ||
|
|
2a1240d1e9 | ||
|
|
0ebb572f48 | ||
|
|
ff2176a586 | ||
|
|
5ad98f2b7c | ||
|
|
cf87b0fadb | ||
|
|
d9f5dda322 | ||
|
|
0584ac195c | ||
|
|
8a9974b6f9 | ||
|
|
60175631df | ||
|
|
5fdacae88b | ||
|
|
fcf5fcd58c | ||
|
|
e9541605ab | ||
|
|
7d8d4f4532 | ||
|
|
9421a449ab | ||
|
|
6edede0db9 | ||
|
|
a15c894385 | ||
|
|
9c57157e44 | ||
|
|
9a662249eb | ||
|
|
772f89e77f | ||
|
|
8661936d7d | ||
|
|
377f2166a1 | ||
|
|
83ac80460e | ||
|
|
ed9a8299b2 | ||
|
|
a9383dfa79 | ||
|
|
f10c470969 | ||
|
|
f3fc11713a | ||
|
|
4c5db31110 | ||
|
|
2dae1e0504 | ||
|
|
f44b16eaa3 | ||
|
|
aa2f61fa0e | ||
|
|
65135f5f7a | ||
|
|
faa1e6f1b2 | ||
|
|
0048ff2a2f | ||
|
|
168aa04c85 | ||
|
|
b033b30f95 | ||
|
|
5ff8e7cadf | ||
|
|
5cff81fc29 | ||
|
|
8ddd93ec27 | ||
|
|
331a2e39eb | ||
|
|
15f75216c7 | ||
|
|
f4b06be24b | ||
|
|
ffb48ed030 | ||
|
|
a91467f3a8 | ||
|
|
b596db3eed | ||
|
|
424ed1b79a | ||
|
|
acb6bbb649 | ||
|
|
345c01677d | ||
|
|
866df56131 | ||
|
|
5d62429164 | ||
|
|
132906c925 | ||
|
|
f6825eea5f | ||
|
|
10aa5ebf03 | ||
|
|
c9efcfab17 | ||
|
|
7cb19ee2b3 | ||
|
|
9e61fb90c5 | ||
|
|
08378dd148 | ||
|
|
de083efcf2 | ||
|
|
3274270951 | ||
|
|
224b766eb1 | ||
|
|
dee178aae5 | ||
|
|
58ff53ec52 | ||
|
|
fd2a216909 | ||
|
|
03470e7bab | ||
|
|
565be454aa | ||
|
|
7ebe09fbf7 | ||
|
|
da60200377 | ||
|
|
790e81349f | ||
|
|
4bacba431b | ||
|
|
c58d799f16 | ||
|
|
25d7970b6f | ||
|
|
3250f1951b | ||
|
|
b78b543011 | ||
|
|
0e9a49d1cf | ||
|
|
e46a7dd6f5 | ||
|
|
04efe88044 | ||
|
|
bcea2a958e | ||
|
|
0a8d6ddba9 | ||
|
|
77fc2f1e86 | ||
|
|
b66987e1ce | ||
|
|
a89eb5e7e3 | ||
|
|
f5ab6ea7ae | ||
|
|
d323072bb6 | ||
|
|
3936fe25dc | ||
|
|
0b569ed8c7 | ||
|
|
c0367fc30e | ||
|
|
25c1cdec95 | ||
|
|
aafe9ae2d6 | ||
|
|
2aa01e309c | ||
|
|
852d21db14 | ||
|
|
8bd548416d | ||
|
|
f76f5db2fa | ||
|
|
ff6b2bffdc | ||
|
|
22460525a0 | ||
|
|
1b66b1bd7c | ||
|
|
03a142174f | ||
|
|
bbcca835a5 | ||
|
|
7cb0986c1f | ||
|
|
e507f1438a | ||
|
|
49b07f898e | ||
|
|
a579e92400 | ||
|
|
1593b64680 | ||
|
|
f78710a4ea | ||
|
|
bc5663f1a3 | ||
|
|
3082950e74 | ||
|
|
b03059b933 | ||
|
|
85f98d7038 | ||
|
|
95ee0f58f2 | ||
|
|
eb318d5ceb | ||
|
|
72217a6771 | ||
|
|
5df68922eb | ||
|
|
bb067f529b | ||
|
|
3b06a27465 | ||
|
|
49b4b8597d | ||
|
|
cd8538da9a | ||
|
|
73fec3bdb7 | ||
|
|
11a6117da6 | ||
|
|
d8d9f94075 | ||
|
|
a670c2a674 | ||
|
|
01e1e4e5b9 | ||
|
|
f0315b2715 | ||
|
|
018c562447 | ||
|
|
9482355c47 | ||
|
|
b2189ae88b | ||
|
|
7a5eab9541 | ||
|
|
9c136f66d4 | ||
|
|
5a06a9dec1 | ||
|
|
9467d4cb0b | ||
|
|
d5577421f8 | ||
|
|
df4c4d5be2 | ||
|
|
4dee72a487 | ||
|
|
cd08cd54a4 | ||
|
|
ab7101e3d2 | ||
|
|
7ebd3a086a | ||
|
|
c0fddd0a14 | ||
|
|
759ed40d98 | ||
|
|
5e4e634625 | ||
|
|
c086eb088d | ||
|
|
2edf02dccb | ||
|
|
00ac4afb9f | ||
|
|
9079a083d2 | ||
|
|
ee969efe5f | ||
|
|
fd174d7e92 | ||
|
|
e052dc282b | ||
|
|
847266d027 | ||
|
|
f53daa4450 | ||
|
|
2fa547cdea | ||
|
|
ac9ca67861 | ||
|
|
a420670217 | ||
|
|
bc1e231775 | ||
|
|
8f0a012345 | ||
|
|
3e8ffe179b | ||
|
|
1286b967ed | ||
|
|
c83f307b62 | ||
|
|
5dfd0274b9 | ||
|
|
0ccf11256f | ||
|
|
7f0c89f378 | ||
|
|
e7ba0b7371 | ||
|
|
ba97415ef9 | ||
|
|
eb6a745a18 | ||
|
|
add4990044 | ||
|
|
3841ee1d51 | ||
|
|
9c3867e173 | ||
|
|
75f7fd546c | ||
|
|
7e4154b063 | ||
|
|
f4f1092f1d | ||
|
|
7cbf5cd075 | ||
|
|
e0f5cdacf0 | ||
|
|
3186e47807 | ||
|
|
a78a7e1f67 | ||
|
|
cdff00970b | ||
|
|
ccb8fe908a | ||
|
|
b88959f60c | ||
|
|
1504041c82 | ||
|
|
dc228b952a | ||
|
|
a630563cbc | ||
|
|
80e2cea4aa | ||
|
|
243c819257 | ||
|
|
08f1f94fcb | ||
|
|
8855e5bfc9 | ||
|
|
427bd93921 | ||
|
|
ee19426f4d | ||
|
|
f81f075670 | ||
|
|
2ccdbf1050 | ||
|
|
fa124dd340 | ||
|
|
00c9ac363f | ||
|
|
a77ceb6871 | ||
|
|
48cc52be07 | ||
|
|
9e33e57294 | ||
|
|
b20cabb6e4 | ||
|
|
6a7247ab44 | ||
|
|
7334128a2e | ||
|
|
1d0b9ed302 | ||
|
|
6a36e8a8dc | ||
|
|
5956dd591f | ||
|
|
e1e70dd927 | ||
|
|
85e69f6882 | ||
|
|
5600e21d16 | ||
|
|
f59ee209d2 | ||
|
|
c7c460f6e0 | ||
|
|
665a551fcd | ||
|
|
32efbdfb32 | ||
|
|
57f510d67f | ||
|
|
afa0bed5fc | ||
|
|
ec6f89111e | ||
|
|
fdba7259ab | ||
|
|
de0c339e0b | ||
|
|
b8eab65536 | ||
|
|
91e64c3f27 | ||
|
|
71eefc3315 | ||
|
|
203f24742a | ||
|
|
9b38af4d7d | ||
|
|
c8f055c9e3 | ||
|
|
e7571c539c | ||
|
|
250275fbfb | ||
|
|
03cec5cdd7 | ||
|
|
8d746a701e | ||
|
|
7cf6651d2c | ||
|
|
feaaaa3e8b | ||
|
|
92b5dda2bc | ||
|
|
ed8f71e459 | ||
|
|
5528434fb6 | ||
|
|
9f9a5186e0 | ||
|
|
71129fca2d | ||
|
|
42a46b75f1 | ||
|
|
5e42f347d8 | ||
|
|
85dc2e5b9b | ||
|
|
281785f6bd | ||
|
|
c583446ade | ||
|
|
b85b3abe20 | ||
|
|
debd41081e | ||
|
|
13bfe50d00 | ||
|
|
c23b74e150 | ||
|
|
da150dbb1c | ||
|
|
ef269ea2e0 | ||
|
|
0ead7eacfd | ||
|
|
c8dd433e8b | ||
|
|
0231ee4ad3 | ||
|
|
6c6ce30389 | ||
|
|
88cddc35dd | ||
|
|
3a616fed4d | ||
|
|
3f1870841c | ||
|
|
548c3b46ad | ||
|
|
dda168fc10 | ||
|
|
0370b0fa23 | ||
|
|
4b9fb10fdb | ||
|
|
f25070d441 | ||
|
|
c0e303632e | ||
|
|
0ff755b236 | ||
|
|
8bccc6e68f | ||
|
|
20df224b19 | ||
|
|
99254b4d52 | ||
|
|
4fd1b52d1f | ||
|
|
ab7c0b40f2 | ||
|
|
851ae574d1 | ||
|
|
b4441bff04 | ||
|
|
3be0136901 | ||
|
|
6df66a77d0 | ||
|
|
003247d883 | ||
|
|
e0c4d5068d | ||
|
|
907641f6ea | ||
|
|
79cc9af212 | ||
|
|
aff1db1543 | ||
|
|
a573d3a332 | ||
|
|
82f96668fa | ||
|
|
cc9368ccb4 | ||
|
|
5b4b243e3d | ||
|
|
96191fe577 | ||
|
|
c8b4b83b71 | ||
|
|
80a2f7224e | ||
|
|
b82d83e271 | ||
|
|
054990aafa | ||
|
|
ede007c2dd | ||
|
|
d9b5e4ae8d | ||
|
|
5e9e003bb0 | ||
|
|
5b25060730 | ||
|
|
8186a1d7f8 | ||
|
|
4689275845 | ||
|
|
7d143087c9 | ||
|
|
f0e9881c7e | ||
|
|
f2c52d1570 | ||
|
|
3d26ce9f8d | ||
|
|
7c3b9c843f | ||
|
|
4c1ec0404a | ||
|
|
bd9478204d | ||
|
|
35661d065e | ||
|
|
7be98166ee | ||
|
|
f1f0ee3a21 | ||
|
|
9aab61f5a7 | ||
|
|
dd9e12601e | ||
|
|
c560285d88 | ||
|
|
f50971b6a9 | ||
|
|
88e13bb236 | ||
|
|
bc57e9e647 | ||
|
|
06f24a73d2 | ||
|
|
354667bb6d | ||
|
|
b888c95024 | ||
|
|
adc4d47251 | ||
|
|
c333fc6f04 | ||
|
|
71571c4072 | ||
|
|
6c3d6253ef | ||
|
|
4dddc41b71 | ||
|
|
85044d65af | ||
|
|
0368601b16 | ||
|
|
60194d666d | ||
|
|
461a27a674 | ||
|
|
2772abc8d7 | ||
|
|
bd8c7f84dd | ||
|
|
697d2e86d7 | ||
|
|
5a0b4c98aa | ||
|
|
6f2237fc46 | ||
|
|
4f4f270d35 | ||
|
|
8b85eb9b34 | ||
|
|
236ebecf44 | ||
|
|
59f1fe7625 | ||
|
|
d82d67a4b2 | ||
|
|
8f9f0f1d7f | ||
|
|
6fbc953dbd | ||
|
|
82a57a10e7 | ||
|
|
6d172b8e7a | ||
|
|
08279e6288 | ||
|
|
f64d1bbc30 | ||
|
|
381a3406ba | ||
|
|
fb454a28fe | ||
|
|
42edac8a34 | ||
|
|
5319f36788 | ||
|
|
d0a33e34da | ||
|
|
3286d37c64 | ||
|
|
8f228e3035 | ||
|
|
44e2cd14a0 | ||
|
|
48711c6f8b | ||
|
|
b5c780993c | ||
|
|
c462720c28 | ||
|
|
e4aceb7845 | ||
|
|
ef742001e8 | ||
|
|
53f576e50e | ||
|
|
be20b715ca | ||
|
|
758ba3855e | ||
|
|
062881a484 | ||
|
|
810bbc0484 | ||
|
|
cee0c9858c | ||
|
|
086f3efef2 | ||
|
|
80a422e590 | ||
|
|
73dad70356 | ||
|
|
cf904e0a5d | ||
|
|
2e266dfe3c | ||
|
|
eeb40d0cc2 | ||
|
|
11b964b759 | ||
|
|
3f8bde1254 | ||
|
|
bda276f498 | ||
|
|
a4ec06a3b7 | ||
|
|
1dd69eeb6c | ||
|
|
3d8c1080b1 | ||
|
|
bc665384c3 | ||
|
|
8255053242 | ||
|
|
9dfc2caa11 | ||
|
|
413e2baa1c | ||
|
|
8f9b5e9bd2 | ||
|
|
2cc6c1adef | ||
|
|
5bf3e72d37 | ||
|
|
49c6e01049 | ||
|
|
a6a856cb70 | ||
|
|
e2b61231ae | ||
|
|
6c5d2253c9 | ||
|
|
3868df9f8b | ||
|
|
89f9e7a3ee | ||
|
|
48eacb6f79 | ||
|
|
560747c22e | ||
|
|
92a5fa9bed | ||
|
|
e32157e21b | ||
|
|
3f69457a94 | ||
|
|
433029c3a6 | ||
|
|
e2086ac8e4 | ||
|
|
a2b74af59a | ||
|
|
3e562bc9bb | ||
|
|
8df8f78fe2 | ||
|
|
9a37ccfe29 | ||
|
|
b6d15fa3ab | ||
|
|
d69e89f5cb | ||
|
|
6b3ed6c75b | ||
|
|
07d4a7c11f | ||
|
|
865ee192b4 | ||
|
|
95b3b36cd9 | ||
|
|
01c9c32573 | ||
|
|
735abca1b6 | ||
|
|
3ea910bf83 | ||
|
|
6a308dacd7 | ||
|
|
8193f5571a | ||
|
|
359283968a | ||
|
|
eda6c6607c | ||
|
|
8d7ade5604 | ||
|
|
596c20c199 | ||
|
|
ec1b060fc5 | ||
|
|
c898a4770b | ||
|
|
558e2fc35e | ||
|
|
da25b288ee | ||
|
|
d2c26fd504 | ||
|
|
1f819a26e5 | ||
|
|
02f3b965b9 | ||
|
|
2e81137a80 | ||
|
|
b03cb94b43 | ||
|
|
46b487c2f7 | ||
|
|
7b4556e546 | ||
|
|
9ecbe51e34 | ||
|
|
ce67be5a86 | ||
|
|
c81b3d4757 | ||
|
|
fb0fe8617c | ||
|
|
0f009ecbdd | ||
|
|
3b3eef5307 | ||
|
|
ea8df22dbb | ||
|
|
7d2f019681 | ||
|
|
01d7c07920 | ||
|
|
f859cd11bd | ||
|
|
9183870b9e | ||
|
|
b6cfb5a8fe | ||
|
|
757fdba9fd | ||
|
|
a23f6209ae | ||
|
|
d27c504261 | ||
|
|
202bb707ce | ||
|
|
b4ded050e1 | ||
|
|
a9b4be3883 | ||
|
|
9a47f7bf71 | ||
|
|
f14b68202c | ||
|
|
4550ec4716 | ||
|
|
393766a931 | ||
|
|
c5bdc1ccbe | ||
|
|
924e1d741d | ||
|
|
1fbe72b7dd | ||
|
|
5a4efcad0a | ||
|
|
97d7d4b49d | ||
|
|
d5b1d9466a | ||
|
|
64c81e2846 | ||
|
|
96b147b63d | ||
|
|
87aa456bfd | ||
|
|
ab9a2107e4 | ||
|
|
47c924d1f5 | ||
|
|
427f3bb634 | ||
|
|
789a60278c | ||
|
|
88db584566 | ||
|
|
18b022bf6b | ||
|
|
1c5db07342 | ||
|
|
a8070a429a | ||
|
|
7c340b1cc9 | ||
|
|
fd8d439e39 | ||
|
|
91c0cde742 | ||
|
|
e7cc54204f | ||
|
|
079fd0071a | ||
|
|
925d229d67 | ||
|
|
6294167eff | ||
|
|
65955601f0 | ||
|
|
0f6714c6d7 | ||
|
|
5d14adebb5 | ||
|
|
baf4a85d23 | ||
|
|
4234659cac | ||
|
|
0b5ad90bde | ||
|
|
1ca2265fd4 | ||
|
|
a90abbc22e | ||
|
|
10451652f4 | ||
|
|
9393c0136c | ||
|
|
9d417ee2f5 | ||
|
|
e7fb38834a | ||
|
|
6e4c3b2fd6 | ||
|
|
f1265205b9 | ||
|
|
f1af654502 | ||
|
|
80981dbefb | ||
|
|
88118b133a | ||
|
|
c2d9fbca9b | ||
|
|
b1195508ba | ||
|
|
f4f2b456b6 | ||
|
|
4382d29422 | ||
|
|
d6592ca2cb | ||
|
|
5cfb9e3e9d | ||
|
|
c74a8c9fa8 | ||
|
|
dc77417396 | ||
|
|
151a5e2d7f | ||
|
|
fb7282f47a | ||
|
|
9b5840cb70 | ||
|
|
438e0adc77 | ||
|
|
b77f59286f | ||
|
|
1010267dee | ||
|
|
d9f6882a2a | ||
|
|
0ffc55a20a | ||
|
|
d3e53b3cca | ||
|
|
9d383037e4 | ||
|
|
9375e8d010 | ||
|
|
48e396913c | ||
|
|
b1c77dc42b | ||
|
|
6f777f90a8 | ||
|
|
36d2374ff9 | ||
|
|
86259b998e | ||
|
|
560a166613 | ||
|
|
871ee04ed6 | ||
|
|
83f5dd8a8b | ||
|
|
6326774056 | ||
|
|
b6d313bbe6 | ||
|
|
dc0a0e0700 | ||
|
|
33a51ee20d | ||
|
|
a037fac5c5 | ||
|
|
e6602d527c | ||
|
|
d213cfa897 | ||
|
|
f4dabf08e2 | ||
|
|
aea993b96a | ||
|
|
520742cf3e | ||
|
|
83408ef35c | ||
|
|
823d0d5360 | ||
|
|
3105fa9e0f | ||
|
|
4727c18531 | ||
|
|
3b0995cb49 | ||
|
|
df5cadc8ad | ||
|
|
03b2e3bda1 | ||
|
|
c38b71146b | ||
|
|
f87209f822 | ||
|
|
e2267d2737 | ||
|
|
31fe7afbc4 | ||
|
|
8b4f12f2b0 | ||
|
|
7adbb7c06e | ||
|
|
a8631aeae9 | ||
|
|
115ac58fd0 | ||
|
|
ba6a3526a9 | ||
|
|
03349f9fff | ||
|
|
ab0bce77ec | ||
|
|
63b0f1a2f7 | ||
|
|
e3f00ce5fc | ||
|
|
1f3b6490f2 | ||
|
|
c4f2ceb1ca | ||
|
|
f652657d9d | ||
|
|
4869349d57 | ||
|
|
a845dffa63 | ||
|
|
f84e512ded | ||
|
|
cded594346 | ||
|
|
bd501404db | ||
|
|
679be47def | ||
|
|
99eca9fa7e | ||
|
|
c049aed44f | ||
|
|
081b878bbd | ||
|
|
38e5972e45 | ||
|
|
f146f9acb6 | ||
|
|
fd14cf9f1e | ||
|
|
573cabaf24 | ||
|
|
14bc7b9c6a | ||
|
|
868447126f | ||
|
|
69b5048728 | ||
|
|
d92b84fbc3 | ||
|
|
913aec1667 | ||
|
|
0cffda3cfe | ||
|
|
2691f2073a | ||
|
|
1b96d01690 | ||
|
|
b081988e66 | ||
|
|
19b6f88c33 | ||
|
|
f9a29f291e | ||
|
|
55795127a3 | ||
|
|
547db8531b | ||
|
|
4cdba04c88 | ||
|
|
ba04aab75f | ||
|
|
6731067116 | ||
|
|
19574f7897 | ||
|
|
97b5e96e0e | ||
|
|
19f50a9a45 | ||
|
|
91a569ac7f | ||
|
|
2a76ae002e | ||
|
|
6954547b4c | ||
|
|
e313059dd5 | ||
|
|
d324331325 | ||
|
|
3fdf4c56ba | ||
|
|
e9b666d1a8 | ||
|
|
14f192fb00 | ||
|
|
438870e223 | ||
|
|
9370e5e4d0 | ||
|
|
6b92006565 | ||
|
|
de7fdd3e1a | ||
|
|
a1564d1826 | ||
|
|
d0694b3e0b | ||
|
|
f032bdf81c | ||
|
|
16cf1f48d3 | ||
|
|
cacb6136fa | ||
|
|
87021d9fb1 | ||
|
|
27444617e1 | ||
|
|
74b5a4ae7a | ||
|
|
a8402ae782 | ||
|
|
dada0dff78 | ||
|
|
858505918a | ||
|
|
f6fedd5348 | ||
|
|
65d7b3e652 | ||
|
|
6eac4276d5 | ||
|
|
18dcf8af68 | ||
|
|
e3d08893b7 | ||
|
|
56831a247f | ||
|
|
0ba911bf12 | ||
|
|
766ac5ea27 | ||
|
|
7cf1a39b99 | ||
|
|
0768185fea | ||
|
|
3e45b8aace | ||
|
|
481b4fde25 | ||
|
|
6cab572b8f | ||
|
|
df789b943c | ||
|
|
952c2f2f8b | ||
|
|
b8e2b780e3 | ||
|
|
8d00af1d7b | ||
|
|
754d35244f | ||
|
|
2df0bbf387 | ||
|
|
af0531398a | ||
|
|
4b983f92c5 | ||
|
|
8ca2c597e0 | ||
|
|
2e9e5c37b5 | ||
|
|
2fd2b7d628 | ||
|
|
396cc53020 | ||
|
|
240ec72086 | ||
|
|
0d163915d0 | ||
|
|
260d7aa701 | ||
|
|
b66650c2e8 | ||
|
|
25eb24299c | ||
|
|
25ae54223a | ||
|
|
b3678f44b7 | ||
|
|
68af13bb34 | ||
|
|
7d6c592417 | ||
|
|
d815322efe | ||
|
|
8ece236635 | ||
|
|
a45aabe68c | ||
|
|
2ec6a8249a | ||
|
|
2a47379ab5 | ||
|
|
f91ece78e0 | ||
|
|
d8211b65a5 | ||
|
|
95aba3feef | ||
|
|
af80ecb651 | ||
|
|
2da57613bf | ||
|
|
4dbe1588a6 | ||
|
|
02693734d3 | ||
|
|
b9141f98af | ||
|
|
6a61b60a5d | ||
|
|
40a5eabf88 | ||
|
|
db90656483 | ||
|
|
9965b2b72a | ||
|
|
ecd4006514 | ||
|
|
78d7a08618 | ||
|
|
d21464399f | ||
|
|
8a4f4fcea9 | ||
|
|
eb895975e2 | ||
|
|
79279b93fb | ||
|
|
df1767b784 | ||
|
|
e345b56719 | ||
|
|
ddc83df4b6 | ||
|
|
daa6195732 | ||
|
|
0c5d8f1156 | ||
|
|
7a06a6ac59 | ||
|
|
abc0bf3220 | ||
|
|
fd9648f919 | ||
|
|
dedcd0e294 | ||
|
|
2e47eb6fb9 | ||
|
|
ef8c98cb71 | ||
|
|
7e2cfc30f0 | ||
|
|
520a08b205 | ||
|
|
b6471a83aa | ||
|
|
dd09e900c0 | ||
|
|
e7e7893f22 | ||
|
|
8056811b4f | ||
|
|
0bd1a53326 | ||
|
|
838bae964b | ||
|
|
c9d9ec0d63 | ||
|
|
0a6baff26d | ||
|
|
56427da393 | ||
|
|
c1fea8c002 | ||
|
|
447f3fcb35 | ||
|
|
f5eddce1d1 | ||
|
|
24c0bb95ef | ||
|
|
7cd8285251 | ||
|
|
b2e11f1e9e | ||
|
|
edb08770dc | ||
|
|
77cdceabaa | ||
|
|
0c617366e5 | ||
|
|
4b43b5c1c1 | ||
|
|
ffea0bf857 | ||
|
|
aa7303f19f | ||
|
|
80f85a854c | ||
|
|
6c2ac345fd | ||
|
|
6a874498f7 | ||
|
|
9de4ecf8b6 | ||
|
|
7fc20e9ae8 | ||
|
|
f085fc9dd2 | ||
|
|
d4390adb68 | ||
|
|
da1ef67064 | ||
|
|
f704a50e9f | ||
|
|
904c8e3636 | ||
|
|
6994354b8f | ||
|
|
1dc92c49ed | ||
|
|
664676a2b4 | ||
|
|
e955444302 | ||
|
|
410099df70 | ||
|
|
9409f814a4 | ||
|
|
0104a74028 | ||
|
|
4dcc095e5e | ||
|
|
052c33fc8c | ||
|
|
5a0e22eb98 | ||
|
|
92bcc50c0a | ||
|
|
07736d1689 | ||
|
|
62f37c5b1b | ||
|
|
85daf1b3b2 | ||
|
|
d372afd81e | ||
|
|
d1f9434fd5 | ||
|
|
00479aea29 | ||
|
|
18c5f1e90d | ||
|
|
108fe84f5a | ||
|
|
77b572f36a | ||
|
|
1b4cd93dc2 | ||
|
|
afe02efb8f | ||
|
|
c6cc43f0e4 | ||
|
|
1c79c95868 | ||
|
|
49b8232ebd | ||
|
|
105e82ad84 | ||
|
|
7f0403c8c1 | ||
|
|
c1c94d37d7 | ||
|
|
c0560ab0cb | ||
|
|
7813fca946 | ||
|
|
2548830140 | ||
|
|
6d924d3285 | ||
|
|
cda0fafbd1 | ||
|
|
b6c1b7806b | ||
|
|
6f64917e8f | ||
|
|
8dbcda9943 | ||
|
|
7c3f010cd6 | ||
|
|
cdf1b39c5e | ||
|
|
88a6a9d628 | ||
|
|
279f038b9e | ||
|
|
fd8df3a623 | ||
|
|
4474460377 | ||
|
|
a222df31ba | ||
|
|
dd10e5d977 | ||
|
|
42fed1a16c | ||
|
|
2723614d58 | ||
|
|
fec5c03612 | ||
|
|
1a2677ebe6 | ||
|
|
ad4fb2b088 | ||
|
|
c56ac3e909 | ||
|
|
50fc2aa251 | ||
|
|
046ebc3d34 | ||
|
|
bb26a986e6 | ||
|
|
3394f97f86 | ||
|
|
f7270c44cb | ||
|
|
ceb91732bf | ||
|
|
be0a1742ac | ||
|
|
f3984ba5a9 | ||
|
|
34a3209e9b | ||
|
|
232a45bc14 | ||
|
|
a5c9830706 | ||
|
|
bde3be787e | ||
|
|
49efff1fef | ||
|
|
c5f9e61d3a | ||
|
|
26acd6c65a | ||
|
|
33c71d1d2c | ||
|
|
b4aa0a20dd | ||
|
|
fa5f8dbd55 | ||
|
|
a9022d8451 | ||
|
|
d182b20705 | ||
|
|
7da691b52a | ||
|
|
e3706837b9 | ||
|
|
f4d0f1624a | ||
|
|
c763890f04 | ||
|
|
edc46d15f8 | ||
|
|
d24552f5e2 | ||
|
|
e95f0a409d | ||
|
|
9713014130 | ||
|
|
35cf8aada4 | ||
|
|
13c4abf4ad | ||
|
|
0fa695dbd7 | ||
|
|
d473bed4b7 | ||
|
|
5c71a8d74d | ||
|
|
b80146a6f7 | ||
|
|
b1e2e654a9 | ||
|
|
a941dfe7b2 | ||
|
|
1142ef91df | ||
|
|
4056fb9127 | ||
|
|
0325be0827 | ||
|
|
29e6537939 | ||
|
|
600997d8d6 | ||
|
|
67f797abf2 | ||
|
|
2a35c8f9e7 | ||
|
|
2760b67902 | ||
|
|
57aab46fc3 | ||
|
|
8a4cbe3cc9 | ||
|
|
d45b60ceeb | ||
|
|
4591d501b4 | ||
|
|
36957cb4d3 | ||
|
|
8b2247e21b | ||
|
|
cdb2f624de | ||
|
|
2b3370c8d8 | ||
|
|
88dec4cc94 | ||
|
|
87c5f91a74 | ||
|
|
fa3a195077 | ||
|
|
4f640dacab | ||
|
|
351439b4ab | ||
|
|
44282da30d | ||
|
|
668258746b | ||
|
|
ca9460aead | ||
|
|
55492fbe5b | ||
|
|
a084f6c835 | ||
|
|
e162317afa | ||
|
|
ac3069ebfa | ||
|
|
620a274c82 | ||
|
|
e35837e14b | ||
|
|
91b6032a71 | ||
|
|
b57ccf3517 | ||
|
|
44aefc8777 | ||
|
|
d7c4265089 | ||
|
|
b39c124628 | ||
|
|
b5b958c276 | ||
|
|
b5e327e3e9 | ||
|
|
e595b0b782 | ||
|
|
0c67d0838a | ||
|
|
e1a2b5c8d4 | ||
|
|
14d1ca17a9 | ||
|
|
a30c4281d2 | ||
|
|
938ac716a8 | ||
|
|
a04d0b9a0f | ||
|
|
3c07bf4e86 | ||
|
|
c2efa5406e | ||
|
|
494f881f27 | ||
|
|
429d078de7 | ||
|
|
ef732f480f | ||
|
|
4769e05626 | ||
|
|
019cacf07e | ||
|
|
19958eafcf | ||
|
|
f33916e2dc | ||
|
|
1d5af600cc | ||
|
|
8edb7b28a0 | ||
|
|
14b93c5ff3 | ||
|
|
300cdc435d | ||
|
|
dd1596aa53 | ||
|
|
3e460211c8 | ||
|
|
bade0a85e7 | ||
|
|
c265218ba8 | ||
|
|
8b7067d289 | ||
|
|
649647538b | ||
|
|
70bf0cbe84 | ||
|
|
58e0b24006 | ||
|
|
05e4993d2e | ||
|
|
c1a566ce63 | ||
|
|
ec7d0efddf | ||
|
|
15c8cac78b | ||
|
|
9dd04ad268 | ||
|
|
14c36efbab | ||
|
|
f1f3b423ec | ||
|
|
5e93a5806b | ||
|
|
4ae78639f5 | ||
|
|
468057638b | ||
|
|
3edec0c6ca | ||
|
|
e72f39b484 | ||
|
|
33b038e8a7 | ||
|
|
0d48b74bec | ||
|
|
84435662aa | ||
|
|
de6c65c453 | ||
|
|
7945bcb353 | ||
|
|
ca49e94a87 | ||
|
|
3966d6f16f | ||
|
|
17f3e7a38f | ||
|
|
da55425114 | ||
|
|
5a48f8ab0f | ||
|
|
2515196b82 | ||
|
|
77ab7bf68b | ||
|
|
c851b189c5 | ||
|
|
0f70212139 | ||
|
|
96ca806e0d | ||
|
|
7809b9e8ad | ||
|
|
d7963be212 | ||
|
|
742c40a60a | ||
|
|
1e41c6daa4 | ||
|
|
ed1b8fb3f9 | ||
|
|
fcb3e32fee | ||
|
|
53dea7e623 | ||
|
|
f9f79af5bd | ||
|
|
6f571a1e80 | ||
|
|
4f40a607ea | ||
|
|
392a2cba66 | ||
|
|
50c7104e22 | ||
|
|
a9b8b6e6c2 | ||
|
|
76dde9d0ec | ||
|
|
888b89c1c0 | ||
|
|
35489aa708 | ||
|
|
baea48fbec | ||
|
|
ec559b85e2 | ||
|
|
144cc8ac54 | ||
|
|
59936c22c0 | ||
|
|
368730ce0b | ||
|
|
23f92da02f | ||
|
|
f2f0711bf4 | ||
|
|
bdc766980e | ||
|
|
3b8fe1b410 | ||
|
|
616a92a193 | ||
|
|
47cb44c6eb | ||
|
|
b31bbfe14c | ||
|
|
36162f5ccf | ||
|
|
cd0cfc34a3 | ||
|
|
d93d3fbfca | ||
|
|
51134a6897 | ||
|
|
26d9bac78f | ||
|
|
378e2d9e74 | ||
|
|
76c090b694 | ||
|
|
9478c3cc7c | ||
|
|
479f2e0d1f | ||
|
|
6eaeb61d58 | ||
|
|
bb285bf758 | ||
|
|
7e26d3ef3f | ||
|
|
cbe3e49c7f | ||
|
|
50c2b0066f | ||
|
|
62b4871c5c | ||
|
|
d4d875f2e6 | ||
|
|
cf0d007fd4 | ||
|
|
fe009fd66d | ||
|
|
51479e6be0 | ||
|
|
90a6f55f88 | ||
|
|
997a24e91a | ||
|
|
e4f62380d7 | ||
|
|
db3a647c6d | ||
|
|
5aa0fea29b | ||
|
|
b821776b0d | ||
|
|
024b987e4c | ||
|
|
8e9cabf819 | ||
|
|
cdbb929125 | ||
|
|
a824632d95 | ||
|
|
4dfa7902db | ||
|
|
c99ca21649 | ||
|
|
00f7819623 | ||
|
|
10d7741a26 | ||
|
|
f773c46b5d | ||
|
|
ad2c5fe4b4 | ||
|
|
a8667a55bd | ||
|
|
22cce07ec8 | ||
|
|
480c0a7dee | ||
|
|
df2e7fa842 | ||
|
|
7aa9cf9b37 | ||
|
|
ac691eb229 | ||
|
|
0f56e76e7a | ||
|
|
84f8305cdf | ||
|
|
911ff31709 | ||
|
|
7605101665 | ||
|
|
2b0e64e061 | ||
|
|
59ca8f2489 | ||
|
|
f7ee1f64a9 | ||
|
|
64af1d2d84 | ||
|
|
7e3828b726 | ||
|
|
11622fa038 | ||
|
|
2591c61e7d | ||
|
|
e98760a3d5 | ||
|
|
ab0cba8ead | ||
|
|
90c446e565 | ||
|
|
3e4af3a567 | ||
|
|
0bb2e61e9e | ||
|
|
41a579e978 | ||
|
|
299a35d943 | ||
|
|
cd4d00f31a | ||
|
|
7248957553 | ||
|
|
4cb8c91b08 | ||
|
|
3c97fdbc0e | ||
|
|
a3976f0468 | ||
|
|
b98e07ed34 | ||
|
|
27883c976c | ||
|
|
c35d2aff45 | ||
|
|
7cc1741611 | ||
|
|
a900594978 | ||
|
|
567b9dfa39 | ||
|
|
b3e12dcece | ||
|
|
b7d25636e5 | ||
|
|
ce409a2438 | ||
|
|
96ab58691a | ||
|
|
94405e9280 | ||
|
|
e77a54614d | ||
|
|
83cc36ef0b | ||
|
|
3a39cb86e9 | ||
|
|
94121e7cd7 | ||
|
|
83626b18f0 | ||
|
|
65284b29f8 | ||
|
|
36b46f30f5 | ||
|
|
388a29b299 | ||
|
|
f16c1b5ea8 | ||
|
|
a80b2ee6e2 | ||
|
|
02eea3ecf0 | ||
|
|
d3adadf4cf | ||
|
|
95d9c15607 | ||
|
|
8ced0f184e | ||
|
|
8fd2847a48 | ||
|
|
b7cf316f24 | ||
|
|
2143bea176 | ||
|
|
3f656bcf84 | ||
|
|
33402e407f | ||
|
|
a1cac9b837 | ||
|
|
7f8a94bb70 | ||
|
|
7b40ccea85 | ||
|
|
3ba316b015 | ||
|
|
bed7f13008 | ||
|
|
713c841965 | ||
|
|
426f52068b | ||
|
|
6bd7f167a4 | ||
|
|
f79d5d640f | ||
|
|
7db602faec | ||
|
|
622ddb5b49 | ||
|
|
813731a1e0 | ||
|
|
ab9b75236d | ||
|
|
ef130a027b | ||
|
|
b723b11b30 | ||
|
|
fcc96a2c46 | ||
|
|
0eee5d5fc1 | ||
|
|
93d431a831 | ||
|
|
410cd9cfc4 | ||
|
|
48f0307234 | ||
|
|
88ca8d1a72 | ||
|
|
3bbe7d9d07 | ||
|
|
8e252f79f8 | ||
|
|
e6c5e5e8b9 | ||
|
|
ce53d88235 | ||
|
|
fd105e16aa | ||
|
|
46c9927294 | ||
|
|
4ac553e5ff | ||
|
|
f1b46c3205 | ||
|
|
03cbf435e5 | ||
|
|
2134792e4c | ||
|
|
5fed1641a4 | ||
|
|
d610f9f4f1 | ||
|
|
f2dab083f6 | ||
|
|
27b798fa4f | ||
|
|
b3f8b49873 | ||
|
|
507e5ac776 | ||
|
|
81acd46518 | ||
|
|
2e1a1c199e | ||
|
|
79e69a5549 | ||
|
|
94a7c32fb4 | ||
|
|
18e00c7772 | ||
|
|
08c1e69d71 | ||
|
|
5611fd2355 | ||
|
|
d658648a09 | ||
|
|
3cc6df3116 | ||
|
|
e21ca736b8 | ||
|
|
a80a22c819 | ||
|
|
4f820cf1e5 | ||
|
|
c8a3497662 | ||
|
|
7dcd9a9f8d | ||
|
|
d370f56a77 | ||
|
|
43da93bb6f | ||
|
|
6dbdb966fc | ||
|
|
609af0037f | ||
|
|
f6dd1c96f6 | ||
|
|
793a667872 | ||
|
|
1779cc7a2f | ||
|
|
86df5b1285 | ||
|
|
f5193874c8 | ||
|
|
2c569953d0 | ||
|
|
b11731d6b2 | ||
|
|
f9e0548d0c | ||
|
|
1a9fad4022 | ||
|
|
643747b912 | ||
|
|
aaf9e992da | ||
|
|
e4ee30abf1 | ||
|
|
75509d77b5 | ||
|
|
0fc2db50f0 | ||
|
|
ee5d300f72 | ||
|
|
a4d67c3262 | ||
|
|
7c976a83e0 | ||
|
|
890842dce2 | ||
|
|
63f78b6255 | ||
|
|
dea467f692 | ||
|
|
8a1675e12e | ||
|
|
5bd8fa9678 | ||
|
|
1aa4f29300 | ||
|
|
04cf6ea3ab | ||
|
|
03047009b1 | ||
|
|
c79a59655d | ||
|
|
b1bbd72e84 | ||
|
|
162ddb1fdb | ||
|
|
6cc6047962 | ||
|
|
f11d2b5b54 | ||
|
|
132e4fe815 | ||
|
|
6d231597b4 | ||
|
|
a0a1f6455a | ||
|
|
4188427596 | ||
|
|
ea6f90ec17 | ||
|
|
c528cd7819 | ||
|
|
92b7be4d11 | ||
|
|
13dab699b1 | ||
|
|
7eb3da71b5 | ||
|
|
14de84fae6 | ||
|
|
916683b6d6 | ||
|
|
e256969489 | ||
|
|
7a2826a2fe | ||
|
|
45cebd774d | ||
|
|
1f58b05255 | ||
|
|
30b3ad218f | ||
|
|
7c1888644a | ||
|
|
2ec9e69fd4 | ||
|
|
0bb0ac079a | ||
|
|
fcc236d906 | ||
|
|
17da7c88d0 | ||
|
|
4d93187d31 | ||
|
|
645e51dc1d | ||
|
|
8155505b41 | ||
|
|
d39af2206c | ||
|
|
133d21ad38 | ||
|
|
09d020508c | ||
|
|
dc39a8db62 | ||
|
|
9591e6caee | ||
|
|
a65807ff08 | ||
|
|
059c7ed74a | ||
|
|
98385a7658 | ||
|
|
49bf58a2ae | ||
|
|
327ec61ee3 | ||
|
|
cd7a65a313 | ||
|
|
23514bf5c2 | ||
|
|
974627f700 | ||
|
|
3b456e0037 | ||
|
|
231ac187fe | ||
|
|
959bcae557 | ||
|
|
694dff8a5c | ||
|
|
68caa26407 | ||
|
|
4cfd954e1e | ||
|
|
293d545b97 | ||
|
|
4df7e6adde | ||
|
|
449f647e58 | ||
|
|
f2a627c107 | ||
|
|
2ecb09ba7e | ||
|
|
522a1cdc5b | ||
|
|
c0c2ed2bf5 | ||
|
|
c774272366 | ||
|
|
533015b93e | ||
|
|
f4e52863c0 | ||
|
|
7a06633173 | ||
|
|
1a79bf2be2 | ||
|
|
3701733c8f | ||
|
|
5a21431c31 | ||
|
|
00eadf9791 | ||
|
|
33bf926b50 | ||
|
|
4798ffd055 | ||
|
|
228d1c27b7 | ||
|
|
68878ca98a | ||
|
|
28db5cadee | ||
|
|
8d5903cba9 | ||
|
|
74a8a801e4 | ||
|
|
b12b0ed93d | ||
|
|
7917c5d9ec | ||
|
|
6ecae6adb3 | ||
|
|
6d991313b1 | ||
|
|
43ef9b5a3a | ||
|
|
87bb81cd66 | ||
|
|
332cfb38c1 | ||
|
|
275479867d | ||
|
|
4f1e9fd256 | ||
|
|
80d11ca751 | ||
|
|
60f1a1a554 | ||
|
|
851d96de8a | ||
|
|
ecb1a6187c | ||
|
|
d4a6342295 | ||
|
|
a10903a197 | ||
|
|
c38c2a6455 | ||
|
|
e748efacd8 | ||
|
|
42ff902576 | ||
|
|
7e2716800b | ||
|
|
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 |
34
.gitignore
vendored
34
.gitignore
vendored
@@ -2,10 +2,44 @@
|
||||
*.orig
|
||||
*.swp
|
||||
*.rej
|
||||
*.log
|
||||
/*.xml
|
||||
*.o
|
||||
*.d
|
||||
|
||||
/build
|
||||
/contrib
|
||||
/depot
|
||||
/public
|
||||
/repos/allwinner
|
||||
/repos/imx
|
||||
/repos/riscv
|
||||
/repos/rpi
|
||||
/repos/world
|
||||
/repos/zynq
|
||||
/experiments
|
||||
|
||||
compile_commands.json
|
||||
.cache/
|
||||
repos/ealanos/.vscode/settings.json
|
||||
repos/ealanos/.vscode/c_cpp_properties.json
|
||||
repos/base-tukija/.vscode/c_cpp_properties.json
|
||||
repos/base-nova/include/nova/syscall-generic_REMOTE_4066947.h
|
||||
repos/base-nova/include/nova/syscall-generic_LOCAL_4066947.h
|
||||
repos/base-nova/include/nova/syscall-generic_BASE_4066947.h
|
||||
repos/base-nova/include/nova/syscall-generic_BACKUP_4066947.h
|
||||
.code-workspace.code-workspace
|
||||
.gitignore
|
||||
base-hw.log
|
||||
crash.log
|
||||
debug.log
|
||||
ealanos.code-workspace
|
||||
.vscode/configurationCache.log
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/dryrun.log
|
||||
.vscode/extension.log
|
||||
.vscode/settings.json
|
||||
.vscode/targets.log
|
||||
repos/base/.vscode/c_cpp_properties.json
|
||||
boot-paros
|
||||
stdcxx.S
|
||||
|
||||
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/>.
|
||||
|
||||
73
README
73
README
@@ -4,17 +4,19 @@
|
||||
=================================
|
||||
|
||||
|
||||
This is the source tree of the reference implementation of the Genode OS
|
||||
architecture. For a general overview about the architecture, please refer to
|
||||
the project's official website:
|
||||
This is the source code of Genode, which is a framework for creating
|
||||
component-based operating systems. It combines capability-based security,
|
||||
microkernel technology, sandboxed device drivers, and virtualization with
|
||||
a novel operating system architecture. For a general overview about the
|
||||
architecture, please refer to the project's official website:
|
||||
|
||||
:Official project website for the Genode OS Framework:
|
||||
:Website for the Genode OS Framework:
|
||||
|
||||
[https://genode.org/documentation/general-overview]
|
||||
|
||||
The current implementation can be compiled for 8 different kernels: Linux,
|
||||
L4ka::Pistachio, L4/Fiasco, OKL4, NOVA, Fiasco.OC, seL4, and a custom
|
||||
kernel for running Genode directly on ARM-based hardware. Whereas the Linux
|
||||
Genode-based operating systems can be compiled for a variety of kernels: Linux,
|
||||
L4ka::Pistachio, L4/Fiasco, OKL4, NOVA, Fiasco.OC, seL4, and a custom "hw"
|
||||
microkernel for running Genode without a 3rd-party kernel. Whereas the Linux
|
||||
version serves us as development vehicle and enables us to rapidly develop the
|
||||
generic parts of the system, the actual target platforms of the framework are
|
||||
microkernels. There is no "perfect" microkernel - and neither should there be
|
||||
@@ -22,7 +24,7 @@ one. If a microkernel pretended to be fit for all use cases, it wouldn't be
|
||||
"micro". Hence, all microkernels differ in terms of their respective features,
|
||||
complexity, and supported hardware architectures.
|
||||
|
||||
Genode allows the use of each of the kernels listed above with a rich set of
|
||||
Genode allows for the use of each of the supported kernels with a rich set of
|
||||
device drivers, protocol stacks, libraries, and applications in a uniform way.
|
||||
For developers, the framework provides an easy way to target multiple different
|
||||
kernels instead of tying the development to a particular kernel technology. For
|
||||
@@ -37,7 +39,7 @@ Documentation
|
||||
#############
|
||||
|
||||
The primary documentation is the book "Genode Foundations", which is available
|
||||
on the front page of Genode website:
|
||||
on the front page of the Genode website:
|
||||
|
||||
:Download the book "Genode Foundations":
|
||||
|
||||
@@ -65,34 +67,30 @@ 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':
|
||||
|
||||
Local depot and public archive of Genode packages. Please refer to
|
||||
Additional hardware support
|
||||
###########################
|
||||
|
||||
! doc/depot.txt
|
||||
The framework supports a variety of hardware platforms such as different ARM
|
||||
SoC families via supplemental repositories.
|
||||
|
||||
for more details.
|
||||
:Repositories maintained by Genode Labs:
|
||||
|
||||
[https://github.com/orgs/genodelabs/repositories]
|
||||
|
||||
|
||||
Additional community-maintained components
|
||||
@@ -107,13 +105,32 @@ system scenarios.
|
||||
[https://github.com/genodelabs/genode-world]
|
||||
|
||||
|
||||
Community blog
|
||||
##############
|
||||
|
||||
Genodians.org presents ideas, announcements, experience stories, and tutorials
|
||||
around Genode, informally written by Genode users and developers.
|
||||
|
||||
:Genodians.org:
|
||||
|
||||
[https://genodians.org]
|
||||
|
||||
|
||||
Contact
|
||||
#######
|
||||
|
||||
The best way to get in touch with Genode developers and users is the project's
|
||||
mailing list. Please feel welcome to join in!
|
||||
The community forum is organized by Genode users to help newcomers, share ideas
|
||||
and experiences, and discuss Genode-related projects.
|
||||
|
||||
:Genode Mailing Lists:
|
||||
:Community forum:
|
||||
|
||||
[https://genode.discourse.group]
|
||||
|
||||
The mailing list is the primary way for reaching out to Genode's core
|
||||
developers, for receiving announcements, and for the project's annual road-map
|
||||
discussion.
|
||||
|
||||
:Genode Mailing List:
|
||||
|
||||
[https://genode.org/community/mailing-lists]
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
-----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
|
||||
AD4WIQSFq6G0496kOfRE2qnpSz5BlOa1+AUCWpAOsgIbAwUJA8JnAAULCQgHAgYV
|
||||
CAkKCwIEFgIDAQIeAQIXgAAKCRDpSz5BlOa1+NGTEACg69FezAbc9Rzeb7j66NwW
|
||||
3x/Zpi/jbmezMEtCZqAOcR8HJ7C0DN8gmCWPPB6oxAEeyL/i2cUb+9F0fTD6N7OL
|
||||
TSOH75mNlyB9b8D2HdDILnLy4ClEitEOHFLMnlP58PGVtUNgbmsiM6cLLQtlJKvg
|
||||
1xHlBTG9Ic8qgBcd808lLSC1XWN+nufVYBTE2RHNZqGeIWqPG5z1eW/JJO4M3V3j
|
||||
MAw1p5Rpf9G6iWNxURutQOl/ii+97IKmHXX7N6ZRzawMGkOCAGNk1xeI71wCrALv
|
||||
i3m7NmXb6XIJjD88hO5xfjjRO/0Gcw3vdmTXcVNzM1TvWj8ZsU6XjnMvNxa4LHqh
|
||||
MxWuHlX0cAeCOzo1LJZ54f13hJ3YlTCrv68UIoNGRVi1LEbpE0sU0Ycdbw7ur2Gt
|
||||
8Brx5WXv3hXTL8s3fmJzYU3/cFDfXjnaRiMWcNYdvckdHy6R7zPTk1NOvmfkolnO
|
||||
W73ivdbonXpn0YqRGo2L76GdahLaVYn2gEeisqHnyeBCvI2snI+dMlEK0YNFrEkP
|
||||
wgtWnF131Oorn0HMS6mpjcq4su4s5d84KCMGevFnW69oBRG27Bk/fJQiv2dSqkZg
|
||||
+3TnyNApg1G7Bp5uD83mOvJWKdTWAntCJSQGbg1dmEsOBG+Bu7EE5LVBoMH3h/LQ
|
||||
GB7c5NpgNIFQ2DZy2vkOI7kCDQRakA6yARAAws48PKN3BQPEM0M4kTO57/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+VveSEBOEAEQEAAYkCPAQYAQgAJhYhBIWrobTj3qQ59ETaqelLPkGU5rX4
|
||||
BQJakA6yAhsMBQkDwmcAAAoJEOlLPkGU5rX4QjEQAIJF78XjvGomhafMsWlcd7fP
|
||||
/j45B+KIpyruc7wHtLqWibi+YoDuvtG4m1/4Ckcz5qNrV0f5nQojEAeCSCh7Sl+s
|
||||
yAJ9tmP1XET29DJq1t0iMsu+RDCLhdOfL/Wi/YJARtDloYbDlD8Rc/JnL2aOx2W/
|
||||
Ybajj2lloxSDxKCnzCh1aZixie1YaQSm8ErshT2k4qTx48D3mRoBLAYyzdEbLkl3
|
||||
ZBGDQy3Xk/miJ/hsj6L3w3G2YjMywZZZEjgDSUgSJ6MazBTgMmbCy1/0YGh7rNF7
|
||||
iUoWyDZq4qiDGNAI695I6tas7s4X2dhZn10xgbJoa5Dq2rqQLek+ErEsr3DFYN53
|
||||
7e9H0vJ9ydXB7piRJ9bxVFBng5CX9677IN5k9T/0lvcZWAFnDcHiMkIjIrTQ1Y04
|
||||
WkG6DMVvzLD+PKA07cZLf692rsrbfpP4sGj8X6baWh58mGAMMwZ2Dy07grsi73qI
|
||||
p/H4r4c/xRsH6nTbvb40zLfqcCz1xOTEcDtflYGMoeshu/H2EoruNMFi3c/9WO2G
|
||||
3zrSOUenWFSiacbsh8HVE9HUFGddBTB3SrLddO5vvvi15OvGI4aWpnkW+9s4107h
|
||||
jE0d0+c/Xm4AS0T59OGj/cd45k/vRe5vaPhQobZ6hXBzkKWPVt5uH8xbROiGiqdR
|
||||
jMuaeWIldeJ60aeu39Dh
|
||||
=JE0L
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -1 +0,0 @@
|
||||
https://depot.1337.cx
|
||||
@@ -1,37 +0,0 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1
|
||||
|
||||
mQENBFm3BlYBCADR2ZGIWiYurf/urQ+rAZs3HMobXQ/fckc3FOAdY9qiklrvPr9s
|
||||
maZZyMF+Wn4J2AmsGctJbBUt3ujcmk09AgZIzrHpVJRagUSz9q+bK7NvAfenDC2q
|
||||
w4HS5yE9DYxXOjxrcS5a2HhKfE5sZef1zPtFIkEZCJXCvh4IL6maLijOrUZPf9R6
|
||||
VJ+0itNh0hK9KiYsKA7CwrWuFaw7ZenVkEBV1HGXybFh9aInTTSqopyU6qYLDK1X
|
||||
U0NG24cjM8TDbMGTaoScpLchcftBGEhjYg7Y2FCu455MDVdrmoOoxDINYgDU1KN6
|
||||
8GBKKJ+xqG703/o550l+rCMB+TxMN5zKTFhXABEBAAG0IkVtZXJ5IEhlbWluZ3dh
|
||||
eSA8ZWhtcnlAcG9zdGVvLm5ldD6JAVQEEwEIAD4CGwMFCwkIBwIGFQgJCgsCBBYC
|
||||
AwECHgECF4AWIQRuEEFO5xYHgfX+6P+xTQQ6JrPSxwUCWgHubgUJAZm9OgAKCRCx
|
||||
TQQ6JrPSxyJ0B/0eBOIloo3zJwtuQnNXe2ZFAmHFF7MJhrr0IpZ0n5K0OHTFPqXN
|
||||
VJ+vhTGuI/SlF3a9YEHohIT2KKal1aq+/wVkX6Kdi4G4nGTEXdRsTwlzN/GXHBPF
|
||||
IW0iUOInJOliKReaamsR/rgXXH5sstq2IU4x+NpHMT/OrkQPNSqVX0RjS9i76Awo
|
||||
+EqdtW8g3y8qWd8WtTfhbMlQLhuzm99aADbspr4nK9WhZ7UHYLJAz/u7LzZlRiI5
|
||||
hNa85BCPhNuYz5NTHhn4L9r6PdbKPzUV173XrlAtlteYuGIHk4d/zSAwlgDevChL
|
||||
0MDRq1vvgfQ2V0SwIqRqIfnO31Ph8uktJ8WRiQEfBBABCAAJBQJaAReyAgcAAAoJ
|
||||
EIZq4LBroLaERpQH/3Dw0H6N9YF2ATmkse6NNNQjxhKSUoA34UBWj0v4Q1AvXEe6
|
||||
nHRR0mAa9Gije9ixKUg85VbKM3lUhXCFqW5jzyzpF1rzzTpAHaUTYKb8M2D9iRKo
|
||||
9ejTK3KrgpstYJ8jthfosxeC+lK24WUXKKWPjgoIhv7Thd31ea/PZdkFVd1MpSwg
|
||||
5BHRHcogsJI9uou7zWYbap9/k0lxKHJWklLh/oXet+aAoUIL0kTU+nILy3/RZJGW
|
||||
9WlnZR9g3qSQ8YNpgNSrraEtXpcs6MGsWZSzbzJ1U95NL87NbWEOYgHZA++vhEy5
|
||||
EXVrd8SuSHbUbqNF36gz1cxmEuKwxAaWZ1/UbGW5AQ0EWbcGVgEIANC9LozG/TXV
|
||||
4j0TniuLrsq7kkNH+OJQexcD19pBrmEV4eYYD6c8BB9CaBITqvKIqtG0VJrmB5S5
|
||||
D0oW4mQI+TkcX+Q7y3S7dUkc856d03aUX3vVcNhXEbNgM19qxAGieC8WH2kr4XU1
|
||||
psu1WvFCXOktrE5c8H0rPCQ1jseB0S67XCA9BLwAqlqu0OuTpbWddjXuE1ahi0ig
|
||||
Yt5YsHvgCMLup208azQqGCnJ5tFotqzbLg3I6+QzMcLySqsN4BzYmUGbOSSZdUhX
|
||||
DWxwAK1dB8qa27iwsxCMncdGnqOTkq+mXRmu8ztPTUivyC6YHJ+O5lXvMMADZi4j
|
||||
8RpQQlh5gFkAEQEAAYkBNgQYAQgAIBYhBG4QQU7nFgeB9f7o/7FNBDoms9LHBQJZ
|
||||
twZWAhsMAAoJELFNBDoms9LHTmIH/0PuzpA3Ezdrb4xfVwnhUUZGiqfNzULCZipT
|
||||
qtfym6Ove6To4BbXAihWwnCYs4sgipabW1WaXsDDvU+AmOmz4EPyTna23fUzYRSL
|
||||
MT/kk77d+BGRGeA8/Gj/BgjPlHlFa7ukbT1DL1lSV0RMQ32tDGnhJ7wMBx4GoYU+
|
||||
xjlsxrYKKdvZKOQVCCFn4KY/GavqT+8pYYI63stSPGspboQR2iboKqc350MVMvzz
|
||||
IaDt14YiOYlgV6LoNj2VaPJvFqm9ML+plYl4PPQZTV6KAhFWCDJq2DzEQqwG6RU4
|
||||
SsneHAqMlG4A5SSMTLEd9F2gZ2sJicybr1WbNLj1KF74ckUhpM4=
|
||||
=p4q9
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -1,31 +0,0 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQENBFpT5C4BCADHk4DtY2IQI6KlE+2td4wXKw0dILOobGExRffOgdB5d0WWKQgW
|
||||
gFw+UaywFxgJT0p2b7XoVsXE0bOz4tQRMdMxtYhL0qAhyj9+DsqqCBp0EcBD3XEz
|
||||
spm0DdNCEVfUbIQUstbSNt1kDGIlqPvZmoRj5YwDECW6ULG8jTWhaAz9SybJCE86
|
||||
jLPzZHjKtVhCVO1X0ogSxvvYGemUpqVCLfKcIb1TucieKKCrnjiHwp0XZ41DWqSb
|
||||
kBwWW2YQMEsw8JNGNTfCCUFf6+1l4mMixtv2sEqFiH1wQJ0c4gSa4iSYZ+eNmzJ0
|
||||
B13K8kONOctSg3NYZz/dC1aUzLOTkgJHqEPHABEBAAG0KVN0ZWZhbiBLYWxrb3dz
|
||||
a2kgPHNrYWxrQGRlcG90Lmdlbm9kZS5vcmc+iQFUBBMBCAA+FiEEI2X1/oP+p+Ls
|
||||
2L28qrC4CLnp/P8FAlrQZGACGwMFCQPCZwAFCwkIBwIGFQgJCgsCBBYCAwECHgEC
|
||||
F4AACgkQqrC4CLnp/P9kKQgAxc11eDhYkMVg9cuipFoqtV5lY9aT2qkocZ28IhbF
|
||||
LXhy9lcn5FlxZSVdkzJQ5tUf4nSuhhMb6z3r8edaOebcYAyFk0DTymNpcEyT2XHd
|
||||
lsOcInhfU423m1tCNHdmxtv9HERtj2zS1KNkjWxY6xsqfEw1eDfUvdS3K9KpUqc6
|
||||
vWZwsPd9EHxW3mzWJS3lrSAnNsCwtdmiqB9045Yss4KednMcN6qxE+uHppQ+25Ib
|
||||
5ZICpiVqOJ+eQXeY3kRx84lfZJr3uFdn00RSU5fn0uol8ZZYX9tQd9SC1GIlkyYj
|
||||
HxNLKNVaYzF1nnmR1s7cpY6PUAYbt0im6kd4VJ1wQcWTnrkBDQRaU+QuAQgAuame
|
||||
2VDCgNmiwu+QmWyNN4jzbE7+VNmDr37HO9lZRIROC4eACPOGfUL03jLGvUn7rrxQ
|
||||
JK+Pit6gXXCoIWDhCMNRSZKho416KJZWxF2jxKBKGQ7DtWaTR3YOzSf0ka9DZSrp
|
||||
wG22xS0Uf1U/0ZBIf24LbyUDFLc8zt4eey2D9AHm+9vCf7wnf8TV6SNIXRz3wj7d
|
||||
VqoZLXRTT7twBSaNahLhNtg7fhS8Nu6/THuwXpNKPAvAsgJRTGk7kmrKj5P7rOZA
|
||||
rNHC1pvK1EWJJi2onHOmCzBccKRp9SeQlj+ddqG6seZhEnRYG6l7uhkyNZoyvKxO
|
||||
Fguc5g8Xf37VyuRMfwARAQABiQE8BBgBCAAmFiEEI2X1/oP+p+Ls2L28qrC4CLnp
|
||||
/P8FAlpT5C4CGwwFCQPCZwAACgkQqrC4CLnp/P/IOAf+LnQVtU7aHh4AZDsi1wXq
|
||||
KBo5l6r3G8tC/S0HEf8nnWMUio2/mwVrkbuTvBeKrcQ/mXFHHAG8YCAIHPgR7T0y
|
||||
2L6l2PL4HoXiLD8EwJ0sWZu2waxuxcTX+bb1i3Xm3squnqDtCX3pyoXWx0GVgrz9
|
||||
7I/zitxeER+35ScaZ+JAAcNW59LpiV1SdIXqbtrw5QBJBuZUp0bvnzCNvdZLhnhb
|
||||
gWfwPEfcXFt5K87iTmfMFJOJpbUrEz/NWE9gOBCBjqxW0wVb+IWr0oFWvfxjuBq7
|
||||
IW9DezwkN1wAavP6g7+B4esCD6SRq+3CCzbT1By3X2h3SevU8tHkCSA3cIKgWdyD
|
||||
2A==
|
||||
=IsaH
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -1 +0,0 @@
|
||||
https://s3.eu-central-1.amazonaws.com/dev.depot.gapfruit.com
|
||||
@@ -1,18 +0,0 @@
|
||||
-----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-----
|
||||
@@ -1,503 +0,0 @@
|
||||
|
||||
|
||||
=======================
|
||||
The Genode build system
|
||||
=======================
|
||||
|
||||
|
||||
Norman Feske
|
||||
|
||||
Abstract
|
||||
########
|
||||
|
||||
The Genode OS Framework comes with a custom build system that is designed for
|
||||
the creation of highly modular and portable systems software. Understanding
|
||||
its basic concepts is pivotal for using the full potential of the framework.
|
||||
This document introduces those concepts and the best practises of putting them
|
||||
to good use. Beside building software components from source code, common
|
||||
and repetitive development tasks are the testing of individual components
|
||||
and the integration of those components into complex system scenarios. To
|
||||
streamline such tasks, the build system is accompanied with special tooling
|
||||
support. This document introduces those tools.
|
||||
|
||||
|
||||
Build directories and repositories
|
||||
##################################
|
||||
|
||||
The build system is supposed to never touch the source tree. The procedure of
|
||||
building components and integrating them into system scenarios is done at
|
||||
a distinct build directory. One build directory targets a specific platform,
|
||||
i.e., a kernel and hardware architecture. Because the source tree is decoupled
|
||||
from the build directory, one source tree can have many different build
|
||||
directories associated, each targeted at another platform.
|
||||
|
||||
The recommended way for creating a build directory is the use of the
|
||||
'create_builddir' tool located at '<genode-dir>/tool/'. By starting the tool
|
||||
without arguments, its usage information will be printed. For creating a new
|
||||
build directory, one of the listed target platforms must be specified.
|
||||
Furthermore, the location of the new build directory has to be specified via
|
||||
the 'BUILD_DIR=' argument. For example:
|
||||
|
||||
! cd <genode-dir>
|
||||
! ./tool/create_builddir linux_x86 BUILD_DIR=/tmp/build.linux_x86
|
||||
|
||||
This command will create a new build directory for the Linux/x86 platform
|
||||
at _/tmp/build.linux_x86/_.
|
||||
|
||||
|
||||
Build-directory configuration via 'build.conf'
|
||||
==============================================
|
||||
|
||||
The fresh build directory will contain a 'Makefile', which is a symlink to
|
||||
_tool/builddir/build.mk_. This makefile is the front end of the build system
|
||||
and not supposed to be edited. Beside the makefile, there is a _etc/_
|
||||
subdirectory that contains the build-directory configuration. For most
|
||||
platforms, there is only a single _build.conf_ file, which defines the parts of
|
||||
the Genode source tree incorporated in the build process. Those parts are
|
||||
called _repositories_.
|
||||
|
||||
The repository concept allows for keeping the source code well separated for
|
||||
different concerns. For example, the platform-specific code for each target
|
||||
platform is located in a dedicated _base-<platform>_ repository. Also, different
|
||||
abstraction levels and features of the system are residing in different
|
||||
repositories. The _etc/build.conf_ file defines the set of repositories to
|
||||
consider in the build process. At build time, the build system overlays the
|
||||
directory structures of all repositories specified via the 'REPOSITORIES'
|
||||
declaration to form a single logical source tree. By changing the list of
|
||||
'REPOSITORIES', the view of the build system on the source tree can be altered.
|
||||
The _etc/build.conf_ as found in a fresh created build directory will list the
|
||||
_base-<platform>_ repository of the platform selected at the 'create_builddir'
|
||||
command line as well as the 'base', 'os', and 'demo' repositories needed for
|
||||
compiling Genode's default demonstration scenario. Furthermore, there are a
|
||||
number of commented-out lines that can be uncommented for enabling additional
|
||||
repositories.
|
||||
|
||||
Note that the order of the repositories listed in the 'REPOSITORIES' declaration
|
||||
is important. Front-most repositories shadow subsequent repositories. This
|
||||
makes the repository mechanism a powerful tool for tweaking existing repositories:
|
||||
By adding a custom repository in front of another one, customized versions of
|
||||
single files (e.g., header files or target description files) can be supplied to
|
||||
the build system without changing the original repository.
|
||||
|
||||
|
||||
Building targets
|
||||
================
|
||||
|
||||
To build all targets contained in the list of 'REPOSITORIES' as defined in
|
||||
_etc/build.conf_, simply issue 'make'. This way, all components that are
|
||||
compatible with the build directory's base platform will be built. In practice,
|
||||
however, only some of those components may be of interest. Hence, the build
|
||||
can be tailored to those components which are of actual interest by specifying
|
||||
source-code subtrees. For example, using the following command
|
||||
! make core server/nitpicker
|
||||
the build system builds all targets found in the 'core' and 'server/nitpicker'
|
||||
source directories. You may specify any number of subtrees to the build
|
||||
system. As indicated by the build output, the build system revisits
|
||||
each library that is used by each target found in the specified subtrees.
|
||||
This is very handy for developing libraries because instead of re-building
|
||||
your library and then your library-using program, you just build your program
|
||||
and that's it. This concept even works recursively, which means that libraries
|
||||
may depend on other libraries.
|
||||
|
||||
In practice, you won't ever need to build the _whole tree_ but only the
|
||||
targets that you are interested in.
|
||||
|
||||
|
||||
Cleaning the build directory
|
||||
============================
|
||||
|
||||
To remove all but kernel-related generated files, use
|
||||
! make clean
|
||||
|
||||
To remove all generated files, use
|
||||
! make cleanall
|
||||
|
||||
Both 'clean' and 'cleanall' won't remove any files from the _bin/_
|
||||
subdirectory. This makes the _bin/_ a safe place for files that are
|
||||
unrelated to the build process, yet required for the integration stage, e.g.,
|
||||
binary data.
|
||||
|
||||
|
||||
Controlling the verbosity of the build process
|
||||
==============================================
|
||||
|
||||
To understand the inner workings of the build process in more detail, you can
|
||||
tell the build system to display each directory change by specifying
|
||||
|
||||
! make VERBOSE_DIR=
|
||||
|
||||
If you are interested in the arguments that are passed to each invocation of
|
||||
'make', you can make them visible via
|
||||
|
||||
! make VERBOSE_MK=
|
||||
|
||||
Furthermore, you can observe each single shell-command invocation by specifying
|
||||
|
||||
! make VERBOSE=
|
||||
|
||||
Of course, you can combine these verboseness toggles for maximizing the noise.
|
||||
|
||||
|
||||
Enabling parallel builds
|
||||
========================
|
||||
|
||||
To utilize multiple CPU cores during the build process, you may invoke 'make'
|
||||
with the '-j' argument. If manually specifying this argument becomes an
|
||||
inconvenience, you may add the following line to your _etc/build.conf_ file:
|
||||
|
||||
! MAKE += -j<N>
|
||||
|
||||
This way, the build system will always use '<N>' CPUs for building.
|
||||
|
||||
|
||||
Caching inter-library dependencies
|
||||
==================================
|
||||
|
||||
The build system allows to repeat the last build without performing any
|
||||
library-dependency checks by using:
|
||||
|
||||
! make again
|
||||
|
||||
The use of this feature can significantly improve the work flow during
|
||||
development because in contrast to source-codes, library dependencies rarely
|
||||
change. So the time needed for re-creating inter-library dependencies at each
|
||||
build can be saved.
|
||||
|
||||
|
||||
Repository directory layout
|
||||
###########################
|
||||
|
||||
Each Genode repository has the following layout:
|
||||
|
||||
Directory | Description
|
||||
------------------------------------------------------------
|
||||
'doc/' | Documentation, specific for the repository
|
||||
------------------------------------------------------------
|
||||
'etc/' | Default configuration of the build process
|
||||
------------------------------------------------------------
|
||||
'mk/' | The build system
|
||||
------------------------------------------------------------
|
||||
'include/' | Globally visible header files
|
||||
------------------------------------------------------------
|
||||
'src/' | Source codes and target build descriptions
|
||||
------------------------------------------------------------
|
||||
'lib/mk/' | Library build descriptions
|
||||
|
||||
|
||||
Creating targets and libraries
|
||||
##############################
|
||||
|
||||
Target descriptions
|
||||
===================
|
||||
|
||||
A good starting point is to look at the init target. The source code of init is
|
||||
located at _os/src/init/_. In this directory, you will find a target description
|
||||
file named _target.mk_. This file contains the building instructions and it is
|
||||
usually very simple. The build process is controlled by defining the following
|
||||
variables.
|
||||
|
||||
|
||||
Build variables to be defined by you
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:'TARGET': is the name of the binary to be created. This is the
|
||||
only *mandatory variable* to be defined in a _target.mk_ file.
|
||||
|
||||
:'REQUIRES': expresses the requirements that must be satisfied in order to
|
||||
build the target. You find more details about the underlying mechanism in
|
||||
Section [Specializations].
|
||||
|
||||
:'LIBS': is the list of libraries that are used by the target.
|
||||
|
||||
:'SRC_CC': contains the list of '.cc' source files. The default search location
|
||||
for source codes is the directory, where the _target.mk_ file resides.
|
||||
|
||||
:'SRC_C': contains the list of '.c' source files.
|
||||
|
||||
:'SRC_S': contains the list of assembly '.s' source files.
|
||||
|
||||
:'SRC_BIN': contains binary data files to be linked to the target.
|
||||
|
||||
:'INC_DIR': is the list of include search locations. Directories should
|
||||
always be appended by using +=. Never use an assignment!
|
||||
|
||||
:'EXT_OBJECTS': is a list of Genode-external objects or libraries. This
|
||||
variable is mostly used for interfacing Genode with legacy software
|
||||
components.
|
||||
|
||||
|
||||
Rarely used variables
|
||||
---------------------
|
||||
|
||||
:'CC_OPT': contains additional compiler options to be used for '.c' as
|
||||
well as for '.cc' files.
|
||||
|
||||
:'CC_CXX_OPT': contains additional compiler options to be used for the
|
||||
C++ compiler only.
|
||||
|
||||
:'CC_C_OPT': contains additional compiler options to be used for the
|
||||
C compiler only.
|
||||
|
||||
|
||||
Specifying search locations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When specifying search locations for header files via the 'INC_DIR' variable or
|
||||
for source files via 'vpath', relative pathnames are illegal to use. Instead,
|
||||
you can use the following variables to reference locations within the
|
||||
source-code repository, where your target lives:
|
||||
|
||||
:'REP_DIR': is the base directory of the current source-code repository.
|
||||
Normally, specifying locations relative to the base of the repository is
|
||||
never used by _target.mk_ files but needed by library descriptions.
|
||||
|
||||
:'PRG_DIR': is the directory, where your _target.mk_ file resides. This
|
||||
variable is always to be used when specifying a relative path.
|
||||
|
||||
|
||||
Library descriptions
|
||||
====================
|
||||
|
||||
In contrast to target descriptions that are scattered across the whole source
|
||||
tree, library descriptions are located at the central place _lib/mk_. Each
|
||||
library corresponds to a _<libname>.mk_ file. The base of the description file
|
||||
is the name of the library. Therefore, no 'TARGET' variable needs to be set.
|
||||
The source-code locations are expressed as '$(REP_DIR)'-relative 'vpath'
|
||||
commands.
|
||||
|
||||
Library-description files support the following additional declarations:
|
||||
|
||||
:'SHARED_LIB = yes': declares that the library should be built as a shared
|
||||
object rather than a static library. The resulting object will be called
|
||||
_<libname>.lib.so_.
|
||||
|
||||
|
||||
Specializations
|
||||
===============
|
||||
|
||||
Building components for different platforms likely implicates portions of code
|
||||
that are tied to certain aspects of the target platform. For example, a target
|
||||
platform may be characterized by
|
||||
|
||||
* A kernel API such as L4v2, Linux, L4.sec,
|
||||
* A hardware architecture such as x86, ARM, Coldfire,
|
||||
* A certain hardware facility such as a custom device, or
|
||||
* Other properties such as software license requirements.
|
||||
|
||||
Each of these attributes express a specialization of the build process. The
|
||||
build system provides a generic mechanism to handle such specializations.
|
||||
|
||||
The _programmer_ of a software component knows the properties on which his
|
||||
software relies and thus, specifies these requirements in his build description
|
||||
file.
|
||||
|
||||
The _user/customer/builder_ decides to build software for a specific platform
|
||||
and defines the platform specifics via the 'SPECS' variable per build
|
||||
directory in _etc/specs.conf_. In addition to an (optional) _etc/specs.conf_
|
||||
file within the build directory, the build system incorporates the first
|
||||
_etc/specs.conf_ file found in the repositories as configured for the
|
||||
build directory. For example, for a 'linux_x86' build directory, the
|
||||
_base-linux/etc/specs.conf_ file is used by default. The build directory's
|
||||
'specs.conf' file can still be used to extend the 'SPECS' declarations, for
|
||||
example to enable special features.
|
||||
|
||||
Each '<specname>' in the 'SPECS' variable instructs the build system to
|
||||
|
||||
* Include the 'make'-rules of a corresponding _base/mk/spec-<specname>.mk_
|
||||
file. This enables the customization of the build process for each platform.
|
||||
|
||||
* Search for _<libname>.mk_ files in the _lib/mk/<specname>/_ subdirectory.
|
||||
This way, we can provide alternative implementations of one and the same
|
||||
library interface for different platforms.
|
||||
|
||||
Before a target or library gets built, the build system checks if the 'REQUIRES'
|
||||
entries of the build description file are satisfied by entries of the 'SPECS'
|
||||
variable. The compilation is executed only if each entry in the 'REQUIRES'
|
||||
variable is present in the 'SPECS' variable as supplied by the build directory
|
||||
configuration.
|
||||
|
||||
|
||||
Building tools to be executed on the host platform
|
||||
===================================================
|
||||
|
||||
Sometimes, software requires custom tools that are used to generate source
|
||||
code or other ingredients for the build process, for example IDL compilers.
|
||||
Such tools won't be executed on top of Genode but on the host platform
|
||||
during the build process. Hence, they must be compiled with the tool chain
|
||||
installed on the host, not the Genode tool chain.
|
||||
|
||||
The Genode build system accommodates the building of such host tools as a side
|
||||
effect of building a library or a target. Even though it is possible to add
|
||||
the tool compilation step to a regular build description file, it is
|
||||
recommended to introduce a dedicated pseudo library for building such tools.
|
||||
This way, the rules for building host tools are kept separate from rules that
|
||||
refer to Genode programs. By convention, the pseudo library should be named
|
||||
_<package>_host_tools_ and the host tools should be built at
|
||||
_<build-dir>/tool/<package>/_. With _<package>_, we refer to the name of the
|
||||
software package the tool belongs to, e.g., qt5 or mupdf. To build a tool
|
||||
named _<tool>_, the pseudo library contains a custom make rule like the
|
||||
following:
|
||||
|
||||
! $(BUILD_BASE_DIR)/tool/<package>/<tool>:
|
||||
! $(MSG_BUILD)$(notdir $@)
|
||||
! $(VERBOSE)mkdir -p $(dir $@)
|
||||
! $(VERBOSE)...build commands...
|
||||
|
||||
To let the build system trigger the rule, add the custom target to the
|
||||
'HOST_TOOLS' variable:
|
||||
|
||||
! HOST_TOOLS += $(BUILD_BASE_DIR)/tool/<package>/<tool>
|
||||
|
||||
Once the pseudo library for building the host tools is in place, it can be
|
||||
referenced by each target or library that relies on the respective tools via
|
||||
the 'LIBS' declaration. The tool can be invoked by referring to
|
||||
'$(BUILD_BASE_DIR)/tool/<package>/tool'.
|
||||
|
||||
For an example of using custom host tools, please refer to the mupdf package
|
||||
found within the libports repository. During the build of the mupdf library,
|
||||
two custom tools fontdump and cmapdump are invoked. The tools are built via
|
||||
the _lib/mk/mupdf_host_tools.mk_ library description file. The actual mupdf
|
||||
library (_lib/mk/mupdf.mk_) has the pseudo library 'mupdf_host_tools' listed
|
||||
in its 'LIBS' declaration and refers to the tools relative to
|
||||
'$(BUILD_BASE_DIR)'.
|
||||
|
||||
|
||||
Automated integration and testing
|
||||
#################################
|
||||
|
||||
Genode's cross-kernel portability is one of the prime features of the
|
||||
framework. However, each kernel takes a different route when it comes to
|
||||
configuring, integrating, and booting the system. Hence, for using a particular
|
||||
kernel, profound knowledge about the boot concept and the kernel-specific tools
|
||||
is required. To streamline the testing of Genode-based systems across the many
|
||||
different supported kernels, the framework comes equipped with tools that
|
||||
relieve you from these peculiarities.
|
||||
|
||||
Run scripts
|
||||
===========
|
||||
|
||||
Using so-called run scripts, complete Genode systems can be described in a
|
||||
concise and kernel-independent way. Once created, a run script can be used
|
||||
to integrate and test-drive a system scenario directly from the build directory.
|
||||
The best way to get acquainted with the concept is reviewing the run script
|
||||
for the 'hello_tutorial' located at _hello_tutorial/run/hello.run_.
|
||||
Let's revisit each step expressed in the _hello.run_ script:
|
||||
|
||||
* Building the components needed for the system using the 'build' command.
|
||||
This command instructs the build system to compile the targets listed in
|
||||
the brace block. It has the same effect as manually invoking 'make' with
|
||||
the specified argument from within the build directory.
|
||||
|
||||
* Creating a new boot directory using the 'create_boot_directory' command.
|
||||
The integration of the scenario is performed in a dedicated directory at
|
||||
_<build-dir>/var/run/<run-script-name>/_. When the run script is finished,
|
||||
this directory will contain all components of the final system. In the
|
||||
following, we will refer to this directory as run directory.
|
||||
|
||||
* Installing the Genode 'config' file into the run directory using the
|
||||
'install_config' command. The argument to this command will be written
|
||||
to a file called 'config' at the run directory picked up by
|
||||
Genode's init process.
|
||||
|
||||
* Creating a bootable system image using the 'build_boot_image' command.
|
||||
This command copies the specified list of files from the _<build-dir>/bin/_
|
||||
directory to the run directory and executes the platform-specific steps
|
||||
needed to transform the content of the run directory into a bootable
|
||||
form. This form depends on the actual base platform and may be an ISO
|
||||
image or a bootable ELF image.
|
||||
|
||||
* Executing the system image using the 'run_genode_until' command. Depending
|
||||
on the base platform, the system image will be executed using an emulator.
|
||||
For most platforms, Qemu is the tool of choice used by default. On Linux,
|
||||
the scenario is executed by starting 'core' directly from the run
|
||||
directory. The 'run_genode_until' command takes a regular expression
|
||||
as argument. If the log output of the scenario matches the specified
|
||||
pattern, the 'run_genode_until' command returns. If specifying 'forever'
|
||||
as argument (as done in 'hello.run'), this command will never return.
|
||||
If a regular expression is specified, an additional argument determines
|
||||
a timeout in seconds. If the regular expression does not match until
|
||||
the timeout is reached, the run script will abort.
|
||||
|
||||
Please note that the _hello.run_ script does not contain kernel-specific
|
||||
information. Therefore it can be executed from the build directory of any base
|
||||
platform by using:
|
||||
|
||||
! make run/hello
|
||||
|
||||
When invoking 'make' with an argument of the form 'run/*', the build system
|
||||
will look in all repositories for a run script with the specified name. The run
|
||||
script must be located in one of the repositories 'run/' subdirectories and
|
||||
have the file extension '.run'.
|
||||
|
||||
For a more comprehensive run script, _os/run/demo.run_ serves as a good
|
||||
example. This run script describes Genode's default demo scenario. As seen in
|
||||
'demo.run', parts of init's configuration can be made dependent on the
|
||||
platform's properties expressed as spec values. For example, the PCI driver
|
||||
gets included in init's configuration only on platforms with a PCI bus. For
|
||||
appending conditional snippets to the _config_ file, there exists the 'append_if'
|
||||
command, which takes a condition as first and the snippet as second argument.
|
||||
To test for a SPEC value, the command '[have_spec <spec-value>]' is used as
|
||||
condition. Analogously to how 'append_if' appends strings, there exists
|
||||
'lappend_if' to append list items. The latter command is used to conditionally
|
||||
include binaries to the list of boot modules passed to the 'build_boot_image'
|
||||
command.
|
||||
|
||||
|
||||
The run mechanism explained
|
||||
===========================
|
||||
|
||||
Under the hood, run scripts are executed by an expect interpreter. When the
|
||||
user invokes a run script via _make run/<run-script>_, the build system invokes
|
||||
the run tool at _<genode-dir>/tool/run_ with the run script as argument. The
|
||||
run tool is an expect script that has no other purpose than defining several
|
||||
commands used by run scripts, including a platform-specific script snippet
|
||||
called run environment ('env'), and finally including the actual run script.
|
||||
Whereas _tool/run_ provides the implementations of generic and largely
|
||||
platform-independent commands, the _env_ snippet included from the platform's
|
||||
respective _base-<platform>/run/env_ file contains all platform-specific
|
||||
commands. For reference, the most simplistic run environment is the one at
|
||||
_base-linux/run/env_, which implements the 'create_boot_directory',
|
||||
'install_config', 'build_boot_image', and 'run_genode_until' commands for Linux
|
||||
as base platform. For the other platforms, the run environments are far more
|
||||
elaborative and document precisely how the integration and boot concept works
|
||||
on each platform. Hence, the _base-<platform>/run/env_ files are not only
|
||||
necessary parts of Genode's tooling support but serve as resource for
|
||||
peculiarities of using each kernel.
|
||||
|
||||
|
||||
Using run script to implement test cases
|
||||
========================================
|
||||
|
||||
Because run scripts are actually expect scripts, the whole arsenal of
|
||||
language features of the Tcl scripting language is available to them. This
|
||||
turns run scripts into powerful tools for the automated execution of test
|
||||
cases. A good example is the run script at _libports/run/lwip.run_, which tests
|
||||
the lwIP stack by running a simple Genode-based HTTP server on Qemu. It fetches
|
||||
and validates a HTML page from this server. The run script makes use of a
|
||||
regular expression as argument to the 'run_genode_until' command to detect the
|
||||
state when the web server becomes ready, subsequently executes the 'lynx' shell
|
||||
command to fetch the web site, and employs Tcl's support for regular
|
||||
expressions to validate the result. The run script works across base platforms
|
||||
that use Qemu as execution environment.
|
||||
|
||||
To get the most out of the run mechanism, a basic understanding of the Tcl
|
||||
scripting language is required. Furthermore the functions provided by
|
||||
_tool/run_ and _base-<platform>/run/env_ should be studied.
|
||||
|
||||
|
||||
Automated testing across base platforms
|
||||
=======================================
|
||||
|
||||
To execute one or multiple test cases on more than one base platform, there
|
||||
exists a dedicated tool at _tool/autopilot_. Its primary purpose is the
|
||||
nightly execution of test cases. The tool takes a list of platforms and 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.
|
||||
|
||||
|
||||
@@ -16,28 +16,24 @@ research projects on Genode.
|
||||
Applications and library infrastructure
|
||||
#######################################
|
||||
|
||||
:GNU Privacy Guard:
|
||||
:Port of the Ladybird web browser:
|
||||
|
||||
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.
|
||||
[https://ladybird.org/ - Ladybird] is a new web browser developed
|
||||
independently from the large browser-engine vendors. It is designed to
|
||||
be light-weight and portable. Among the supported platforms is Qt,
|
||||
which is available for Genode. This makes the porting of Ladybird a
|
||||
tempting application of the Goa SDK.
|
||||
|
||||
:VNC server implementing Genode's framebuffer session interface:
|
||||
:Goa SDK running on Sculpt OS:
|
||||
|
||||
With 'Input' and 'Framebuffer', Genode provides two low-level interfaces
|
||||
used by interactive applications. For example, the Nitpicker GUI server uses
|
||||
these interfaces as a client and, in turn, exports multiple virtual
|
||||
'Framebuffer' and 'Input' interfaces to its clients. This enables a
|
||||
highly modular use of applications such as the nesting of GUIs. By
|
||||
implementing the 'Framebuffer' and 'Input' interfaces with a VNC server
|
||||
implementation, all graphical workloads of Genode would become available over
|
||||
the network. One immediate application of this implementation is the remote
|
||||
testing of graphical Genode applications running on a headless server.
|
||||
Genode's [https://github.com/genodelabs/goa - Goa SDK] is currently used
|
||||
in Linux-based development environments, facilitating cross-compilation
|
||||
to Genode. The goal of this project is the ability to use Goa directly on
|
||||
Sculpt OS without the need for a Linux VM. This entails a number of
|
||||
challenges, ranging from running the Goa tool itself by porting the expect
|
||||
interpreter, over running the Genode tool chain, adjusting the
|
||||
network-facing Goa commands to Genode's environment, to crafting custom
|
||||
support for executing 'goa run' as a sandboxed Genode subsystem.
|
||||
|
||||
:Interfacing with the SAFE network:
|
||||
|
||||
@@ -50,43 +46,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
|
||||
that allows the arbitrary routing of session requests throughout the
|
||||
hierarchic process structure. Even though primarily designed for expressing
|
||||
mandatory-access control rules, the concept scales far beyond this use case.
|
||||
For example, it can be used to run an arbitrary number of processes
|
||||
implementing the same interface and connecting the different interface
|
||||
implementations. One special case of this scenario is a chain of audio
|
||||
filters with each using the 'Audio_out' session interface for both roles
|
||||
client and server. Combined with the Nitpicker GUI server and Genode's
|
||||
support for real-time priorities, this base techniques enable the creation of
|
||||
flexible audio mixer / switchboard applications, which require dedicated
|
||||
frameworks (e.g., Jack audio) on traditional operating systems. The goal of
|
||||
this project is to create a showcase implementation demonstrating the
|
||||
feasibility for creating high-quality audio applications on Genode.
|
||||
Furthermore, we wish for feedback regarding the current design of our bulk
|
||||
streaming interface when used for low-latency applications.
|
||||
|
||||
:Graphical on-target IPC tracing tool using Qt:
|
||||
|
||||
Analysing the interaction of components of a multi-server operating system
|
||||
@@ -116,37 +75,62 @@ 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.
|
||||
The [https://github.com/genodelabs/goa - Goa SDK] streamlines the process
|
||||
of developing, porting, packaging, and publishing software for Genode,
|
||||
and Sculpt OS in particular.
|
||||
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]
|
||||
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].
|
||||
C++ library, and a variety of supported 3rd-party libraries, porting
|
||||
software to Genode is relatively straight forward.
|
||||
A wish list of software that we'd like to have available on Genode is
|
||||
available at
|
||||
[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
|
||||
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
|
||||
###############################################
|
||||
|
||||
:GTK:
|
||||
|
||||
Genode supports Qt as a native toolkit. But many popular applications
|
||||
are built upon [https://www.gtk.org/ - GTK]. A port of GTK to Genode would
|
||||
allow for the use of these applications on Sculpt OS without the need
|
||||
of a Linux VM. A tangible goal for this line of work could be the port
|
||||
of [https://mtpaint.sourceforge.net/ - mtPaint] to Sculpt OS.
|
||||
|
||||
: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,47 +139,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,
|
||||
there were numerous attempts to make the Go runtime available on Genode
|
||||
but so far, none of those undertakings have landed in the official
|
||||
Genode source tree. To goal of this project is the hosting of
|
||||
Go-written applications - in particular networking applications - as
|
||||
Genode components. The topic comprises work on the tool-chain
|
||||
and build-system integration, the porting the runtime libraries, and
|
||||
the glue between the Go and Genode environments.
|
||||
|
||||
:Combination of CAmkES with Genode:
|
||||
|
||||
[https://wiki.sel4.systems/CAmkES - CAmkES] is a component framework for
|
||||
seL4. In contrast to Genode, which is a dynamic system, CAmkES-based systems
|
||||
are defined at design time and remain fixed at runtime. Hence, CAmkES and
|
||||
Genode can be seen as the opposite ends of component-based used-land
|
||||
architectures. The goal of this project is to build a bridge between
|
||||
both projects with the potential to cross-pollinate the respective communities.
|
||||
Among the principal approaches are embedding of a single CAmkES
|
||||
component as a Genode component (e.g., an individual device driver),
|
||||
the hosting of a dynamic Genode system as a component within a
|
||||
CAmkES system, or the hosting of a CAmkES system composition as a Genode
|
||||
subsystem.
|
||||
|
||||
:Runtime for the D programming language:
|
||||
|
||||
The D systems programming language was designed to overcome many gripes that
|
||||
@@ -209,66 +152,64 @@ Application frameworks and runtime environments
|
||||
programs, and interfacing D programs with other Genode components written in
|
||||
C++.
|
||||
|
||||
:Using Haskell as systems-development language:
|
||||
:Xlib compatibility:
|
||||
|
||||
The goal of this project is the application of functional programming
|
||||
i.e., Haskell, for the implementation of low-level Genode components.
|
||||
Implementing critical functionalities in such a high-level language instead
|
||||
of a classical systems language such as C or C++ would pave the way towards
|
||||
analyzing such components with formal methods.
|
||||
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.
|
||||
|
||||
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
|
||||
Xen that is based on Haskell.
|
||||
: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 record/play (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 fun to play with.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
:Support for additional ARM SoCs:
|
||||
|
||||
Genode's ARM support has been focused on NXP's i.MX family, Allwinner A64
|
||||
(used by the PinePhone), and to a lesser degree the Raspberry Pi. To make
|
||||
Genode compatible with a larger variety of devices, the support for further
|
||||
chip families calls for exploration. For example,
|
||||
[https://en.wikipedia.org/wiki/Rockchip - Rockchip] SoCs are getting
|
||||
popular in products by open-source hardware vendors such as
|
||||
[https://pine64.com/ - Pine64] and [https://mntre.com/ - MNT].
|
||||
The first steps have been [https://github.com/mickenx/genode-rockchip - already taken]
|
||||
by [https://genodians.org/mickenx/index - Michael Grunditz]!
|
||||
Another example is the Mediatek SoC family, which is popular in
|
||||
affordable consumer smartphones.
|
||||
Another example is the Mediatek SoC family, which is popular in
|
||||
affordable consumer smartphones.
|
||||
|
||||
The process of bringing an OS like Genode to a new SoC is full of technical
|
||||
challenges and labor-intensive, yet extremely gratifying.
|
||||
As a guide through this process, the
|
||||
[https://genode.org/documentation/genode-platforms-23-05.pdf - Genode Platforms]
|
||||
book breaks the challenge down to a sequence of manageable steps, where
|
||||
each step can be celebrated as a success.
|
||||
|
||||
|
||||
Virtualization
|
||||
##############
|
||||
|
||||
:VirtualBox on top of KVM on Linux:
|
||||
|
||||
Genode's version of VirtualBox replaces the original in-kernel VirtualBox
|
||||
hypervisor by the virtualization mechanism of the NOVA hypervisor or the
|
||||
Muen separation kernel. Those mechanisms look very similar the KVM
|
||||
interface of the Linux kernel. It should in principle be possible to
|
||||
re-target Genode's version of VirtualBox to KVM. This way, VirtualBox and
|
||||
Qemu/KVM-based virtual machines could co-exist on the same system, which
|
||||
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
|
||||
overly complex Linux OS from the trusted computing base of Xen
|
||||
guests OSes.
|
||||
|
||||
Xen is a hypervisor that can host multiple virtual machines on one physical
|
||||
machine. For driving physical devices and for virtual-machine management, Xen
|
||||
relies on a privileged guest OS called Dom0. Currently, Linux is the
|
||||
predominant choice to be used as Dom0, which implicates a trusted computing
|
||||
base of millions of lines of code for the other guest OSes.
|
||||
|
||||
Even though Xen was designed as hypervisor, a thorough analysis done by Julian
|
||||
Stecklina concludes that Xen qualifies well as a kernel for Genode. For
|
||||
example, Julian implemented a version of Genode's IPC framework that utilizes
|
||||
Xen's communication mechanisms (event channels and shared memory).
|
||||
|
||||
:Genode as virtualization layer for Qubes OS:
|
||||
|
||||
[https://www.qubes-os.org/ - Qubes OS] is a desktop operating system
|
||||
@@ -295,128 +236,46 @@ Virtualization
|
||||
KVM interface based on Genode's VFS plugin concept.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
System management and tools
|
||||
###########################
|
||||
|
||||
:Isochronous USB devices:
|
||||
:Virtual network-boot infrastructure as Sculpt component:
|
||||
|
||||
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.
|
||||
Network-based development work flows for PCs require a variety of tools and
|
||||
network-configuration peculiarities. Think of a development network with a
|
||||
custom configured DHCP server, a TFTP or HTTP server on the development
|
||||
machine, the provisioning of a PXE boot loader, tooling for obtaining serial
|
||||
output over AMT, or tooling for remote power control via AMT.
|
||||
|
||||
:Sound on the Raspberry Pi:
|
||||
The goal of this project would be the hosting of all those functions in a
|
||||
Sculpt OS component "devnet" that is exclusively in charge of a dedicated
|
||||
LAN port of the developer's Sculpt machine. By connecting a test machine to
|
||||
this LAN port, the test machine becomes immediately available as development
|
||||
target without any manual installation or configuration steps needed. The
|
||||
devnet component would interface with the rest of the Sculpt system as a
|
||||
client of a file-system session (containing the boot payloads) and a
|
||||
terminal session (for the virtual serial connection).
|
||||
|
||||
The goal of this project is a component that uses the Raspberry Pi's
|
||||
PWM device to implement Genode's audio-out-session interface. Since
|
||||
Genode's version of libSDL already supports this interface as audio
|
||||
backend, the new driver will make the sound of all SDL-based games
|
||||
available on the Raspberry Pi.
|
||||
:Statistical profiler using Sculpt's GDB monitor:
|
||||
|
||||
:Framebuffer for UEFI and Coreboot:
|
||||
Starting with version 24.04, Sculpt OS provides the ability to supervise
|
||||
selected components
|
||||
[https://genodians.org/chelmuth/2024-05-17-on-target-debugging - using the GDB protocol].
|
||||
The underlying mechanism and infrastructure could be leveraged for
|
||||
implementing a statistical profiler that monitors components live.
|
||||
Using the on-target information obtained via Sculpt's "download debug info"
|
||||
option, the tool could display a sorted list of the most executed
|
||||
functions, facilitating interactive on-target analysis and experimentation.
|
||||
|
||||
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].
|
||||
:Remote management of Sculpt OS via Puppet:
|
||||
|
||||
: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
|
||||
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.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
:Microkernelizing Linux:
|
||||
|
||||
Thanks to Genode's generic interfaces for I/O access as provided by core, all
|
||||
Genode device drivers including drivers ported from Linux and gPXE can be
|
||||
executed as user-level components on all supported microkernels. However, so
|
||||
far, we have not enabled the use of these device drivers on Linux as base
|
||||
platform. The goal of this project is the systematic replacement of in-kernel
|
||||
Linux device drivers by Genode processes running in user space, effectively
|
||||
reducing the Linux kernel to a runtime for Genode's core process. But moving
|
||||
drivers to Genode processes is just the beginning. By employing further
|
||||
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.
|
||||
|
||||
:Support for the HelenOS/SPARTAN kernel:
|
||||
|
||||
[http://www.helenos.org - HelenOS] is a microkernel-based multi-server OS
|
||||
developed at the university of Prague. It is based on the SPARTAN microkernel,
|
||||
which runs on a wide variety of CPU architectures including Sparc, MIPS, and
|
||||
PowerPC. This broad platform support makes SPARTAN an interesting kernel to
|
||||
look at alone. But a further motivation is the fact that SPARTAN does not
|
||||
follow the classical L4 road, providing a kernel API that comes with an own
|
||||
terminology and different kernel primitives. This makes the mapping of
|
||||
SPARTAN's kernel API to Genode a challenging endeavour and would provide us
|
||||
with feedback regarding the universality of Genode's internal interfaces.
|
||||
Finally, this project has the potential to ignite a further collaboration
|
||||
between the HelenOS and Genode communities.
|
||||
|
||||
:Support for the XNU kernel (Darwin):
|
||||
|
||||
XNU is the kernel used by Darwin and Mac OS X. It is derived from the
|
||||
MACH microkernel and extended with a UNIX-like syscall API. Because the
|
||||
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:
|
||||
|
||||
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...]
|
||||
|
||||
|
||||
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
|
||||
by the graphics card via an x86 emulator. To initialize a graphics mode, this
|
||||
code needs to access device hardware. Currently, we permit access to all
|
||||
device registers requested by the graphics-card's code. These devices include
|
||||
the system timer, the PCI configuration registers, and the interrupt
|
||||
controller, which are critical for the proper operating of the kernel. The
|
||||
goal of this work is to restrict the permissions of the VESA driver to a
|
||||
minimum by virtualizing all devices but the actual graphics card.
|
||||
[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.
|
||||
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
Coding style guidelines for Genode
|
||||
##################################
|
||||
|
||||
Things to avoid
|
||||
===============
|
||||
|
||||
Please avoid using pre-processor macros. C++ provides language
|
||||
features for almost any case, for which a C programmer uses
|
||||
macros.
|
||||
|
||||
:Defining constants:
|
||||
|
||||
Use 'enum' instead of '#define'
|
||||
! enum { MAX_COLORS = 3 };
|
||||
! enum {
|
||||
! COLOR_RED = 1,
|
||||
! COLOR_BLUE = 2,
|
||||
! COLOR_GREEN = 3
|
||||
! };
|
||||
|
||||
:Meta programming:
|
||||
|
||||
Use templates instead of pre-processor macros. In contrast to macros,
|
||||
templates are type-safe and fit well with the implementation syntax.
|
||||
|
||||
:Conditional-code inclusion:
|
||||
|
||||
Please avoid C-hacker style '#ifdef CONFIG_PLATFROM' - '#endif'
|
||||
constructs. Instead, factor-out the encapsulated code into a
|
||||
separate file and introduce a proper function interface.
|
||||
The build process should then be used to select the appropriate
|
||||
platform-specific files at compile time. Keep platform dependent
|
||||
code as small as possible. Never pollute existing generic code
|
||||
with platform-specific code.
|
||||
|
||||
|
||||
Header of each file
|
||||
===================
|
||||
|
||||
! /*
|
||||
! * \brief Short description of the file
|
||||
! * \author Original author
|
||||
! * \date Creation date
|
||||
! *
|
||||
! * Some more detailed description. This is optional.
|
||||
! */
|
||||
|
||||
|
||||
Identifiers
|
||||
===========
|
||||
|
||||
* The first character of class names are uppercase, any other characters are
|
||||
lowercase.
|
||||
* Function and variable names are lower case.
|
||||
* 'Multi_word_identifiers' use underline to separate words.
|
||||
* 'CONSTANTS' and template arguments are upper case.
|
||||
* Private and protected members of a class begin with an '_'-character.
|
||||
* Accessor methods are named after their corresponding attributes:
|
||||
|
||||
! /**
|
||||
! * Request private member variable
|
||||
! */
|
||||
! int value() const { return _value; }
|
||||
!
|
||||
! /**
|
||||
! * Set the private member variable
|
||||
! */
|
||||
! void value(int value) { _value = value; }
|
||||
|
||||
* Accessors that return a boolean value do not carry an 'is_' prefix. E.g.,
|
||||
a method for requesting the validity of an object should be named
|
||||
'valid()', not 'is_valid()'.
|
||||
|
||||
|
||||
Indentation
|
||||
===========
|
||||
|
||||
* Use one tab per indentation step. *Do not mix tabs and spaces!*
|
||||
* Use no tabs except at the beginning of a line.
|
||||
* Use spaces for the alignment of continuation lines such as function
|
||||
arguments that span multiple lines. The alignment spaces of such lines
|
||||
should start after the (tab-indented) indentation level. For example:
|
||||
! {
|
||||
! <tab>function_with_many_arguments(arg1,
|
||||
! <tab><--- spaces for aligment --->arg2,
|
||||
! ...
|
||||
! }
|
||||
* Remove trailing spaces at the end of lines
|
||||
|
||||
This way, each developer can set his preferred tab size in his editor
|
||||
and the source code always looks good.
|
||||
|
||||
_Hint:_ In VIM, use the 'set list' and 'set listchars' commands to make tabs
|
||||
and spaces visible.
|
||||
|
||||
|
||||
Switch statements
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Switch-statement blocks should be indented as follows:
|
||||
|
||||
! switch (color) {
|
||||
!
|
||||
! case BLUE:
|
||||
! <tab>break;
|
||||
!
|
||||
! case GREEN:
|
||||
! <tab>{
|
||||
! <tab><tab>int declaration_required;
|
||||
! <tab><tab>...
|
||||
! <tab>}
|
||||
!
|
||||
! default:
|
||||
! }
|
||||
|
||||
Please note that the case labels have the same indentation
|
||||
level as the switch statement. This avoids a two-level
|
||||
indentation-change at the end of the switch block that
|
||||
would occur otherwise.
|
||||
|
||||
|
||||
Vertical whitespaces
|
||||
====================
|
||||
|
||||
In header files:
|
||||
|
||||
* Leave two empty lines between classes.
|
||||
* Leave one empty line between member functions.
|
||||
|
||||
In implementation files:
|
||||
|
||||
* Leave two empty lines between functions.
|
||||
|
||||
|
||||
Braces
|
||||
======
|
||||
|
||||
* Braces after class, struct and function names are placed at a new line:
|
||||
! class Foo
|
||||
! {
|
||||
! public:
|
||||
!
|
||||
! void method(void)
|
||||
! {
|
||||
! ...
|
||||
! }
|
||||
! };
|
||||
|
||||
except for one-line functions.
|
||||
|
||||
* All other occurrences of open braces (for 'if', 'while', 'do', 'for',
|
||||
'namespace', 'enum' etc.) are at the end of a line:
|
||||
|
||||
! if (flag) {
|
||||
! ..
|
||||
! } else {
|
||||
! ..
|
||||
! }
|
||||
|
||||
* One-line functions should be written on a single line as long as the line
|
||||
length does not exceed approximately 80 characters.
|
||||
Typically, this applies for accessor functions.
|
||||
If slightly more space than one line is needed, indent as follows:
|
||||
|
||||
! int heavy_computation(int a, int lot, int of, int args) {
|
||||
! return a + lot + of + args; }
|
||||
|
||||
|
||||
Comments
|
||||
========
|
||||
|
||||
Function/method header
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each public or protected (but no private) method in a header-file should be
|
||||
prepended by a header as follows:
|
||||
|
||||
! /**
|
||||
! * Short description
|
||||
! *
|
||||
! * \param a meaning of parameter a
|
||||
! * \param b meaning of parameter b
|
||||
! * \param c,d meaning of parameters c and d
|
||||
! *
|
||||
! * \throw Exception_type meaning of the exception
|
||||
! *
|
||||
! * \return meaning of return value
|
||||
! *
|
||||
! * More detailed information about the function. This is optional.
|
||||
! */
|
||||
|
||||
Descriptions of parameters and return values should be lower-case and brief.
|
||||
More elaborative descriptions can be documented in the text area below.
|
||||
|
||||
In implementation files, only local and private functions should feature
|
||||
function headers.
|
||||
|
||||
|
||||
Single-line comments
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
! /* use this syntax for single line comments */
|
||||
|
||||
A single-line comment should be prepended by an empty line.
|
||||
Single-line comments should be short - no complete sentences. Use lower-case.
|
||||
|
||||
C++-style comments ('//') should only be used for temporarily commenting-out
|
||||
code. Such commented-out garbage is easy to 'grep' and there are handy
|
||||
'vim'-macros available for creating and removing such comments.
|
||||
|
||||
|
||||
Variable descriptions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Use the same syntax as for single-line comments. Insert two or more
|
||||
spaces before your comment starts.
|
||||
|
||||
! int size; /* in kilobytes */
|
||||
|
||||
|
||||
Multi-line comments
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Multi-line comments are more detailed descriptions in the form of
|
||||
sentences.
|
||||
A multi-line comment should be enclosed by empty lines.
|
||||
|
||||
! /*
|
||||
! * This is some tricky
|
||||
! * algorithm that works
|
||||
! * as follows:
|
||||
! * ...
|
||||
! */
|
||||
|
||||
The first and last line of a multi-line comment contain no words.
|
||||
|
||||
|
||||
Source-code blocks
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For structuring your source code, you can entitle the different
|
||||
parts of a file like this:
|
||||
|
||||
! <- two empty lines
|
||||
!
|
||||
! /********************
|
||||
! ** Event handlers **
|
||||
! ********************/
|
||||
! <- one empty line
|
||||
|
||||
Note the two stars at the left and right. There are two of them to
|
||||
make the visible width of the border match its height (typically,
|
||||
characters are ca. twice as high as wide).
|
||||
|
||||
A source-code block header represents a headline for the following
|
||||
code. To couple this headline with the following code closer than
|
||||
with previous code, leave two empty lines above and one empty line
|
||||
below the source-code block header.
|
||||
|
||||
|
||||
Order of public, protected, and private blocks
|
||||
==============================================
|
||||
|
||||
For consistency reasons, use the following class layout:
|
||||
|
||||
! class Sandstein
|
||||
! {
|
||||
! private:
|
||||
! ...
|
||||
! protected:
|
||||
! ...
|
||||
! public:
|
||||
! };
|
||||
|
||||
Typically, the private section contains member variables that are used
|
||||
by public accessor functions below. In this common case, we only reference
|
||||
symbols that are defined above as it is done when programming plain C.
|
||||
|
||||
Leave one empty line (or a line that contains only a brace) above and below
|
||||
a 'private', 'protected', or 'public' label. This also applies when the
|
||||
label is followed by a source-code block header.
|
||||
@@ -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,13 +31,14 @@ 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',
|
||||
'audio_out_session', 'log_session', 'nic_session', and 'timer_session'
|
||||
(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.
|
||||
'platform_session', 'capture_session', 'event_session', 'block_session',
|
||||
'record_session', 'play_session', 'log_session', 'uplink_session', and
|
||||
'timer_session' (see _os/include/_ for the interface definitions).
|
||||
Those interfaces are uniform across hardware platforms and kernel base
|
||||
platforms. Usually, each device driver accommodates one client at a
|
||||
time.
|
||||
|
||||
:Resource multiplexers: provide mechanisms to multiplex device resources
|
||||
to multiple clients. A typical resource multiplexer requests one
|
||||
@@ -59,27 +65,42 @@ 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/driver/_ subdirectory of source-code
|
||||
repositories. The most predominant repositories hosting device drivers are
|
||||
'os', 'dde_ipxe', 'dde_linux'.
|
||||
'os', 'dde_ipxe', 'dde_linux', 'pc'. The main source tree is accompanied
|
||||
by a variety of optional source-code repositories, each hosting the support of
|
||||
a different SoC family such as NXP's i.MX, Allwinner, Xilinx Zynq, or RISC-V.
|
||||
|
||||
:Repositories maintained by Genode Labs:
|
||||
|
||||
[https://github.com/orgs/genodelabs/repositories]
|
||||
|
||||
|
||||
Platform devices
|
||||
================
|
||||
|
||||
:'os/src/drivers/platform/': Platform drivers for various platforms.
|
||||
:_os/src/driver/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/driver/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/pci_decode/_:
|
||||
A component that reports the physical information about PCI devices after
|
||||
parsing and initializing the PCI bus. The reported information is usually
|
||||
consumed by the platform driver.
|
||||
|
||||
:_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 +114,68 @@ UART devices
|
||||
|
||||
The UART device drivers implement the UART-session interface.
|
||||
|
||||
:'os/src/drivers/uart/spec/pl011':
|
||||
:_os/src/driver/uart/spec/pbxa9/_:
|
||||
Driver for the PL011 UART as found on many ARM-based platforms.
|
||||
|
||||
:'os/src/drivers/uart/spec/i8250':
|
||||
:_os/src/driver/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/driver/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/driver/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/driver/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/driver/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/driver/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':
|
||||
Driver for LCD output on i.MX53 SoCs.
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/rpi':
|
||||
Driver for the HDMI output of the Raspberry Pi.
|
||||
|
||||
:'os/src/drivers/framebuffer/spec/sdl':
|
||||
:_os/src/driver/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/driver/framebuffer/virtio/_:
|
||||
Driver for the Virtio virtual graphics device as supported by Qemu.
|
||||
|
||||
:'dde_linux/src/drivers/framebuffer/intel':
|
||||
:_os/src/driver/gpu/intel/_:
|
||||
An Intel Graphics GPU multiplexer for Broadwell and newer.
|
||||
|
||||
:_pc/src/driver/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'.
|
||||
:_pc/src/driver/usb_host/_:
|
||||
USB host-controller driver that provides an USB session interface to
|
||||
USB drivers.
|
||||
|
||||
:_dde_linux/src/driver/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
|
||||
@@ -197,14 +195,14 @@ provided by the kernel, or a pseudo time source (busy):
|
||||
Audio drivers
|
||||
=============
|
||||
|
||||
Audio drivers implement the Audio_out session interface defined at
|
||||
'os/include/audio_out_session/' for playback and optionally the audio_in
|
||||
interface for recording.
|
||||
Audio drivers use the audio mixer's record session interface defined at
|
||||
_os/include/record_session/_ for audio output and optionally the play
|
||||
session interface _os/include/play_session/_ for audio input.
|
||||
|
||||
:'os/src/drivers/audio/spec/linux':
|
||||
:_os/src/driver/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/driver/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,121 +212,98 @@ 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/driver/sd_card/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':
|
||||
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':
|
||||
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/driver/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/driver/nvme/_:
|
||||
Driver for NVMe block devices on x86 PCs.
|
||||
|
||||
:_os/src/driver/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/driver/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/driver/nic/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/driver/nic/_:
|
||||
Device drivers ported from the iPXE project. Supported devices are Intel
|
||||
E1000 and pcnet32.
|
||||
|
||||
:'dde_linux/src/drivers/wifi':
|
||||
The wifi_drv component is a port of the Linux mac802.11 stack, including the
|
||||
:_pc/src/driver/nic/pc/_:
|
||||
The PC NIC-driver component uses network driver code of the Linux kernel
|
||||
to drive common network cards as found in commodity PC hardware.
|
||||
|
||||
:_pc/src/driver/wifi/_:
|
||||
The wifi driver 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/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':
|
||||
Driver for accessing the GPIO pins of i.MX53 platforms.
|
||||
|
||||
:'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.
|
||||
:_dde_linux/src/driver/usb_net/_:
|
||||
USB network driver using the USB session interface.
|
||||
|
||||
|
||||
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
|
||||
multiple clients to use the audio-out interface. The mixing is done by simply
|
||||
adding and clamping the signals of all present clients.
|
||||
:Audio output: The audio mixer located at _os/src/server/record_play_mixer/_
|
||||
allows for the routing and mixing of audio signals from play-session clients
|
||||
to record-session 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_block' 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).
|
||||
|
||||
The NIC-uplink component located at _os/src/server/nic_uplink/_ connects
|
||||
a NIC client directly to a network driver (as uplink client) without routing.
|
||||
|
||||
: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_block'.
|
||||
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.
|
||||
@@ -340,204 +315,209 @@ 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':
|
||||
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_block':
|
||||
Provides the content of a ROM file as a block session, similar to the
|
||||
loop-mount mechanism on Linux
|
||||
|
||||
:'os/src/server/ram_block':
|
||||
Provides the content of a RAM dataspace as a block session. In contrast
|
||||
to 'rom_block', 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':
|
||||
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 GUI session.
|
||||
|
||||
:'demo/src/server/nitlog':
|
||||
Provides a LOG session, printing log output on screen via a nitpicker
|
||||
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':
|
||||
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_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':
|
||||
:_dde_linux/src/app/wireguard/_:
|
||||
Port of the Linux implementation of the WireGuard VPN as Genode component.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
:_os/src/lib/vfs/tap/_:
|
||||
A VFS plugin that allows for packet-level access of a NIC or uplink session.
|
||||
|
||||
:_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.
|
||||
|
||||
:_os/src/lib/vfs/tap/_:
|
||||
A VFS plugin for the interaction with raw network packets.
|
||||
|
||||
:_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_fatfs':
|
||||
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/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/qt6/_:
|
||||
Qt6 application framework.
|
||||
|
||||
:'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':
|
||||
:_libports/lib/mk/libarchive.mk_:
|
||||
Library providing a common interface to a variety of archive
|
||||
formats.
|
||||
|
||||
:'libports/lib/mk/lz4.mk':
|
||||
:_libports/lib/mk/lz4.mk_:
|
||||
Library for processing LZ4 lossless compression archives.
|
||||
|
||||
:'libports/lib/mk/liblzma.mk':
|
||||
:_libports/lib/mk/liblzma.mk_:
|
||||
Library for processing LZMA archives.
|
||||
|
||||
:'libports/lib/mk/libgcrypt.mk':
|
||||
:_libports/lib/mk/libgcrypt.mk_:
|
||||
GnuPG library for OpenPGP processing, e.g., signature verification.
|
||||
|
||||
|
||||
@@ -545,103 +525,95 @@ 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.
|
||||
:_os/src/monitor/_:
|
||||
Variant of init that allows for the debugging of components via GDB over a
|
||||
remote connection.
|
||||
|
||||
:'ports/src/app/arora':
|
||||
Arora is a Qt-based web browser using the Webkit engine.
|
||||
|
||||
:'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/qt6/qt_launchpad/_:
|
||||
Graphical application starter implemented using Qt.
|
||||
|
||||
:'libports/src/app/qt5/examples/':
|
||||
:_libports/src/app/qt6/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':
|
||||
:_os/src/app/trace_logger/_:
|
||||
Convenient, runtime-configurable frontend to the tracing facility.
|
||||
|
||||
:'os/src/app/rom_reporter':
|
||||
:_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':
|
||||
:_os/src/app/log_core/_:
|
||||
Component transforming core and kernel output to Genode LOG output.
|
||||
|
||||
|
||||
Package-management components
|
||||
=============================
|
||||
|
||||
:'gems/src/app/depot_query':
|
||||
:_gems/src/app/depot_query/_:
|
||||
Tool for querying subsystem information from a depot.
|
||||
|
||||
:'gems/src/app/depot_download_manager':
|
||||
:_gems/src/app/depot_download_manager/_:
|
||||
Tool for managing the download of depot content.
|
||||
|
||||
:'gems/src/app/depot_deploy':
|
||||
:_gems/src/app/depot_deploy/_:
|
||||
Subsystem init configuration generator based on blueprints.
|
||||
|
||||
:'libports/src/app/fetchurl':
|
||||
:_gems/src/app/depot_remove/_:
|
||||
Tool for the orderly removal of depot content.
|
||||
|
||||
:_libports/src/app/fetchurl/_:
|
||||
A runtime-configurable frontend to the libcURL library for
|
||||
downloading content.
|
||||
|
||||
:'libports/src/app/extract':
|
||||
:_libports/src/app/extract/_:
|
||||
Tool for extracting archives using libarchive.
|
||||
|
||||
:'ports/src/app/verify':
|
||||
:_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
|
||||
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/virtualbox6/_: 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.
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ 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,
|
||||
|
||||
@@ -1,70 +1,333 @@
|
||||
|
||||
Conventions for the Genode development
|
||||
|
||||
|
||||
Norman Feske
|
||||
==================================================
|
||||
Conventions and coding-style guidelines for Genode
|
||||
==================================================
|
||||
|
||||
|
||||
Documentation
|
||||
#############
|
||||
|
||||
Documentation and naming of files
|
||||
#################################
|
||||
|
||||
We use the GOSH syntax [https://github.com/nfeske/gosh] for documentation and
|
||||
README files.
|
||||
|
||||
We encourage that each directory contains a file called 'README' that briefly
|
||||
explains what the directory is about.
|
||||
|
||||
README files
|
||||
############
|
||||
File names
|
||||
----------
|
||||
|
||||
Each directory should contain a file called 'README' that briefly explains
|
||||
what the directory is about. In 'doc/Makefile' is a rule for
|
||||
generating a directory overview from the 'README' files automatically.
|
||||
|
||||
You can structure your 'README' file by using the GOSH style for subsections:
|
||||
! Subsection
|
||||
! ~~~~~~~~~~
|
||||
Do not use chapters or sections in your 'README' files.
|
||||
|
||||
|
||||
Filenames
|
||||
#########
|
||||
|
||||
All normal filenames are lowercase. Filenames should be chosen to be
|
||||
expressive. Someone who explores your files for the first time might not
|
||||
All normal file names are lowercase. Filenames should be chosen to be
|
||||
expressive. Someone who explores your files for the first time might not
|
||||
understand what 'mbi.cc' means but 'multiboot_info.cc' would ring a bell. If a
|
||||
filename contains multiple words, use the '_' to separate them (instead of
|
||||
file name contains multiple words, use the '_' to separate them (instead of
|
||||
'miscmath.h', use 'misc_math.h').
|
||||
|
||||
|
||||
Coding style
|
||||
############
|
||||
|
||||
A common coding style helps a lot to ease collaboration. The official coding
|
||||
style of the Genode base components is described in 'doc/coding_style.txt'.
|
||||
If you consider working closely together with the Genode main developers,
|
||||
your adherence to this style is greatly appreciated.
|
||||
Things to avoid
|
||||
===============
|
||||
|
||||
Please avoid using pre-processor macros. C++ provides language
|
||||
features for almost any case, for which a C programmer uses
|
||||
macros.
|
||||
|
||||
:Defining constants:
|
||||
|
||||
Use 'enum' instead of '#define'
|
||||
! enum { MAX_COLORS = 3 };
|
||||
! enum {
|
||||
! COLOR_RED = 1,
|
||||
! COLOR_BLUE = 2,
|
||||
! COLOR_GREEN = 3
|
||||
! };
|
||||
|
||||
:Meta programming:
|
||||
|
||||
Use templates instead of pre-processor macros. In contrast to macros,
|
||||
templates are type-safe and fit well with the implementation syntax.
|
||||
|
||||
:Conditional-code inclusion:
|
||||
|
||||
Please avoid C-hacker style '#ifdef CONFIG_PLATFROM' - '#endif'
|
||||
constructs. Instead, factor-out the encapsulated code into a
|
||||
separate file and introduce a proper function interface.
|
||||
The build process should then be used to select the appropriate
|
||||
platform-specific files at compile time. Keep platform dependent
|
||||
code as small as possible. Never pollute existing generic code
|
||||
with platform-specific code.
|
||||
|
||||
|
||||
Include files and RPC interfaces
|
||||
################################
|
||||
Header of each file
|
||||
===================
|
||||
|
||||
Never place include files directly into the '<repository>/include/' directory
|
||||
but use a meaningful subdirectory that corresponds to the component that
|
||||
provides the interfaces.
|
||||
|
||||
Each RPC interface is represented by a separate include subdirectory. For
|
||||
an example, see 'base/include/ram_session/'. The header file that defines
|
||||
the RPC function interface has the same base name as the directory. The RPC
|
||||
stubs are called 'client.h' and 'server.h'. If your interface uses a custom
|
||||
capability type, it is defined in 'capability.h'. Furthermore, if your
|
||||
interface is a session interface of a service, it is good practice to
|
||||
provide a connection class in a 'connection.h' file for managing session-
|
||||
construction arguments and the creation and destruction of sessions.
|
||||
|
||||
Specialization-dependent include directories are placed in 'include/<specname>/'.
|
||||
! /*
|
||||
! * \brief Short description of the file
|
||||
! * \author Original author
|
||||
! * \date Creation date
|
||||
! *
|
||||
! * Some more detailed description. This is optional.
|
||||
! */
|
||||
|
||||
|
||||
Service Names
|
||||
#############
|
||||
Identifiers
|
||||
===========
|
||||
|
||||
* The first character of class names are uppercase, any other characters are
|
||||
lowercase.
|
||||
* Function and variable names are lower case.
|
||||
* 'Multi_word_identifiers' use underline to separate words.
|
||||
* 'CONSTANTS' and template arguments are upper case.
|
||||
* Private and protected members of a class begin with an '_'-character.
|
||||
* Accessor methods are named after their corresponding attributes:
|
||||
|
||||
! /**
|
||||
! * Request private member variable
|
||||
! */
|
||||
! int value() const { return _value; }
|
||||
!
|
||||
! /**
|
||||
! * Set the private member variable
|
||||
! */
|
||||
! void value(int value) { _value = value; }
|
||||
|
||||
* Accessors that return a boolean value do not carry an 'is_' prefix. E.g.,
|
||||
a method for requesting the validity of an object should be named
|
||||
'valid()', not 'is_valid()'.
|
||||
|
||||
|
||||
Indentation
|
||||
===========
|
||||
|
||||
* Use one tab per indentation step. *Do not mix tabs and spaces!*
|
||||
* Use no tabs except at the beginning of a line.
|
||||
* Use spaces for the alignment of continuation lines such as function
|
||||
arguments that span multiple lines. The alignment spaces of such lines
|
||||
should start after the (tab-indented) indentation level. For example:
|
||||
! {
|
||||
! <tab>function_with_many_arguments(arg1,
|
||||
! <tab><--- spaces for aligment --->arg2,
|
||||
! ...
|
||||
! }
|
||||
* Remove trailing spaces at the end of lines
|
||||
|
||||
This way, each developer can set his preferred tab size in his editor
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Switch-statement blocks should be indented as follows:
|
||||
|
||||
! switch (color) {
|
||||
!
|
||||
! case BLUE:
|
||||
! <tab>break;
|
||||
!
|
||||
! case GREEN:
|
||||
! <tab>{
|
||||
! <tab><tab>int declaration_required;
|
||||
! <tab><tab>...
|
||||
! <tab>}
|
||||
!
|
||||
! default:
|
||||
! }
|
||||
|
||||
Please note that the case labels have the same indentation
|
||||
level as the switch statement. This avoids a two-level
|
||||
indentation-change at the end of the switch block that
|
||||
would occur otherwise.
|
||||
|
||||
|
||||
Vertical whitespaces
|
||||
====================
|
||||
|
||||
In header files:
|
||||
|
||||
* Leave two empty lines between classes.
|
||||
* Leave one empty line between member functions.
|
||||
|
||||
In implementation files:
|
||||
|
||||
* Leave two empty lines between functions.
|
||||
|
||||
|
||||
Braces
|
||||
======
|
||||
|
||||
* Braces after class, struct and function names are placed at a new line:
|
||||
! class Foo
|
||||
! {
|
||||
! public:
|
||||
!
|
||||
! void method(void)
|
||||
! {
|
||||
! ...
|
||||
! }
|
||||
! };
|
||||
|
||||
except for one-line functions.
|
||||
|
||||
* All other occurrences of open braces (for 'if', 'while', 'do', 'for',
|
||||
'namespace', 'enum' etc.) are at the end of a line:
|
||||
|
||||
! if (flag) {
|
||||
! ..
|
||||
! } else {
|
||||
! ..
|
||||
! }
|
||||
|
||||
* One-line functions should be written on a single line as long as the line
|
||||
length does not exceed approximately 80 characters.
|
||||
Typically, this applies for accessor functions.
|
||||
If slightly more space than one line is needed, indent as follows:
|
||||
|
||||
! int heavy_computation(int a, int lot, int of, int args) {
|
||||
! return a + lot + of + args; }
|
||||
|
||||
|
||||
Comments
|
||||
========
|
||||
|
||||
Function/method header
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Each public or protected (but no private) method in a header-file should be
|
||||
prepended by a header as follows:
|
||||
|
||||
! /**
|
||||
! * Short description
|
||||
! *
|
||||
! * \param a meaning of parameter a
|
||||
! * \param b meaning of parameter b
|
||||
! * \param c,d meaning of parameters c and d
|
||||
! *
|
||||
! * \throw Exception_type meaning of the exception
|
||||
! *
|
||||
! * \return meaning of return value
|
||||
! *
|
||||
! * More detailed information about the function. This is optional.
|
||||
! */
|
||||
|
||||
Descriptions of parameters and return values should be lower-case and brief.
|
||||
More elaborative descriptions can be documented in the text area below.
|
||||
|
||||
In implementation files, only local and private functions should feature
|
||||
function headers.
|
||||
|
||||
|
||||
Single-line comments
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
! /* use this syntax for single line comments */
|
||||
|
||||
A single-line comment should be prepended by an empty line.
|
||||
Single-line comments should be short - no complete sentences. Use lower-case.
|
||||
|
||||
C++-style comments ('//') should only be used for temporarily commenting-out
|
||||
code. Such commented-out garbage is easy to 'grep' and there are handy
|
||||
'vim'-macros available for creating and removing such comments.
|
||||
|
||||
|
||||
Variable descriptions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Use the same syntax as for single-line comments. Insert two or more
|
||||
spaces before your comment starts.
|
||||
|
||||
! int size; /* in kilobytes */
|
||||
|
||||
|
||||
Multi-line comments
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Multi-line comments are more detailed descriptions in the form of
|
||||
sentences.
|
||||
A multi-line comment should be enclosed by empty lines.
|
||||
|
||||
! /*
|
||||
! * This is some tricky
|
||||
! * algorithm that works
|
||||
! * as follows:
|
||||
! * ...
|
||||
! */
|
||||
|
||||
The first and last line of a multi-line comment contain no words.
|
||||
|
||||
|
||||
Source-code blocks
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For structuring your source code, you can entitle the different
|
||||
parts of a file like this:
|
||||
|
||||
! <- two empty lines
|
||||
!
|
||||
! /********************
|
||||
! ** Event handlers **
|
||||
! ********************/
|
||||
! <- one empty line
|
||||
|
||||
Note the two stars at the left and right. There are two of them to
|
||||
make the visible width of the border match its height (typically,
|
||||
characters are ca. twice as high as wide).
|
||||
|
||||
A source-code block header represents a headline for the following
|
||||
code. To couple this headline with the following code closer than
|
||||
with previous code, leave two empty lines above and one empty line
|
||||
below the source-code block header.
|
||||
|
||||
|
||||
Order of public, protected, and private blocks
|
||||
==============================================
|
||||
|
||||
For consistency reasons, use the following class layout:
|
||||
|
||||
! class Sandstein
|
||||
! {
|
||||
! private:
|
||||
! ...
|
||||
! protected:
|
||||
! ...
|
||||
! public:
|
||||
! };
|
||||
|
||||
Typically, the private section contains member variables that are used
|
||||
by public accessor functions below. In this common case, we only reference
|
||||
symbols that are defined above as it is done when programming plain C.
|
||||
|
||||
Leave one empty line (or a line that contains only a brace) above and below
|
||||
a 'private', 'protected', or 'public' label. This also applies when the
|
||||
label is followed by a source-code block header.
|
||||
|
||||
|
||||
Naming of Genode services
|
||||
=========================
|
||||
|
||||
Service names as announced via the 'parent()->announce()' function follow
|
||||
the following convention:
|
||||
|
||||
514
doc/depot.txt
514
doc/depot.txt
@@ -1,514 +0,0 @@
|
||||
|
||||
|
||||
============================
|
||||
Package management on Genode
|
||||
============================
|
||||
|
||||
|
||||
Norman Feske
|
||||
|
||||
|
||||
|
||||
Motivation and inspiration
|
||||
##########################
|
||||
|
||||
The established system-integration work flow with Genode is based on
|
||||
the 'run' tool, which automates the building, configuration, integration,
|
||||
and testing of Genode-based systems. Whereas the run tool succeeds in
|
||||
overcoming the challenges that come with Genode's diversity of kernels and
|
||||
supported hardware platforms, its scalability is somewhat limited to
|
||||
appliance-like system scenarios: The result of the integration process is
|
||||
a system image with a certain feature set. Whenever requirements change,
|
||||
the system image is replaced with a new created image that takes those
|
||||
requirements into account. In practice, there are two limitations of this
|
||||
system-integration approach:
|
||||
|
||||
First, since the run tool implicitly builds all components required for a
|
||||
system scenario, the system integrator has to compile all components from
|
||||
source. E.g., if a system includes a component based on Qt5, one needs to
|
||||
compile the entire Qt5 application framework, which induces significant
|
||||
overhead to the actual system-integration tasks of composing and configuring
|
||||
components.
|
||||
|
||||
Second, general-purpose systems tend to become too complex and diverse to be
|
||||
treated as system images. When looking at commodity OSes, each installation
|
||||
differs with respect to the installed set of applications, user preferences,
|
||||
used device drivers and system preferences. A system based on the run tool's
|
||||
work flow would require the user to customize the run script of the system for
|
||||
each tweak. To stay up to date, the user would need to re-create the
|
||||
system image from time to time while manually maintaining any customizations.
|
||||
In practice, this is a burden, very few end users are willing to endure.
|
||||
|
||||
The primary goal of Genode's package management is to overcome these
|
||||
scalability limitations, in particular:
|
||||
|
||||
* Alleviating the need to build everything that goes into system scenarios
|
||||
from scratch,
|
||||
* Facilitating modular system compositions while abstracting from technical
|
||||
details,
|
||||
* On-target system update and system development,
|
||||
* Assuring the user that system updates are safe to apply by providing the
|
||||
ability to easily roll back the system or parts thereof to previous versions,
|
||||
* Securing the integrity of the deployed software,
|
||||
* Fostering a federalistic evolution of Genode systems,
|
||||
* Low friction for existing developers.
|
||||
|
||||
The design of Genode's package-management concept is largely influenced by Git
|
||||
as well as the [https://nixos.org/nix/ - Nix] package manager. In particular
|
||||
the latter opened our eyes to discover the potential that lies beyond the
|
||||
package management employed in state-of-the art commodity systems. Even though
|
||||
we considered adapting Nix for Genode and actually conducted intensive
|
||||
experiments in this direction (thanks to Emery Hemingway who pushed forward
|
||||
this line of work), we settled on a custom solution that leverages Genode's
|
||||
holistic view on all levels of the operating system including the build system
|
||||
and tooling, source structure, ABI design, framework API, system
|
||||
configuration, inter-component interaction, and the components itself. Whereby
|
||||
Nix is designed for being used on top of Linux, Genode's whole-systems view
|
||||
led us to simplifications that eliminated the needs for Nix' powerful features
|
||||
like its custom description language.
|
||||
|
||||
|
||||
Nomenclature
|
||||
############
|
||||
|
||||
When speaking about "package management", one has to clarify what a "package"
|
||||
in the context of an operating system represents. Traditionally, a package
|
||||
is the unit of delivery of a bunch of "dumb" files, usually wrapped up in
|
||||
a compressed archive. A package may depend on the presence of other
|
||||
packages. Thereby, a dependency graph is formed. To express how packages fit
|
||||
with each other, a package is usually accompanied with meta data
|
||||
(description). Depending on the package manager, package descriptions follow
|
||||
certain formalisms (e.g., package-description language) and express
|
||||
more-or-less complex concepts such as versioning schemes or the distinction
|
||||
between hard and soft dependencies.
|
||||
|
||||
Genode's package management does not follow this notion of a "package".
|
||||
Instead of subsuming all deliverable content under one term, we distinguish
|
||||
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 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'.
|
||||
|
||||
|
||||
Raw-data archives
|
||||
=================
|
||||
|
||||
A raw-data archive contains arbitrary data that is - in contrast to executable
|
||||
binaries - independent from the processor architecture. Examples are
|
||||
configuration data, game assets, images, or fonts. The content of raw-data
|
||||
archives is expected to be consumed by components at runtime. It is not
|
||||
relevant for the build process for executable binaries. Each raw-data
|
||||
archive contains merely a collection of data files. There is no meta data.
|
||||
|
||||
|
||||
API archive
|
||||
===========
|
||||
|
||||
An API archive has the structure of a Genode source-code repository. It may
|
||||
contain all the typical content of such a source-code repository such as header
|
||||
files (in the _include/_ subdirectory), source codes (in the _src/_
|
||||
subdirectory), library-description files (in the _lib/mk/_ subdirectory), or
|
||||
ABI symbols (_lib/symbols/_ subdirectory). At the top level, a LICENSE file is
|
||||
expected that clarifies the license of the contained source code. There is no
|
||||
meta data contained in an API archive.
|
||||
|
||||
An API archive is meant to provide _ingredients_ for building components. The
|
||||
canonical example is the public programming interface of a library (header
|
||||
files) and the library's binary interface in the form of an ABI-symbols file.
|
||||
One API archive may contain the interfaces of multiple libraries. For example,
|
||||
the interfaces of libc and libm may be contained in a single "libc" API
|
||||
archive because they are closely related to each other. Conversely, an API
|
||||
archive may contain a single header file only. The granularity of those
|
||||
archives may vary. But they have in common that they are used at build time
|
||||
only, not at runtime.
|
||||
|
||||
|
||||
Source archive
|
||||
==============
|
||||
|
||||
Like an API archive, a source archive has the structure of a Genode
|
||||
source-tree repository and is expected to contain all the typical content of
|
||||
such a source repository along with a LICENSE file. But unlike an API archive,
|
||||
it contains descriptions of actual build targets in the form of Genode's usual
|
||||
'target.mk' files.
|
||||
|
||||
In addition to the source code, a source archive contains a file
|
||||
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
|
||||
|
||||
The 'used_apis' file declares the APIs needed to incorporate into the build
|
||||
process when building the source archive. Hence, they represent _build-time_
|
||||
_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'
|
||||
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
|
||||
implemented by this version of the libc source package (note the differing
|
||||
versions of the API and source archives)
|
||||
|
||||
|
||||
Binary archive
|
||||
==============
|
||||
|
||||
A binary archive contains the build result of the equally-named source archive
|
||||
when built for a particular architecture. That is, all files that would appear
|
||||
at the _<build-dir>/bin/_ subdirectory when building all targets present in
|
||||
the source archive. There is no meta data present in a binary archive.
|
||||
|
||||
A binary archive is created out of the content of its corresponding source
|
||||
archive and all API archives listed in the source archive's 'used_apis' file.
|
||||
Note that since a binary archive depends on only one source archive, which
|
||||
has no further dependencies, all binary archives can be built independently
|
||||
from each other.
|
||||
For example, a libc-using application needs the source code of the
|
||||
application as well as the libc's API archive (the libc's header file and
|
||||
ABI) but it does not need the actual libc library to be present.
|
||||
|
||||
|
||||
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/2018-02-26' looks as follows:
|
||||
|
||||
! 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
|
||||
("genodelabs"), the archive type, followed by the versioned name of the
|
||||
archive.
|
||||
|
||||
An 'archives' file may specify raw archives, source archives, or package
|
||||
archives (as type 'pkg'). It thereby allows the expression of _runtime
|
||||
dependencies_. If a package archive lists another package archive, it inherits
|
||||
the content of the listed archive. This way, a new package archive may easily
|
||||
customize an existing package archive.
|
||||
|
||||
A package archive does not specify binary archives directly as they differ
|
||||
between the architecture and are already referenced by the source archives.
|
||||
|
||||
In addition to an 'archives' file, a package archive is expected to contain
|
||||
a 'README' file explaining the purpose of the collection.
|
||||
|
||||
|
||||
Depot structure
|
||||
###############
|
||||
|
||||
Archives are stored within a directory tree called _depot/_. The depot
|
||||
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>/
|
||||
|
||||
The <user> stands for the origin of the contained archives. For example, the
|
||||
official archives provided by Genode Labs reside in a _genodelabs/_
|
||||
subdirectory. Within this directory, there is a 'pubkey' file with the
|
||||
user's public key that is used to verify the integrity of archives downloaded
|
||||
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
|
||||
"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
|
||||
may incorporate archives of different origins, which fosters the goal of a
|
||||
federalistic development, where contributions of different origins can be
|
||||
easily combined.
|
||||
|
||||
The actual archives are stored in the subdirectories named after the archive
|
||||
types ('raw', 'api', 'src', 'bin', 'pkg'). Archives contained in the _bin/_
|
||||
subdirectories are further subdivided in the various architectures (like
|
||||
'x86_64', or 'arm_v7').
|
||||
|
||||
|
||||
Depot management
|
||||
################
|
||||
|
||||
The tools for managing the depot content reside under the _tool/depot/_
|
||||
directory. When invoked without arguments, each tool prints a brief
|
||||
description of the tool and its arguments.
|
||||
|
||||
Unless stated otherwise, the tools are able to consume any number of archives
|
||||
as arguments. By default, they perform their work sequentially. This can be
|
||||
changed by the '-j<N>' argument, where <N> denotes the desired level of
|
||||
parallelization. For example, by specifying '-j4' to the _tool/depot/build_
|
||||
tool, four concurrent jobs are executed during the creation of binary archives.
|
||||
|
||||
|
||||
Downloading archives
|
||||
====================
|
||||
|
||||
The depot can be populated with archives in two ways, either by creating
|
||||
the content from locally available source codes as explained by Section
|
||||
[Automated extraction of archives from the source tree], or by downloading
|
||||
ready-to-use archives from a web server.
|
||||
|
||||
In order to download archives originating from a specific user, the depot's
|
||||
corresponding user subdirectory must contain two files:
|
||||
|
||||
:_pubkey_: contains the public key of the GPG key pair used by the creator
|
||||
(aka "user") of the to-be-downloaded archives for signing the archives. The
|
||||
file contains the ASCII-armored version of the public key.
|
||||
|
||||
:_download_: contains the base URL of the web server where to fetch archives
|
||||
from. The web server is expected to mirror the structure of the depot.
|
||||
That is, the base URL is followed by a sub directory for the user,
|
||||
which contains the archive-type-specific subdirectories.
|
||||
|
||||
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/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
|
||||
archive is downloaded as well. All archive types are accepted as arguments
|
||||
including binary and package archives. Furthermore, it is possible to download
|
||||
all binary archives referenced by a package archive. For example, the
|
||||
following command downloads the window-manager (wm) package archive including
|
||||
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_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
|
||||
the form of a _public/_ directory located in the root of Genode's source tree.
|
||||
As its name suggests, the _public/_ directory contains data that is imported
|
||||
from or to-be exported to the public. The download tool populates it with the
|
||||
downloaded archives in their compressed form accompanied with their
|
||||
signatures.
|
||||
|
||||
The compressed archives are not extracted before their signature is checked
|
||||
against the public key defined at _depot/<user>/pubkey_. If however the
|
||||
signature is valid, the archive content is imported to the target destination
|
||||
within the depot. This procedure ensures that depot content - whenever
|
||||
downloaded - is blessed by a cryptographic signature of its creator.
|
||||
|
||||
|
||||
Building binary archives from source archives
|
||||
=============================================
|
||||
|
||||
With the depot populated with source and API archives, one can use the
|
||||
_tool/depot/build_ tool to produce binary archives. The arguments have the
|
||||
form '<user>/bin/<arch>/<src-name>' where '<arch>' stands for the targeted
|
||||
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/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.
|
||||
Only the final result of the built process is preserved. In the example above,
|
||||
that would be the _zlib.lib.so_ library.
|
||||
|
||||
For debugging purposes, it might be interesting to inspect the intermediate
|
||||
state of the build. This is possible by adding 'KEEP_BUILD_DIR=1' as argument
|
||||
to the build command. The binary's intermediate build directory can be
|
||||
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 'REBUILD=1' argument.
|
||||
|
||||
|
||||
Publishing archives
|
||||
===================
|
||||
|
||||
Archives located in the depot can be conveniently made available to the public
|
||||
using the _tool/depot/publish_ tool. Given an archive path, the tool takes
|
||||
care of determining all archives that are implicitly needed by the specified
|
||||
one, wrapping the archive's content into compressed tar archives, and signing
|
||||
those.
|
||||
|
||||
As a precondition, the tool requires you to possess the private key that
|
||||
matches the _depot/<you>/pubkey_ file within your depot. The key pair should
|
||||
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/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 /.../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.
|
||||
The content of the _public/_ directory is now ready to be copied to a
|
||||
web server, e.g., by using rsync.
|
||||
|
||||
|
||||
Automated extraction of archives from the source tree
|
||||
#####################################################
|
||||
|
||||
Genode users are expected to populate their local depot with content obtained
|
||||
via the _tool/depot/download_ tool. However, Genode developers need a way to
|
||||
create depot archives locally in order to make them available to users. Thanks
|
||||
to the _tool/depot/extract_ tool, the assembly of archives does not need to be
|
||||
a manual process. Instead, archives can be conveniently generated out of the
|
||||
source codes present in the Genode source tree and the _contrib/_ directory.
|
||||
|
||||
However, the granularity of splitting source code into archives, the
|
||||
definition of what a particular API entails, and the relationship between
|
||||
archives must be augmented by the archive creator as this kind of information
|
||||
is not present in the source tree as is. This is where so-called "archive
|
||||
recipes" enter the picture. An archive recipe defines the content of an
|
||||
archive. Such recipes can be located at an _recipes/_ subdirectory of any
|
||||
source-code repository, similar to how port descriptions and run scripts
|
||||
are organized. Each _recipe/_ directory contains subdirectories for the
|
||||
archive types, which, in turn, contain a directory for each archive. The
|
||||
latter is called a _recipe directory_.
|
||||
|
||||
Recipe directory
|
||||
----------------
|
||||
|
||||
The recipe directory is named after the archive _omitting the archive version_
|
||||
and contains at least one file named _hash_. This file defines the version
|
||||
of the archive along with a hash value of the archive's content
|
||||
separated by a space character. By tying the version name to a particular hash
|
||||
value, the _extract_ tool is able to detect the appropriate points in time
|
||||
whenever the version should be increased due to a change of the archive's
|
||||
content.
|
||||
|
||||
API, source, and raw-data archive recipes
|
||||
-----------------------------------------
|
||||
|
||||
Recipe directories for API, source, or raw-data archives contain a
|
||||
_content.mk_ file that defines the archive content in the form of make
|
||||
rules. The content.mk file is executed from the archive's location within
|
||||
the depot. Hence, the contained rules can refer to archive-relative files as targets.
|
||||
The first (default) rule of the content.mk file is executed with a customized
|
||||
make environment:
|
||||
|
||||
:GENODE_DIR: A variable that holds the path to root of the Genode source tree,
|
||||
:REP_DIR: A variable with the path to source code repository where the recipe
|
||||
is located
|
||||
:port_dir: A make function that returns the directory of a port within the
|
||||
_contrib/_ directory. The function expects the location of the
|
||||
corresponding port file as argument, for example, the 'zlib' recipe
|
||||
residing in the _libports/_ repository may specify '$(REP_DIR)/ports/zlib'
|
||||
to access the 3rd-party zlib source code.
|
||||
|
||||
Source archive recipes contain simplified versions of the 'used_apis' and
|
||||
(for libraries) 'api' files as found in the archives. In contrast to the
|
||||
depot's counterparts of these files, which contain version-suffixed names,
|
||||
the files contained in recipe directories omit the version suffix. This
|
||||
is possible because the extract tool always extracts the _current_ version
|
||||
of a given archive from the source tree. This current version is already
|
||||
defined in the corresponding recipe directory.
|
||||
|
||||
Package-archive recipes
|
||||
-----------------------
|
||||
|
||||
The recipe directory for a package archive contains the verbatim content of
|
||||
the to-be-created package archive except for the _archives_ file. All other
|
||||
files are copied verbatim to the archive. The content of the recipe's
|
||||
_archives_ file may omit the version information from the listed ingredients.
|
||||
Furthermore, the user part of each entry can be left blank by using '_' as a
|
||||
wildcard. When generating the package archive from the recipe, the extract
|
||||
tool will replace this wildcard with the user that creates the archive.
|
||||
|
||||
|
||||
Convenience front-end to the extract, build tools
|
||||
#################################################
|
||||
|
||||
For developers, the work flow of interacting with the depot is most often the
|
||||
combination of the _extract_ and _build_ tools whereas the latter expects
|
||||
concrete version names as arguments. The _create_ tool accelerates this common
|
||||
usage pattern by allowing the user to omit the version names. Operations
|
||||
implicitly refer to the _current_ version of the archives as defined in
|
||||
the recipes.
|
||||
|
||||
Furthermore, the _create_ tool is able to manage version updates for the
|
||||
developer. If invoked with the argument 'UPDATE_VERSIONS=1', it automatically
|
||||
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
|
||||
########################################
|
||||
|
||||
The depot tools are not meant to replace the run tool but rather to complement
|
||||
it. When both tools are combined, the run tool implicitly refers to "current"
|
||||
archive versions as defined for the archive's corresponding recipes. This way,
|
||||
the regular run-tool work flow can be maintained while attaining a
|
||||
productivity boost by fetching content from the depot instead of building it.
|
||||
|
||||
Run scripts can use the 'import_from_depot' function to incorporate archive
|
||||
content from the depot into a scenario. The function must be called after the
|
||||
'create_boot_directory' function and takes any number of pkg, src, or raw
|
||||
archives as arguments. An archive is specified as depot-relative path of the
|
||||
form '<user>/<type>/name'. Run scripts may call 'import_from_depot'
|
||||
repeatedly. Each argument can refer to a specific version of an archive or
|
||||
just the version-less archive name. In the latter case, the current version
|
||||
(as defined by a corresponding archive recipe in the source tree) is used.
|
||||
|
||||
If a 'src' archive is specified, the run tool integrates the content of
|
||||
the corresponding binary archive into the scenario. The binary archives
|
||||
are selected according the spec values as defined for the build directory.
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
|
||||
=============================
|
||||
How to start exploring Genode
|
||||
=============================
|
||||
|
||||
Norman Feske
|
||||
|
||||
|
||||
Abstract
|
||||
########
|
||||
|
||||
This guide is meant to provide you a painless start with using the Genode OS
|
||||
Framework. It explains the steps needed to get a simple demo system running
|
||||
on Linux first, followed by the instructions on how to run the same scenario
|
||||
on a microkernel.
|
||||
|
||||
|
||||
Quick start to build Genode for Linux
|
||||
#####################################
|
||||
|
||||
The best starting point for exploring Genode is to run it on Linux. Make sure
|
||||
that your system satisfies the following requirements:
|
||||
|
||||
* GNU Make version 3.81 or newer
|
||||
* 'libSDL-dev'
|
||||
* 'tclsh' and 'expect'
|
||||
* 'byacc' (only needed for the L4/Fiasco kernel)
|
||||
* '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',
|
||||
'flex', 'g++', 'git', 'gperf', 'libxml2-utils', 'subversion', and 'xsltproc'.
|
||||
|
||||
Your exploration of Genode starts with obtaining the source code of the
|
||||
[https://sourceforge.net/projects/genode/files/latest/download - latest version]
|
||||
of the framework. For detailed instructions and alternatives to the
|
||||
download from Sourceforge please refer to [https://genode.org/download].
|
||||
Furthermore, you will need to install the official Genode tool chain, which
|
||||
you can download at [https://genode.org/download/tool-chain].
|
||||
|
||||
The Genode build system never touches the source tree but generates object
|
||||
files, libraries, and programs in a dedicated build directory. We do not have a
|
||||
build directory yet. For a quick start, let us create one for the Linux base
|
||||
platform:
|
||||
|
||||
! cd <genode-dir>
|
||||
! ./tool/create_builddir x86_64
|
||||
|
||||
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.
|
||||
|
||||
To give Genode a try, build and execute a simple demo scenario via:
|
||||
|
||||
! cd build/x86_64
|
||||
! make KERNEL=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. 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' variable. 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
|
||||
================================
|
||||
|
||||
Running Genode on Linux is the most convenient way to get acquainted with the
|
||||
framework. However, the point where Genode starts to shine is when used as the
|
||||
user land executed on a microkernel. The framework supports a variety of
|
||||
different kernels such as L4/Fiasco, L4ka::Pistachio, OKL4, and NOVA. Those
|
||||
kernels largely differ in terms of feature sets, build systems, tools, and boot
|
||||
concepts. To relieve you from dealing with those peculiarities, Genode provides
|
||||
you with an unified way of using them. For each kernel platform, there exists
|
||||
a dedicated description file that enables the 'prepare_port' tool to fetch and
|
||||
prepare the designated 3rd-party sources. Just issue the following command
|
||||
within the toplevel directory of the Genode source tree:
|
||||
|
||||
! ./tool/ports/prepare_port <platform>
|
||||
|
||||
Note that each 'base-<platform>' directory comes with a 'README' file, which
|
||||
you should revisit first when exploring the base platform. Additionally, most
|
||||
'base-<platform>' directories provide more in-depth information within their
|
||||
respective 'doc/' subdirectories.
|
||||
|
||||
For the VESA driver on x86, the x86emu library is required and can be
|
||||
downloaded and prepared by again invoking the 3rd-party sources preparation
|
||||
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 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:
|
||||
|
||||
# Download the kernel:
|
||||
! cd <genode-dir>
|
||||
! ./tool/ports/prepare_port okl4
|
||||
# Create a build directory
|
||||
! ./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/x86_32 KERNEL=okl4 run/demo
|
||||
|
||||
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
|
||||
####################################
|
||||
|
||||
Now that you have taken the first steps into using Genode, you may seek to
|
||||
get more in-depth knowledge and practical experience. The foundation for doing
|
||||
so is a basic understanding of the build system. The documentation at
|
||||
'build_system.txt' provides you with the information about the layout of the
|
||||
source tree, how new components are integrated, and how complete system
|
||||
scenarios can be expressed. Equipped with this knowledge, it is time to get
|
||||
hands-on experience with creating custom Genode components. A good start is the
|
||||
'hello_tutorial', which shows you how to implement a simple client-server
|
||||
scenario. To compose complex scenarios out of many small components, the
|
||||
documentation of the Genode's configuration concept at 'os/doc/init.txt' is an
|
||||
essential reference.
|
||||
|
||||
Certainly, you will have further questions on your way with exploring Genode.
|
||||
The best place to get these questions answered is the Genode mailing list.
|
||||
Please feel welcome to ask your questions and to join the discussions:
|
||||
|
||||
:Genode Mailing Lists:
|
||||
|
||||
[https://genode.org/community/mailing-lists]
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
|
||||
|
||||
==========================
|
||||
Google Summer of Code 2012
|
||||
==========================
|
||||
|
||||
|
||||
Genode Labs has applied as mentoring organization for the Google Summer of Code
|
||||
program in 2012. This document summarizes all information important to Genode's
|
||||
participation in the program.
|
||||
|
||||
:[http://www.google-melange.com/gsoc/homepage/google/gsoc2012]:
|
||||
Visit the official homepage of the Google Summer of Code program.
|
||||
|
||||
*Update* Genode Labs was not accepted as mentoring organization for GSoC 2012.
|
||||
|
||||
|
||||
Application of Genode Labs as mentoring organization
|
||||
####################################################
|
||||
|
||||
:Organization ID: genodelabs
|
||||
|
||||
:Organization name: Genode Labs
|
||||
|
||||
:Organization description:
|
||||
|
||||
Genode Labs is a self-funded company founded by the original creators of the
|
||||
Genode OS project. Its primary mission is to bring the Genode operating-system
|
||||
technology, which started off as an academic research project, to the real
|
||||
world. At present, Genode Labs is the driving force behind the Genode OS
|
||||
project.
|
||||
|
||||
:Organization home page url:
|
||||
|
||||
http://www.genode-labs.com
|
||||
|
||||
:Main organization license:
|
||||
|
||||
GNU General Public License version 2
|
||||
|
||||
:Admins:
|
||||
|
||||
nfeske, chelmuth
|
||||
|
||||
:What is the URL for your Ideas page?:
|
||||
|
||||
[http://genode.org/community/gsoc_2012]
|
||||
|
||||
:What is the main IRC channel for your organization?:
|
||||
|
||||
#genode
|
||||
|
||||
:What is the main development mailing list for your organization?:
|
||||
|
||||
genode-main@lists.sourceforge.net
|
||||
|
||||
:Why is your organization applying to participate? What do you hope to gain?:
|
||||
|
||||
During the past three months, our project underwent the transition from a
|
||||
formerly company-internal development to a completely open and transparent
|
||||
endeavour. By inviting a broad community for participation in shaping the
|
||||
project, we hope to advance Genode to become a broadly used and recognised
|
||||
technology. GSoC would help us to build our community.
|
||||
|
||||
The project has its roots at the University of Technology Dresden where the
|
||||
Genode founders were former members of the academic research staff. We have
|
||||
a long and successful track record with regard to supervising students. GSoC
|
||||
would provide us with the opportunity to establish and cultivate
|
||||
relationships to new students and to spawn excitement about Genode OS
|
||||
technology.
|
||||
|
||||
:Does your organization have an application templateo?:
|
||||
|
||||
GSoC student projects follow the same procedure as regular community
|
||||
contributions, in particular the student is expected to sign the Genode
|
||||
Contributor's Agreement. (see [http://genode.org/community/contributions])
|
||||
|
||||
:What criteria did you use to select your mentors?:
|
||||
|
||||
We selected the mentors on the basis of their long-time involvement with the
|
||||
project and their time-tested communication skills. For each proposed working
|
||||
topic, there is least one stakeholder with profound technical background within
|
||||
Genode Labs. This person will be the primary contact person for the student
|
||||
working on the topic. However, we will encourgage the student to make his/her
|
||||
development transparant to all community members (i.e., via GitHub). So
|
||||
So any community member interested in the topic is able to bring in his/her
|
||||
ideas at any stage of development. Consequently, in practive, there will be
|
||||
multiple persons mentoring each students.
|
||||
|
||||
:What is your plan for dealing with disappearing students?:
|
||||
|
||||
Actively contact them using all channels of communication available to us,
|
||||
find out the reason for disappearance, trying to resolve the problems. (if
|
||||
they are related to GSoC or our project for that matter).
|
||||
|
||||
:What is your plan for dealing with disappearing mentors?:
|
||||
|
||||
All designated mentors are local to Genode Labs. So the chance for them to
|
||||
disappear to very low. However, if a mentor disappears for any serious reason
|
||||
(i.e., serious illness), our organization will provide a back-up mentor.
|
||||
|
||||
:What steps will you take to encourage students to interact with your community?:
|
||||
|
||||
First, we discussed GSoC on our mailing list where we received an overly
|
||||
positive response. We checked back with other Open-Source projects related to
|
||||
our topics, exchanged ideas, and tried to find synergies between our
|
||||
respective projects. For most project ideas, we have created issues in our
|
||||
issue tracker to collect technical information and discuss the topic.
|
||||
For several topics, we already observed interests of students to participate.
|
||||
|
||||
During the work on the topics, the mentors will try to encourage the
|
||||
students to play an active role in discussions on our mailing list, also on
|
||||
topics that are not strictly related to the student project. We regard an
|
||||
active participation as key to to enable new community members to develop a
|
||||
holistic view onto our project and gather a profound understanding of our
|
||||
methodologies.
|
||||
|
||||
Student projects will be carried out in a transparent fashion at GitHub.
|
||||
This makes it easy for each community member to get involved, discuss
|
||||
the rationale behind design decisions, and audit solutions.
|
||||
|
||||
|
||||
Topics
|
||||
######
|
||||
|
||||
While discussing GSoC participation on our mailing list, we identified the
|
||||
following topics as being well suited for GSoC projects. However, if none of
|
||||
those topics receives resonance from students, there is more comprehensive list
|
||||
of topics available at our road map and our collection of future challenges:
|
||||
|
||||
:[http://genode.org/about/road-map]: Road-map
|
||||
:[http://genode.org/about/challenges]: Challenges
|
||||
|
||||
|
||||
Combining Genode with the HelenOS/SPARTAN kernel
|
||||
================================================
|
||||
|
||||
[http://www.helenos.org - HelenOS] is a microkernel-based multi-server OS
|
||||
developed at the university of Prague. It is based on the SPARTAN microkernel,
|
||||
which runs on a wide variety of CPU architectures including Sparc, MIPS, and
|
||||
PowerPC. This broad platform support makes SPARTAN an interesting kernel to
|
||||
look at alone. But a further motivation is the fact that SPARTAN does not
|
||||
follow the classical L4 road, providing a kernel API that comes with an own
|
||||
terminology and different kernel primitives. This makes the mapping of
|
||||
SPARTAN's kernel API to Genode a challenging endeavour and would provide us
|
||||
with feedback regarding the universality of Genode's internal interfaces.
|
||||
Finally, this project has the potential to ignite a further collaboration
|
||||
between the HelenOS and Genode communities.
|
||||
|
||||
|
||||
Block-level encryption
|
||||
======================
|
||||
|
||||
Protecting privacy is one of the strongest motivational factors for developing
|
||||
Genode. One pivotal element with that respect is the persistence of information
|
||||
via block-level encryption. For example, to use Genode every day at Genode
|
||||
Labs, it's crucial to protect the confidentiality of some information that's
|
||||
not part of the Genode code base, e.g., emails and reports. There are several
|
||||
expansion stages imaginable to reach the goal and the basic building blocks
|
||||
(block-device interface, ATA/SATA driver for Qemu) are already in place.
|
||||
|
||||
:[https://github.com/genodelabs/genode/issues/55 - Discuss the issue...]:
|
||||
|
||||
|
||||
Virtual NAT
|
||||
===========
|
||||
|
||||
For sharing one physical network interface among multiple applications, Genode
|
||||
comes with a component called nic_bridge, which implements proxy ARP. Through
|
||||
this component, each application receives a distinct (virtual) network
|
||||
interface that is visible to the real network. I.e., each application requests
|
||||
an IP address via a DHCP request at the local network. An alternative approach
|
||||
would be a component that implements NAT on Genode's NIC session interface.
|
||||
This way, the whole Genode system would use only one IP address visible to the
|
||||
local network. (by stacking multiple nat and nic_bridge components together, we
|
||||
could even form complex virtual networks inside a single Genode system)
|
||||
|
||||
The implementation of the virtual NAT could follow the lines of the existing
|
||||
nic_bridge component. For parsing network packets, there are already some handy
|
||||
utilities available (at os/include/net/).
|
||||
|
||||
:[https://github.com/genodelabs/genode/issues/114 - Discuss the issue...]:
|
||||
|
||||
|
||||
Runtime for the Go or D programming language
|
||||
============================================
|
||||
|
||||
Genode is implemented in C++. However, we are repeatedly receiving requests
|
||||
for offering more safe alternatives for implementing OS-level functionality
|
||||
such as device drivers, file systems, and other protocol stacks. The goals
|
||||
for this project are to investigate the Go and D programming languages with
|
||||
respect to their use within Genode, port the runtime of of those languages
|
||||
to Genode, and provide a useful level of integration with Genode.
|
||||
|
||||
|
||||
Block cache
|
||||
===========
|
||||
|
||||
Currently, there exists only the iso9660 server that is able to cache block
|
||||
accesses. A generic solution for caching block-device accesses would be nice.
|
||||
One suggestion is a component that requests a block session (routed to a block
|
||||
device driver) as back end and also announces a block service (front end)
|
||||
itself. Such a block-cache server waits for requests at the front end and
|
||||
forwards them to the back end. But it uses its own memory to cache blocks.
|
||||
|
||||
The first version could support only read-only block devices (such as CDROM) by
|
||||
caching the results of read accesses. In this version, we already need an
|
||||
eviction strategy that kicks in once the block cache gets saturated. For a
|
||||
start this could be FIFO or LRU (least recently used).
|
||||
|
||||
A more sophisticated version would support write accesses, too. Here we need a
|
||||
way to sync blocks to the back end at regular intervals in order to guarantee
|
||||
that all block-write accesses are becoming persistent after a certain time. We
|
||||
would also need a way to explicitly flush the block cache (i.e., when the
|
||||
front-end block session gets closed).
|
||||
|
||||
:[https://github.com/genodelabs/genode/issues/113 - Discuss the issue...]:
|
||||
|
||||
|
||||
; _Since Genode Labs was not accepted as GSoC mentoring organization, the_
|
||||
; _following section has become irrelevant. Hence, it is commented-out_
|
||||
;
|
||||
; Student applications
|
||||
; ####################
|
||||
;
|
||||
; The formal steps for applying to the GSoC program will be posted once Genode
|
||||
; Labs is accepted as mentoring organization. If you are a student interested
|
||||
; in working on a Genode-related GSoC project, now is a good time to get
|
||||
; involved with the Genode community. The best way is joining the discussions
|
||||
; at our mailing list and the issue tracker. This way, you will learn about
|
||||
; the currently relevant topics, our discussion culture, and the people behind
|
||||
; the project.
|
||||
;
|
||||
; :[http://genode.org/community/mailing-lists]: Join our mailing list
|
||||
; :[https://github.com/genodelabs/genode/issues]: Discuss issues around Genode
|
||||
|
||||
1487
doc/news.txt
1487
doc/news.txt
File diff suppressed because it is too large
Load Diff
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.
|
||||
@@ -1,898 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 18.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
After being developed for over a decade, Genode remained a mystery for many
|
||||
people who looked at the project from a distance as it does not seem to fit
|
||||
any established category of software. In 2018 - declared as the Year of Sculpt
|
||||
on our [https://genode.org/about/road-map - roadmap] - this will hopefully
|
||||
change. Genode 18.02 features the first revision of Sculpt, which is a
|
||||
Genode-based operating system for general-purpose computing. After being used
|
||||
as day-to-day OS by the entire team of Genode Labs for several months, we feel
|
||||
that the time is right to share the system with a broader audience (Section
|
||||
[Sculpt for Early Adopters]).
|
||||
|
||||
One fundamental feature of Sculpt is the ability to install and deploy
|
||||
software from within the running operating system, which is universally
|
||||
expected from any modern general-purpose OS. Section
|
||||
[On-target package installation and deployment] presents Genode's unique
|
||||
take on the topic of software installation and deployment.
|
||||
|
||||
Besides Sculpt, the current release has no shortage of other improvements.
|
||||
Genode's growing arsenal of 3rd-party software received profound updates and
|
||||
additions, including VirtualBox, Muen, seL4, several GNU packages, and
|
||||
libraries. Also the user-level networking stack - including the Linux-based
|
||||
LxIP stack and our custom NIC-router component - received a lot of attention.
|
||||
Thanks to the added network driver for i.MX-based hardware, this networking
|
||||
infrastructure becomes usable on embedded platforms based on this SoC.
|
||||
Furthermore, the current release continues the cultivation of the Nim
|
||||
programming language for Genode components.
|
||||
|
||||
|
||||
Sculpt for Early Adopters
|
||||
#########################
|
||||
|
||||
The current release features the first revision of Sculpt, which is a
|
||||
Genode-based operating system for general-purpose computing. This initial
|
||||
version is called Sculpt for Early Adopters (EA). Its target audience are
|
||||
enthusiasts who are already familiar with Genode and are eager to use a
|
||||
Genode-based operating system on their machines. As outlined on the
|
||||
[https://genode.org/about/road-map - roadmap], later versions will become
|
||||
increasingly approachable.
|
||||
|
||||
[image sculpt_overview]
|
||||
|
||||
Please refer to the official
|
||||
[https://genode.org/documentation/articles/sculpt-ea - Sculpt documentation]
|
||||
to step right into the adventure.
|
||||
|
||||
|
||||
On-target package installation and deployment
|
||||
#############################################
|
||||
|
||||
In May last year, we introduced the package-management concept for Genode to
|
||||
pursue two goals. First, to overcome the naturally limited scalability of
|
||||
composing Genode systems solely from source. This limit became evident in
|
||||
complex system scenarios that incorporate a huge amount of 3rd party software.
|
||||
Thanks to the introduced _depot_ concept and its integration in Genode's
|
||||
workflow - in particular the run tool - the work of system integration became
|
||||
much more structured (by caring about packages instead of individual build
|
||||
targets), robust (by avoiding conditions in run scripts), and quick (by the
|
||||
accelerated test cycle when using pre-built packages).
|
||||
|
||||
The second goal is the ability to update and extend a running Genode system on
|
||||
the fly. We are happy to have reached this goal with the current release. As
|
||||
exemplified by the Sculpt scenario, packages cannot only be used as building
|
||||
blocks for system images but also as subsystems dynamically installed and
|
||||
deployed on target. Even though installation and deployment are closely
|
||||
related topics, both involve distinct challenges, which allow Genode to shine.
|
||||
|
||||
|
||||
Installation / update
|
||||
=====================
|
||||
|
||||
In traditional operating systems, the installation and update of system
|
||||
software is the job of privileged programs. For example, a package manager in
|
||||
a GNU/Linux system is typically executed with root privileges. This is
|
||||
troublesome because the functionality of such a program is extremely complex.
|
||||
In particular it is exposed to the network and has to parse content
|
||||
originating from potentially untrusted parties. Therefore, potential software
|
||||
vulnerabilities should be expected. However, in modern OSes, these programs
|
||||
are just assumed to behave correctly. If this overly optimistic assumption
|
||||
doesn't hold, the entire system is at risk.
|
||||
|
||||
Genode helps us to mitigate this problem by modelling each installation step
|
||||
as a distinct component composition where each component has a well-defined
|
||||
and extremely narrow role. The installation is an iterative sequence that
|
||||
is orchestrated by the so-called download-manager component
|
||||
(Figure [depot_download]).
|
||||
|
||||
[image depot_download]
|
||||
|
||||
Initially, the download manager receives a list of content to be installed
|
||||
into the local depot, which is stored on the file system. The depot may
|
||||
already be populated with (portions of) this content. In the first step, the
|
||||
download manager must determine the parts that are missing. To do that, it
|
||||
does not access the file system directly but instead hands over this task to a
|
||||
disposable helper component called _depot-query_ that is spawned within a
|
||||
dynamic init instance. This indirection has two benefits. First, the download
|
||||
manager is not bothered with the complexity of accessing the file system. It
|
||||
does not even have any notion of files. Second, the download manager is
|
||||
effectively shielded from the file system. Should the file system misbehave,
|
||||
the liveliness of the download manager remains unaffected.
|
||||
|
||||
[image depot_download_query_deps]
|
||||
|
||||
The depot-query component reports its findings to a report session. The report
|
||||
eventually reaches the download manager as an updated ROM module. Given the
|
||||
list of missing content, the download manager has to determine the information
|
||||
of where to obtain the content from and the public key of the content creator.
|
||||
This information is contained within the depot. So the download manager issues
|
||||
another request to the depot-query component in order to obtain it.
|
||||
|
||||
[image depot_download_query_url]
|
||||
|
||||
Once the depot-query component has responded, the download manager knows what
|
||||
content to get, where to get it, and how to verify it. To download the
|
||||
content, it changes the dynamic init instance as follows.
|
||||
|
||||
[image depot_download_fetch]
|
||||
|
||||
The depot-query component is now gone. Actually, the entire depot has moved
|
||||
out of sight. Instead, a fresh _fetchurl_ component is spawned. This component
|
||||
is connected to the network as well as the writeable download directory
|
||||
_public/_. Internally, fetchurl employs a complex software stack, which
|
||||
includes the C runtime, curl, libssl, and libssh. Hence, we expect this
|
||||
component to be vulnerable. Since it is facing the network, we assume that
|
||||
vulnerabilities are exploitable. In the worst case where the component is
|
||||
completely in the hands of an attacker, it may write wrong content into the
|
||||
_public/_ location. But compared to executing curl or wget as root on a
|
||||
traditional Unix system, the reach of an attack is quite limited. For example,
|
||||
the mere existence of the download manager remains completely out of view of
|
||||
fetchurl. However, the content of _public/_ must not be trusted. To reinforce
|
||||
trust in the downloaded content, the content is accompanied with cryptographic
|
||||
signatures created by the content creator. Before we touch the content, we
|
||||
first check its authenticity. To perform this verification step, the download
|
||||
manager reshapes the dynamic init instance as follows.
|
||||
|
||||
[image depot_download_verify]
|
||||
|
||||
Note that fetchurl exists no more and network connectivity is cut, effectively
|
||||
disposing any form of malware that might have infected fetchurl. Next a new
|
||||
_verify_ component enters the picture. It is configured with a list of content
|
||||
to check, the signatures of the content, and the public key of the content's
|
||||
presumed creator. Since it accesses the _public/_ location exclusively, it is
|
||||
not prone to any potential time-of-check to time-of-use problems during the
|
||||
verification. Under the hood, the _verify_ component employs a hugely complex
|
||||
implementation based on GnuPG. It would be naive to fully trust this code.
|
||||
However, when embedded in our scenario, the reach of a bug is limited because
|
||||
the verify component has no access to any mutable system state. It could
|
||||
merely give the wrong answer (which is of course bad but there is no way we
|
||||
can magically solve this).
|
||||
|
||||
Knowing that the downloaded content is indeed the same content as intended
|
||||
by the creator, it is time for extraction. For this step, the download
|
||||
manager - again - reshapes the dynamic init instance:
|
||||
|
||||
[image depot_download_extract]
|
||||
|
||||
This time, both the _public/_ location as well as the trusted _depot/_ are
|
||||
visible and a new _extract_ component is spawned. As the depot may host
|
||||
content from multiple sources, which potentially distrust each other, the
|
||||
content of each content provider resides in a dedicated subdirectory within
|
||||
the depot. Instead of handing over access to the entire depot to the extract
|
||||
tool, we mediate the file-system access via a _chroot_ component that limits
|
||||
the view to the depot-provider's respective subdirectory. In the worst case
|
||||
where a misbehaving content provider delivers a forged (but correctly signed)
|
||||
archive to exploit a vulnerability of the extract component, the reach of the
|
||||
attack remains limited to the content provider's space within the depot.
|
||||
|
||||
After the extraction step has completed, the depot is populated with the new
|
||||
content, which may - in turn - include new dependency information. At this
|
||||
point, the download manager starts a new iteration. This iterative process
|
||||
terminates as soon as the depot-query component signals that no content of
|
||||
the software installation is missing.
|
||||
|
||||
The bottom line here is that we are able to use complex and useful software
|
||||
like curl, libarchive, liblzma, and GnuPG while largely distrusting it. In
|
||||
contrast to this software that sums up to hundreds of thousand lines of code,
|
||||
the download manager comprises less than 1000 lines of code. The software
|
||||
installation procedure described above is implemented by the 'depot_download'
|
||||
subsystem hosted in the gems repository and illustrated by an equally named
|
||||
run script. It also forms the basis of the install/update mechanism of the
|
||||
Sculpt scenario.
|
||||
|
||||
|
||||
Deployment
|
||||
==========
|
||||
|
||||
Once software has entered the system in the form of depot content, the
|
||||
remaining question is how to turn this content into running subsystems. The
|
||||
answer is given by the following illustration.
|
||||
|
||||
[image sculpt_deploy_runtime]
|
||||
|
||||
Like for the installation process described above, the scenario employs a
|
||||
dynamic init instance that is accompanied by an orchestrating component. The
|
||||
latter is called _depot-deploy_. The depot-deploy component queries
|
||||
information from the depot using the same depot-query component that was used
|
||||
during the installation. Based on the returned _blueprint_ information for the
|
||||
to-be-deployed subsystems, it generates the configuration for the dynamic init
|
||||
instance. The subsystems hosted within this init instance access the depot
|
||||
content via mere ROM sessions as provided by the FS-ROM component. This makes
|
||||
the use of the depot transparent to the hosted subsystems.
|
||||
|
||||
The depot-deploy component is located in the gems repository and accompanied
|
||||
by a same-named run script. More importantly, it is featured in the deploy
|
||||
runtime of the Sculpt system.
|
||||
|
||||
|
||||
Base framework and OS-level infrastructure
|
||||
##########################################
|
||||
|
||||
Increased default warning level
|
||||
===============================
|
||||
|
||||
For building Genode components written in C++, the compiler flags -Wextra,
|
||||
-Weffc++, and -Werror are now enabled in addition to -Wall by default.
|
||||
|
||||
If this strict warning level is inapplicable for a given component or
|
||||
library, it is possible to explicitly disable the strictness in the
|
||||
respective build-description file by adding the following line:
|
||||
|
||||
! CC_CXX_WARN_STRICT =
|
||||
|
||||
We adjusted almost all the code of the base, base-<kernel>, os, and demo
|
||||
repositories to comply with this new warning level. For most components
|
||||
hosted in the higher-level repositories (libports, ports, dde_*, gems),
|
||||
the strictness is disabled as of now and will be enabled component-wise
|
||||
wherever feasible.
|
||||
|
||||
While adjusting our code base, we identified the following patterns worth
|
||||
mentioning:
|
||||
|
||||
* A class with virtual functions can no longer publicly inherit base
|
||||
classes without a vtable. The inherited object may either be moved
|
||||
to a member variable, or inherited privately. The latter would be
|
||||
used for classes that inherit 'List::Element' or 'Avl_node'. In order
|
||||
to enable the 'List' and 'Avl_tree' to access the meta data, the
|
||||
'List' must become a friend.
|
||||
|
||||
* Instead of adding a virtual destructor to abstract base classes,
|
||||
we inherit the new 'Interface' class, which contains a virtual
|
||||
destructor. This way, single-line abstract base classes can stay
|
||||
as compact as they are. The 'Interface' utility resides in
|
||||
_base/include/util/interface.h_.
|
||||
|
||||
* With the new warning level, all member variables must be explicitly
|
||||
initialized. Basic types may be initialized with '='. All other types
|
||||
are initialized with braces '{ ... }' or as class initializers. If
|
||||
basic types and non-basic types appear in a row, it is nice to only
|
||||
use the brace syntax (also for basic types) and align the braces.
|
||||
|
||||
* If a class contains pointers as members, it must now also provide a
|
||||
copy constructor and assignment operator. In most cases, one
|
||||
would make them private, effectively disallowing the objects to be
|
||||
copied. Unfortunately, this warning cannot be fixed by inheriting
|
||||
our existing 'Noncopyable' class (the compiler fails to detect that
|
||||
the inheriting class cannot be copied and still gives the error).
|
||||
For now, we have to manually add declarations for both the copy
|
||||
constructor and the assignment operator as private class members.
|
||||
Those declarations should be prepended with a comment like this:
|
||||
|
||||
! /*
|
||||
! * Noncopyable
|
||||
! */
|
||||
! Thread(Thread const &);
|
||||
! Thread &operator = (Thread const &);
|
||||
|
||||
In the future, we plan to revisit these occurrences and try to replace
|
||||
the pointers with references. In the presence of at least one
|
||||
reference member, the compiler would no longer implicitly generate
|
||||
a copy constructor. So we could remove the manual declaration.
|
||||
|
||||
The following caveats are expected, even if you disable the strictness
|
||||
in your component:
|
||||
|
||||
* If your component has a class called 'Interface', it may collide with
|
||||
the new 'Genode::Interface' class. You may have to disambiguate the
|
||||
names.
|
||||
|
||||
* The 'Genode::Rpc_client' is no longer a 'Genode::Capability'. Hence,
|
||||
classes inherited from 'Genode::Rpc_client' cannot refer to a
|
||||
'Capability' but must refer to 'Genode::Capability'.
|
||||
|
||||
* The 'Surface' class is no longer copyable, which led to API
|
||||
changes of users of this class. E.g., the 'Nitpicker_buffer'
|
||||
utility does no longer offer accessors for the contained surfaces
|
||||
but a new 'apply_to_surface' method that takes a lambda function as
|
||||
argument.
|
||||
|
||||
|
||||
Init
|
||||
====
|
||||
|
||||
Init selects session routes based on the requested service and the client's
|
||||
label. The latter can be matched as 'label' (exact match), 'label_prefix', or
|
||||
'label_suffix' (either end of the label matches). With the new version, these
|
||||
options are complemented with an additional 'label_last' attribute that covers
|
||||
the prominent case where the last part of the label identifies a requested
|
||||
resource at the server. A typical example is the routing of a ROM session
|
||||
based on the name of the requested ROM module.
|
||||
|
||||
|
||||
Reflecting the core log to the application level
|
||||
================================================
|
||||
|
||||
Core records now log messages in a ring buffer and exports this
|
||||
memory as ROM named 'core_log'. User applications may monitor this ring buffer
|
||||
and present or transfer the content as appropriate. The example component in
|
||||
_repos/os/src/app/log_core_ transforms the content into normal log
|
||||
messages, which may be routed to graphical terminals or stored on
|
||||
file systems, e.g. by using the fs_log server.
|
||||
|
||||
|
||||
NIC-router improvements
|
||||
=======================
|
||||
|
||||
During the past three months, the NIC router has received several improvements
|
||||
that were mainly inspired by our daily experience with the component as part
|
||||
of our Sculpt based working environments.
|
||||
|
||||
The most notable new feature is the support for multiple NIC sessions at one
|
||||
domain. If multiple NIC-session clients connect to one domain, the NIC router
|
||||
acts as a simple hub between them. I.e., for every packet that is routed to
|
||||
the domain, each connected session receives a copy of the packet. The same
|
||||
applies for domain-local packets, meaning packets that target an IP address
|
||||
inside the IP subnet of the domain they came from. This domain-local
|
||||
forwarding applies before considering any other routing rules. So, in other
|
||||
words, it is not possible to route such traffic to another domain.
|
||||
|
||||
Furthermore, the logging features of the NIC router were improved. First, the
|
||||
router is now capable of periodically sending a report via Genode's report
|
||||
session. This can be activated by adding the new '<report>' node to the router
|
||||
configuration:
|
||||
|
||||
! <config>
|
||||
! <report interval_sec="5" bytes="yes" config="yes">
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
So far, the report provides per-domain information about the amount of sent
|
||||
and received data ('bytes' attribute) and the current IPv4 configuration like
|
||||
IP address, subnet mask, and gateway address ('config' attribute).
|
||||
|
||||
Second, there is a new verbosity option in the '<config>' node:
|
||||
|
||||
! <config verbose_domain_state="yes">
|
||||
|
||||
When this option is set, the NIC router will output a short message to the log
|
||||
for each general state change of a domain. Currently, this includes the
|
||||
IP-configuration state (IP address, subnet mask, gateway address) and the
|
||||
number of connected NIC sessions. This is a useful addition because the
|
||||
purpose of the regular verbose option is to give a very deep insight into
|
||||
almost every activity of the router, which is vital for debugging
|
||||
sophisticated problems but normally floods the log. Therefore, the regular
|
||||
verbose option is not viable for complex setups like a Sculpt desktop
|
||||
environment. In such a context, the new domain-state verbosity is pretty
|
||||
discreet but already gives a good hint on why, for instance, packets get
|
||||
dropped despite the routing rules being correct.
|
||||
|
||||
Last but not least, the timeout configuration of the NIC router has been
|
||||
reworked and now allows for a much more precise adaption to the network
|
||||
environment. The former 'rtt_sec' attribute of the '<config>' node has been
|
||||
replaced by the following new attributes (default values shown):
|
||||
|
||||
! <config dhcp_discover_timeout_sec="10"
|
||||
! dhcp_request_timeout_sec="10"
|
||||
! dhcp_offer_timeout_sec="10"
|
||||
! udp_idle_timeout_sec="30"
|
||||
! tcp_idle_timeout_sec="600"
|
||||
! tcp_max_segm_lifetime_sec="30">
|
||||
|
||||
Details about the new attributes can be found in the
|
||||
_os/src/server/nic_router/README_ file. The default values should be
|
||||
appropriate for the common use case so that specifying them is normally not
|
||||
necessary.
|
||||
|
||||
|
||||
New watch mechanism for file-system session
|
||||
===========================================
|
||||
|
||||
The file-system session already provided a way for watching files or
|
||||
directories for changes. However, the original mechanism was arguably hard to
|
||||
use. In addition to opening the to-be-watched file-system node, the client had
|
||||
to submit a so-called content-changed request into the session's request
|
||||
queue. In turn, the server delivered the change notification by acknowledging
|
||||
this request.
|
||||
|
||||
The new mechanism is much less bureaucratic. A file or directory can be
|
||||
watched by opening a watch handle rather than submitting a 'CONTENT_CHANGED'
|
||||
packet to the server. Whenever a change happens at a node with an open watch
|
||||
handle, a CONTENT_CHANGED packet will be sent from the server to the client.
|
||||
This serializes the registration with other handle operations and separates
|
||||
I/O handle state from notification handle state.
|
||||
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
We changed libc's handling of 'clock_gettime' to be explicitly configurable
|
||||
rather than relying on built-in heuristics. With the new version, the libc
|
||||
opens a timer session as a time source only if the 'rtc' attribute of the
|
||||
'<libc>' configuration node is defined. If not configured, 'clock_gettime'
|
||||
returns 0.
|
||||
|
||||
This change may require the adjustment of components that implicitly rely on
|
||||
the libc as time source. To enable such a component to use relative time
|
||||
(based on a timer session) but no wall-clock time, one can manually provide a
|
||||
pseudo real-time clock value as follows:
|
||||
|
||||
! <vfs>
|
||||
! <dir name="dev">
|
||||
! <log/> <null/> <inline name="rtc">2000-01-01 00:00</inline>
|
||||
! </dir>
|
||||
! </vfs>
|
||||
! <libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
|
||||
|
||||
|
||||
GUI stack and terminal improvements
|
||||
===================================
|
||||
|
||||
Nit-FB improvements
|
||||
-------------------
|
||||
|
||||
The nit_fb component provides a framebuffer and input service while using the
|
||||
nitpicker GUI server as back end. The new version adds the 'initial_width' and
|
||||
'initial_height' attributes, which accommodate the use case where nit_fb is
|
||||
used in a dynamic fashion like as a client of a window system. Here, the
|
||||
initial dimensions define the initial window size but - in contrast to the
|
||||
existing 'width' and 'height' attributes - the actual size can change
|
||||
afterwards.
|
||||
|
||||
Terminal resizing
|
||||
-----------------
|
||||
|
||||
The terminal-session interface gained the ability to propagate resize events
|
||||
from the server to the client. The new version of the graphical terminal uses
|
||||
this mechanism to support window resizing as well as dynamically changing the
|
||||
font size. At the client side, noux has become able to reflect terminal-size
|
||||
changes to noux applications. Applications based on ncurses (e.g., vim) are
|
||||
able to gracefully respond to such changes now.
|
||||
|
||||
|
||||
Using chroot to enforce read-only file-system access
|
||||
====================================================
|
||||
|
||||
By placing a chroot component in-between a file-system client and server, the
|
||||
client's view on the file system can be limited to a specific directory. With
|
||||
the current release, chroot can additionally be used to restrict a writeable
|
||||
file-system session to become read-only. This is accomplished by the new
|
||||
'writeable' attribute of chroot's policy nodes. By default, it is set to "no".
|
||||
|
||||
|
||||
API changes
|
||||
===========
|
||||
|
||||
Noncopyable AVL node/tree
|
||||
-------------------------
|
||||
|
||||
Copying an AVL node generally violates the integrity of the corresponding
|
||||
tree. To rule out subtle bugs where AVL nodes are accidentally copied, AVL
|
||||
nodes are no longer copyable.
|
||||
|
||||
New 'Buffered_xml' utility
|
||||
--------------------------
|
||||
|
||||
The 'Buffered_xml' utility located at _os/buffered_xml.h_ simplifies the
|
||||
implementation of dynamically reconfigurable components that need to keep a
|
||||
verbatim copy of certain parts of their configuration during configuration
|
||||
updates.
|
||||
|
||||
New 'List_model' utility
|
||||
------------------------
|
||||
|
||||
More and more components respond to dynamic configuration updates. For most
|
||||
components, such updates are quite simple: replace an old internal state by a
|
||||
new one. But in cases like init, menu_view, or window decorator, a
|
||||
differential update is in order. Until now, each of these components employed
|
||||
custom code for this task. As this code is not trivial, a common solution is
|
||||
preferable. This solution comes in the form of the new 'List_model' utility
|
||||
located at _base/include/util/list_model.h_. It introduces a light-weight
|
||||
formalism to feed a component-internal data model from an externally-provided
|
||||
XML structure.
|
||||
|
||||
Dynamically expandable reporter utility
|
||||
---------------------------------------
|
||||
|
||||
In many cases, components that generate reports don't explicitly handle the
|
||||
situation where the default buffer size of 4096 bytes is exceeded by the
|
||||
report. This problem is easy to miss because reports are often small at
|
||||
testing time but become larger when deployed in complex scenarios. In most
|
||||
cases, the best way to handle an 'Xml_generator::Buffer_exceeded' exception is
|
||||
upgrading the report session. The new 'Expanding_reporter' that accompanies
|
||||
the original 'Reporter' in _os/reporter.h_ eases the handling of this common
|
||||
case.
|
||||
|
||||
|
||||
Languages and runtime environments
|
||||
##################################
|
||||
|
||||
Nim programming language
|
||||
========================
|
||||
|
||||
A new Nim library for constructing Genode servers is now available in the
|
||||
World repository. This module provides utilities for the asynchronous
|
||||
session-creation procedure introduced in the
|
||||
[https://genode.org/documentation/release-notes/16.11#New_session-creation_procedure - 16.11]
|
||||
release. Some introductory code snippets are provided here for the
|
||||
adventurous.
|
||||
|
||||
An example of server creation using the 'genodeservers' module:
|
||||
|
||||
! import romclient, genodeservers
|
||||
!
|
||||
! var
|
||||
! sessionsRom = newRomClient "session_requests"
|
||||
! # synchronously open a ROM client to the parent
|
||||
! romContent = sessionsRom.stream.readAll()
|
||||
! # copy the ROM content to a heap string
|
||||
! requestsParser = initSessionRequestsParser(romContent)
|
||||
! # a state machine for parsing 'session_requests' XML
|
||||
!
|
||||
! for id, service, label in requestsParser.create:
|
||||
! # the `create` iterator provider for the parser
|
||||
! # hides the details of parsing the XML data
|
||||
! discard txBufSize = requestsParser.argInt "tx_buf_size"
|
||||
! # extract typed session arguments from the current parser state
|
||||
! discard label.lastLabelElement()
|
||||
! # label handling utilities are provided
|
||||
! if service == "MyService":
|
||||
! myCreateSessionProc(id, label)
|
||||
!
|
||||
|
||||
This module streamlines the handling of session metadata, but the developer
|
||||
must still provide hand-crafted wrappers over the C++ methods for managing
|
||||
RPC objects and passing session capabilities to the parent. Most notoriously
|
||||
a global pointer symbol, `genodeEnv`, is used to expose the component
|
||||
environment object. In the future, this will be replaced by a typed object
|
||||
passed from runtime to an application entry procedure.
|
||||
|
||||
! type MySessionCapability {.
|
||||
! importcpp: "My_session::Session_capability",
|
||||
! header: "my_session/capability.h".}
|
||||
! # import a capability type
|
||||
!
|
||||
! type MyNativeSessionBase {.
|
||||
! importcpp: "My_session::Session_rpc_object",
|
||||
! header: "my_session/rpc_object.h".}
|
||||
! # import C++ session RPC object
|
||||
!
|
||||
! type MyNativeSession = Constructible[MyNativeSessionBase]
|
||||
! # apply the C++ Constructible template to defer calling
|
||||
! # the object constructor
|
||||
!
|
||||
! proc construct(cppObj: MyNativeSession) {.
|
||||
! importcpp: "#.construct(*genodeEnv)".}
|
||||
! # call the C++ constructor, passing the global Genode::Env
|
||||
!
|
||||
! proc manage(cppObj: MyNativeSession): MySessionCapability {.
|
||||
! importcpp: "genodeEnv->ep().manage(*#)".}
|
||||
! # call a method from the gobal Env, dereferencing
|
||||
! # thru the Constructible template
|
||||
!
|
||||
! type MyNimSessionObj = ref object
|
||||
! cppImpl: MyNativeSession
|
||||
! cap: MySessionCapability
|
||||
! id: SessionId
|
||||
! # C++ RPC objects are best kept in native
|
||||
! # reference-counted Nim objects
|
||||
!
|
||||
! proc manage(obj: MyNimSessionObj) =
|
||||
! obj.cppImpl.construct() # call our wrapped constructor
|
||||
! GC_ref(obj)
|
||||
! # manually increase the reference count on our session
|
||||
! # object to prevent the component entrypoint from
|
||||
! # referencing an RPC object that has been lost and
|
||||
! # freed from the heap
|
||||
! obj.cap = obj.cppImpl.manage() # store our capability
|
||||
!
|
||||
! proc myCreateSessionProc(id: SessionId): MyNimSessionObj =
|
||||
! result = new MyNimSessionObj
|
||||
! # create our object on the heap
|
||||
! result.manage()
|
||||
! # construct and manage our RPC object
|
||||
! result.id = id
|
||||
! # store the session id from our parent
|
||||
|
||||
Procedures for calling Nim code from an RPC object, dissolving
|
||||
and destructing RPC objects, and managing the session lifetime
|
||||
are exercises left to the reader.
|
||||
|
||||
|
||||
Updated VirtualBox
|
||||
==================
|
||||
|
||||
Our VirtualBox port got updated from version 5.1.22 to version 5.1.32 in order
|
||||
to leverage the security updates and improved audio support. Additionally the
|
||||
boot time of Linux guests got improved by adjusting our custom virtualization
|
||||
back end.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New trace-logging component
|
||||
===========================
|
||||
|
||||
The new trace-logger component can be used to easily gather, process, and
|
||||
export different types of tracing data. Furthermore, it marks the next step
|
||||
towards a user framework that makes access to Genode's manifold tracing
|
||||
abilities
|
||||
([https://genode.org/documentation/release-notes/13.08#Light-weight_event_tracing - 13.08],
|
||||
[https://genode.org/documentation/release-notes/13.11#Improved_event_tracing - 13.11],
|
||||
[https://genode.org/documentation/release-notes/15.08#Enhanced_tracing_facilities - 15.08])
|
||||
intuitive and convenient.
|
||||
|
||||
The component can filter the available tracing subjects according to session
|
||||
label policies and thread names. The processing of the tracing data can then
|
||||
be configured for each selected subject individually, for groups of subjects,
|
||||
or for all subjects together. The resulting data is exported as log output.
|
||||
|
||||
This is an example configuration of the trace logger, which shows the default
|
||||
value for each attribute (except policy.thread and policy.label):
|
||||
|
||||
! <config verbose="no"
|
||||
! session_ram="10M"
|
||||
! session_arg_buffer="4K"
|
||||
! session_parent_levels="0"
|
||||
! period_sec="5"
|
||||
! activity="no"
|
||||
! affinity="no"
|
||||
! default_policy="null"
|
||||
! default_buffer="4K">
|
||||
!
|
||||
! <policy label="init -> timer" />
|
||||
! <policy label_suffix=" -> ram_fs" />
|
||||
! <policy label_prefix="init -> encryption -> "
|
||||
! thread="worker"
|
||||
! policy="null"
|
||||
! buffer="4K" />
|
||||
! </config>
|
||||
|
||||
The most important features so far when it comes to processing the traced
|
||||
data are:
|
||||
|
||||
* Trace CPU activity and affinity ('activity' and 'affinity' attribute),
|
||||
* Install individual policies for the creation of further tracing data
|
||||
('policy' attributes) for instance, 'rpc_name' for a log of issued RPC calls),
|
||||
* Dimensioning the subject-local trace buffers and the frequency of Trace Logger
|
||||
data examination ('buffer' and 'period' attributes), and
|
||||
* Configure the session to the Tracing server ('session' attributes).
|
||||
|
||||
A comprehensive documentation of the trace-logger component can be found in
|
||||
_os/src/app/trace_logger/README_. An example of how to use the component is
|
||||
given through the run script _os/run/trace_logger.run_.
|
||||
|
||||
|
||||
New component for extracting archives
|
||||
=====================================
|
||||
|
||||
The new 'extract' component located at _libports/src/app/extract_ extracts
|
||||
the content of an arbitrary number of tar.xz archives according to its
|
||||
configuration. It is used by the depot-download subsystem described in
|
||||
Section [On-target package installation and deployment]. The component
|
||||
is accompanied by the run script _libports/run/extract.run_ that illustrates
|
||||
its use.
|
||||
|
||||
|
||||
New signature-checking tool based on GnuPG
|
||||
==========================================
|
||||
|
||||
The on-target installation of software packages requires a way to verify
|
||||
cryptographic signatures of downloaded content within a Genode system.
|
||||
The new 'verify' component located at _ports/src/app/verify_ facilitates the
|
||||
code of GnuPG to verify detached OpenPGP signatures against public keys.
|
||||
Since GnuPG depends on libgcrypt and libgpg-error, ports of those libraries
|
||||
were added to the libports repository. The component comes with the run
|
||||
script _ports/run/verify.run_ that demonstrates its usage.
|
||||
|
||||
|
||||
Fetchurl component for downloading files
|
||||
========================================
|
||||
|
||||
Fetchurl is a component for downloading files from the network, based
|
||||
on the curl library. It used to reside in the genode-world repository.
|
||||
Since it has become a mandatory part of Genode's on-target software
|
||||
installation mechanism, we have moved it to the _libports_ repository now.
|
||||
Besides this relocation, fetchurl received a welcome modernization. In
|
||||
particular, the new version uses the modern socket-fs infrastructure of
|
||||
the libc instead of relying on the deprecated libc_lwip plugin as a hard-wired
|
||||
dependency.
|
||||
|
||||
|
||||
New interactive FLIF image viewer
|
||||
=================================
|
||||
|
||||
A simple image viewing application for the FLIF lossless image format was
|
||||
written from scratch using the FLIF reference decoder library. The viewer can
|
||||
be used to interactively view a directory of images and supports animation of
|
||||
GIF-like FLIF files.
|
||||
|
||||
|
||||
Ported 3rd-party software
|
||||
=========================
|
||||
|
||||
With the current release, the following 3rd-party software becomes available
|
||||
on Genode:
|
||||
|
||||
:[https://www.libarchive.org/ - libarchive]: is a library for uncompressing
|
||||
and extracting various archive formats. It nicely wraps format-specific
|
||||
libraries like zlib behind a unified and easy-to-use API. The port can
|
||||
be found in the _libports_ repository.
|
||||
|
||||
:[https://lz4.github.io/lz4/ - lz4] and [https://tukaani.org/xz/ - liblzma]:
|
||||
implement modern compression algorithms as supported by libarchive.
|
||||
Thanks to Ben Larson for contributing the port of these libraries.
|
||||
|
||||
:[https://www.tcl.tk/ - Tcl]: is used as scripting language for various
|
||||
Genode tools. With the new 'check_abi' tool described in Section
|
||||
[Automated ABI consistency checks], the Tcl shell 'tclsh' has become
|
||||
a dependency of the build system. Therefore, we made 'tclsh' available as
|
||||
noux package. Note, however, that this port comprises solely the
|
||||
functionality needed for simple scripting.
|
||||
|
||||
:[http://flif.info/ - FLIF]: is a library for the Free Lossless Image
|
||||
Format. Thanks to Emery Hemingway for making it available in the
|
||||
genode-world repository.
|
||||
|
||||
:[https://github.com/json-c/json-c/wiki - JSON-C]:
|
||||
is a library for processing JSON-formatted data. Thanks to
|
||||
Johannes Kliemann for contributing the port to the genode-world
|
||||
repository.
|
||||
|
||||
:[https://www.nlnetlabs.nl/projects/ldns/ - Drill (ldns)]:
|
||||
provides a utility for DNS testing. Thanks to Emery Hemingway for adding it
|
||||
to the genode-world repository as a side activity of improving Genode's
|
||||
network stack.
|
||||
|
||||
|
||||
Updated packages for the Noux runtime environment
|
||||
=================================================
|
||||
|
||||
The current release updates the following noux packages: less (version 487),
|
||||
grep (version 3.1), coreutils (version 8.29), tar (version 1.30), findutils
|
||||
(version 4.6), which (version 2.21), sed (version 4.4), and bash (version
|
||||
4.4.18). Thanks to Hinnerk van Bruinehsen for this welcome contribution.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Ethernet-driver for i.MX-based Wandboard
|
||||
========================================
|
||||
|
||||
The current release contains a port of the Linux kernel driver for the
|
||||
Ethernet card family originally produced by Freescale. We followed our
|
||||
established approach to tailor an independent device-driver environment (DDE)
|
||||
for the specific driver. To profit from synergies with the existing drivers of
|
||||
the _dde_linux_ repository, we took the Linux kernel 4.4.3 as reference.
|
||||
|
||||
For now the current version is limited to support the Wandboard Quad as this
|
||||
is the i.MX-based board that is nightly tested by our infrastructure. The
|
||||
support of other boards using the same IP core is planned for future releases.
|
||||
|
||||
The driver can be found in _dde_linux/src/drivers/nic/fec_. To test the driver,
|
||||
no further configuration is needed and you can have a look at one of the
|
||||
automatic network tests, like _lwip.run_, as a reference.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Thanks to Johannes Schlatow from the TU Braunschweig, the support of the
|
||||
Zynq-7000 boards by our base-hw kernel got extended. It is now possible to use
|
||||
all CPU cores instead of only the primary one.
|
||||
|
||||
|
||||
Updated Muen separation kernel
|
||||
==============================
|
||||
|
||||
The Muen SK port has been updated to the latest development version 0.9. The
|
||||
most notable features and improvements are the Crash Audit facility and support
|
||||
for MirageOS/Solo5 subjects which may be executed alongside Genode/base-hw.
|
||||
|
||||
Thanks to this feature, the Muen project has reached a milestone by
|
||||
self-hosting the [https://muen.sk] website on a Muen system. Currently, the
|
||||
network driver is provided by a Linux subject but with some work it should be
|
||||
possible to replace it with a Genode/base-hw nic_drv in the future.
|
||||
|
||||
Further details regarding Muen v0.9 can be found in the project's release
|
||||
notes [https://groups.google.com/forum/#!topic/muen-dev/FPL9sc4yaBE].
|
||||
|
||||
|
||||
Updated seL4 kernel
|
||||
===================
|
||||
|
||||
Our remaining patches regarding UEFI framebuffer support got integrated into
|
||||
the upstream codebase of the seL4 kernel. Hence, we updated our seL4 port to
|
||||
the upstream version containing our patches.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
Package management
|
||||
==================
|
||||
|
||||
The package-management tools introduced last year have become a vital part
|
||||
of Genode's workflow.
|
||||
|
||||
:Package management documentation:
|
||||
[https://genode.org/documentation/developer-resources/package_management]
|
||||
|
||||
Prompted by the development of the on-target installation and deployment
|
||||
mechanism featured in the current release, the tools received the following
|
||||
refinements:
|
||||
|
||||
:Use of tar.xz as archive format: This change significantly reduces the size of
|
||||
published depot content compared to the previously used tar.gz format.
|
||||
|
||||
:Subdirectories for archive versions:
|
||||
In the original version of the depot layout, archives were named as
|
||||
'<archive-name>-<version>'. Hence, the depot - in particular the download
|
||||
location - had directories that grew in two dimensions. First, when new
|
||||
archives were added. Second, when new versions of existing archives were
|
||||
added (usually corresponding to Genode's release cycle). In the mid-term,
|
||||
this would have resulted in a huge number of directory entries, e.g., in the
|
||||
_src/_ subdirectory. To avoid this problem, the new version uses the scheme
|
||||
'<archive-name>/<version>' instead. This way, at the _src/_ level, each
|
||||
archive has one subdirectory (the number of subdirectories corresponds to
|
||||
the number of archives). Inside the subdirectory, there is one entry per
|
||||
version.
|
||||
|
||||
:Controlled rebuild of binary archives:
|
||||
When calling the depot/create tool for a binary archive with 'FORCE=1', the
|
||||
underlying source archives are re-extracted and the binary archive is
|
||||
rebuilt. This is usually done after local changes in the source tree to
|
||||
apply version updates to depot archives as needed. However, the implicit
|
||||
rebuild is superfluous whenever the source-version remains the same. This is
|
||||
particular inconvenient when re-creating pkg archives that refer to a large
|
||||
number of src archives. Here, all binaries referenced by the pkg archive are
|
||||
rebuilt each time. The new 'REBUILD' argument allows the user to skip
|
||||
superfluous rebuilds in such situations. Normally, 'FORCE=1' implies
|
||||
'REBUILD=1'. However, by explicitly specifying 'REBUILD=', existing binary
|
||||
archives whose versions remain unchanged are kept instead of being rebuilt.
|
||||
|
||||
|
||||
Offline validation of XML configurations
|
||||
========================================
|
||||
|
||||
The _tool/run_ tool now automatically checks configurations against
|
||||
target-specific XML schemes. Each component may define a configuration
|
||||
scheme-file in its _target.mk_ file as follows:
|
||||
|
||||
! CONFIG_XSD = my_config.xsd
|
||||
|
||||
When the run tool checks the configuration of an instance of Genode's init
|
||||
component, it additionally iterates through all start nodes of this
|
||||
configuration. For each start node, it checks whether the according component
|
||||
provides a configuration-scheme file and, if so, applies it to the
|
||||
configuration inside the start node. This is done recursively. I.e., also the
|
||||
child configurations of a sub-init of a sub-init ... of the top-level init
|
||||
are covered this way.
|
||||
|
||||
Whenever the run tool detects an error in one of the checked configurations,
|
||||
it stops and points out the location of the error. By now, there exist
|
||||
configuration schemes for the init, the NIC router, and the trace logger
|
||||
components. Our intention is that every component that interprets its
|
||||
configuration will eventually be accompanied by such a scheme - not only to
|
||||
validate actual configuration input but also to serve as documentation for
|
||||
users of the component.
|
||||
|
||||
|
||||
Automated ABI consistency checks
|
||||
================================
|
||||
|
||||
In [https://genode.org/documentation/release-notes/17.02#Genode_Application_Binary_Interface - version 17.02],
|
||||
we introduced a kernel-agnostic ABI, which ultimately paved the ground for
|
||||
Genode's package management. For the time being, the ABI is not set in stone.
|
||||
It is expected to evolve for some time until it hopefully approaches ABI
|
||||
stability in the mid term. Whenever Genode's API changes, the ABI may be
|
||||
affected. For example, symbol sizes may grow. Until now, side effects on the
|
||||
ABI had to be curated manually. In practice, however, such side effects are
|
||||
too easy to miss. Therefore, the current release adds a mandatory ABI checking
|
||||
step to the build process. A new _tool/check_abi_ tool is invoked whenever a
|
||||
shared object is built. It reports flaws in the ABI definition (such as
|
||||
duplicated symbols) as well as inconsistencies between a shared object and its
|
||||
ABI.
|
||||
|
||||
@@ -1,766 +0,0 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 18.05
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The driver behind the release 18.05 is the rapid evolution of the Sculpt
|
||||
general-purpose OS. Following the initial version from February, which was
|
||||
targeted at early adopters, the new Sculpt for The Curious (TC) introduces a
|
||||
much more welcoming and empowering user experience (Section
|
||||
[Sculpt for The Curious]).
|
||||
|
||||
It goes without saying that the interactive and dynamic nature of the Sculpt
|
||||
scenario puts a lot more pressure on Genode's components compared to static
|
||||
workloads. For example, Sculpt calls for the dynamic adjustment of user-level
|
||||
network routing, the dynamic detection and management of partitions and file
|
||||
systems, the support of USB storage devices from diverse vendors, and a way to
|
||||
adapt the visual appearance to a great variety of screen resolutions. Most
|
||||
improvements described below are our responses to these challenges.
|
||||
|
||||
That said, the release is not short of new features either. E.g., it features
|
||||
the initial port of OpenJDK's HotSpot VM for executing Java programs on Genode
|
||||
directly (Section [Java language support]), improves the support for the NXP
|
||||
i.MX family of SoCs (Section [NXP i.MX SoC]), and enhances the VFS with new
|
||||
plugins for copy-on-write and the auditing of file accesses
|
||||
(Section [New VFS plugins]).
|
||||
|
||||
The release is complemented by the annual update of the Genode Foundations
|
||||
book (PDF), which covers the fundamentals of the framework in great detail
|
||||
(Section [New revision of the Genode Foundations book]).
|
||||
|
||||
|
||||
Sculpt for The Curious
|
||||
######################
|
||||
|
||||
With Sculpt for The Curious (TC), Genode 18.05 features the second revision of
|
||||
the Sculpt general-purpose OS. Compared to the initial version for Early
|
||||
Adopters (EA), it features a new interactive system-management component that
|
||||
streamlines common tasks like the management of storage devices, or
|
||||
configuring the network connectivity. The highlights of the new version of the
|
||||
base system image are:
|
||||
|
||||
* Live-customization of almost all aspects of the system,
|
||||
* The ability to install and run software in memory only,
|
||||
* Hotplugging of USB storage devices,
|
||||
* New support for NVMe storage devices in addition to SATA disks,
|
||||
* Interactive network configuration including Wifi connectivity,
|
||||
* Interactive management and inspection of storage devices and partitions,
|
||||
* The option to host a complete and customized Sculpt installation on a
|
||||
USB stick,
|
||||
* Automated on-demand installation of software packages with visual feedback,
|
||||
* Scalable fonts that are automatically adjusted to the screen resolution, and
|
||||
* UEFI boot supported by default.
|
||||
|
||||
The base image is extensible by downloadable software packages that may
|
||||
originate from different sources, safeguarded by cryptographic signatures.
|
||||
It contains several example subsystems as a starting point:
|
||||
|
||||
* Basic GUI components like a window manager, a scalable backdrop, a
|
||||
font server, and a simple software-rendering demo,
|
||||
* A light-weight noux runtime for executing command-line-based software
|
||||
such as GNU coreutils, bash, and vim.
|
||||
* A package for downloading the installer and a suitable virtual-machine
|
||||
configuration for Debian Linux,
|
||||
* VirtualBox running Debian Linux,
|
||||
* An example for running libretro-based games,
|
||||
* A disposable VM that runs Firefox on TinyCore Linux, executed either in
|
||||
VirtualBox or the light-weight Seoul virtual-machine monitor,
|
||||
* A Qt5-based text editor.
|
||||
|
||||
Please refer to the updated
|
||||
[https://genode.org/documentation/articles/sculpt-tc - Sculpt documentation]
|
||||
to explore Sculpt TC.
|
||||
|
||||
The Sculpt version included with the current release requires the user to
|
||||
build a boot image by hand. Following the steps described in the
|
||||
documentation, this procedure takes a few minutes. We plan to provide
|
||||
downloadable boot images a few weeks down the road once Sculpt TC received
|
||||
intensive day-to-day testing by the early adopters. Your feedback is very
|
||||
welcome!
|
||||
|
||||
|
||||
New revision of the Genode Foundations book
|
||||
###########################################
|
||||
|
||||
The "Genode Foundations" book received its annual revision, which reflects
|
||||
the evolution of the framework over the past year. Specifically, the changes
|
||||
since the last year's edition are:
|
||||
|
||||
: <div class="visualClear"><!-- --></div>
|
||||
: <p>
|
||||
: <div style="clear: both; float: left; margin-right:20px;">
|
||||
: <a class="internal-link" href="https://genode.org">
|
||||
: <img class="image-inline" src="http://genode.org/documentation/genode-foundations-title.png">
|
||||
: </a>
|
||||
: </div>
|
||||
: </p>
|
||||
|
||||
* Changed boot-loader infrastructure on PC hardware
|
||||
* Package management
|
||||
* Structural changes of Genode's custom base-hw kernel
|
||||
* API improvements: Unicode handling, support for XML-based data models,
|
||||
timeout-handling API
|
||||
|
||||
: <div class="visualClear"><!-- --></div>
|
||||
|
||||
To examine the changes in detail, please refer to the book's
|
||||
[https://github.com/nfeske/genode-manual/commits/master - revision history].
|
||||
|
||||
|
||||
Storage infrastructure
|
||||
######################
|
||||
|
||||
VFS library and plugin interface
|
||||
================================
|
||||
|
||||
The VFS (Virtual-File-System) library was expanded to meet new requirements
|
||||
for the Sculpt scenario. The traditional file-system medium for component
|
||||
state and configuration sculpting is the *ram_fs* server, but with the
|
||||
limitation that files stored in the server are ephemeral. Any changes to
|
||||
the initial state are lost when a system is shut down or the *ram_fs* server
|
||||
is restarted. Now that persistent storage is usually served by a VFS plugin
|
||||
hosted by the VFS server, it was a natural progression to introduce a means
|
||||
for indicating VFS changes with 'File_system' session notifications. To this
|
||||
end the VFS server was amended to send session notifications, and notification
|
||||
support was added to the Rump and FatFs VFS plugins, allowing Ext2 and FAT
|
||||
file-systems to host dynamic component state and configuration information.
|
||||
|
||||
Using the VFS for serving font data produced from files stored in the VFS made
|
||||
it practical to allow VFS plugins to introspect the file system. Plugins now
|
||||
have the means to access arbitrary paths from the file-system root or they may
|
||||
host and expose their own internal file systems.
|
||||
|
||||
While the core of the VFS library is small compared to contemporaries in other
|
||||
operating systems, the moment came to promote the VFS from a static to a
|
||||
shared library. Components that use the C runtime have always loaded the VFS
|
||||
dynamically as a subsystem of _libc.lib.so_, but native components carried the
|
||||
bulk of its implementation. The VFS library is now provided as a shared
|
||||
library and is included with the front-end server in the _src/vfs_ depot
|
||||
archive. This change affects components that have been rebuilt against the
|
||||
shared library but do not have their ROM policies updated to allow access to
|
||||
the _vfs.lib.so_ ROM.
|
||||
|
||||
|
||||
New VFS plugins
|
||||
===============
|
||||
|
||||
File-system introspection has made two additional plugins possible, the *audit*
|
||||
and *cow* plugins.
|
||||
|
||||
The *audit* plugin logs VFS paths as they are accessed to a dedicated LOG
|
||||
session. This is useful for finding the files required by third-party
|
||||
components without relying on documentation or auditing source code.
|
||||
|
||||
The *cow* plugin emulates copy-on-write behavior by copying the contents of
|
||||
files lying in a read-only path to a read-write path as they are opened. This
|
||||
plugin is considered a proof-of-concept and under-performing, but opens a way
|
||||
of experimenting with seeding user-managed file-systems from immutable
|
||||
file-system archives.
|
||||
|
||||
Plugins of this kind are most appropriately instantiated in the VFS server
|
||||
with policies to restrict the intended components into paths provided by the
|
||||
plugins. This prevents a component from escaping the effect of the plugin. An
|
||||
example of "auditing" a libc component follows:
|
||||
|
||||
! <start name="audit_fs">
|
||||
! <binary name="vfs"/>
|
||||
! <config>
|
||||
! <vfs>
|
||||
! <dir name="data"> <!-- source files -->
|
||||
! <tar "data.tar"/>
|
||||
! <ram/>
|
||||
! </dir>
|
||||
! <dir name="audit"> <!-- virtual path that captures /data -->
|
||||
! <audit path="/data"/>
|
||||
! </dir>
|
||||
! </vfs>
|
||||
! <!-- route into virtual audit path -->
|
||||
! <policy label_suffix="audit" root="/audit" writeable="yes"/>
|
||||
! </config>
|
||||
! </start>
|
||||
!
|
||||
! <start name="app">
|
||||
! <config>
|
||||
! <libc stdout="/log" stderr="/log"/>
|
||||
! <vfs>
|
||||
! <log/>
|
||||
! <fs label="audit"/>
|
||||
! </vfs>
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
|
||||
Improved disk-partition discovery and access
|
||||
============================================
|
||||
|
||||
The 'part_blk' component, which parses the partition table on a block device
|
||||
and provides access to each partition through a block session, was extended to
|
||||
make it easier to implement a management component on top of it. It now
|
||||
features additional attributes in its report. For one the block size of each
|
||||
partition as well as the type of the file system on the partition are
|
||||
reported. The file system probing implementation is minimal and only contains
|
||||
file systems that are commonly used on Genode systems, i.e., FAT32 and Ext2.
|
||||
Furthermore, on GPT formatted disks, each partition has an 'expandable'
|
||||
attribute that contains the number of blocks by which the partition can be
|
||||
grown. The following exemplary report illustrates the adjustments:
|
||||
|
||||
!<partitions type="gpt" total_blocks="500118192" gpt_total="500118125" gpt_used="302254080">
|
||||
! <partition number="1" name="BIOS boot partition"
|
||||
! type="21686148-6449-6e6f-744e-656564454649" guid="db0701aa-02ae-474d-92d0-82738bfce5d2"
|
||||
! start="2048" length="2048" block_size="512"/>
|
||||
! <partition number="2" name="EFI System"
|
||||
! type="c12a7328-f81f-11d2-ba4b-00a0c93ec93b" guid="74e43226-2afb-4575-bdda-83bf72f5a6e7"
|
||||
! start="4096" length="262144" block_size="512" file_system="FAT32"/>
|
||||
! <partition number="3" name="GENODE"
|
||||
! type="0fc63daf-8483-4772-8e79-3d69d8477de4" guid="a950091d-87ba-4800-85bf-7b6a58abe6d5"
|
||||
! start="235147264" length="67108864" block_size="512" file_system="Ext2"
|
||||
! expandable="197862064"/>
|
||||
!</partitions>
|
||||
|
||||
The heuristics of how the component probes the partition table were also
|
||||
loosened. Instead of explicitly enabling support for GPT, the component will
|
||||
now always try to parse the MBR as well as the GPT. It will bail out if both
|
||||
are considered valid since using GPT/MBR hybrid tables is not supported and it
|
||||
should be up to the user to make an educated decision. In cases where there is
|
||||
no partition table, a 'partitions' report of 'type="disk"' will be generated
|
||||
in which the complete disk is presented as partition number '0'. This is
|
||||
needed as compatibility fallback for Sculpt EA installations.
|
||||
|
||||
|
||||
Creating and modifying GUID partition tables
|
||||
============================================
|
||||
|
||||
Part of the enhancements of Sculpt TC is the ability to manipulate the block
|
||||
device used by Sculpt. We implemented a component called 'gpt_write', which
|
||||
can create and modify a GPT and its entries. It considers alignment
|
||||
constraints to make better use of 512e devices. It will, however, not perform
|
||||
any boundary checking. It does not handle overlapping partitions and only when
|
||||
applying a partition, it makes sure that the partition will fit. The following
|
||||
configuration illustrates its operation:
|
||||
|
||||
!<start name="gpt_write">
|
||||
! <resource name="RAM" quantum="2M"/>
|
||||
! <config verbose="yes" initialize="yes" align="4K">
|
||||
! <actions>
|
||||
! <add entry="1" type="BIOS" label="GRUB BIOS" start="2048" size="1M"/>
|
||||
! <add entry="2" type="EFI" label="EFI System" start="4096" size="16M"/>
|
||||
! <add entry="3" type="Linux" label="GENODE" start="36864" size="128M"/>
|
||||
! <add type="BDP" label="FAT32 Data" size="max"/>
|
||||
! <delete entry="1"/>
|
||||
! <delete label="FAT32 Data"/>
|
||||
! <modify label="GENODE" new_label="GENODE*" new_size="max"/>
|
||||
! </actions>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
Please read _repos/gems/src/app/gpt_write/README_ for more detailed information
|
||||
on how to use the component and feel free to check out the run script
|
||||
_repos/gems/run/gpt_write.run_.
|
||||
|
||||
|
||||
User-level networking
|
||||
#####################
|
||||
|
||||
NIC router
|
||||
==========
|
||||
|
||||
The NIC router has received major improvements that were mainly motivated by
|
||||
our daily experience with the Sculpt scenario where the router serves as NAPT
|
||||
component in front of the virtual machines that host our work OS's. In this
|
||||
role, it is subject to a permanent load driven by real-world tasks.
|
||||
Furthermore, it has to have a user interface that makes it a pleasant
|
||||
experience to deploy in a dynamic environment. This led to our primary goal:
|
||||
We had to overcome the need to restart the NIC router, and thereby all
|
||||
components that depend on it, whenever its configuration changes and while
|
||||
doing so, not to interrupt the communication of its client unnecessarily.
|
||||
|
||||
We managed to make the NIC router fully re-configurable at runtime in a way
|
||||
that it always tries to keep as much state information as possible throughout
|
||||
the process. This means that network communication going through the NIC
|
||||
router is not affected by a configuration update unless the configuration
|
||||
change affects parts that were involved in an existing communication channel.
|
||||
|
||||
One prerequisite for this feature was that NIC session clients can connect at
|
||||
any time to the NIC router regardless of whether there is a matching domain
|
||||
for the session or not. As long as a session has no domain, the NIC router
|
||||
does not send any packet to it and drops all packets coming from it. But, at
|
||||
least, the session and the corresponding client component stay alive, even if
|
||||
their already assigned domain disappears with a new configuration.
|
||||
|
||||
At the uplink, in contrast, the lifetime of the session remains bound to the
|
||||
lifetime of the domain. The uplink domain-tag received a new attribute
|
||||
named 'label' (only considered at the domain-tag of the uplink). It denotes
|
||||
the label of the uplink session. With these two particularities of the uplink
|
||||
domain, one can now easily switch between different NIC session servers. The
|
||||
NIC router will close and request the corresponding NIC session with the
|
||||
current 'label' value if the 'domain' node is removed/added or the label
|
||||
changes. Thereby, the NIC router can now be used to dynamically switch between
|
||||
network interfaces like wireless and wired adapters.
|
||||
|
||||
Furthermore, we improved the NIC router's ability to handle DNS server
|
||||
information. Domains can wait for the DNS server info of the DHCP client of
|
||||
another domain. This is done with the new attribute 'dns_server_from' in the
|
||||
'<dhcp_server>' tag. Each time the DNS server info of the remote domain
|
||||
changes, the DHCP server with the 'dns_server_from' attribute will toggle the
|
||||
link state of each session at its domain. This can be used by clients as a
|
||||
hint to request their DHCP info anew from the NIC router and thereby receive
|
||||
the updated DNS server information.
|
||||
|
||||
When it comes to protocols, the most notable change is that the NIC router now
|
||||
also supports routing and NAPT for ICMP. With the new '<icmp>' sub node of the
|
||||
'<domain>' tag, ICMP routes to other domains can be created. Instead of ports,
|
||||
the ICMP IDs are used for NAPT. Similar to the 'udp-ports' and 'tcp-ports'
|
||||
attributes, the size of the ID space for each NAPT client is configured via
|
||||
the new 'icmp-ids' attribute in the '<nat>' tag.
|
||||
|
||||
Last but not least, the following small features were also added to the NIC
|
||||
router:
|
||||
|
||||
:Attribute 'verbose_packets' for the '<config>' and the '<domain>' node:
|
||||
Toggles the logging of most important protocol header fields globally or
|
||||
domain-locally. The 'verbose' attribute does not affect this kind of debug
|
||||
output anymore.
|
||||
|
||||
:Report DNS server info:
|
||||
If the 'config' attribute in the '<report>' node is enabled, the NIC router
|
||||
will now also report the DNS server info for each domain.
|
||||
|
||||
:Attribute 'config_triggers' in the '<report>' node:
|
||||
Toggles whether the NIC router immediately sends a report whenever the IPv4
|
||||
configuration of a domain changes, regardless of any timeouts.
|
||||
|
||||
:IPv4 point-to-point support:
|
||||
If a domain receives an IP configuration with a subnet mask of
|
||||
255.255.255.255 it will switch to point-to-point IPv4 (requires a valid
|
||||
gateway address at the domain).
|
||||
|
||||
:ICMP destination unreachable on non-routable packets:
|
||||
The NIC router now responds with an ICMP "destination unreachable" packet to
|
||||
packets that are not routable at an interface with a domain.
|
||||
|
||||
For more information, have a look at the _os/src/server/nic_router/README_
|
||||
file. Examples can be found in the run scripts
|
||||
_dde_linux/run/nic_router_uplinks.run_,
|
||||
_libports/run/nic_router_dyn_config.run_, and _os/run/ping_nic_router.run_.
|
||||
|
||||
|
||||
NIC dump
|
||||
========
|
||||
|
||||
The output level of the NIC dump component can now be configured per protocol
|
||||
by using the protocol names as attributes: 'eth', 'arp', 'ipv4', 'dhcp',
|
||||
'udp', 'icmp', and 'tcp'.
|
||||
|
||||
The available debug levels are:
|
||||
|
||||
:no: Do not print out this protocol.
|
||||
:name: Print only the protocol name.
|
||||
:default: Print a short summary of the most important header values.
|
||||
:all: Print all available header values.
|
||||
|
||||
Additionally, you can set a default debug level for protocols that are not
|
||||
configured using the 'default' attribute.
|
||||
|
||||
For more information, please refer to _os/src/server/nic_dump/README_.
|
||||
|
||||
|
||||
GUI stack
|
||||
#########
|
||||
|
||||
With Sculpt becoming more and more end-user oriented, Genode's GUI stack came
|
||||
into focus. It was time to reconsider several interim solutions that worked
|
||||
well in the past but would not scale up to a modern general-purpose OS. Two
|
||||
concrete examples are the support of scalable fonts and Unicode characters. In
|
||||
the past, Genode used to restrict textual output to the Latin-1 character set
|
||||
and employed pixel-based fonts only. The current release overcomes these
|
||||
limitations by featuring completely new text-output facilities.
|
||||
|
||||
|
||||
UTF-8 support and improved text rendering
|
||||
=========================================
|
||||
|
||||
The UTF-8 text encoding overcomes the severely limited code-point range of the
|
||||
ASCII and Latin-1 character sets by representing characters by a varying
|
||||
number of bytes. Today, UTF-8 is generally considered as the standard encoding
|
||||
for text. The new UTF-8 decoder at _os/util/utf8.h_ clears the path for
|
||||
Genode's native GUI components to follow suit. The first beneficiary is
|
||||
Genode's graphical terminal, which has become able to display Unicode
|
||||
characters and pass user input as UTF-8-encoded data to its terminal-session
|
||||
client.
|
||||
|
||||
|
||||
Terminal enhancements
|
||||
=====================
|
||||
|
||||
Speaking of the graphical terminal, the current incarnation got a welcome
|
||||
overhaul. First, we reduced its complexity by removing obsolete features like
|
||||
built-in keyboard-layout handling, which are no longer needed when combining
|
||||
the terminal with our modern input-filter component. Furthermore, the terminal
|
||||
has become dynamically resizeable, forwarding screen-size changes to the
|
||||
terminal client. Should the client be a Noux runtime, such a change is
|
||||
reflected to the running application as a SIG_WINCH signal. The application -
|
||||
e.g., Vim - responds to the signal by requesting the new terminal size.
|
||||
Finally, the terminal protocol was changed from 'linux' escape sequences to
|
||||
'screen' escape sequences in the anticipation of making the terminal more
|
||||
flexible in the future.
|
||||
|
||||
|
||||
Text rendering
|
||||
==============
|
||||
|
||||
Throughout Genode, many GUI components reused the text-output utilities
|
||||
of the nitpicker GUI server. These utilities, however, relied on a simple
|
||||
pixel font format. To make the text output more flexible, nitpicker's text
|
||||
painter located at _nitpicker_gfx/text_painter.h_ has been replaced by a
|
||||
completely new implementation that decouples the font format from the
|
||||
glyph rendering and takes UTF-8 strings as input. In the process, the glyph
|
||||
rendering got a lot more sophisticated, supporting horizontal sub-pixel
|
||||
positioning and filtering.
|
||||
|
||||
|
||||
Font-format support
|
||||
===================
|
||||
|
||||
To remove the omnipresent use of fixed-size pixel fonts throughout Genode,
|
||||
the following new components entered the picture:
|
||||
|
||||
First, the new 'ttf_font' library implements nitpicker's font interface by
|
||||
using the TrueType renderer of the STB single-header library.
|
||||
|
||||
Second, the new 'vfs_ttf' VFS plugin uses the 'ttf_font' library to export a
|
||||
rendered TrueType font as a virtual file system. The various font properties
|
||||
as well as the actual glyph images become accessible as regular files. This
|
||||
way, an application that needs to draw text can read the glyph data directly
|
||||
from its VFS instead of depending on a font-rendering library.
|
||||
|
||||
Third, the new 'Vfs_font' utility located at _gems/include/gems/vfs_font.h_
|
||||
implements nitpicker's font interface by obtaining the glyphs from the
|
||||
component-local VFS. It is complemented by the 'Cached_font' utility, which
|
||||
implements an LRU glyph cache.
|
||||
|
||||
With this infrastructure in place, several existing GUI components could
|
||||
be updated, most prominently the graphical terminal and the menu-view
|
||||
widget-rendering engine. By facilitating the VFS as interface for propagating
|
||||
glyph data, components no longer need to manage fonts and their configuration
|
||||
individually. They just access their VFS. When integrating the component into
|
||||
a scenario, one can decide whether to mount a font-rendering library directly
|
||||
at the component, or - alternatively - route a file-system session to a
|
||||
central font server. The latter is just a regular VFS server with the fonts
|
||||
mounted as pseudo file systems. Since the glyph renderer is a VFS plugin, it
|
||||
could be replaced by another implementation in the future without touching any
|
||||
component.
|
||||
|
||||
|
||||
Modernized API for input-event processing
|
||||
=========================================
|
||||
|
||||
Genode's input-session interface changed very little over the years. Even
|
||||
though it received evolutionary enhancements from time to time, its design
|
||||
resembled a traditional C-style interface from the medieval era. We found that
|
||||
the interface left too much room for interpretation. In particular, the meta
|
||||
data per event type was defined in a rather ad-hoc way, which raised
|
||||
uncertainties. For example, is a button-press event accompanied with a
|
||||
positional value or not? To remove these uncertainties, the current release
|
||||
replaces the 'Input::Event', with a new implementation that facilitates a safe
|
||||
way of accessing event meta data. Besides this design change, there is one
|
||||
noteworthy semantic change as well. With the new interface, symbolic character
|
||||
information are provided along with their corresponding press events rather
|
||||
than as distinct events, which - according to our practical findings - greatly
|
||||
simplifies the consumer side of the 'Input::Event' interface.
|
||||
|
||||
|
||||
Improved keyboard-focus handling
|
||||
================================
|
||||
|
||||
The nitpicker GUI server multiplexes one screen among multiple GUI clients in
|
||||
a secure way. One aspect remained underdeveloped so far, which is the keyboard
|
||||
focus handling. Nitpicker's 'Session:focus' call previously triggered a one-off
|
||||
focus change at call time. This focus change did not pass the same code paths
|
||||
as a focus change triggered by a "focus" ROM update, which led to
|
||||
inconsistencies.
|
||||
|
||||
The new version changes the implementation of 'Session::focus' such that the
|
||||
relationship of the caller and the focused session is preserved beyond the
|
||||
call time. Whenever the calling session is focused in the future, the
|
||||
specified session will receive the focus instead. So 'Session::focus' no
|
||||
longer represents a single operation but propagates the information about the
|
||||
inter-session relationship. This information is taken into account whenever
|
||||
the focus is evaluated regardless of how the change is triggered. This makes
|
||||
the focus handling in scenarios like the window manager more robust.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
NVMe storage devices
|
||||
====================
|
||||
|
||||
Since NVMe devices have become common in contemporary systems, it is time to
|
||||
provide a driver for such devices on Genode. With this release, we introduce a
|
||||
component that is able to drive consumer-grade NVMe storage devices, i.e.,
|
||||
there is no support for namespace management or other enterprise-grade
|
||||
features. For now, to keep things simple, the driver uses the device in an
|
||||
old-fashioned way and uses only one I/O queue with at most 128 entries. That
|
||||
is to say it does not exploit the parallelism necessary to unlock the full
|
||||
potential of NVMe storage. Nonetheless, it performs well. The following
|
||||
snippet illustrates its configuration:
|
||||
|
||||
!<start name="nvme_drv">
|
||||
! <resource name="ram" quantum="8M"/>
|
||||
! <provides><service name="Block"/></provides>
|
||||
! <config>
|
||||
! <report namespace="yes"/>
|
||||
! <policy label_prefix="client1" writeable="yes"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
The component will generate a report, which contains all active namespaces, if
|
||||
reporting is enabled by setting the 'namespace' attribute of the '<report>'
|
||||
node to 'yes'. A report may look like the following example:
|
||||
|
||||
!<controller model="QEMU NVMe Ctrl" serial="FNRD">
|
||||
! <namespace id="1" block_count="32768" block_size="512"/>
|
||||
!</controller>
|
||||
|
||||
For an example on how to integrate this component, please have a look at the
|
||||
_repos/os/run/nvme.run_ script.
|
||||
|
||||
While implementing the NVMe driver, a new component for testing block-sessions
|
||||
was used. In contrast to the already existing 'blk_bench' and 'blk_cli'
|
||||
components, it features a variety of different test patterns, which can be
|
||||
selected in its configuration and can be used to test a block component more
|
||||
thoroughly. For more information please refer to
|
||||
_repos/os/src/app/block_tester/README_
|
||||
|
||||
|
||||
NXP i.MX SoC
|
||||
============
|
||||
|
||||
We extended the Linux kernel driver port for Ethernet cards found in NXP i.MX
|
||||
SoC, which was introduced in the previous release. Now does it not only
|
||||
support i.MX6Q SoC based boards like the Wandboard, but the i.MX53 and i.MX6SX
|
||||
SoC as well. The new driver was successfully tested with the i.MX53 Quick
|
||||
Start Board and the Nitrogen6 SOLOX. The latter board even contains two
|
||||
Ethernet cards. But due to technical limitations of the board design, the same
|
||||
driver instance has to be used for both cards. Currently, the driver is
|
||||
tweaked to run on different boards via its configuration ROM. When no
|
||||
configuration is provided, it appropriates the values for successfully
|
||||
executing on the Wandboard. The following is an example configuration for the
|
||||
i.MX53:
|
||||
|
||||
! <config>
|
||||
! <card name="fec0" type="fsl,imx25-fec" mii="rmii" irq="87" mmio="0x63fec000"/>
|
||||
! </config>
|
||||
|
||||
As a side effect of enabling networking on the Nitrogen6 SOLOX, support for
|
||||
GPIO based signals has been added to the framework too. The existing GPIO
|
||||
driver for i.MX53 SoC got extended to additionally support the i.MX6 family.
|
||||
|
||||
There are some known limitations when using different drivers like Ethernet
|
||||
and SD-card drivers on the Wandboard right now. At the moment, those drivers
|
||||
adjust clock parameters and I/O pin configurations independently from each
|
||||
other, which can lead to inconsistencies. We plan to address those issues with
|
||||
the implementation of a platform driver for the i.MX6 SoC family.
|
||||
|
||||
|
||||
Improved USB-storage driver
|
||||
===========================
|
||||
|
||||
We improved the stability of the USB-storage driver (usb_block_drv) and
|
||||
made it compatible with a lot more devices as the driver has become a pivotal
|
||||
ingredient of the Sculpt scenario. Due to the changes, the way the driver
|
||||
operates has changed. On the one hand, now it first tries to use 10-byte
|
||||
Command Descriptor Blocks (CDB) in its SCSI layer and will only switch to
|
||||
16-byte CDBs when it encounters a device whose blocks cannot be completely
|
||||
accessed via the former descriptor size. On the other hand, because some
|
||||
tested devices stopped working after issuing a USB device reset, the reset was
|
||||
made optional. By setting the 'reset_device' attribute in the '<config>' node
|
||||
to 'yes', the driver is instructed to perform the USB device reset.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Packaged Qt5 framework
|
||||
======================
|
||||
|
||||
We created package recipes for all previously ported Qt5 libraries and their
|
||||
dependencies and adapted the run scripts accordingly. Please note that the
|
||||
host tools needed for building Qt applications (moc, rcc, uic) are not built
|
||||
automatically anymore, but need to be built and installed manually with the
|
||||
new 'tool/tool_chain_qt5' script.
|
||||
|
||||
|
||||
Java language support
|
||||
=====================
|
||||
|
||||
Over the course of the past year, we started to look into Java support for
|
||||
Genode with the ultimate goal of porting an existing Java Virtual Machine
|
||||
(JVM), which translates and executes Java byte code, to Genode. After
|
||||
investigating possible JVM candidates, it became obvious that
|
||||
[http://openjdk.java.net - OpenJDK] is the only viable option when looking for
|
||||
a functional, maintained, feature complete, and open-source Java SDK.
|
||||
Therefore, we decided upon OpenJDK version 9 and started to port OpenJDK's
|
||||
HotSpot virtual machine.
|
||||
|
||||
In the first step, we followed the approach to enable HotSpot's internal
|
||||
Just-in Time (JIT) compiler, which translates byte code into machine code and
|
||||
is the option with the most to offer performance wise. But we also wanted
|
||||
support for ARM platforms and soon realized, there was almost no JIT compiler
|
||||
support for ARM other than for Linux. The Linux version is deeply integrated
|
||||
into the Linux system libraries (e.g., glibc), which makes it very hard to
|
||||
bring the compiler onto Genode. For example, Genode uses FreeBSD's libc and
|
||||
that would now have to offer glibc semantics.
|
||||
|
||||
After additional research, we found the so-called interpreter version of the
|
||||
HotSpot VM. This version does not compile byte code, but interprets and
|
||||
emulates the code at runtime. It is of course slower than the JIT compiler
|
||||
version, but also machine-architecture independent, so the same HotSpot VM can
|
||||
be compiled for x86 and ARM platforms. With the JVM running on Genode, we
|
||||
added networking and file-system access support via Genode's VFS layer. Note,
|
||||
there is no graphical toolkit support as of now, but most standard library
|
||||
classes should work. Also, the byte code has to be compiled on a different
|
||||
host system (e.g., Linux, *BSD) as of now, since we did not bring the Java
|
||||
compiler to Genode.
|
||||
|
||||
To give Java a spin, a run script can be found under _ports/run/java.run_.
|
||||
|
||||
|
||||
Ada language support
|
||||
====================
|
||||
|
||||
Support for components and libraries written in the Ada/SPARK programming
|
||||
language experienced a rework with the final goal of seamless integration with
|
||||
the base framework. We added a new _ada_ library, which contains a (currently
|
||||
minimal) runtime taken from the sources of our GCC port and thus is always
|
||||
consistent with the tool chain in use. It is built as a shared library
|
||||
_ada.lib.so_ that needs to be added to the list of boot modules.
|
||||
|
||||
The example in _libports/src/test/ada_ showcases the implementation of an Ada
|
||||
component using a custom library _test-ada_, which is also implemented in Ada.
|
||||
|
||||
|
||||
Seoul VMM on NOVA
|
||||
=================
|
||||
|
||||
The Seoul/Vancouver VMM - introduced to Genode with release 11.11 - received
|
||||
some renovations to be able to run recent Linux VMs. Namely the output of the
|
||||
guest during early boot is now visible and the network models got revised.
|
||||
Additionally, the Seoul VMM has been packaged and can be used in Sculpt.
|
||||
|
||||
|
||||
Ported software
|
||||
===============
|
||||
|
||||
The [https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby - Stubby]
|
||||
DNS daemon has been ported to begin experimentations with DNS as a native
|
||||
service. There is a tendency for DNS configuration frameworks to diverge
|
||||
between operating systems and releases, an inconvenience that is magnified
|
||||
when maintaining virtual machines. Name-server configuration via DHCP has been
|
||||
the only constant, so hosting DNS natively and configuring virtual-machines
|
||||
with the *nic_router* DHCP server presents itself as a viable solution to the
|
||||
guest resolver quagmire. Expect DNS services in later Sculpt releases.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Accessing PCI via ECAM/MMCONF
|
||||
=============================
|
||||
|
||||
The platform driver on x86 is trusted with guarding access to PCI
|
||||
devices. Up to now, I/O ports have been used to configure the PCI subsystem.
|
||||
|
||||
On modern x86 architectures, PCI devices can be configured by using Memory
|
||||
Mapped I/O (MMIO). This method was introduced with PCI Express and is called
|
||||
Enhanced Configuration Access Mechanism (ECAM). For Each PCI device a separate
|
||||
4 KiB MMIO page exists to serves as the configuration interface between OS and
|
||||
PCI device.
|
||||
|
||||
The exact location of all the 4K MMIO pages of the PCI devices is machine
|
||||
specific and must be determined during the bootstrap phase. The ACPI driver on
|
||||
Genode is in charge of this procedure and reports the location of the
|
||||
ECAM/MMCONF region to the platform driver via the 'acpi' ROM.
|
||||
|
||||
Besides using a modern PCI interface, switching to ECAM/MMCON served to ease
|
||||
the execution of Genode/hw on top of the Muen separation kernel.
|
||||
|
||||
|
||||
Kernel-agnostic platform-information handling
|
||||
=============================================
|
||||
|
||||
Up to now, special kernel-specific information was propagated to components
|
||||
such as Virtualbox, the Seoul VMM, and the timer by reusing the
|
||||
kernel-provided data structures. For Genode/NOVA, the hypervisor info page
|
||||
(HIP) was exported as an ordinary Genode ROM. With the rise of Sculpt and the
|
||||
packaging of components in a - as far as possible - kernel-independent way,
|
||||
the propagation of kernel-specific information became a stumbling block.
|
||||
|
||||
With this release we abandon the 'hypervisor_info_page' ROM of Genode/NOVA and
|
||||
replace it with a Genode ROM called 'platform_info'. The 'platform_info' ROM
|
||||
is planned to contain solely information about the host hardware, which may
|
||||
not be gathered otherwise by Genode components. In the current state it
|
||||
contains information required by VMMs, namely whether AMD SVM or Intel VMX is
|
||||
available and usable. Additionally, the ROM contains information about the
|
||||
frequency of the time stamp counter.
|
||||
|
||||
|
||||
Updated seL4 kernel to version 9.0.1
|
||||
====================================
|
||||
|
||||
Thanks to Hinnerk van Bruinehsen, the seL4 version used by Genode has been
|
||||
updated to 9.0.1.
|
||||
|
||||
|
||||
Updated Muen separation kernel
|
||||
==============================
|
||||
|
||||
With the addition of memory-mapped access to the PCI config-space in Genode,
|
||||
base-hw subjects on Muen now only see the effectively assigned physical
|
||||
devices. This makes it possible to run Genode in parallel with other subjects
|
||||
and to pass-through different PCI devices for each instance.
|
||||
|
||||
The Muen update also brings a much simplified subject info structure plus some
|
||||
tweaks to the Muen system policy XML format to facilitate easier integration
|
||||
of new hardware platform specifications.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
Validating 3rd-party code downloads via SHA256
|
||||
==============================================
|
||||
|
||||
This release removes support for verifying source code of third-party ports
|
||||
with the SHA1 hash algorithm. Last year, SHA1 was banished as a credible
|
||||
cryptographic hash function after the demonstration of a full collision
|
||||
attack. Since the
|
||||
[https://genode.org/documentation/release-notes/14.05 - 14.05 release],
|
||||
port files have been verified using SHA1, this release replaces all file
|
||||
digests with SHA256 digests. Any port definitions maintained in external
|
||||
repositories are required to make these replacements as well. No collisions
|
||||
have been discovered against source code archives but nonetheless there is an
|
||||
obligation to widen our margin of safety.
|
||||
|
||||
|
||||
Creating GPT-based disk images by default
|
||||
=========================================
|
||||
|
||||
Up to now Genode's run tool was able to create x86 bootable images in three
|
||||
flavours:
|
||||
|
||||
* Either as ISO bootable by BIOS legacy - 'image/iso', or as
|
||||
* GPT partitioned disk image only bootable by UEFI - 'image/uefi', or as
|
||||
* MBR partitioned disk image only bootable by BIOS legacy - 'image/disk'.
|
||||
|
||||
With Sculpt came the demand to have a single image type that is in principle
|
||||
bootable by both UEFI and BIOS legacy. Additionally with Sculpt, we began to
|
||||
prefer working with GPT partitioned devices.
|
||||
|
||||
In the light of the new demands, we changed the 'image/disk' run tool support
|
||||
to create a GPT partitioned disk image bootable by a legacy BIOS and by UEFI.
|
||||
File diff suppressed because it is too large
Load Diff
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.
|
||||
899
doc/release_notes/18-02.txt
Normal file
899
doc/release_notes/18-02.txt
Normal file
@@ -0,0 +1,899 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 18.02
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
After being developed for over a decade, Genode remained a mystery for many
|
||||
people who looked at the project from a distance as it does not seem to fit
|
||||
any established category of software. In 2018 - declared as the Year of Sculpt
|
||||
on our [https://genode.org/about/road-map - roadmap] - this will hopefully
|
||||
change. Genode 18.02 features the first revision of Sculpt, which is a
|
||||
Genode-based operating system for general-purpose computing. After being used
|
||||
as day-to-day OS by the entire team of Genode Labs for several months, we feel
|
||||
that the time is right to share the system with a broader audience (Section
|
||||
[Sculpt for Early Adopters]).
|
||||
|
||||
One fundamental feature of Sculpt is the ability to install and deploy
|
||||
software from within the running operating system, which is universally
|
||||
expected from any modern general-purpose OS. Section
|
||||
[On-target package installation and deployment] presents Genode's unique
|
||||
take on the topic of software installation and deployment.
|
||||
|
||||
Besides Sculpt, the current release has no shortage of other improvements.
|
||||
Genode's growing arsenal of 3rd-party software received profound updates and
|
||||
additions, including VirtualBox, Muen, seL4, several GNU packages, and
|
||||
libraries. Also the user-level networking stack - including the Linux-based
|
||||
LxIP stack and our custom NIC-router component - received a lot of attention.
|
||||
Thanks to the added network driver for i.MX-based hardware, this networking
|
||||
infrastructure becomes usable on embedded platforms based on this SoC.
|
||||
Furthermore, the current release continues the cultivation of the Nim
|
||||
programming language for Genode components.
|
||||
|
||||
|
||||
Sculpt for Early Adopters
|
||||
#########################
|
||||
|
||||
The current release features the first revision of Sculpt, which is a
|
||||
Genode-based operating system for general-purpose computing. This initial
|
||||
version is called Sculpt for Early Adopters (EA). Its target audience are
|
||||
enthusiasts who are already familiar with Genode and are eager to use a
|
||||
Genode-based operating system on their machines. As outlined on the
|
||||
[https://genode.org/about/road-map - roadmap], later versions will become
|
||||
increasingly approachable.
|
||||
|
||||
[image sculpt_overview]
|
||||
|
||||
Please refer to the official
|
||||
[https://genode.org/documentation/articles/sculpt-ea - Sculpt documentation]
|
||||
to step right into the adventure.
|
||||
|
||||
|
||||
On-target package installation and deployment
|
||||
#############################################
|
||||
|
||||
In May last year, we introduced the package-management concept for Genode to
|
||||
pursue two goals. First, to overcome the naturally limited scalability of
|
||||
composing Genode systems solely from source. This limit became evident in
|
||||
complex system scenarios that incorporate a huge amount of 3rd party software.
|
||||
Thanks to the introduced _depot_ concept and its integration in Genode's
|
||||
workflow - in particular the run tool - the work of system integration became
|
||||
much more structured (by caring about packages instead of individual build
|
||||
targets), robust (by avoiding conditions in run scripts), and quick (by the
|
||||
accelerated test cycle when using pre-built packages).
|
||||
|
||||
The second goal is the ability to update and extend a running Genode system on
|
||||
the fly. We are happy to have reached this goal with the current release. As
|
||||
exemplified by the Sculpt scenario, packages cannot only be used as building
|
||||
blocks for system images but also as subsystems dynamically installed and
|
||||
deployed on target. Even though installation and deployment are closely
|
||||
related topics, both involve distinct challenges, which allow Genode to shine.
|
||||
|
||||
|
||||
Installation / update
|
||||
=====================
|
||||
|
||||
In traditional operating systems, the installation and update of system
|
||||
software is the job of privileged programs. For example, a package manager in
|
||||
a GNU/Linux system is typically executed with root privileges. This is
|
||||
troublesome because the functionality of such a program is extremely complex.
|
||||
In particular it is exposed to the network and has to parse content
|
||||
originating from potentially untrusted parties. Therefore, potential software
|
||||
vulnerabilities should be expected. However, in modern OSes, these programs
|
||||
are just assumed to behave correctly. If this overly optimistic assumption
|
||||
doesn't hold, the entire system is at risk.
|
||||
|
||||
Genode helps us to mitigate this problem by modelling each installation step
|
||||
as a distinct component composition where each component has a well-defined
|
||||
and extremely narrow role. The installation is an iterative sequence that
|
||||
is orchestrated by the so-called download-manager component
|
||||
(Figure [depot_download]).
|
||||
|
||||
[image depot_download]
|
||||
|
||||
Initially, the download manager receives a list of content to be installed
|
||||
into the local depot, which is stored on the file system. The depot may
|
||||
already be populated with (portions of) this content. In the first step, the
|
||||
download manager must determine the parts that are missing. To do that, it
|
||||
does not access the file system directly but instead hands over this task to a
|
||||
disposable helper component called _depot-query_ that is spawned within a
|
||||
dynamic init instance. This indirection has two benefits. First, the download
|
||||
manager is not bothered with the complexity of accessing the file system. It
|
||||
does not even have any notion of files. Second, the download manager is
|
||||
effectively shielded from the file system. Should the file system misbehave,
|
||||
the liveliness of the download manager remains unaffected.
|
||||
|
||||
[image depot_download_query_deps]
|
||||
|
||||
The depot-query component reports its findings to a report session. The report
|
||||
eventually reaches the download manager as an updated ROM module. Given the
|
||||
list of missing content, the download manager has to determine the information
|
||||
of where to obtain the content from and the public key of the content creator.
|
||||
This information is contained within the depot. So the download manager issues
|
||||
another request to the depot-query component in order to obtain it.
|
||||
|
||||
[image depot_download_query_url]
|
||||
|
||||
Once the depot-query component has responded, the download manager knows what
|
||||
content to get, where to get it, and how to verify it. To download the
|
||||
content, it changes the dynamic init instance as follows.
|
||||
|
||||
[image depot_download_fetch]
|
||||
|
||||
The depot-query component is now gone. Actually, the entire depot has moved
|
||||
out of sight. Instead, a fresh _fetchurl_ component is spawned. This component
|
||||
is connected to the network as well as the writeable download directory
|
||||
_public/_. Internally, fetchurl employs a complex software stack, which
|
||||
includes the C runtime, curl, libssl, and libssh. Hence, we expect this
|
||||
component to be vulnerable. Since it is facing the network, we assume that
|
||||
vulnerabilities are exploitable. In the worst case where the component is
|
||||
completely in the hands of an attacker, it may write wrong content into the
|
||||
_public/_ location. But compared to executing curl or wget as root on a
|
||||
traditional Unix system, the reach of an attack is quite limited. For example,
|
||||
the mere existence of the download manager remains completely out of view of
|
||||
fetchurl. However, the content of _public/_ must not be trusted. To reinforce
|
||||
trust in the downloaded content, the content is accompanied with cryptographic
|
||||
signatures created by the content creator. Before we touch the content, we
|
||||
first check its authenticity. To perform this verification step, the download
|
||||
manager reshapes the dynamic init instance as follows.
|
||||
|
||||
[image depot_download_verify]
|
||||
|
||||
Note that fetchurl exists no more and network connectivity is cut, effectively
|
||||
disposing any form of malware that might have infected fetchurl. Next a new
|
||||
_verify_ component enters the picture. It is configured with a list of content
|
||||
to check, the signatures of the content, and the public key of the content's
|
||||
presumed creator. Since it accesses the _public/_ location exclusively, it is
|
||||
not prone to any potential time-of-check to time-of-use problems during the
|
||||
verification. Under the hood, the _verify_ component employs a hugely complex
|
||||
implementation based on GnuPG. It would be naive to fully trust this code.
|
||||
However, when embedded in our scenario, the reach of a bug is limited because
|
||||
the verify component has no access to any mutable system state. It could
|
||||
merely give the wrong answer (which is of course bad but there is no way we
|
||||
can magically solve this).
|
||||
|
||||
Knowing that the downloaded content is indeed the same content as intended
|
||||
by the creator, it is time for extraction. For this step, the download
|
||||
manager - again - reshapes the dynamic init instance:
|
||||
|
||||
[image depot_download_extract]
|
||||
|
||||
This time, both the _public/_ location as well as the trusted _depot/_ are
|
||||
visible and a new _extract_ component is spawned. As the depot may host
|
||||
content from multiple sources, which potentially distrust each other, the
|
||||
content of each content provider resides in a dedicated subdirectory within
|
||||
the depot. Instead of handing over access to the entire depot to the extract
|
||||
tool, we mediate the file-system access via a _chroot_ component that limits
|
||||
the view to the depot-provider's respective subdirectory. In the worst case
|
||||
where a misbehaving content provider delivers a forged (but correctly signed)
|
||||
archive to exploit a vulnerability of the extract component, the reach of the
|
||||
attack remains limited to the content provider's space within the depot.
|
||||
|
||||
After the extraction step has completed, the depot is populated with the new
|
||||
content, which may - in turn - include new dependency information. At this
|
||||
point, the download manager starts a new iteration. This iterative process
|
||||
terminates as soon as the depot-query component signals that no content of
|
||||
the software installation is missing.
|
||||
|
||||
The bottom line here is that we are able to use complex and useful software
|
||||
like curl, libarchive, liblzma, and GnuPG while largely distrusting it. In
|
||||
contrast to this software that sums up to hundreds of thousand lines of code,
|
||||
the download manager comprises less than 1000 lines of code. The software
|
||||
installation procedure described above is implemented by the 'depot_download'
|
||||
subsystem hosted in the gems repository and illustrated by an equally named
|
||||
run script. It also forms the basis of the install/update mechanism of the
|
||||
Sculpt scenario.
|
||||
|
||||
|
||||
Deployment
|
||||
==========
|
||||
|
||||
Once software has entered the system in the form of depot content, the
|
||||
remaining question is how to turn this content into running subsystems. The
|
||||
answer is given by the following illustration.
|
||||
|
||||
[image sculpt_deploy_runtime]
|
||||
|
||||
Like for the installation process described above, the scenario employs a
|
||||
dynamic init instance that is accompanied by an orchestrating component. The
|
||||
latter is called _depot-deploy_. The depot-deploy component queries
|
||||
information from the depot using the same depot-query component that was used
|
||||
during the installation. Based on the returned _blueprint_ information for the
|
||||
to-be-deployed subsystems, it generates the configuration for the dynamic init
|
||||
instance. The subsystems hosted within this init instance access the depot
|
||||
content via mere ROM sessions as provided by the FS-ROM component. This makes
|
||||
the use of the depot transparent to the hosted subsystems.
|
||||
|
||||
The depot-deploy component is located in the gems repository and accompanied
|
||||
by a same-named run script. More importantly, it is featured in the deploy
|
||||
runtime of the Sculpt system.
|
||||
|
||||
|
||||
Base framework and OS-level infrastructure
|
||||
##########################################
|
||||
|
||||
Increased default warning level
|
||||
===============================
|
||||
|
||||
For building Genode components written in C++, the compiler
|
||||
flags -Wextra, -Weffc++, and -Werror are now enabled in addition
|
||||
to -Wall by default.
|
||||
|
||||
If this strict warning level is inapplicable for a given component or
|
||||
library, it is possible to explicitly disable the strictness in the
|
||||
respective build-description file by adding the following line:
|
||||
|
||||
! CC_CXX_WARN_STRICT =
|
||||
|
||||
We adjusted almost all the code of the base, base-<kernel>, os, and demo
|
||||
repositories to comply with this new warning level. For most components
|
||||
hosted in the higher-level repositories (libports, ports, dde_*, gems),
|
||||
the strictness is disabled as of now and will be enabled component-wise
|
||||
wherever feasible.
|
||||
|
||||
While adjusting our code base, we identified the following patterns worth
|
||||
mentioning:
|
||||
|
||||
* A class with virtual functions can no longer publicly inherit base
|
||||
classes without a vtable. The inherited object may either be moved
|
||||
to a member variable, or inherited privately. The latter would be
|
||||
used for classes that inherit 'List::Element' or 'Avl_node'. In order
|
||||
to enable the 'List' and 'Avl_tree' to access the meta data, the
|
||||
'List' must become a friend.
|
||||
|
||||
* Instead of adding a virtual destructor to abstract base classes,
|
||||
we inherit the new 'Interface' class, which contains a virtual
|
||||
destructor. This way, single-line abstract base classes can stay
|
||||
as compact as they are. The 'Interface' utility resides in
|
||||
_base/include/util/interface.h_.
|
||||
|
||||
* With the new warning level, all member variables must be explicitly
|
||||
initialized. Basic types may be initialized with '='. All other types
|
||||
are initialized with braces '{ ... }' or as class initializers. If
|
||||
basic types and non-basic types appear in a row, it is nice to only
|
||||
use the brace syntax (also for basic types) and align the braces.
|
||||
|
||||
* If a class contains pointers as members, it must now also provide a
|
||||
copy constructor and assignment operator. In most cases, one
|
||||
would make them private, effectively disallowing the objects to be
|
||||
copied. Unfortunately, this warning cannot be fixed by inheriting
|
||||
our existing 'Noncopyable' class (the compiler fails to detect that
|
||||
the inheriting class cannot be copied and still gives the error).
|
||||
For now, we have to manually add declarations for both the copy
|
||||
constructor and the assignment operator as private class members.
|
||||
Those declarations should be prepended with a comment like this:
|
||||
|
||||
! /*
|
||||
! * Noncopyable
|
||||
! */
|
||||
! Thread(Thread const &);
|
||||
! Thread &operator = (Thread const &);
|
||||
|
||||
In the future, we plan to revisit these occurrences and try to replace
|
||||
the pointers with references. In the presence of at least one
|
||||
reference member, the compiler would no longer implicitly generate
|
||||
a copy constructor. So we could remove the manual declaration.
|
||||
|
||||
The following caveats are expected, even if you disable the strictness
|
||||
in your component:
|
||||
|
||||
* If your component has a class called 'Interface', it may collide with
|
||||
the new 'Genode::Interface' class. You may have to disambiguate the
|
||||
names.
|
||||
|
||||
* The 'Genode::Rpc_client' is no longer a 'Genode::Capability'. Hence,
|
||||
classes inherited from 'Genode::Rpc_client' cannot refer to a
|
||||
'Capability' but must refer to 'Genode::Capability'.
|
||||
|
||||
* The 'Surface' class is no longer copyable, which led to API
|
||||
changes of users of this class. E.g., the 'Nitpicker_buffer'
|
||||
utility does no longer offer accessors for the contained surfaces
|
||||
but a new 'apply_to_surface' method that takes a lambda function as
|
||||
argument.
|
||||
|
||||
|
||||
Init
|
||||
====
|
||||
|
||||
Init selects session routes based on the requested service and the client's
|
||||
label. The latter can be matched as 'label' (exact match), 'label_prefix', or
|
||||
'label_suffix' (either end of the label matches). With the new version, these
|
||||
options are complemented with an additional 'label_last' attribute that covers
|
||||
the prominent case where the last part of the label identifies a requested
|
||||
resource at the server. A typical example is the routing of a ROM session
|
||||
based on the name of the requested ROM module.
|
||||
|
||||
|
||||
Reflecting the core log to the application level
|
||||
================================================
|
||||
|
||||
Core records now log messages in a ring buffer and exports this
|
||||
memory as ROM named 'core_log'. User applications may monitor this ring buffer
|
||||
and present or transfer the content as appropriate. The example component in
|
||||
_repos/os/src/app/log_core_ transforms the content into normal log
|
||||
messages, which may be routed to graphical terminals or stored on
|
||||
file systems, e.g. by using the fs_log server.
|
||||
|
||||
|
||||
NIC-router improvements
|
||||
=======================
|
||||
|
||||
During the past three months, the NIC router has received several improvements
|
||||
that were mainly inspired by our daily experience with the component as part
|
||||
of our Sculpt based working environments.
|
||||
|
||||
The most notable new feature is the support for multiple NIC sessions at one
|
||||
domain. If multiple NIC-session clients connect to one domain, the NIC router
|
||||
acts as a simple hub between them. I.e., for every packet that is routed to
|
||||
the domain, each connected session receives a copy of the packet. The same
|
||||
applies for domain-local packets, meaning packets that target an IP address
|
||||
inside the IP subnet of the domain they came from. This domain-local
|
||||
forwarding applies before considering any other routing rules. So, in other
|
||||
words, it is not possible to route such traffic to another domain.
|
||||
|
||||
Furthermore, the logging features of the NIC router were improved. First, the
|
||||
router is now capable of periodically sending a report via Genode's report
|
||||
session. This can be activated by adding the new '<report>' node to the router
|
||||
configuration:
|
||||
|
||||
! <config>
|
||||
! <report interval_sec="5" bytes="yes" config="yes">
|
||||
! ...
|
||||
! </config>
|
||||
|
||||
So far, the report provides per-domain information about the amount of sent
|
||||
and received data ('bytes' attribute) and the current IPv4 configuration like
|
||||
IP address, subnet mask, and gateway address ('config' attribute).
|
||||
|
||||
Second, there is a new verbosity option in the '<config>' node:
|
||||
|
||||
! <config verbose_domain_state="yes">
|
||||
|
||||
When this option is set, the NIC router will output a short message to the log
|
||||
for each general state change of a domain. Currently, this includes the
|
||||
IP-configuration state (IP address, subnet mask, gateway address) and the
|
||||
number of connected NIC sessions. This is a useful addition because the
|
||||
purpose of the regular verbose option is to give a very deep insight into
|
||||
almost every activity of the router, which is vital for debugging
|
||||
sophisticated problems but normally floods the log. Therefore, the regular
|
||||
verbose option is not viable for complex setups like a Sculpt desktop
|
||||
environment. In such a context, the new domain-state verbosity is pretty
|
||||
discreet but already gives a good hint on why, for instance, packets get
|
||||
dropped despite the routing rules being correct.
|
||||
|
||||
Last but not least, the timeout configuration of the NIC router has been
|
||||
reworked and now allows for a much more precise adaption to the network
|
||||
environment. The former 'rtt_sec' attribute of the '<config>' node has been
|
||||
replaced by the following new attributes (default values shown):
|
||||
|
||||
! <config dhcp_discover_timeout_sec="10"
|
||||
! dhcp_request_timeout_sec="10"
|
||||
! dhcp_offer_timeout_sec="10"
|
||||
! udp_idle_timeout_sec="30"
|
||||
! tcp_idle_timeout_sec="600"
|
||||
! tcp_max_segm_lifetime_sec="30">
|
||||
|
||||
Details about the new attributes can be found in the
|
||||
_os/src/server/nic_router/README_ file. The default values should be
|
||||
appropriate for the common use case so that specifying them is normally not
|
||||
necessary.
|
||||
|
||||
|
||||
New watch mechanism for file-system session
|
||||
===========================================
|
||||
|
||||
The file-system session already provided a way for watching files or
|
||||
directories for changes. However, the original mechanism was arguably hard to
|
||||
use. In addition to opening the to-be-watched file-system node, the client had
|
||||
to submit a so-called content-changed request into the session's request
|
||||
queue. In turn, the server delivered the change notification by acknowledging
|
||||
this request.
|
||||
|
||||
The new mechanism is much less bureaucratic. A file or directory can be
|
||||
watched by opening a watch handle rather than submitting a 'CONTENT_CHANGED'
|
||||
packet to the server. Whenever a change happens at a node with an open watch
|
||||
handle, a CONTENT_CHANGED packet will be sent from the server to the client.
|
||||
This serializes the registration with other handle operations and separates
|
||||
I/O handle state from notification handle state.
|
||||
|
||||
|
||||
C runtime
|
||||
=========
|
||||
|
||||
We changed libc's handling of 'clock_gettime' to be explicitly configurable
|
||||
rather than relying on built-in heuristics. With the new version, the libc
|
||||
opens a timer session as a time source only if the 'rtc' attribute of the
|
||||
'<libc>' configuration node is defined. If not configured, 'clock_gettime'
|
||||
returns 0.
|
||||
|
||||
This change may require the adjustment of components that implicitly rely on
|
||||
the libc as time source. To enable such a component to use relative time
|
||||
(based on a timer session) but no wall-clock time, one can manually provide a
|
||||
pseudo real-time clock value as follows:
|
||||
|
||||
! <vfs>
|
||||
! <dir name="dev">
|
||||
! <log/> <null/> <inline name="rtc">2000-01-01 00:00</inline>
|
||||
! </dir>
|
||||
! </vfs>
|
||||
! <libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc"/>
|
||||
|
||||
|
||||
GUI stack and terminal improvements
|
||||
===================================
|
||||
|
||||
Nit-FB improvements
|
||||
-------------------
|
||||
|
||||
The nit_fb component provides a framebuffer and input service while using the
|
||||
nitpicker GUI server as back end. The new version adds the 'initial_width' and
|
||||
'initial_height' attributes, which accommodate the use case where nit_fb is
|
||||
used in a dynamic fashion like as a client of a window system. Here, the
|
||||
initial dimensions define the initial window size but - in contrast to the
|
||||
existing 'width' and 'height' attributes - the actual size can change
|
||||
afterwards.
|
||||
|
||||
Terminal resizing
|
||||
-----------------
|
||||
|
||||
The terminal-session interface gained the ability to propagate resize events
|
||||
from the server to the client. The new version of the graphical terminal uses
|
||||
this mechanism to support window resizing as well as dynamically changing the
|
||||
font size. At the client side, noux has become able to reflect terminal-size
|
||||
changes to noux applications. Applications based on ncurses (e.g., vim) are
|
||||
able to gracefully respond to such changes now.
|
||||
|
||||
|
||||
Using chroot to enforce read-only file-system access
|
||||
====================================================
|
||||
|
||||
By placing a chroot component in-between a file-system client and server, the
|
||||
client's view on the file system can be limited to a specific directory. With
|
||||
the current release, chroot can additionally be used to restrict a writeable
|
||||
file-system session to become read-only. This is accomplished by the new
|
||||
'writeable' attribute of chroot's policy nodes. By default, it is set to "no".
|
||||
|
||||
|
||||
API changes
|
||||
===========
|
||||
|
||||
Noncopyable AVL node/tree
|
||||
-------------------------
|
||||
|
||||
Copying an AVL node generally violates the integrity of the corresponding
|
||||
tree. To rule out subtle bugs where AVL nodes are accidentally copied, AVL
|
||||
nodes are no longer copyable.
|
||||
|
||||
New 'Buffered_xml' utility
|
||||
--------------------------
|
||||
|
||||
The 'Buffered_xml' utility located at _os/buffered_xml.h_ simplifies the
|
||||
implementation of dynamically reconfigurable components that need to keep a
|
||||
verbatim copy of certain parts of their configuration during configuration
|
||||
updates.
|
||||
|
||||
New 'List_model' utility
|
||||
------------------------
|
||||
|
||||
More and more components respond to dynamic configuration updates. For most
|
||||
components, such updates are quite simple: replace an old internal state by a
|
||||
new one. But in cases like init, menu_view, or window decorator, a
|
||||
differential update is in order. Until now, each of these components employed
|
||||
custom code for this task. As this code is not trivial, a common solution is
|
||||
preferable. This solution comes in the form of the new 'List_model' utility
|
||||
located at _base/include/util/list_model.h_. It introduces a light-weight
|
||||
formalism to feed a component-internal data model from an externally-provided
|
||||
XML structure.
|
||||
|
||||
Dynamically expandable reporter utility
|
||||
---------------------------------------
|
||||
|
||||
In many cases, components that generate reports don't explicitly handle the
|
||||
situation where the default buffer size of 4096 bytes is exceeded by the
|
||||
report. This problem is easy to miss because reports are often small at
|
||||
testing time but become larger when deployed in complex scenarios. In most
|
||||
cases, the best way to handle an 'Xml_generator::Buffer_exceeded' exception is
|
||||
upgrading the report session. The new 'Expanding_reporter' that accompanies
|
||||
the original 'Reporter' in _os/reporter.h_ eases the handling of this common
|
||||
case.
|
||||
|
||||
|
||||
Languages and runtime environments
|
||||
##################################
|
||||
|
||||
Nim programming language
|
||||
========================
|
||||
|
||||
A new Nim library for constructing Genode servers is now available in the
|
||||
World repository. This module provides utilities for the asynchronous
|
||||
session-creation procedure introduced in the
|
||||
[https://genode.org/documentation/release-notes/16.11#New_session-creation_procedure - 16.11]
|
||||
release. Some introductory code snippets are provided here for the
|
||||
adventurous.
|
||||
|
||||
An example of server creation using the 'genodeservers' module:
|
||||
|
||||
! import romclient, genodeservers
|
||||
!
|
||||
! var
|
||||
! sessionsRom = newRomClient "session_requests"
|
||||
! # synchronously open a ROM client to the parent
|
||||
! romContent = sessionsRom.stream.readAll()
|
||||
! # copy the ROM content to a heap string
|
||||
! requestsParser = initSessionRequestsParser(romContent)
|
||||
! # a state machine for parsing 'session_requests' XML
|
||||
!
|
||||
! for id, service, label in requestsParser.create:
|
||||
! # the `create` iterator provider for the parser
|
||||
! # hides the details of parsing the XML data
|
||||
! discard txBufSize = requestsParser.argInt "tx_buf_size"
|
||||
! # extract typed session arguments from the current parser state
|
||||
! discard label.lastLabelElement()
|
||||
! # label handling utilities are provided
|
||||
! if service == "MyService":
|
||||
! myCreateSessionProc(id, label)
|
||||
!
|
||||
|
||||
This module streamlines the handling of session metadata, but the developer
|
||||
must still provide hand-crafted wrappers over the C++ methods for managing
|
||||
RPC objects and passing session capabilities to the parent. Most notoriously
|
||||
a global pointer symbol, `genodeEnv`, is used to expose the component
|
||||
environment object. In the future, this will be replaced by a typed object
|
||||
passed from runtime to an application entry procedure.
|
||||
|
||||
! type MySessionCapability {.
|
||||
! importcpp: "My_session::Session_capability",
|
||||
! header: "my_session/capability.h".}
|
||||
! # import a capability type
|
||||
!
|
||||
! type MyNativeSessionBase {.
|
||||
! importcpp: "My_session::Session_rpc_object",
|
||||
! header: "my_session/rpc_object.h".}
|
||||
! # import C++ session RPC object
|
||||
!
|
||||
! type MyNativeSession = Constructible[MyNativeSessionBase]
|
||||
! # apply the C++ Constructible template to defer calling
|
||||
! # the object constructor
|
||||
!
|
||||
! proc construct(cppObj: MyNativeSession) {.
|
||||
! importcpp: "#.construct(*genodeEnv)".}
|
||||
! # call the C++ constructor, passing the global Genode::Env
|
||||
!
|
||||
! proc manage(cppObj: MyNativeSession): MySessionCapability {.
|
||||
! importcpp: "genodeEnv->ep().manage(*#)".}
|
||||
! # call a method from the gobal Env, dereferencing
|
||||
! # thru the Constructible template
|
||||
!
|
||||
! type MyNimSessionObj = ref object
|
||||
! cppImpl: MyNativeSession
|
||||
! cap: MySessionCapability
|
||||
! id: SessionId
|
||||
! # C++ RPC objects are best kept in native
|
||||
! # reference-counted Nim objects
|
||||
!
|
||||
! proc manage(obj: MyNimSessionObj) =
|
||||
! obj.cppImpl.construct() # call our wrapped constructor
|
||||
! GC_ref(obj)
|
||||
! # manually increase the reference count on our session
|
||||
! # object to prevent the component entrypoint from
|
||||
! # referencing an RPC object that has been lost and
|
||||
! # freed from the heap
|
||||
! obj.cap = obj.cppImpl.manage() # store our capability
|
||||
!
|
||||
! proc myCreateSessionProc(id: SessionId): MyNimSessionObj =
|
||||
! result = new MyNimSessionObj
|
||||
! # create our object on the heap
|
||||
! result.manage()
|
||||
! # construct and manage our RPC object
|
||||
! result.id = id
|
||||
! # store the session id from our parent
|
||||
|
||||
Procedures for calling Nim code from an RPC object, dissolving
|
||||
and destructing RPC objects, and managing the session lifetime
|
||||
are exercises left to the reader.
|
||||
|
||||
|
||||
Updated VirtualBox
|
||||
==================
|
||||
|
||||
Our VirtualBox port got updated from version 5.1.22 to version 5.1.32 in order
|
||||
to leverage the security updates and improved audio support. Additionally the
|
||||
boot time of Linux guests got improved by adjusting our custom virtualization
|
||||
back end.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
New trace-logging component
|
||||
===========================
|
||||
|
||||
The new trace-logger component can be used to easily gather, process, and
|
||||
export different types of tracing data. Furthermore, it marks the next step
|
||||
towards a user framework that makes access to Genode's manifold tracing
|
||||
abilities
|
||||
([https://genode.org/documentation/release-notes/13.08#Light-weight_event_tracing - 13.08],
|
||||
[https://genode.org/documentation/release-notes/13.11#Improved_event_tracing - 13.11],
|
||||
[https://genode.org/documentation/release-notes/15.08#Enhanced_tracing_facilities - 15.08])
|
||||
intuitive and convenient.
|
||||
|
||||
The component can filter the available tracing subjects according to session
|
||||
label policies and thread names. The processing of the tracing data can then
|
||||
be configured for each selected subject individually, for groups of subjects,
|
||||
or for all subjects together. The resulting data is exported as log output.
|
||||
|
||||
This is an example configuration of the trace logger, which shows the default
|
||||
value for each attribute (except policy.thread and policy.label):
|
||||
|
||||
! <config verbose="no"
|
||||
! session_ram="10M"
|
||||
! session_arg_buffer="4K"
|
||||
! session_parent_levels="0"
|
||||
! period_sec="5"
|
||||
! activity="no"
|
||||
! affinity="no"
|
||||
! default_policy="null"
|
||||
! default_buffer="4K">
|
||||
!
|
||||
! <policy label="init -> timer" />
|
||||
! <policy label_suffix=" -> ram_fs" />
|
||||
! <policy label_prefix="init -> encryption -> "
|
||||
! thread="worker"
|
||||
! policy="null"
|
||||
! buffer="4K" />
|
||||
! </config>
|
||||
|
||||
The most important features so far when it comes to processing the traced
|
||||
data are:
|
||||
|
||||
* Trace CPU activity and affinity ('activity' and 'affinity' attribute),
|
||||
* Install individual policies for the creation of further tracing data
|
||||
('policy' attributes) for instance, 'rpc_name' for a log of issued RPC calls),
|
||||
* Dimensioning the subject-local trace buffers and the frequency of Trace Logger
|
||||
data examination ('buffer' and 'period' attributes), and
|
||||
* Configure the session to the Tracing server ('session' attributes).
|
||||
|
||||
A comprehensive documentation of the trace-logger component can be found in
|
||||
_os/src/app/trace_logger/README_. An example of how to use the component is
|
||||
given through the run script _os/run/trace_logger.run_.
|
||||
|
||||
|
||||
New component for extracting archives
|
||||
=====================================
|
||||
|
||||
The new 'extract' component located at _libports/src/app/extract_ extracts
|
||||
the content of an arbitrary number of tar.xz archives according to its
|
||||
configuration. It is used by the depot-download subsystem described in
|
||||
Section [On-target package installation and deployment]. The component
|
||||
is accompanied by the run script _libports/run/extract.run_ that illustrates
|
||||
its use.
|
||||
|
||||
|
||||
New signature-checking tool based on GnuPG
|
||||
==========================================
|
||||
|
||||
The on-target installation of software packages requires a way to verify
|
||||
cryptographic signatures of downloaded content within a Genode system.
|
||||
The new 'verify' component located at _ports/src/app/verify_ facilitates the
|
||||
code of GnuPG to verify detached OpenPGP signatures against public keys.
|
||||
Since GnuPG depends on libgcrypt and libgpg-error, ports of those libraries
|
||||
were added to the libports repository. The component comes with the run
|
||||
script _ports/run/verify.run_ that demonstrates its usage.
|
||||
|
||||
|
||||
Fetchurl component for downloading files
|
||||
========================================
|
||||
|
||||
Fetchurl is a component for downloading files from the network, based
|
||||
on the curl library. It used to reside in the genode-world repository.
|
||||
Since it has become a mandatory part of Genode's on-target software
|
||||
installation mechanism, we have moved it to the _libports_ repository now.
|
||||
Besides this relocation, fetchurl received a welcome modernization. In
|
||||
particular, the new version uses the modern socket-fs infrastructure of
|
||||
the libc instead of relying on the deprecated libc_lwip plugin as a hard-wired
|
||||
dependency.
|
||||
|
||||
|
||||
New interactive FLIF image viewer
|
||||
=================================
|
||||
|
||||
A simple image viewing application for the FLIF lossless image format was
|
||||
written from scratch using the FLIF reference decoder library. The viewer can
|
||||
be used to interactively view a directory of images and supports animation of
|
||||
GIF-like FLIF files.
|
||||
|
||||
|
||||
Ported 3rd-party software
|
||||
=========================
|
||||
|
||||
With the current release, the following 3rd-party software becomes available
|
||||
on Genode:
|
||||
|
||||
:[https://www.libarchive.org/ - libarchive]: is a library for uncompressing
|
||||
and extracting various archive formats. It nicely wraps format-specific
|
||||
libraries like zlib behind a unified and easy-to-use API. The port can
|
||||
be found in the _libports_ repository.
|
||||
|
||||
:[https://lz4.github.io/lz4/ - lz4] and [https://tukaani.org/xz/ - liblzma]:
|
||||
implement modern compression algorithms as supported by libarchive.
|
||||
Thanks to Ben Larson for contributing the port of these libraries.
|
||||
|
||||
:[https://www.tcl.tk/ - Tcl]: is used as scripting language for various
|
||||
Genode tools. With the new 'check_abi' tool described in Section
|
||||
[Automated ABI consistency checks], the Tcl shell 'tclsh' has become
|
||||
a dependency of the build system. Therefore, we made 'tclsh' available as
|
||||
noux package. Note, however, that this port comprises solely the
|
||||
functionality needed for simple scripting.
|
||||
|
||||
:[https://flif.info/ - FLIF]: is a library for the Free Lossless Image
|
||||
Format. Thanks to Emery Hemingway for making it available in the
|
||||
genode-world repository.
|
||||
|
||||
:[https://github.com/json-c/json-c/wiki - JSON-C]:
|
||||
is a library for processing JSON-formatted data. Thanks to
|
||||
Johannes Kliemann for contributing the port to the genode-world
|
||||
repository.
|
||||
|
||||
:[https://www.nlnetlabs.nl/projects/ldns/ - Drill (ldns)]:
|
||||
provides a utility for DNS testing. Thanks to Emery Hemingway for adding it
|
||||
to the genode-world repository as a side activity of improving Genode's
|
||||
network stack.
|
||||
|
||||
|
||||
Updated packages for the Noux runtime environment
|
||||
=================================================
|
||||
|
||||
The current release updates the following noux packages: less (version 487),
|
||||
grep (version 3.1), coreutils (version 8.29), tar (version 1.30), findutils
|
||||
(version 4.6), which (version 2.21), sed (version 4.4), and bash (version
|
||||
4.4.18). Thanks to Hinnerk van Bruinehsen for this welcome contribution.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
Ethernet-driver for i.MX-based Wandboard
|
||||
========================================
|
||||
|
||||
The current release contains a port of the Linux kernel driver for the
|
||||
Ethernet card family originally produced by Freescale. We followed our
|
||||
established approach to tailor an independent device-driver environment (DDE)
|
||||
for the specific driver. To profit from synergies with the existing drivers of
|
||||
the _dde_linux_ repository, we took the Linux kernel 4.4.3 as reference.
|
||||
|
||||
For now the current version is limited to support the Wandboard Quad as this
|
||||
is the i.MX-based board that is nightly tested by our infrastructure. The
|
||||
support of other boards using the same IP core is planned for future releases.
|
||||
|
||||
The driver can be found in _dde_linux/src/drivers/nic/fec_. To test the driver,
|
||||
no further configuration is needed and you can have a look at one of the
|
||||
automatic network tests, like _lwip.run_, as a reference.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Execution on bare hardware (base-hw)
|
||||
====================================
|
||||
|
||||
Thanks to Johannes Schlatow from the TU Braunschweig, the support of the
|
||||
Zynq-7000 boards by our base-hw kernel got extended. It is now possible to use
|
||||
all CPU cores instead of only the primary one.
|
||||
|
||||
|
||||
Updated Muen separation kernel
|
||||
==============================
|
||||
|
||||
The Muen SK port has been updated to the latest development version 0.9. The
|
||||
most notable features and improvements are the Crash Audit facility and support
|
||||
for MirageOS/Solo5 subjects which may be executed alongside Genode/base-hw.
|
||||
|
||||
Thanks to this feature, the Muen project has reached a milestone by
|
||||
self-hosting the [https://muen.sk] website on a Muen system. Currently, the
|
||||
network driver is provided by a Linux subject but with some work it should be
|
||||
possible to replace it with a Genode/base-hw nic_drv in the future.
|
||||
|
||||
Further details regarding Muen v0.9 can be found in the project's release
|
||||
notes [https://groups.google.com/forum/#!topic/muen-dev/FPL9sc4yaBE].
|
||||
|
||||
|
||||
Updated seL4 kernel
|
||||
===================
|
||||
|
||||
Our remaining patches regarding UEFI framebuffer support got integrated into
|
||||
the upstream codebase of the seL4 kernel. Hence, we updated our seL4 port to
|
||||
the upstream version containing our patches.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
Package management
|
||||
==================
|
||||
|
||||
The package-management tools introduced last year have become a vital part
|
||||
of Genode's workflow.
|
||||
|
||||
:Package management documentation:
|
||||
[https://genode.org/documentation/developer-resources/package_management]
|
||||
|
||||
Prompted by the development of the on-target installation and deployment
|
||||
mechanism featured in the current release, the tools received the following
|
||||
refinements:
|
||||
|
||||
:Use of tar.xz as archive format: This change significantly reduces the size of
|
||||
published depot content compared to the previously used tar.gz format.
|
||||
|
||||
:Subdirectories for archive versions:
|
||||
In the original version of the depot layout, archives were named as
|
||||
'<archive-name>-<version>'. Hence, the depot - in particular the download
|
||||
location - had directories that grew in two dimensions. First, when new
|
||||
archives were added. Second, when new versions of existing archives were
|
||||
added (usually corresponding to Genode's release cycle). In the mid-term,
|
||||
this would have resulted in a huge number of directory entries, e.g., in the
|
||||
_src/_ subdirectory. To avoid this problem, the new version uses the scheme
|
||||
'<archive-name>/<version>' instead. This way, at the _src/_ level, each
|
||||
archive has one subdirectory (the number of subdirectories corresponds to
|
||||
the number of archives). Inside the subdirectory, there is one entry per
|
||||
version.
|
||||
|
||||
:Controlled rebuild of binary archives:
|
||||
When calling the depot/create tool for a binary archive with 'FORCE=1', the
|
||||
underlying source archives are re-extracted and the binary archive is
|
||||
rebuilt. This is usually done after local changes in the source tree to
|
||||
apply version updates to depot archives as needed. However, the implicit
|
||||
rebuild is superfluous whenever the source-version remains the same. This is
|
||||
particular inconvenient when re-creating pkg archives that refer to a large
|
||||
number of src archives. Here, all binaries referenced by the pkg archive are
|
||||
rebuilt each time. The new 'REBUILD' argument allows the user to skip
|
||||
superfluous rebuilds in such situations. Normally, 'FORCE=1' implies
|
||||
'REBUILD=1'. However, by explicitly specifying 'REBUILD=', existing binary
|
||||
archives whose versions remain unchanged are kept instead of being rebuilt.
|
||||
|
||||
|
||||
Offline validation of XML configurations
|
||||
========================================
|
||||
|
||||
The _tool/run_ tool now automatically checks configurations against
|
||||
target-specific XML schemes. Each component may define a configuration
|
||||
scheme-file in its _target.mk_ file as follows:
|
||||
|
||||
! CONFIG_XSD = my_config.xsd
|
||||
|
||||
When the run tool checks the configuration of an instance of Genode's init
|
||||
component, it additionally iterates through all start nodes of this
|
||||
configuration. For each start node, it checks whether the according component
|
||||
provides a configuration-scheme file and, if so, applies it to the
|
||||
configuration inside the start node. This is done recursively. I.e., also the
|
||||
child configurations of a sub-init of a sub-init ... of the top-level init
|
||||
are covered this way.
|
||||
|
||||
Whenever the run tool detects an error in one of the checked configurations,
|
||||
it stops and points out the location of the error. By now, there exist
|
||||
configuration schemes for the init, the NIC router, and the trace logger
|
||||
components. Our intention is that every component that interprets its
|
||||
configuration will eventually be accompanied by such a scheme - not only to
|
||||
validate actual configuration input but also to serve as documentation for
|
||||
users of the component.
|
||||
|
||||
|
||||
Automated ABI consistency checks
|
||||
================================
|
||||
|
||||
In [https://genode.org/documentation/release-notes/17.02#Genode_Application_Binary_Interface - version 17.02],
|
||||
we introduced a kernel-agnostic ABI, which ultimately paved the ground for
|
||||
Genode's package management. For the time being, the ABI is not set in stone.
|
||||
It is expected to evolve for some time until it hopefully approaches ABI
|
||||
stability in the mid term. Whenever Genode's API changes, the ABI may be
|
||||
affected. For example, symbol sizes may grow. Until now, side effects on the
|
||||
ABI had to be curated manually. In practice, however, such side effects are
|
||||
too easy to miss. Therefore, the current release adds a mandatory ABI checking
|
||||
step to the build process. A new _tool/check_abi_ tool is invoked whenever a
|
||||
shared object is built. It reports flaws in the ABI definition (such as
|
||||
duplicated symbols) as well as inconsistencies between a shared object and its
|
||||
ABI.
|
||||
|
||||
766
doc/release_notes/18-05.txt
Normal file
766
doc/release_notes/18-05.txt
Normal file
@@ -0,0 +1,766 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 18.05
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The driver behind the release 18.05 is the rapid evolution of the Sculpt
|
||||
general-purpose OS. Following the initial version from February, which was
|
||||
targeted at early adopters, the new Sculpt for The Curious (TC) introduces a
|
||||
much more welcoming and empowering user experience (Section
|
||||
[Sculpt for The Curious]).
|
||||
|
||||
It goes without saying that the interactive and dynamic nature of the Sculpt
|
||||
scenario puts a lot more pressure on Genode's components compared to static
|
||||
workloads. For example, Sculpt calls for the dynamic adjustment of user-level
|
||||
network routing, the dynamic detection and management of partitions and file
|
||||
systems, the support of USB storage devices from diverse vendors, and a way to
|
||||
adapt the visual appearance to a great variety of screen resolutions. Most
|
||||
improvements described below are our responses to these challenges.
|
||||
|
||||
That said, the release is not short of new features either. E.g., it features
|
||||
the initial port of OpenJDK's HotSpot VM for executing Java programs on Genode
|
||||
directly (Section [Java language support]), improves the support for the NXP
|
||||
i.MX family of SoCs (Section [NXP i.MX SoC]), and enhances the VFS with new
|
||||
plugins for copy-on-write and the auditing of file accesses
|
||||
(Section [New VFS plugins]).
|
||||
|
||||
The release is complemented by the annual update of the Genode Foundations
|
||||
book (PDF), which covers the fundamentals of the framework in great detail
|
||||
(Section [New revision of the Genode Foundations book]).
|
||||
|
||||
|
||||
Sculpt for The Curious
|
||||
######################
|
||||
|
||||
With Sculpt for The Curious (TC), Genode 18.05 features the second revision of
|
||||
the Sculpt general-purpose OS. Compared to the initial version for Early
|
||||
Adopters (EA), it features a new interactive system-management component that
|
||||
streamlines common tasks like the management of storage devices, or
|
||||
configuring the network connectivity. The highlights of the new version of the
|
||||
base system image are:
|
||||
|
||||
* Live-customization of almost all aspects of the system,
|
||||
* The ability to install and run software in memory only,
|
||||
* Hotplugging of USB storage devices,
|
||||
* New support for NVMe storage devices in addition to SATA disks,
|
||||
* Interactive network configuration including Wifi connectivity,
|
||||
* Interactive management and inspection of storage devices and partitions,
|
||||
* The option to host a complete and customized Sculpt installation on a
|
||||
USB stick,
|
||||
* Automated on-demand installation of software packages with visual feedback,
|
||||
* Scalable fonts that are automatically adjusted to the screen resolution, and
|
||||
* UEFI boot supported by default.
|
||||
|
||||
The base image is extensible by downloadable software packages that may
|
||||
originate from different sources, safeguarded by cryptographic signatures.
|
||||
It contains several example subsystems as a starting point:
|
||||
|
||||
* Basic GUI components like a window manager, a scalable backdrop, a
|
||||
font server, and a simple software-rendering demo,
|
||||
* A light-weight noux runtime for executing command-line-based software
|
||||
such as GNU coreutils, bash, and vim.
|
||||
* A package for downloading the installer and a suitable virtual-machine
|
||||
configuration for Debian Linux,
|
||||
* VirtualBox running Debian Linux,
|
||||
* An example for running libretro-based games,
|
||||
* A disposable VM that runs Firefox on TinyCore Linux, executed either in
|
||||
VirtualBox or the light-weight Seoul virtual-machine monitor,
|
||||
* A Qt5-based text editor.
|
||||
|
||||
Please refer to the updated
|
||||
[https://genode.org/documentation/articles/sculpt-tc - Sculpt documentation]
|
||||
to explore Sculpt TC.
|
||||
|
||||
The Sculpt version included with the current release requires the user to
|
||||
build a boot image by hand. Following the steps described in the
|
||||
documentation, this procedure takes a few minutes. We plan to provide
|
||||
downloadable boot images a few weeks down the road once Sculpt TC received
|
||||
intensive day-to-day testing by the early adopters. Your feedback is very
|
||||
welcome!
|
||||
|
||||
|
||||
New revision of the Genode Foundations book
|
||||
###########################################
|
||||
|
||||
The "Genode Foundations" book received its annual revision, which reflects
|
||||
the evolution of the framework over the past year. Specifically, the changes
|
||||
since the last year's edition are:
|
||||
|
||||
: <div class="visualClear"><!-- --></div>
|
||||
: <p>
|
||||
: <div style="clear: both; float: left; margin-right:20px;">
|
||||
: <a class="internal-link" href="https://genode.org">
|
||||
: <img class="image-inline" src="https://genode.org/documentation/genode-foundations-title.png">
|
||||
: </a>
|
||||
: </div>
|
||||
: </p>
|
||||
|
||||
* Changed boot-loader infrastructure on PC hardware
|
||||
* Package management
|
||||
* Structural changes of Genode's custom base-hw kernel
|
||||
* API improvements: Unicode handling, support for XML-based data models,
|
||||
timeout-handling API
|
||||
|
||||
: <div class="visualClear"><!-- --></div>
|
||||
|
||||
To examine the changes in detail, please refer to the book's
|
||||
[https://github.com/nfeske/genode-manual/commits/master - revision history].
|
||||
|
||||
|
||||
Storage infrastructure
|
||||
######################
|
||||
|
||||
VFS library and plugin interface
|
||||
================================
|
||||
|
||||
The VFS (Virtual-File-System) library was expanded to meet new requirements
|
||||
for the Sculpt scenario. The traditional file-system medium for component
|
||||
state and configuration sculpting is the *ram_fs* server, but with the
|
||||
limitation that files stored in the server are ephemeral. Any changes to
|
||||
the initial state are lost when a system is shut down or the *ram_fs* server
|
||||
is restarted. Now that persistent storage is usually served by a VFS plugin
|
||||
hosted by the VFS server, it was a natural progression to introduce a means
|
||||
for indicating VFS changes with 'File_system' session notifications. To this
|
||||
end the VFS server was amended to send session notifications, and notification
|
||||
support was added to the Rump and FatFs VFS plugins, allowing Ext2 and FAT
|
||||
file-systems to host dynamic component state and configuration information.
|
||||
|
||||
Using the VFS for serving font data produced from files stored in the VFS made
|
||||
it practical to allow VFS plugins to introspect the file system. Plugins now
|
||||
have the means to access arbitrary paths from the file-system root or they may
|
||||
host and expose their own internal file systems.
|
||||
|
||||
While the core of the VFS library is small compared to contemporaries in other
|
||||
operating systems, the moment came to promote the VFS from a static to a
|
||||
shared library. Components that use the C runtime have always loaded the VFS
|
||||
dynamically as a subsystem of _libc.lib.so_, but native components carried the
|
||||
bulk of its implementation. The VFS library is now provided as a shared
|
||||
library and is included with the front-end server in the _src/vfs_ depot
|
||||
archive. This change affects components that have been rebuilt against the
|
||||
shared library but do not have their ROM policies updated to allow access to
|
||||
the _vfs.lib.so_ ROM.
|
||||
|
||||
|
||||
New VFS plugins
|
||||
===============
|
||||
|
||||
File-system introspection has made two additional plugins possible, the *audit*
|
||||
and *cow* plugins.
|
||||
|
||||
The *audit* plugin logs VFS paths as they are accessed to a dedicated LOG
|
||||
session. This is useful for finding the files required by third-party
|
||||
components without relying on documentation or auditing source code.
|
||||
|
||||
The *cow* plugin emulates copy-on-write behavior by copying the contents of
|
||||
files lying in a read-only path to a read-write path as they are opened. This
|
||||
plugin is considered a proof-of-concept and under-performing, but opens a way
|
||||
of experimenting with seeding user-managed file-systems from immutable
|
||||
file-system archives.
|
||||
|
||||
Plugins of this kind are most appropriately instantiated in the VFS server
|
||||
with policies to restrict the intended components into paths provided by the
|
||||
plugins. This prevents a component from escaping the effect of the plugin. An
|
||||
example of "auditing" a libc component follows:
|
||||
|
||||
! <start name="audit_fs">
|
||||
! <binary name="vfs"/>
|
||||
! <config>
|
||||
! <vfs>
|
||||
! <dir name="data"> <!-- source files -->
|
||||
! <tar "data.tar"/>
|
||||
! <ram/>
|
||||
! </dir>
|
||||
! <dir name="audit"> <!-- virtual path that captures /data -->
|
||||
! <audit path="/data"/>
|
||||
! </dir>
|
||||
! </vfs>
|
||||
! <!-- route into virtual audit path -->
|
||||
! <policy label_suffix="audit" root="/audit" writeable="yes"/>
|
||||
! </config>
|
||||
! </start>
|
||||
!
|
||||
! <start name="app">
|
||||
! <config>
|
||||
! <libc stdout="/log" stderr="/log"/>
|
||||
! <vfs>
|
||||
! <log/>
|
||||
! <fs label="audit"/>
|
||||
! </vfs>
|
||||
! </config>
|
||||
! </start>
|
||||
|
||||
|
||||
Improved disk-partition discovery and access
|
||||
============================================
|
||||
|
||||
The 'part_blk' component, which parses the partition table on a block device
|
||||
and provides access to each partition through a block session, was extended to
|
||||
make it easier to implement a management component on top of it. It now
|
||||
features additional attributes in its report. For one the block size of each
|
||||
partition as well as the type of the file system on the partition are
|
||||
reported. The file system probing implementation is minimal and only contains
|
||||
file systems that are commonly used on Genode systems, i.e., FAT32 and Ext2.
|
||||
Furthermore, on GPT formatted disks, each partition has an 'expandable'
|
||||
attribute that contains the number of blocks by which the partition can be
|
||||
grown. The following exemplary report illustrates the adjustments:
|
||||
|
||||
!<partitions type="gpt" total_blocks="500118192" gpt_total="500118125" gpt_used="302254080">
|
||||
! <partition number="1" name="BIOS boot partition"
|
||||
! type="21686148-6449-6e6f-744e-656564454649" guid="db0701aa-02ae-474d-92d0-82738bfce5d2"
|
||||
! start="2048" length="2048" block_size="512"/>
|
||||
! <partition number="2" name="EFI System"
|
||||
! type="c12a7328-f81f-11d2-ba4b-00a0c93ec93b" guid="74e43226-2afb-4575-bdda-83bf72f5a6e7"
|
||||
! start="4096" length="262144" block_size="512" file_system="FAT32"/>
|
||||
! <partition number="3" name="GENODE"
|
||||
! type="0fc63daf-8483-4772-8e79-3d69d8477de4" guid="a950091d-87ba-4800-85bf-7b6a58abe6d5"
|
||||
! start="235147264" length="67108864" block_size="512" file_system="Ext2"
|
||||
! expandable="197862064"/>
|
||||
!</partitions>
|
||||
|
||||
The heuristics of how the component probes the partition table were also
|
||||
loosened. Instead of explicitly enabling support for GPT, the component will
|
||||
now always try to parse the MBR as well as the GPT. It will bail out if both
|
||||
are considered valid since using GPT/MBR hybrid tables is not supported and it
|
||||
should be up to the user to make an educated decision. In cases where there is
|
||||
no partition table, a 'partitions' report of 'type="disk"' will be generated
|
||||
in which the complete disk is presented as partition number '0'. This is
|
||||
needed as compatibility fallback for Sculpt EA installations.
|
||||
|
||||
|
||||
Creating and modifying GUID partition tables
|
||||
============================================
|
||||
|
||||
Part of the enhancements of Sculpt TC is the ability to manipulate the block
|
||||
device used by Sculpt. We implemented a component called 'gpt_write', which
|
||||
can create and modify a GPT and its entries. It considers alignment
|
||||
constraints to make better use of 512e devices. It will, however, not perform
|
||||
any boundary checking. It does not handle overlapping partitions and only when
|
||||
applying a partition, it makes sure that the partition will fit. The following
|
||||
configuration illustrates its operation:
|
||||
|
||||
!<start name="gpt_write">
|
||||
! <resource name="RAM" quantum="2M"/>
|
||||
! <config verbose="yes" initialize="yes" align="4K">
|
||||
! <actions>
|
||||
! <add entry="1" type="BIOS" label="GRUB BIOS" start="2048" size="1M"/>
|
||||
! <add entry="2" type="EFI" label="EFI System" start="4096" size="16M"/>
|
||||
! <add entry="3" type="Linux" label="GENODE" start="36864" size="128M"/>
|
||||
! <add type="BDP" label="FAT32 Data" size="max"/>
|
||||
! <delete entry="1"/>
|
||||
! <delete label="FAT32 Data"/>
|
||||
! <modify label="GENODE" new_label="GENODE*" new_size="max"/>
|
||||
! </actions>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
Please read _repos/gems/src/app/gpt_write/README_ for more detailed information
|
||||
on how to use the component and feel free to check out the run script
|
||||
_repos/gems/run/gpt_write.run_.
|
||||
|
||||
|
||||
User-level networking
|
||||
#####################
|
||||
|
||||
NIC router
|
||||
==========
|
||||
|
||||
The NIC router has received major improvements that were mainly motivated by
|
||||
our daily experience with the Sculpt scenario where the router serves as NAPT
|
||||
component in front of the virtual machines that host our work OS's. In this
|
||||
role, it is subject to a permanent load driven by real-world tasks.
|
||||
Furthermore, it has to have a user interface that makes it a pleasant
|
||||
experience to deploy in a dynamic environment. This led to our primary goal:
|
||||
We had to overcome the need to restart the NIC router, and thereby all
|
||||
components that depend on it, whenever its configuration changes and while
|
||||
doing so, not to interrupt the communication of its client unnecessarily.
|
||||
|
||||
We managed to make the NIC router fully re-configurable at runtime in a way
|
||||
that it always tries to keep as much state information as possible throughout
|
||||
the process. This means that network communication going through the NIC
|
||||
router is not affected by a configuration update unless the configuration
|
||||
change affects parts that were involved in an existing communication channel.
|
||||
|
||||
One prerequisite for this feature was that NIC session clients can connect at
|
||||
any time to the NIC router regardless of whether there is a matching domain
|
||||
for the session or not. As long as a session has no domain, the NIC router
|
||||
does not send any packet to it and drops all packets coming from it. But, at
|
||||
least, the session and the corresponding client component stay alive, even if
|
||||
their already assigned domain disappears with a new configuration.
|
||||
|
||||
At the uplink, in contrast, the lifetime of the session remains bound to the
|
||||
lifetime of the domain. The uplink domain-tag received a new attribute
|
||||
named 'label' (only considered at the domain-tag of the uplink). It denotes
|
||||
the label of the uplink session. With these two particularities of the uplink
|
||||
domain, one can now easily switch between different NIC session servers. The
|
||||
NIC router will close and request the corresponding NIC session with the
|
||||
current 'label' value if the 'domain' node is removed/added or the label
|
||||
changes. Thereby, the NIC router can now be used to dynamically switch between
|
||||
network interfaces like wireless and wired adapters.
|
||||
|
||||
Furthermore, we improved the NIC router's ability to handle DNS server
|
||||
information. Domains can wait for the DNS server info of the DHCP client of
|
||||
another domain. This is done with the new attribute 'dns_server_from' in the
|
||||
'<dhcp_server>' tag. Each time the DNS server info of the remote domain
|
||||
changes, the DHCP server with the 'dns_server_from' attribute will toggle the
|
||||
link state of each session at its domain. This can be used by clients as a
|
||||
hint to request their DHCP info anew from the NIC router and thereby receive
|
||||
the updated DNS server information.
|
||||
|
||||
When it comes to protocols, the most notable change is that the NIC router now
|
||||
also supports routing and NAPT for ICMP. With the new '<icmp>' sub node of the
|
||||
'<domain>' tag, ICMP routes to other domains can be created. Instead of ports,
|
||||
the ICMP IDs are used for NAPT. Similar to the 'udp-ports' and 'tcp-ports'
|
||||
attributes, the size of the ID space for each NAPT client is configured via
|
||||
the new 'icmp-ids' attribute in the '<nat>' tag.
|
||||
|
||||
Last but not least, the following small features were also added to the NIC
|
||||
router:
|
||||
|
||||
:Attribute 'verbose_packets' for the '<config>' and the '<domain>' node:
|
||||
Toggles the logging of most important protocol header fields globally or
|
||||
domain-locally. The 'verbose' attribute does not affect this kind of debug
|
||||
output anymore.
|
||||
|
||||
:Report DNS server info:
|
||||
If the 'config' attribute in the '<report>' node is enabled, the NIC router
|
||||
will now also report the DNS server info for each domain.
|
||||
|
||||
:Attribute 'config_triggers' in the '<report>' node:
|
||||
Toggles whether the NIC router immediately sends a report whenever the IPv4
|
||||
configuration of a domain changes, regardless of any timeouts.
|
||||
|
||||
:IPv4 point-to-point support:
|
||||
If a domain receives an IP configuration with a subnet mask of
|
||||
255.255.255.255 it will switch to point-to-point IPv4 (requires a valid
|
||||
gateway address at the domain).
|
||||
|
||||
:ICMP destination unreachable on non-routable packets:
|
||||
The NIC router now responds with an ICMP "destination unreachable" packet to
|
||||
packets that are not routable at an interface with a domain.
|
||||
|
||||
For more information, have a look at the _os/src/server/nic_router/README_
|
||||
file. Examples can be found in the run scripts
|
||||
_dde_linux/run/nic_router_uplinks.run_,
|
||||
_libports/run/nic_router_dyn_config.run_, and _os/run/ping_nic_router.run_.
|
||||
|
||||
|
||||
NIC dump
|
||||
========
|
||||
|
||||
The output level of the NIC dump component can now be configured per protocol
|
||||
by using the protocol names as attributes: 'eth', 'arp', 'ipv4', 'dhcp',
|
||||
'udp', 'icmp', and 'tcp'.
|
||||
|
||||
The available debug levels are:
|
||||
|
||||
:no: Do not print out this protocol.
|
||||
:name: Print only the protocol name.
|
||||
:default: Print a short summary of the most important header values.
|
||||
:all: Print all available header values.
|
||||
|
||||
Additionally, you can set a default debug level for protocols that are not
|
||||
configured using the 'default' attribute.
|
||||
|
||||
For more information, please refer to _os/src/server/nic_dump/README_.
|
||||
|
||||
|
||||
GUI stack
|
||||
#########
|
||||
|
||||
With Sculpt becoming more and more end-user oriented, Genode's GUI stack came
|
||||
into focus. It was time to reconsider several interim solutions that worked
|
||||
well in the past but would not scale up to a modern general-purpose OS. Two
|
||||
concrete examples are the support of scalable fonts and Unicode characters. In
|
||||
the past, Genode used to restrict textual output to the Latin-1 character set
|
||||
and employed pixel-based fonts only. The current release overcomes these
|
||||
limitations by featuring completely new text-output facilities.
|
||||
|
||||
|
||||
UTF-8 support and improved text rendering
|
||||
=========================================
|
||||
|
||||
The UTF-8 text encoding overcomes the severely limited code-point range of the
|
||||
ASCII and Latin-1 character sets by representing characters by a varying
|
||||
number of bytes. Today, UTF-8 is generally considered as the standard encoding
|
||||
for text. The new UTF-8 decoder at _os/util/utf8.h_ clears the path for
|
||||
Genode's native GUI components to follow suit. The first beneficiary is
|
||||
Genode's graphical terminal, which has become able to display Unicode
|
||||
characters and pass user input as UTF-8-encoded data to its terminal-session
|
||||
client.
|
||||
|
||||
|
||||
Terminal enhancements
|
||||
=====================
|
||||
|
||||
Speaking of the graphical terminal, the current incarnation got a welcome
|
||||
overhaul. First, we reduced its complexity by removing obsolete features like
|
||||
built-in keyboard-layout handling, which are no longer needed when combining
|
||||
the terminal with our modern input-filter component. Furthermore, the terminal
|
||||
has become dynamically resizeable, forwarding screen-size changes to the
|
||||
terminal client. Should the client be a Noux runtime, such a change is
|
||||
reflected to the running application as a SIG_WINCH signal. The application -
|
||||
e.g., Vim - responds to the signal by requesting the new terminal size.
|
||||
Finally, the terminal protocol was changed from 'linux' escape sequences to
|
||||
'screen' escape sequences in the anticipation of making the terminal more
|
||||
flexible in the future.
|
||||
|
||||
|
||||
Text rendering
|
||||
==============
|
||||
|
||||
Throughout Genode, many GUI components reused the text-output utilities
|
||||
of the nitpicker GUI server. These utilities, however, relied on a simple
|
||||
pixel font format. To make the text output more flexible, nitpicker's text
|
||||
painter located at _nitpicker_gfx/text_painter.h_ has been replaced by a
|
||||
completely new implementation that decouples the font format from the
|
||||
glyph rendering and takes UTF-8 strings as input. In the process, the glyph
|
||||
rendering got a lot more sophisticated, supporting horizontal sub-pixel
|
||||
positioning and filtering.
|
||||
|
||||
|
||||
Font-format support
|
||||
===================
|
||||
|
||||
To remove the omnipresent use of fixed-size pixel fonts throughout Genode,
|
||||
the following new components entered the picture:
|
||||
|
||||
First, the new 'ttf_font' library implements nitpicker's font interface by
|
||||
using the TrueType renderer of the STB single-header library.
|
||||
|
||||
Second, the new 'vfs_ttf' VFS plugin uses the 'ttf_font' library to export a
|
||||
rendered TrueType font as a virtual file system. The various font properties
|
||||
as well as the actual glyph images become accessible as regular files. This
|
||||
way, an application that needs to draw text can read the glyph data directly
|
||||
from its VFS instead of depending on a font-rendering library.
|
||||
|
||||
Third, the new 'Vfs_font' utility located at _gems/include/gems/vfs_font.h_
|
||||
implements nitpicker's font interface by obtaining the glyphs from the
|
||||
component-local VFS. It is complemented by the 'Cached_font' utility, which
|
||||
implements an LRU glyph cache.
|
||||
|
||||
With this infrastructure in place, several existing GUI components could
|
||||
be updated, most prominently the graphical terminal and the menu-view
|
||||
widget-rendering engine. By facilitating the VFS as interface for propagating
|
||||
glyph data, components no longer need to manage fonts and their configuration
|
||||
individually. They just access their VFS. When integrating the component into
|
||||
a scenario, one can decide whether to mount a font-rendering library directly
|
||||
at the component, or - alternatively - route a file-system session to a
|
||||
central font server. The latter is just a regular VFS server with the fonts
|
||||
mounted as pseudo file systems. Since the glyph renderer is a VFS plugin, it
|
||||
could be replaced by another implementation in the future without touching any
|
||||
component.
|
||||
|
||||
|
||||
Modernized API for input-event processing
|
||||
=========================================
|
||||
|
||||
Genode's input-session interface changed very little over the years. Even
|
||||
though it received evolutionary enhancements from time to time, its design
|
||||
resembled a traditional C-style interface from the medieval era. We found that
|
||||
the interface left too much room for interpretation. In particular, the meta
|
||||
data per event type was defined in a rather ad-hoc way, which raised
|
||||
uncertainties. For example, is a button-press event accompanied with a
|
||||
positional value or not? To remove these uncertainties, the current release
|
||||
replaces the 'Input::Event', with a new implementation that facilitates a safe
|
||||
way of accessing event meta data. Besides this design change, there is one
|
||||
noteworthy semantic change as well. With the new interface, symbolic character
|
||||
information are provided along with their corresponding press events rather
|
||||
than as distinct events, which - according to our practical findings - greatly
|
||||
simplifies the consumer side of the 'Input::Event' interface.
|
||||
|
||||
|
||||
Improved keyboard-focus handling
|
||||
================================
|
||||
|
||||
The nitpicker GUI server multiplexes one screen among multiple GUI clients in
|
||||
a secure way. One aspect remained underdeveloped so far, which is the keyboard
|
||||
focus handling. Nitpicker's 'Session:focus' call previously triggered a one-off
|
||||
focus change at call time. This focus change did not pass the same code paths
|
||||
as a focus change triggered by a "focus" ROM update, which led to
|
||||
inconsistencies.
|
||||
|
||||
The new version changes the implementation of 'Session::focus' such that the
|
||||
relationship of the caller and the focused session is preserved beyond the
|
||||
call time. Whenever the calling session is focused in the future, the
|
||||
specified session will receive the focus instead. So 'Session::focus' no
|
||||
longer represents a single operation but propagates the information about the
|
||||
inter-session relationship. This information is taken into account whenever
|
||||
the focus is evaluated regardless of how the change is triggered. This makes
|
||||
the focus handling in scenarios like the window manager more robust.
|
||||
|
||||
|
||||
Device drivers
|
||||
##############
|
||||
|
||||
NVMe storage devices
|
||||
====================
|
||||
|
||||
Since NVMe devices have become common in contemporary systems, it is time to
|
||||
provide a driver for such devices on Genode. With this release, we introduce a
|
||||
component that is able to drive consumer-grade NVMe storage devices, i.e.,
|
||||
there is no support for namespace management or other enterprise-grade
|
||||
features. For now, to keep things simple, the driver uses the device in an
|
||||
old-fashioned way and uses only one I/O queue with at most 128 entries. That
|
||||
is to say it does not exploit the parallelism necessary to unlock the full
|
||||
potential of NVMe storage. Nonetheless, it performs well. The following
|
||||
snippet illustrates its configuration:
|
||||
|
||||
!<start name="nvme_drv">
|
||||
! <resource name="ram" quantum="8M"/>
|
||||
! <provides><service name="Block"/></provides>
|
||||
! <config>
|
||||
! <report namespace="yes"/>
|
||||
! <policy label_prefix="client1" writeable="yes"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
The component will generate a report, which contains all active namespaces, if
|
||||
reporting is enabled by setting the 'namespace' attribute of the '<report>'
|
||||
node to 'yes'. A report may look like the following example:
|
||||
|
||||
!<controller model="QEMU NVMe Ctrl" serial="FNRD">
|
||||
! <namespace id="1" block_count="32768" block_size="512"/>
|
||||
!</controller>
|
||||
|
||||
For an example on how to integrate this component, please have a look at the
|
||||
_repos/os/run/nvme.run_ script.
|
||||
|
||||
While implementing the NVMe driver, a new component for testing block-sessions
|
||||
was used. In contrast to the already existing 'blk_bench' and 'blk_cli'
|
||||
components, it features a variety of different test patterns, which can be
|
||||
selected in its configuration and can be used to test a block component more
|
||||
thoroughly. For more information please refer to
|
||||
_repos/os/src/app/block_tester/README_
|
||||
|
||||
|
||||
NXP i.MX SoC
|
||||
============
|
||||
|
||||
We extended the Linux kernel driver port for Ethernet cards found in NXP i.MX
|
||||
SoC, which was introduced in the previous release. Now does it not only
|
||||
support i.MX6Q SoC based boards like the Wandboard, but the i.MX53 and i.MX6SX
|
||||
SoC as well. The new driver was successfully tested with the i.MX53 Quick
|
||||
Start Board and the Nitrogen6 SOLOX. The latter board even contains two
|
||||
Ethernet cards. But due to technical limitations of the board design, the same
|
||||
driver instance has to be used for both cards. Currently, the driver is
|
||||
tweaked to run on different boards via its configuration ROM. When no
|
||||
configuration is provided, it appropriates the values for successfully
|
||||
executing on the Wandboard. The following is an example configuration for the
|
||||
i.MX53:
|
||||
|
||||
! <config>
|
||||
! <card name="fec0" type="fsl,imx25-fec" mii="rmii" irq="87" mmio="0x63fec000"/>
|
||||
! </config>
|
||||
|
||||
As a side effect of enabling networking on the Nitrogen6 SOLOX, support for
|
||||
GPIO based signals has been added to the framework too. The existing GPIO
|
||||
driver for i.MX53 SoC got extended to additionally support the i.MX6 family.
|
||||
|
||||
There are some known limitations when using different drivers like Ethernet
|
||||
and SD-card drivers on the Wandboard right now. At the moment, those drivers
|
||||
adjust clock parameters and I/O pin configurations independently from each
|
||||
other, which can lead to inconsistencies. We plan to address those issues with
|
||||
the implementation of a platform driver for the i.MX6 SoC family.
|
||||
|
||||
|
||||
Improved USB-storage driver
|
||||
===========================
|
||||
|
||||
We improved the stability of the USB-storage driver (usb_block_drv) and
|
||||
made it compatible with a lot more devices as the driver has become a pivotal
|
||||
ingredient of the Sculpt scenario. Due to the changes, the way the driver
|
||||
operates has changed. On the one hand, now it first tries to use 10-byte
|
||||
Command Descriptor Blocks (CDB) in its SCSI layer and will only switch to
|
||||
16-byte CDBs when it encounters a device whose blocks cannot be completely
|
||||
accessed via the former descriptor size. On the other hand, because some
|
||||
tested devices stopped working after issuing a USB device reset, the reset was
|
||||
made optional. By setting the 'reset_device' attribute in the '<config>' node
|
||||
to 'yes', the driver is instructed to perform the USB device reset.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Packaged Qt5 framework
|
||||
======================
|
||||
|
||||
We created package recipes for all previously ported Qt5 libraries and their
|
||||
dependencies and adapted the run scripts accordingly. Please note that the
|
||||
host tools needed for building Qt applications (moc, rcc, uic) are not built
|
||||
automatically anymore, but need to be built and installed manually with the
|
||||
new 'tool/tool_chain_qt5' script.
|
||||
|
||||
|
||||
Java language support
|
||||
=====================
|
||||
|
||||
Over the course of the past year, we started to look into Java support for
|
||||
Genode with the ultimate goal of porting an existing Java Virtual Machine
|
||||
(JVM), which translates and executes Java byte code, to Genode. After
|
||||
investigating possible JVM candidates, it became obvious that
|
||||
[https://openjdk.java.net - OpenJDK] is the only viable option when looking for
|
||||
a functional, maintained, feature complete, and open-source Java SDK.
|
||||
Therefore, we decided upon OpenJDK version 9 and started to port OpenJDK's
|
||||
HotSpot virtual machine.
|
||||
|
||||
In the first step, we followed the approach to enable HotSpot's internal
|
||||
Just-in Time (JIT) compiler, which translates byte code into machine code and
|
||||
is the option with the most to offer performance wise. But we also wanted
|
||||
support for ARM platforms and soon realized, there was almost no JIT compiler
|
||||
support for ARM other than for Linux. The Linux version is deeply integrated
|
||||
into the Linux system libraries (e.g., glibc), which makes it very hard to
|
||||
bring the compiler onto Genode. For example, Genode uses FreeBSD's libc and
|
||||
that would now have to offer glibc semantics.
|
||||
|
||||
After additional research, we found the so-called interpreter version of the
|
||||
HotSpot VM. This version does not compile byte code, but interprets and
|
||||
emulates the code at runtime. It is of course slower than the JIT compiler
|
||||
version, but also machine-architecture independent, so the same HotSpot VM can
|
||||
be compiled for x86 and ARM platforms. With the JVM running on Genode, we
|
||||
added networking and file-system access support via Genode's VFS layer. Note,
|
||||
there is no graphical toolkit support as of now, but most standard library
|
||||
classes should work. Also, the byte code has to be compiled on a different
|
||||
host system (e.g., Linux, *BSD) as of now, since we did not bring the Java
|
||||
compiler to Genode.
|
||||
|
||||
To give Java a spin, a run script can be found under _ports/run/java.run_.
|
||||
|
||||
|
||||
Ada language support
|
||||
====================
|
||||
|
||||
Support for components and libraries written in the Ada/SPARK programming
|
||||
language experienced a rework with the final goal of seamless integration with
|
||||
the base framework. We added a new _ada_ library, which contains a (currently
|
||||
minimal) runtime taken from the sources of our GCC port and thus is always
|
||||
consistent with the tool chain in use. It is built as a shared library
|
||||
_ada.lib.so_ that needs to be added to the list of boot modules.
|
||||
|
||||
The example in _libports/src/test/ada_ showcases the implementation of an Ada
|
||||
component using a custom library _test-ada_, which is also implemented in Ada.
|
||||
|
||||
|
||||
Seoul VMM on NOVA
|
||||
=================
|
||||
|
||||
The Seoul/Vancouver VMM - introduced to Genode with release 11.11 - received
|
||||
some renovations to be able to run recent Linux VMs. Namely the output of the
|
||||
guest during early boot is now visible and the network models got revised.
|
||||
Additionally, the Seoul VMM has been packaged and can be used in Sculpt.
|
||||
|
||||
|
||||
Ported software
|
||||
===============
|
||||
|
||||
The [https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby - Stubby]
|
||||
DNS daemon has been ported to begin experimentations with DNS as a native
|
||||
service. There is a tendency for DNS configuration frameworks to diverge
|
||||
between operating systems and releases, an inconvenience that is magnified
|
||||
when maintaining virtual machines. Name-server configuration via DHCP has been
|
||||
the only constant, so hosting DNS natively and configuring virtual-machines
|
||||
with the *nic_router* DHCP server presents itself as a viable solution to the
|
||||
guest resolver quagmire. Expect DNS services in later Sculpt releases.
|
||||
|
||||
|
||||
Platforms
|
||||
#########
|
||||
|
||||
Accessing PCI via ECAM/MMCONF
|
||||
=============================
|
||||
|
||||
The platform driver on x86 is trusted with guarding access to PCI
|
||||
devices. Up to now, I/O ports have been used to configure the PCI subsystem.
|
||||
|
||||
On modern x86 architectures, PCI devices can be configured by using Memory
|
||||
Mapped I/O (MMIO). This method was introduced with PCI Express and is called
|
||||
Enhanced Configuration Access Mechanism (ECAM). For Each PCI device a separate
|
||||
4 KiB MMIO page exists to serves as the configuration interface between OS and
|
||||
PCI device.
|
||||
|
||||
The exact location of all the 4K MMIO pages of the PCI devices is machine
|
||||
specific and must be determined during the bootstrap phase. The ACPI driver on
|
||||
Genode is in charge of this procedure and reports the location of the
|
||||
ECAM/MMCONF region to the platform driver via the 'acpi' ROM.
|
||||
|
||||
Besides using a modern PCI interface, switching to ECAM/MMCON served to ease
|
||||
the execution of Genode/hw on top of the Muen separation kernel.
|
||||
|
||||
|
||||
Kernel-agnostic platform-information handling
|
||||
=============================================
|
||||
|
||||
Up to now, special kernel-specific information was propagated to components
|
||||
such as Virtualbox, the Seoul VMM, and the timer by reusing the
|
||||
kernel-provided data structures. For Genode/NOVA, the hypervisor info page
|
||||
(HIP) was exported as an ordinary Genode ROM. With the rise of Sculpt and the
|
||||
packaging of components in a - as far as possible - kernel-independent way,
|
||||
the propagation of kernel-specific information became a stumbling block.
|
||||
|
||||
With this release we abandon the 'hypervisor_info_page' ROM of Genode/NOVA and
|
||||
replace it with a Genode ROM called 'platform_info'. The 'platform_info' ROM
|
||||
is planned to contain solely information about the host hardware, which may
|
||||
not be gathered otherwise by Genode components. In the current state it
|
||||
contains information required by VMMs, namely whether AMD SVM or Intel VMX is
|
||||
available and usable. Additionally, the ROM contains information about the
|
||||
frequency of the time stamp counter.
|
||||
|
||||
|
||||
Updated seL4 kernel to version 9.0.1
|
||||
====================================
|
||||
|
||||
Thanks to Hinnerk van Bruinehsen, the seL4 version used by Genode has been
|
||||
updated to 9.0.1.
|
||||
|
||||
|
||||
Updated Muen separation kernel
|
||||
==============================
|
||||
|
||||
With the addition of memory-mapped access to the PCI config-space in Genode,
|
||||
base-hw subjects on Muen now only see the effectively assigned physical
|
||||
devices. This makes it possible to run Genode in parallel with other subjects
|
||||
and to pass-through different PCI devices for each instance.
|
||||
|
||||
The Muen update also brings a much simplified subject info structure plus some
|
||||
tweaks to the Muen system policy XML format to facilitate easier integration
|
||||
of new hardware platform specifications.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
Validating 3rd-party code downloads via SHA256
|
||||
==============================================
|
||||
|
||||
This release removes support for verifying source code of third-party ports
|
||||
with the SHA1 hash algorithm. Last year, SHA1 was banished as a credible
|
||||
cryptographic hash function after the demonstration of a full collision
|
||||
attack. Since the
|
||||
[https://genode.org/documentation/release-notes/14.05 - 14.05 release],
|
||||
port files have been verified using SHA1, this release replaces all file
|
||||
digests with SHA256 digests. Any port definitions maintained in external
|
||||
repositories are required to make these replacements as well. No collisions
|
||||
have been discovered against source code archives but nonetheless there is an
|
||||
obligation to widen our margin of safety.
|
||||
|
||||
|
||||
Creating GPT-based disk images by default
|
||||
=========================================
|
||||
|
||||
Up to now Genode's run tool was able to create x86 bootable images in three
|
||||
flavours:
|
||||
|
||||
* Either as ISO bootable by BIOS legacy - 'image/iso', or as
|
||||
* GPT partitioned disk image only bootable by UEFI - 'image/uefi', or as
|
||||
* MBR partitioned disk image only bootable by BIOS legacy - 'image/disk'.
|
||||
|
||||
With Sculpt came the demand to have a single image type that is in principle
|
||||
bootable by both UEFI and BIOS legacy. Additionally with Sculpt, we began to
|
||||
prefer working with GPT partitioned devices.
|
||||
|
||||
In the light of the new demands, we changed the 'image/disk' run tool support
|
||||
to create a GPT partitioned disk image bootable by a legacy BIOS and by UEFI.
|
||||
1075
doc/release_notes/18-08.txt
Normal file
1075
doc/release_notes/18-08.txt
Normal file
File diff suppressed because it is too large
Load Diff
681
doc/release_notes/19-08.txt
Normal file
681
doc/release_notes/19-08.txt
Normal file
@@ -0,0 +1,681 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 19.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
The stated theme of this year's [https://genode.org/about/road-map - road map]
|
||||
is "bridging worlds", which expresses our ambition to smoothen the practical
|
||||
use of Genode-based systems such as Sculpt OS. The current release pays
|
||||
tribute to this ambition by addressing a great number of practical concerns:
|
||||
How to accommodate the staggering variety of keyboard layouts out there?
|
||||
(Section [Flexible keyboard layouts])
|
||||
How can the system gracefully respond when confronted with exotic USB devices?
|
||||
(Section [Storage-stack improvements])
|
||||
How to set the system time from within the system? How does SNTP fit in here?
|
||||
(Section [General system time concept])
|
||||
How to approach the remote administration of the system?
|
||||
(Section [Enhanced SSH terminal])
|
||||
How to copy and paste text securely between mutually distrusting subsystems?
|
||||
(Section [Clipboard])
|
||||
Or how to overcome the captive portal of a Hotel WiFi with Sculpt OS?
|
||||
(Section [Disposable VM for handling captive portals])
|
||||
By providing answers to those questions, we believe to make Genode - and Sculpt
|
||||
OS in particular - generally more useful.
|
||||
|
||||
As another take on "bridging worlds", we continue our effort to bring the rich
|
||||
Sculpt OS software stack to the 64-bit ARM world, in particular to our most
|
||||
loved SoC family, namely NXP i.MX. Section [64-bit ARM and NXP i.MX8] reports
|
||||
on our progress in this direction.
|
||||
|
||||
Under the hood, there are a few exciting developments that will greatly reduce
|
||||
the effort of running existing software on Genode. In particular, Genode's
|
||||
(entirely optional) C runtime has gained the ability to emulate the
|
||||
traditional execve and fork mechanisms.
|
||||
(Section [Consolidation of the C runtime and Noux]) This will eventually
|
||||
alleviate the need for our present noux runtime environment to the benefits of
|
||||
better performance and increased flexibility.
|
||||
|
||||
Further highlights of Genode 19.08 are a major update of Qt5 to version 5.13
|
||||
(Section [Updated Qt5]) and the continuation of our kernel-agnostic
|
||||
virtualization story (Section [Virtualization]).
|
||||
|
||||
|
||||
Flexible keyboard layouts
|
||||
#########################
|
||||
|
||||
Genode is used worldwide in a multilingual context beyond Germany and common
|
||||
technical realms of English. Therefore, we had to address localized
|
||||
keyboard-input handling for quite some time now and introduced the
|
||||
_input-filter_ component in
|
||||
[https://genode.org/documentation/release-notes/17.02#Input-event_filter - 17.02].
|
||||
The component merges input streams and applies several forms of input
|
||||
transformations, in particular the application of keyboard layouts to
|
||||
supplement the input-event stream with character events.
|
||||
|
||||
But as we are by no means localization experts, our solution, while performing
|
||||
a solid job for selected layouts, also had some quirks and rough edges when it
|
||||
came to French or even Swiss German. First, our oversimplified notion of
|
||||
[https://en.wikipedia.org/wiki/Caps_Lock - Caps Lock] as _just a pressed Shift_
|
||||
_key_ is plain wrong but part of all our character-generator configurations.
|
||||
We just missed this drawback because none of our developers uses Caps Lock
|
||||
regularly. Further, US English and Germany layouts work very well without
|
||||
[https://en.wikipedia.org/wiki/Dead_key - dead keys], but crossing any German
|
||||
border (except the Austrian) is impossible without support for key sequences
|
||||
composing special characters. The French keyboard layout in Genode tried to
|
||||
alleviate the lack of compose sequences by adding an additional Circumflex
|
||||
modifier and character mapping, which unfortunately is not standard.
|
||||
|
||||
[image keyboard_stack]
|
||||
|
||||
Beginning at this state of affairs, we researched common practice in
|
||||
international keyboard-input handling, sought a quasi-standard source for
|
||||
layout configurations, and addressed the drawbacks mentioned before. During
|
||||
our research we found out that no current implementation is void of critique
|
||||
and, therefore, decided to look more into X11/XKB as our open-source
|
||||
quasi-standard solution, but always had an eye on the proprietary world.
|
||||
|
||||
The handling of key events in X11/XKB happens on three layers.
|
||||
|
||||
:Key codes: On the key-code layer, the device driver programs the
|
||||
keyboard and generates a stream of key-code (i.e., scan-code)
|
||||
events, which represent the physical location of the actual key on
|
||||
the keyboard.
|
||||
|
||||
:Key symbols: These key codes are mapped to key symbols, which
|
||||
represent the label imprinted on the key. So, the key code producing
|
||||
US English _Q_ (QWERTY keyboard) generates _A_ on a French keyboard
|
||||
(AZERTY). Modifiers like Shift, AltGr, and Caps Lock are included in
|
||||
the key-symbol mapping. Additionally, some layouts map key codes to
|
||||
dead key symbols, which start the before-mentioned compose
|
||||
sequences. Key repeat is also implemented as key-symbol repeat
|
||||
actually.
|
||||
|
||||
:Characters: On top of this stack, the key symbols are mapped to
|
||||
characters represented as Unicode codepoints or UTF-8 strings.
|
||||
The procedure obviously includes key symbols that have no character
|
||||
representation (e.g. Control and Alt). Key symbols forming a valid compose
|
||||
sequence generate characters on this level (e.g., dead-key circumflex plus
|
||||
e generates ê).
|
||||
|
||||
We limited our research to Western keyboard-input handling and only had a
|
||||
blink into the direction of Chinese-Japanese-Korean (CJK) and advanced input
|
||||
methods (IM). This simplification is supported by the fact that CJK can also
|
||||
be based on the mechanisms mentioned with some limitations only. Nevertheless,
|
||||
we do not expect to never touch this topic again.
|
||||
|
||||
After doing our homework of keyboard-input handling, we worked on squeezing
|
||||
all available layout information out of X11/XKB, which resulted in a small
|
||||
tool residing in _tool/xkb2ifcfg_. For those wondering, the name is just a
|
||||
silly acronym for _XKB to input-filter_ _configuration_ that pays tribute to
|
||||
the boringness of this task. After building the tool by a run of 'make' in the
|
||||
tool path, it can be used as follows. Please make sure you have libxkbcommon
|
||||
development packages installed beforehand.
|
||||
|
||||
! xkb2ifcfg generate <layout> <variant> <locale>
|
||||
!
|
||||
! xkb2ifcfg generate us euro en_US.UTF-8
|
||||
! xkb2ifcfg generate de nodeadkeys de_DE.UTF-8
|
||||
|
||||
If the parameter combination is available, xkb2ifcfg prints a input-filer
|
||||
chargen configuration for the selected layout to standard output. Valid
|
||||
'layout' and 'variant' options can be figured out from the LAYOUTS section in
|
||||
'man 7 xkeyboard-config', where 'variant' strings are depicted in parentheses
|
||||
after the layout (e.g., 'us(euro)'). The 'locale' option has the standard
|
||||
locale syntax (see /usr/share/i18n/locales). The tool needs all three
|
||||
parameters to gather the correct key-map and compose-sequence information. The
|
||||
generated chargen configurations include '<map>' and '<key>' nodes
|
||||
corresponding to significant modifier states and '<sequence>' nodes (described
|
||||
later). For simplicity of the generator, the '<key>' nodes always use the
|
||||
'code="..."' attribute, but also have a comment with the UTF-8 character
|
||||
appended.
|
||||
|
||||
! <key name="KEY_MINUS" code="0x00df"/> <!-- ß -->
|
||||
|
||||
Last, we addressed the improvement of the input-filter character generator and
|
||||
the actual chargen configuration files in Genode. Therefore, we specified the
|
||||
modifier configuration assumed by the standard chargen files as '<mod1>'
|
||||
corresponds to Shift, '<mod2>' to Control, '<mod3>' to AltGr, and '<mod4>' to
|
||||
Caps Lock.
|
||||
|
||||
! <mod1> <key name="KEY_LEFTSHIFT"/> <key name="KEY_RIGHTSHIFT"/> </mod1>
|
||||
! <mod2> <key name="KEY_LEFTCTRL"/> <key name="KEY_RIGHTCTRL"/> </mod2>
|
||||
! <mod3> <key name="KEY_RIGHTALT"/> </mod3> <!-- AltGr -->
|
||||
! <mod4> <rom name="capslock"/> </mod4>
|
||||
|
||||
As outlined above, the '<key>' nodes generated by xkb2ifcfg always use the
|
||||
'code' attribute for the Unicode codepoint. Because of this and because UTF-8
|
||||
also refers to codepoints, we deprecated the 'b0/b1/b2/b3' attributes for
|
||||
character definition with this release.
|
||||
|
||||
The chargen is also extended by the '<sequence>' configuration node. A
|
||||
sequence node permits the definition of dead-key/composing character
|
||||
sequences. With such sequences, the character is not generated instantly on
|
||||
key press but only after the sequence is completed. If an unfinished sequence
|
||||
can't be completed due to an unmatched character, the sequence is aborted and
|
||||
no character is generated. We support sequences of up to four characters at
|
||||
the moment.
|
||||
|
||||
For example, the French AZERTY
|
||||
[https://docs.microsoft.com/en-us/globalization/keyboards/kbdfr.html - keyboard layout]
|
||||
has a dead key for Circumflex Accent _^_ right of the _P_ key (which is
|
||||
bracket left _[_ on US keyboards). When Circumflex is pressed no visible
|
||||
character should be generated instantly but the accent must be combined with a
|
||||
follow-up character (e.g., Circumflex plus _a_ generates _â_).
|
||||
|
||||
Dead keys can be defined in the '<key>' nodes of any '<map>' by using
|
||||
codepoints not used for direct output, for example, Combining Diacritical
|
||||
Marks beginning at U+0300. The French Circumflex example can be configured
|
||||
like follows.
|
||||
|
||||
! <mod1>
|
||||
! <key name="KEY_LEFTSHIFT"/> <key name="KEY_RIGHTSHIFT"/>
|
||||
! </mod1>
|
||||
! <map>
|
||||
! <key name="KEY_Q" code="0x0061"/> <!-- a -->
|
||||
! <key name="KEY_LEFTBRACE" code="0x0302"/> <!-- dead_circumflex -->
|
||||
! </map>
|
||||
! <map mod1="true">
|
||||
! <key name="KEY_Q" code="0x0041"/> <!-- A -->
|
||||
! </map>
|
||||
! <sequence first="0x0302" second="0x0061" code="0x00e2"/> <!-- â -->
|
||||
! <sequence first="0x0302" second="0x0041" code="0x00c2"/> <!-- Â -->
|
||||
|
||||
Fortunately, the configuration is automatically generated by xkb2ifcfg, but
|
||||
admittedly quite extensive. Therefore, we manually amended the chargen
|
||||
configurations before adding them to Genode, which also gave us the chance to
|
||||
apply some adjustments like follows for AltGr in Swiss German.
|
||||
|
||||
! <map mod1="false" mod2="false" mod3="true" mod4="false">
|
||||
! <key name="KEY_1" code="0x00a6"/> <!-- ¦ (*) -->
|
||||
! <key name="KEY_4" code="0x00b0"/> <!-- ° (*) -->
|
||||
! <key name="KEY_5" code="0x00a7"/> <!-- § (*) -->
|
||||
! </map>
|
||||
|
||||
|
||||
Beside the advanced input methods mentioned before, there are still loose ends
|
||||
we are going to address in the upcoming releases. For example, the current key
|
||||
handling in our Qt5 back end maps localized key symbols incorrectly (think
|
||||
AZERTY vs. QWERTY) in combination with shortcuts like Ctrl-A.
|
||||
|
||||
|
||||
64-bit ARM and NXP i.MX8
|
||||
########################
|
||||
|
||||
64-bit ARM support in our custom base-hw kernel
|
||||
-----------------------------------------------
|
||||
|
||||
By introducing rudimentary Raspberry Pi 3 support on top of the Fiasco.OC
|
||||
kernel in the previous release, the first ARM 64-bit support has entered the
|
||||
Genode OS framework. We continued pursuing the ARM 64-bit path and introduce
|
||||
support for Raspberry Pi 3 as well as the i.MX8 evaluation kit (EVK), this
|
||||
time using our own base-hw kernel.
|
||||
|
||||
Noteworthy additions in the base-hw kernel are support for the AARCH64 system
|
||||
level architecture, and the use of the modern GIC v3 interrupt controller on
|
||||
top of the i.MX8 EVK board. In comparison to the GICv2, GICv3 adds support for
|
||||
more than eight CPUs, more than 1020 interrupt IDs, and offers fast register
|
||||
access to the CPU interface, instead of memory-mapped I/O access. Minor
|
||||
changes had to be made to the page-table implementation of ARMv7 with Large
|
||||
Physical Address Extension (LPAE) to re-use it for ARMv8. Moreover, the
|
||||
internal kernel API for TLB maintenance needed to be changed slightly for all
|
||||
ARM platforms.
|
||||
|
||||
We expanded our regular testing infrastructure with two AARCH64 platforms,
|
||||
namely Raspberry Pi 3 via Qemu and the NXP i.MX8 EVK board as physical
|
||||
hardware. Both platforms are driven with a single CPU core only at the moment.
|
||||
|
||||
|
||||
Network driver for i.MX7 and i.MX8
|
||||
----------------------------------
|
||||
|
||||
We updated the 'fec' network driver to version 4.16.3, which adds support for
|
||||
i.MX7 and i.MX8 SoCs. This makes i.MX8 a viable platform for Genode-based
|
||||
networking scenarios.
|
||||
|
||||
|
||||
Enhanced packaging and test infrastructure for ARMv8
|
||||
----------------------------------------------------
|
||||
|
||||
Besides the improved base-hw kernel, we enabled additional infrastructure for
|
||||
ARMv8 platforms. For example, noux packages - like _coreutils_, _bash_ - are
|
||||
now available, the standard C++ library is in place, and support for Genode's
|
||||
port of the Linux TCP/IP stack is enabled.
|
||||
|
||||
Additionally, ARMv8 is now regularly tested within our nightly
|
||||
_depot_autopilot_ runs.
|
||||
|
||||
|
||||
Base framework and OS-level infrastructure
|
||||
##########################################
|
||||
|
||||
Tracing
|
||||
=======
|
||||
|
||||
Support for fast tracing has been built into Genode for a long time. However,
|
||||
the stakes to take advantage of this feature remained high because convenience
|
||||
functions were not in place. With the current release, we added the support
|
||||
for easy trace setups through a VFS plugin. The plugin is called _vfs_trace_
|
||||
and can be mounted into a Genode component as follows:
|
||||
|
||||
!<config>
|
||||
! <vfs>
|
||||
! <trace ram=32MB/>
|
||||
! </vfs>
|
||||
!</config>
|
||||
|
||||
This configuration will create a trace file system at the root of the VFS. The
|
||||
_ram_ attribute is mandatory and determines the maximum size of all trace
|
||||
buffers. The file system forms a recursive directory structure that represents
|
||||
the parent/child relationship of running components, whereas the leaf
|
||||
directories represent single threads within a component. Each leaf directory
|
||||
currently contains three files:
|
||||
|
||||
:'enable': Start or stop the tracing of a thread by writing "true" or "false"
|
||||
into the file.
|
||||
|
||||
:'buffer_size': Allows for the configuration of the trace-buffer size for the
|
||||
thread in the usual Genode format (e.g. 5M, 512K, 1024).
|
||||
|
||||
:'trace_buffer': This read-only file contains the current content of the trace
|
||||
buffer. Each trace entry can only be read once, after that only new entries
|
||||
appear. "tail -f" can also be used to display continuous output.
|
||||
|
||||
As an example, tracing is started by writing _true_ to the _enable_ file:
|
||||
|
||||
! echo "true" > enable
|
||||
|
||||
The trace buffer can then be displayed using Unix tools like _tail_
|
||||
|
||||
! tail -f trace_buffer
|
||||
|
||||
which provides a continuous output.
|
||||
|
||||
Additionally, we have added the _trace_ function to _base/log.h_ that
|
||||
facilitates identical functionality as _Genode::log_
|
||||
|
||||
! Genode::trace("Tracepoint value: ", value);
|
||||
|
||||
In order to enable tracing, the parent must provide the "TRACE" service. For a
|
||||
real world example on Sculpt OS, please refer to this
|
||||
[https://genodians.org/ssumpf/2019-06-18-trace_fs - Genodians article].
|
||||
|
||||
With the _vfs_trace_ plugin in place, we removed the outdated _trace_fs_.
|
||||
|
||||
|
||||
Consolidation of the C runtime and Noux
|
||||
=======================================
|
||||
|
||||
On our [https://genode.org/about/road-map#August_-_Release_19.08 - road map],
|
||||
we vaguely hinted at our plan for the "consolidation" of the noux runtime,
|
||||
which is actually meant as a polite way of announcing that we are going to
|
||||
remove it. We introduced the
|
||||
[https://genode.org/documentation/release-notes/11.02#Noux_-_an_execution_environment_for_the_GNU_userland - Noux runtime]
|
||||
in 2011 as a way to execute command-line-based GNU software directly on
|
||||
Genode. It has served us well over the years and is - in fact - a crucial
|
||||
ingredient of Sculpt OS and other system scenarios such as the Genodians.org
|
||||
web server. Noux supplements Genode with two valuable assets, namely a
|
||||
flexible and expandable virtual file system (VFS) layer, and the
|
||||
implementation of the
|
||||
[https://genode.org/documentation/release-notes/12.02#Noux_support_for_fork_semantics - Unix way]
|
||||
to spawn applications ('fork' and 'execve').
|
||||
|
||||
In the
|
||||
[https://genode.org/documentation/release-notes/17.02#Enhanced_VFS_infrastructure - meantime],
|
||||
noux' VFS implementation has become independent from the noux runtime and is
|
||||
now prominently employed by Genode's C runtime and the VFS server component.
|
||||
Genode's C runtime became more and more complete, alleviating the use of noux
|
||||
as POSIX compatibility layer except for programs that depended on a working
|
||||
implementation of 'fork' and 'execve'.
|
||||
|
||||
The current release fills this remaining gap in Genode's C runtime by
|
||||
providing 'fork', 'execve', and cousins such as 'wait4' and 'getpid' as
|
||||
regular parts of the libc. This will eventually make noux redundant.
|
||||
|
||||
Note that this change does *NOT* make Genode reliant on POSIX. The C runtime
|
||||
including the Unix features are entirely optional.
|
||||
|
||||
As one stepping stone of this undertaking, noux applications, which previously
|
||||
had to be compiled for noux, have become binary compatible with the regular C
|
||||
runtime. So one can execute programs like 'bash' directly as a Genode
|
||||
component without any friction.
|
||||
|
||||
There are a few collateral improvements of Genode's dynamic linker and the C
|
||||
runtime on the account of the new 'fork' and 'execve' implementation. E.g., in
|
||||
addition to the already supported 'stdin', 'stdout', and 'stderr'
|
||||
configuration, the libc can be instructed to initialize arbitrary file
|
||||
descriptors as follows:
|
||||
|
||||
! <config>
|
||||
! ...
|
||||
! <libc ...>
|
||||
! <fd id="3" path="/dev/log" writeable="yes" readable="no" seek="10"/>
|
||||
! ...
|
||||
! </libc>
|
||||
! </config>
|
||||
|
||||
The libc-based implementation of 'fork' and 'execve' can be tried out via
|
||||
the new _ports/run/bash.run_ script. Note that there are still a number of
|
||||
limitations such as the lack of signal and ioctl handling. Pipes are not
|
||||
supported, and shebangs ('#!') are not interpreted yet. That said, once those
|
||||
missing pieces come into place, we can fade out the use of noux within Genode.
|
||||
|
||||
|
||||
General system time concept
|
||||
===========================
|
||||
|
||||
Briefly speaking, up to now there has been no notion of an overall concept of
|
||||
system time in Genode. Components that need to have access to some kind of
|
||||
real time are either configured locally, e.g., libc-based components access a
|
||||
configured "device" (/dev/rtc), which just might be an inline file system
|
||||
containing an artificial timestamp or the VFS RTC plugin, while other
|
||||
components query some RTC session directly. Most of the time, this session is
|
||||
provided by the 'rtc_drv' on x86 machines, which is somewhat costly as reading
|
||||
the RTC via I/O ports takes time and is therefore done scarcely. For example,
|
||||
the libc will query an RTC source only once and uses this initial value to
|
||||
interpolate the current time. However, for executing long-running components,
|
||||
it will be necessary to adjust the clock to compensate for any occurring clock
|
||||
drift or to correct a misconfigured clock in general. In addition it is
|
||||
desirable to be able to use a remote time source, e.g., an NTP-server, to
|
||||
synchronize the system time.
|
||||
|
||||
To address this, we came up with the following concept:
|
||||
|
||||
[image system_rtc]
|
||||
|
||||
The new "System RTC" component, located at
|
||||
_repos/libports/src/server/system_rtc_, acts as proxy for the RTC service in
|
||||
front of the actual RTC driver. It uses the driver to get the initial RTC
|
||||
value and then uses a timer session (via the timeout framework) to locally
|
||||
interpolate the time. In contrast to querying the RTC driver, querying the
|
||||
System RTC is fast.
|
||||
|
||||
The RTC driver and the System RTC are bundled up together in the new
|
||||
_drivers-rtc-pc_ package. The runtime of this package requests two ROM modules
|
||||
used to update the RTC value. The first one, named 'system_set_rtc', is used
|
||||
to update the proxy component while the second one, called 'hw_set_rtc', is
|
||||
used by the RTC driver to write the value into the battery-backed RTC. A
|
||||
separate component, potentially accessing a remote time source, may generate
|
||||
these ROMs to adjust the time in the package's runtime.
|
||||
|
||||
The new native *SNTP* client at _repos/libports/src/app/sntp_client_ is such a
|
||||
component. It periodically requests the current time from a given SNTP server
|
||||
and generates a report. The report produced by the component contains the time
|
||||
as UTC/GMT. Depending on the system policy, it can be used to update the time
|
||||
of the System RTC and/or instruct the driver to set the RTC value.
|
||||
|
||||
To propagate such changes to RTC values, the RTC session was enhanced by the
|
||||
new 'set' signal. A client of the session can install a signal handler to
|
||||
adapt its own time when necessary. Based on this, the time back end of the
|
||||
libc was changed to instantiate a watch handler for the RTC device, which,
|
||||
when triggered, will cause the libc to re-read the RTC value.
|
||||
|
||||
This constellation should, under normal operation, allow for second to
|
||||
sub-second granularity updates of the overall system time and avoid drifting
|
||||
away from network time.
|
||||
|
||||
|
||||
Accessing SMBIOS tables
|
||||
=======================
|
||||
|
||||
The System Management BIOS (SMBIOS) is a specification that allows for reading
|
||||
management information produced by the BIOS of a system as a collection of
|
||||
data structures in memory. It has the potential to eliminate the need for the
|
||||
operating system to probe hardware for discovering present devices and their
|
||||
characteristics. Nowadays, the SMBIOS specification is implemented widely in
|
||||
PC systems, which includes modern UEFI systems as well. The data structures
|
||||
are referred to as _tables_ or _records_ by public documentation.
|
||||
|
||||
The new native SMBIOS decoder at _os/src/app/smbios_decoder_ can be used on
|
||||
x86 to parse SMBIOS tables and report gathered information in a human-readable
|
||||
way. Besides general table information like number and size of structures,
|
||||
etc., the component supports complete parsing of SMBIOS structures of types
|
||||
"BIOS", "System", and "Baseboard".
|
||||
|
||||
The component is free from any code for acquiring an SMBIOS table through
|
||||
means like the bootloader or BIOS information. It expects a table to be
|
||||
present through a regular Genode ROM session with a 'smbios_table' label. This
|
||||
way, the underlying system is required to find, select, and save the raw table
|
||||
on startup and create a ROM module out of it. This is currently achieved on
|
||||
NOVA and base-hw through an interplay of kernel, the core component, and the
|
||||
ACPI driver and was tested for legacy BIOSes as well as UEFI systems.
|
||||
|
||||
|
||||
Clipboard
|
||||
=========
|
||||
|
||||
Genode introduced a principle copy-and-paste mechanism already
|
||||
[https://genode.org/documentation/release-notes/15.11#Copy_and_paste - four years ago].
|
||||
However, originally created as a part of a tech demo, the mechanism remained
|
||||
unused in our day to day Genode work. This changed now. We took the
|
||||
integration of copy-and-paste support in Sculpt OS as an opportunity to revive
|
||||
and refine the existing mechanism and supplement it with the features needed
|
||||
to make it practical for daily use. We believe that the result aligns ease of
|
||||
use nicely with security. The concept is described in a
|
||||
[https://genodians.org/nfeske/2019-07-03-copy-paste - dedicated article]
|
||||
at Genodians.org.
|
||||
|
||||
On a technical level, the existing clipboard component has received a new
|
||||
option that allows for dynamic information-flow policies based on user
|
||||
interactivity (keyboard focus, activity). When setting the config attribute
|
||||
'match_labels="yes"', the clipboard performs plausibility checks for copy and
|
||||
paste operations against the focus of the Nitpicker GUI server. All aspects of
|
||||
the clipboard policy - including information-flow policies - have become
|
||||
reconfigurable.
|
||||
|
||||
To make window-manager clients compatible with the clipboard's dynamic policy,
|
||||
the window manager got enhanced with the ability to proxy the interaction with
|
||||
the clipboard. GUI clients in turn - in particular the graphical *terminal* -
|
||||
became able to interact with the clipboard. With the '<config>' attribute
|
||||
'copy="yes"' specified, the terminal allows the user to select text to be
|
||||
reported to a "clipboard" report. The selection mode is activated by holding
|
||||
the left shift key. While the selection mode is active, the text position
|
||||
under the mouse pointer is highlighted and the user can select text via the
|
||||
left mouse button. Upon release of the mouse button, the selection is
|
||||
reported. Vice versa, with the '<config>' attribute 'paste="yes"' specified,
|
||||
the terminal allows the user to paste the content of a "clipboard" ROM session
|
||||
to the terminal client by pressing the middle mouse button.
|
||||
|
||||
Finally, we integrated those new abilities into Sculpt OS and into several
|
||||
installable packages, including virtual machines, the noux-system package,
|
||||
and graphical Qt5-based applications.
|
||||
|
||||
|
||||
Enhanced SSH terminal
|
||||
=====================
|
||||
|
||||
This release paves the way for remotely managing Genode devices over SSH.
|
||||
Until now, only interactive SSH sessions were supported. It is now possible to
|
||||
execute commands from a remote SSH client. E.g., 'ssh noux@localhost -p 5555
|
||||
"ls -hal /bin/"'. For non-interactive sessions, ssh_terminal requires a helper
|
||||
component. This component is responsible to create the environment for the
|
||||
command to run in. You can find an example for such a component at
|
||||
_gems/src/test/exec_terminal_. It starts noux in a sub init and executes the
|
||||
provided command inside of it. The new _ssh_exec_channel.run_ script gives a
|
||||
demonstration on how this feature can be used.
|
||||
|
||||
This work is a contribution by Sid Hussmann of
|
||||
[https://gapfruit.com - Gapfruit]. Thanks for this great new feature!
|
||||
|
||||
|
||||
Storage-stack improvements
|
||||
==========================
|
||||
|
||||
The desire of one Genode developer to exchange data via Iomega ZIP drives
|
||||
between an Atari Falcon and Sculpt OS called for a number of small
|
||||
improvements across several components of the storage stack.
|
||||
|
||||
First, the USB-block driver has been changed to exit on an initialization
|
||||
failure instead of waiting for another (supported) device. This change enables
|
||||
the Sculpt manager to detect such conditions and release the USB device
|
||||
hardware by removing the driver component. Such a failed initialization may
|
||||
happen with exotic USB-storage devices such as ZIP drives. With the device
|
||||
released, however, it can be assigned to a virtual machine to access it using
|
||||
a guest OS with a broader support of devices.
|
||||
|
||||
Second, the USB-block driver received new support for issuing the SCSI
|
||||
START-STOP command at initialization time, thereby overcoming the ZIP-drive
|
||||
initialization failure.
|
||||
|
||||
Third, we enhanced the part-block component with the ability to parse AHDI
|
||||
partition schemes and detect the GEMDOS variant of FAT as used by Atari TOS.
|
||||
|
||||
Fourth, we enabled the Rump VFS plugin to access GEMDOS file systems. The
|
||||
GEMDOS variant is readily supported by NetBSD's "msdos" file-system driver.
|
||||
However, it must explicitly be enabled by a mount flag. Hence, we added the
|
||||
principle ability for passing mount flags to NetBSD file-system drivers and
|
||||
enabled the MSDOSFSMNT_GEMDOSFS flag based on the VFS plugin's config
|
||||
attribute 'gemdos="yes"'.
|
||||
|
||||
With these changes in place, data can now be exchanged directly between
|
||||
Atari-formatted disks and Sculpt OS. That said, advanced use cases such as
|
||||
media changes at runtime are not covered yet.
|
||||
|
||||
|
||||
Updated Ada/SPARK runtime
|
||||
=========================
|
||||
|
||||
Genode's Ada/SPARK runtime is developed and maintained by
|
||||
[https://componolit.com - Componolit]. Thanks for this excellent
|
||||
collaboration!
|
||||
|
||||
The updated Componolit Ada runtime 1.1.0 increases the proof coverage and
|
||||
cleans up the source-code structure. SPARK mode is now enabled wherever
|
||||
possible and unneeded abstractions have been removed. Furthermore, the 64-bit
|
||||
addition and subtraction have been proven to be free of runtime errors.
|
||||
As a new feature, the runtime now supports the use of inline assembly in Ada.
|
||||
|
||||
The removal of unneeded features such as the incomplete threading support for
|
||||
the secondary stack has greatly reduced the runtime's complexity while keeping
|
||||
the current functionality available. Also GNAT.IO has been removed as its
|
||||
implementation was incomplete and complex. A simpler replacement has been
|
||||
introduced with 'Componolit.Runtime.Debug'.
|
||||
|
||||
Unrelated to Genode, the runtime now supports [https://muen.sk/ - Muen] and
|
||||
the API/ABI of the runtime has been separated from the GNAT ABI.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Updated Qt5
|
||||
===========
|
||||
|
||||
We updated our Qt5 port to the latest upstream version 5.13.0. Before
|
||||
preparing the 'qt5' port, please make sure to build and install the updated
|
||||
Qt5 host tools with the 'tool/tool_chain_qt5' script.
|
||||
|
||||
|
||||
Virtualization
|
||||
==============
|
||||
|
||||
As follow-up of our work on the
|
||||
[https://genode.org/documentation/release-notes/19.05#Kernel-agnostic_virtual-machine_monitors - kernel agnostic virtual-machine monitor interface]
|
||||
on x86, we added principle support to run our port of VirtualBox on
|
||||
Genode/Fiasco.OC. We write _principle_ support, since we managed to get the
|
||||
VMM running with Fiasco.OC, but unfortunately not all features required by the
|
||||
VMM are available using the Fiasco.OC kernel, e.g., guest FPU registers, PDPTE
|
||||
registers, and task-priority support. In practice this means that the VMs with
|
||||
Windows and Linux come up to a certain point but will fail later whenever the
|
||||
guest state runs out of synchronization between VMM and hardware. In contrast,
|
||||
the Seoul VMM runs fine on Fiasco.OC since it does not depend on the mentioned
|
||||
missing features.
|
||||
|
||||
Our main working items have been the completion of transfer of the available
|
||||
guest registers and control flow synchronization improvements between VMM and
|
||||
Fiasco.OC kernel. Additionally, the usage of priorities for VirtualBox's
|
||||
pthreads in the VMM had to be disabled. Finally, some tests for VirtualBox
|
||||
with Genode/Fiasco.OC are enabled for nightly regular testing now.
|
||||
|
||||
As a side topic, we added support for using the VirtualBox
|
||||
[https://forums.virtualbox.org/viewtopic.php?f=2&t=82299&start=15 - CPU profile]
|
||||
feature, which allows for presenting a different CPUID to the VM than the one
|
||||
of the real CPU. This can help when running Windows 7 on a Kaby Lake or newer
|
||||
CPU, which are considered _unsupported hardware_ and reason enough not to
|
||||
receive security updates from Microsoft. The feature can be used on Genode by
|
||||
adding the 'CpuProfile' attribute to the '<CPU>' XML node in the .vbox file,
|
||||
like:
|
||||
|
||||
! <CPU CpuProfile="Intel Core i7-5600U">
|
||||
|
||||
|
||||
Disposable VM for handling captive portals
|
||||
==========================================
|
||||
|
||||
It is common that WiFi networks require the user to interact with a specific
|
||||
web page before gaining access to full network functionality. Such captive
|
||||
portal pages are completely individual to the accessed network and not limited
|
||||
in the use of common web techniques. Therefore, their handling is best be done
|
||||
using a fully-featured web browser like Mozilla Firefox.
|
||||
|
||||
This is where, in a Genode-based desktop system like Sculpt, a disposable VM
|
||||
for hosting a minimal browser setup becomes desirable. Its goal is to unlock a
|
||||
network for the native Genode surroundings with as little inconvenience as
|
||||
possible just to be thrown away afterwards without any side effects on the
|
||||
system.
|
||||
|
||||
Now, one could use the Firefox appliance VM of Sculpt (see the
|
||||
[https://genode.org/documentation/release-notes/18.05 - release notes] or the
|
||||
[https://genodians.org/alex-ab/2019-03-06-disposal-browser-vm - Genodians article])
|
||||
for this. But this VM aims for a long-term browsing experience which, in the
|
||||
context of mere captive-portal handling, brings some drawbacks like a much
|
||||
higher RAM consumption or the required sessions for USB detection and shared
|
||||
folders.
|
||||
|
||||
Furthermore, in the captive portal VM, there's no need for managing windows or
|
||||
browser tabs. The one browser tab needed can always be shown in fullscreen. It
|
||||
is also unnecessary for the browser to maintain a content cache or remember
|
||||
user data. This can reduce resource consumption.
|
||||
|
||||
[image captive_portal_vm]
|
||||
|
||||
The VM we came up with is provided as package for Sculpt by Martin Stein
|
||||
(depot user 'mstein'). You'll possibly need to manually add Martin's
|
||||
[https://github.com/genodelabs/genode/tree/master/depot/mstein - depot key and download location]
|
||||
to your Sculpt depot directory. After enabling this user, the captive portal
|
||||
VM can be found in the Sculpt menu under "Depot -> mstein -> Virtual
|
||||
Machines -> vbox5-nova-captive-portal".
|
||||
|
||||
The VM is based on a TinyCore 10 Linux with Xserver, i3 WM, and a tailored
|
||||
Firefox browser. The package runtime doesn't need access to your file system,
|
||||
it merely loads some ROMs into a RAM FS, so, it will completely forget any
|
||||
changes made during a session. Therefore, it's also safe to simply remove an
|
||||
instance via the Leitzentrale component-view once you don't need it anymore.
|
||||
The guest additions are also included to make the VM window resizable.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
At Genode Labs, we have used _tool/autopilot_ for the steering of tests in our
|
||||
Continuous Integration workflow for almost a decade now. This implied various
|
||||
improvements over the years and with the completion of our work on
|
||||
[https://genode.org/documentation/release-notes/19.05#Unified_build_directories_for_ARM - unified build directories]
|
||||
it was time to amend this handy tool once again. Unified build directories
|
||||
support building all components for one CPU architecture in one directory
|
||||
saving the build server from the redundant work we previously had with
|
||||
board-specific directories. With the new notion of boards during builds, the
|
||||
definition of the target platform when integrating Genode system scenarios is
|
||||
now a triplet of _CPU architecture_, _board_, and _kernel_. This is reflected
|
||||
in the new '-t <architecture-board-kernel>' command line option, which
|
||||
instructs autopilot to generate a build directory for _architecture_ and
|
||||
execute tests for the _board-kernel_ combination.
|
||||
|
||||
! autopilot -t x86_64-pc-sel4 -t x86_64-pc-nova -r log
|
||||
|
||||
The known options for '-k kernel' and '-p platform' are still supported with
|
||||
the small change that the platform must now be defined as
|
||||
_architecture-board_.
|
||||
|
||||
! autopilot -p x86_64-pc -k sel4 -k nova -r log
|
||||
|
||||
Autopilot now also documents the hidden feature to propagate custom 'RUN_OPTs'
|
||||
via the 'RUN_OPT_AUTOPILOT' environment variable to the run tool executed.
|
||||
Besides that, the tool always appends 'RUN_OPT' with '--autopilot'.
|
||||
|
||||
! RUN_OPT_AUTOPILOT="--depot-dir /data/depot" autopilot ...
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user