mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-22 13:02:56 +01:00
Compare commits
177 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
1
depot/jschlatow/download
Normal file
1
depot/jschlatow/download
Normal file
@@ -0,0 +1 @@
|
||||
https://depot.genode.org
|
||||
59
depot/jschlatow/pubkey
Normal file
59
depot/jschlatow/pubkey
Normal file
@@ -0,0 +1,59 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBGBlsG4BEADBMY44lF/LYiZByj1clJa+aNCEMGtoulxhFgCLIt2DR9r5KRmi
|
||||
iAiweobH6ofbSXYKTOZqhAcmmkw3ihIVCsd1mHbdAAhlsnJetHLgOPL90aXVwce/
|
||||
CM5QDubFmSu1VuaCgp/GaPqtQ/yaIq4LPMK+w2BfNG2M5XBeM8qLzjIHF7KNN4nZ
|
||||
CX48Gx7q2DtIYCMUdIP0oK4dNfPDy6tvXiYvcz3lA2SNa6kszW3/mgIsurUEUFF6
|
||||
vtCjBS5f6vJikWsglvTXqS0Sw5aIPzvosL/U0fjM0BVdi2NK6dWfM4HUduzr5MTD
|
||||
Xc26CETmZ/8Sl4+mj0oUAuHU0SKDm22LNc+qRzXZxtkryDbFuikwtioYf3nIDTiA
|
||||
63YPsx1jHp3mitTQgvRlJdlncmKIxXIUyGXqWpc+QHGUsvbDFdsXRxtt3J+8QWso
|
||||
yLlaeP54E0OTQqdm+EnWGHahEKIwsn8/Gfs87phQsaF8Dlw+A132RukxB6zD35xF
|
||||
/rqu25/8B0tL603Z3TLIyLDNbh4xO/iNohTB1ps+ALRwu48MsXcTMGUeWuRt2YVJ
|
||||
RPG3KfIfnd+KcvJa2XFuzZCk57Jc8qGPmINPY5fJ7F9qIT0/9O7dlxzdoksfKXMf
|
||||
RdiSCiFgmgJTqpXyfEcV7GUHCj9e0WdCSmDIH13bbuUpaTQXxO5d+XkzGwARAQAB
|
||||
tDVKb2hhbm5lcyBTY2hsYXRvdyA8am9oYW5uZXMuc2NobGF0b3dAZ2Vub2RlLWxh
|
||||
YnMuY29tPokCVAQTAQgAPhYhBBHurPU5I/pstoojMcciWBOKaz+1BQJgZbBuAhsD
|
||||
BQkJZgGABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEMciWBOKaz+1L28P/R+T
|
||||
usXX/AdgaTRSY3hFDVnhV+adcyFdmTKWey0lMUMWRGsALd1EIJbqk4HAA81jW68j
|
||||
9XG/kZgkhGKz+vOwOD40Y6G6f1GfKIEknzWok5RgH4p0BT5+ZhbqfX3/Z6z0CsOD
|
||||
mXAo1At9JvGmP6OnpHbCwutEa/KAB2fgrjjgGMZcBlDzIsBugbT+shEAE5et0b0J
|
||||
TrsClqoO71wknMkNp0ijfvCT4VtiCq/UBD5XqYRtzDQC6dMic/dNXKp3JmcsYf17
|
||||
DUNM7RVdVx+v9onWiUre9poVn9YgA/MYwVb4hMyjJEc9R8yQhENSJtdhX2pkXVF6
|
||||
l4ONbkdaw3xJqVO1ouPBI68Ddirwfwk6kgvpkvJ+iCVQ2lWSvPbtrhmTGpeerfQD
|
||||
vbFwtUX1OZhZma5Gq8n5r6VM7N29hQalYaKPBS9AoL3YBO51NsUwde/EmZydlYl6
|
||||
C7Ny+2iuPgKCoXS2zAxM2t9Ar9K0ZhhaiEbSZHoT596M/cWnn483edt15CQZO5w0
|
||||
QNBv5nNKh0J/GmM45TtbhUya9Cpc9Ad2SVYSlNB3KQgC/n+1UQm+8UHOBq/5nuC/
|
||||
Ww2It8g1G9pkGijG/f7flh1qE7KqqYec3cMLWj8hHRYSak3omSYlt4aOJEQPinjo
|
||||
XUw+WBi/Mjrnd6UxB6mNs0VADOHDrCmFBBHcfWIAiQEzBBABCAAdFiEEwNwMDXup
|
||||
zMtoYvj6v6ZIQUWP8uIFAmBlu6wACgkQv6ZIQUWP8uKNqwf+IjqK19dU8zATB50s
|
||||
x4aEqTF6U5J2xO4xiBJlWv55zewjmmOsjJZYKBJd4UzTHqG/0CRUiDzUmsn3q1o+
|
||||
GEwC+bB/LQMi+MaSG4w901Hz2cZ/qXonHfOtISKxmW2wDcOlG8Xsds0X5gfLgIZv
|
||||
4EYK+Nh1HqcEj2/RHRzfT8/WkDSC7AzSd8nuwQL03ZkAW5woh8vX5A/Fgj77mJb+
|
||||
APi6flqnTXxsVnRLHP8ErWQ8Akg07xV5fsOt1bFpY0aKgw2HJCoFyPDzVR09QILo
|
||||
Th3jiHBdNTlbd+Hb1kQJfIyhIpwkNRKBxdbM0wZoKdVMl7xiDMMDHkYpvNyBQTkJ
|
||||
nug/1LkCDQRgZbBuARAAzwJSYFegsVTJxm/6N9gN3vcfbZkvxttQYhNefw2eog7a
|
||||
UZq8Eog4LUuhDmuVt0CWZh5YOz7u4XwjxOzNk6fw630AKiWiNkYtiLYwPyT1tPcz
|
||||
I0XI6EcIYShyOfVZ+egPUELkjdC+SVwIQttQCPpEYnzWjbg22n+XeNRUfAI4EGKj
|
||||
H5bqhKx6sR2cmbB4FPUO1kpYoqhEVdk1wdZI7n93SDPSLsoJSO+xBMPj6HqfXeab
|
||||
gvr3dpqNg05G5g5JQBznILEJBHZBuCfy01j7WNRftdwWCGfWAh53uq6ug1vilodd
|
||||
T1jvWmIbFE66rljH+sbtkZwBuEbEDnwZxNK/g72aQkog3AeDljG1a8GjazN6/upe
|
||||
JD8LfoE8gjlj9Ncg9eYvqnrGR3nv566i7cq7UO10Dl5d6bedpEIo2htm90AI3M8p
|
||||
nmtAZ18cbQodwerFvdQcegdejlpYJmI/3xaPZQqPH0puhDpT3oA53ObmjPb12ztH
|
||||
Za06+klrr1MYb+x4IQYAOO8wwVRY/+YS+YU+6mxePyPMUDJYnIgOcTkg04/O55MF
|
||||
KghOumAY3KTFoE7VlWXrBbhE/MW+Owp8zbtyFovJbmo8H718JHBQwlxzd1cS2Fvd
|
||||
7g7r5eqWZNl+bMJQmgA0ZTAI0gD5PJU+GJEhiky3e29H2tBKqozX539HCxdOJycA
|
||||
EQEAAYkCPAQYAQgAJhYhBBHurPU5I/pstoojMcciWBOKaz+1BQJgZbBuAhsMBQkJ
|
||||
ZgGAAAoJEMciWBOKaz+1y94QAMD//6IqvIQEvsmDsv0hDy/ryPgYA7+2gKQCrvsq
|
||||
rdhXYrBYGwgUPAeuYKgIFQIE+UqFZDwMbZ38DozyXvg4QYTEYQtPOio5WZGMHsNa
|
||||
VYXel8qOKAbSECuP6GFiyX+NsSKYzs+iQLCzzLJS2/N8U1TMbgOwpqcVovpKOHvE
|
||||
XPTUTwnUP25ubY32ElslRACZ/REJIm1Ftmloef50qnFggfCQdSsjevl74Q2+QOHk
|
||||
Nb5w+a+vM6CmTGM1kqEATSJfBkxS7jCnGH4H9t44cEYqECpOYm4eUjxpM/9rxMw8
|
||||
itrVs8preL28zzgKydVLO1JAX4WAw+X1k1Q9EGcRcXRnlxptZ71Lgnv4qCshPAXk
|
||||
Sm5acLgdoOOSDDCSGFtjenyDjoHWfDk22CBwmEtMDtQ02m0+IzkfpNizqKGHBpKm
|
||||
/hsu36teJilJWdAQOmDyrb0VsRweWM+rqClq3GS1+r791836WxQlKvx0/eO0gZOP
|
||||
QjQxOjeCzZ/H8h7HBZ4bwRjQzHGgIbl7k6WPIwmvM4vLQfB44YEi/zDW5ivBcDEo
|
||||
2VnHwAC2EPiVRwhRB/9+I8U09Ngrg2SnO8MkgmZpob1amblnhItM1US8bq/KDKld
|
||||
4sWgWcZO21jEqnEaep4n/9vaxvLHfFa7AYY2EbB+Dfrns80oAqHG78qFyzflnLxx
|
||||
kLJD
|
||||
=7iZV
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
@@ -162,10 +162,6 @@ capture-session and event-session interfaces respectively.
|
||||
:_dde_linux/src/drivers/usb_hid/_:
|
||||
USB Human Interface Device driver using the USB session interface.
|
||||
|
||||
:_os/src/drivers/usb_block/_:
|
||||
USB storage driver that uses the USB session interface and provides
|
||||
a block-session interface.
|
||||
|
||||
|
||||
Timer drivers
|
||||
=============
|
||||
@@ -220,11 +216,6 @@ _os/include/block_session/_.
|
||||
:_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.run_.
|
||||
|
||||
:_os/src/drivers/ahci/_:
|
||||
Driver for SATA disks and CD-ROMs on x86 PCs.
|
||||
|
||||
@@ -232,7 +223,8 @@ _os/include/block_session/_.
|
||||
Driver for NVMe block devices on x86 PCs.
|
||||
|
||||
:_os/src/drivers/usb_block/_:
|
||||
USB Mass Storage Bulk-Only driver using the USB session interface.
|
||||
USB Mass Storage Bulk-Only driver using the USB session interface and provides
|
||||
a block-session interface.
|
||||
|
||||
|
||||
Network interface drivers
|
||||
@@ -257,8 +249,8 @@ defined at _os/include/nic_session/_.
|
||||
The wifi_drv component is a port of the Linux mac802.11 stack, including the
|
||||
iwlwifi driver. It enables the use of Intel Wireless 6xxx and 7xxx cards.
|
||||
|
||||
:_dde_linux/src/drivers/usb/_:
|
||||
For the OMAP4 platform, the USB driver contains the networking driver.
|
||||
:_dde_linux/src/drivers/usb_net/_:
|
||||
USB network driver using the USB session interface.
|
||||
|
||||
:_dde_linux/src/drivers/nic/fec/_:
|
||||
Driver for ethernet NICs of the i.MX SoC family.
|
||||
@@ -450,6 +442,9 @@ Separate components
|
||||
A wrapper for nitpicker's GUI session interface that applies alpha-blending
|
||||
to the of views a GUI client.
|
||||
|
||||
:_os/src/server/black_hole/_:
|
||||
Mockup implementation of Genode session interfaces.
|
||||
|
||||
|
||||
VFS plugins
|
||||
===========
|
||||
|
||||
38
doc/news.txt
38
doc/news.txt
@@ -4,6 +4,44 @@
|
||||
===========
|
||||
|
||||
|
||||
Genode OS Framework release 21.08 | 2021-08-31
|
||||
##############################################
|
||||
|
||||
| The highlights of Genode 21.08 are revamped GPU support as well as new
|
||||
| drivers for the Pinephone and MNT-Reform laptop based on a new streamlined
|
||||
| approach for porting Linux kernel code. Further topics range from VirtualBox
|
||||
| improvements, over media playback in the native web browser, to LTE
|
||||
| connectivity in Sculpt OS.
|
||||
|
||||
For complex driver stacks, Genode largely relies on code ported from other
|
||||
operating systems. The Linux kernel plays a special role because - being the
|
||||
basis for Android - it is the de-facto reference for driving the peripherals
|
||||
of most ARM SoCs. Up to now, however, the porting efforts of driver code from
|
||||
Linux to Genode used to be a time-intensive affair, which forced a narrow
|
||||
focus on very few SoCs on us. With the streamlined porting approach introduced
|
||||
with the new release, we become able to dramatically reduce the costs,
|
||||
creating the prospect of a much broader hardware support. The first success
|
||||
stories of the new way of porting are added graphics drivers for the Pinephone
|
||||
and the MNT-Reform laptop, a network driver for the Pine-A64-LTS board, and an
|
||||
SD-card driver for the MNT-Reform.
|
||||
|
||||
The second spotlight of the release is the largely revamped support for Intel
|
||||
GPUs. In contrast to our experimental GPU-related work of the past, we have
|
||||
now identified a way to cleanly integrate GPU support into the GUI
|
||||
architecture of sophisticated Genode systems such as Sculpt OS. This work is
|
||||
accompanied with an up-to-date version of the Mesa library stack. In
|
||||
combination with the improvements of our custom GPU multiplexer, we are now on
|
||||
a good track to make the use of hardware-accelerated graphics a commodity on
|
||||
Genode.
|
||||
|
||||
Even though most topics of the current release revolve around low-level
|
||||
driver-related work, the new version improves higher-level functionality as
|
||||
well. In particular, it adds the modular integration of mobile-data
|
||||
connectivity to Sculpt OS and enables media playback for our port of the
|
||||
Chromium web engine. Those and more topics are described in the detailed
|
||||
[https:/documentation/release-notes/21.08 - release documentation of version 21.08...]
|
||||
|
||||
|
||||
Genode OS Framework release 21.05 | 2021-05-31
|
||||
##############################################
|
||||
|
||||
|
||||
671
doc/release_notes/21-08.txt
Normal file
671
doc/release_notes/21-08.txt
Normal file
@@ -0,0 +1,671 @@
|
||||
|
||||
|
||||
===============================================
|
||||
Release notes for the Genode OS Framework 21.08
|
||||
===============================================
|
||||
|
||||
Genode Labs
|
||||
|
||||
|
||||
|
||||
Genode 21.08 puts device drivers into the spotlight. It attacks the costs of
|
||||
porting drivers from the Linux kernel and takes a leap forward with respect to
|
||||
GPU support. This low-level work is complemented by several topics that
|
||||
contribute to our vision of hosting video-conferencing scenarios natively on
|
||||
Genode.
|
||||
|
||||
For those of you who follow Genode's release notes over the years, the
|
||||
so-called DDE-Linux is a recurring topic. DDE is short for device-driver
|
||||
environment and denotes our principal approach of running unmodified Linux
|
||||
device-driver code inside Genode components. For over a decade, we iterated
|
||||
many times to find a sustainable and scalable solution for satisfying Genode's
|
||||
driver needs. Thanks to this enduring work, Genode enjoys support for modern
|
||||
hardware such as Intel wireless chips or Intel graphics devices. However, when
|
||||
looking beyond PC hardware, in particular at the plethora of ARM SoCs as
|
||||
potential target platforms for Genode, we found our existing DDE-Linux
|
||||
approach increasingly prohibitive because the investment of manual labour per
|
||||
driver would become unbearable. It was time to recollect, draw from our
|
||||
collective experience gathered over the past years, and re-envision what
|
||||
DDE-Linux could be. Section [Linux-device-driver environment re-imagined]
|
||||
presents the results of this recent line of development that promises to dwarf
|
||||
the costs of driver-porting work compared to our time-tested approach. The
|
||||
results have an immediate impact on our ambition to bring Genode to the
|
||||
Pinephone as our added network and framebuffer drivers for the Allwinner A64
|
||||
SoC leverage the new DDE already.
|
||||
|
||||
The challenge of using hardware-accelerated graphics (GPUs) on Genode makes a
|
||||
guest appearance in the release notes on-and-off since version
|
||||
[https://genode.org/documentation/release-notes/10.08#Gallium3D_and_Intel_s_Graphics_Execution_Manager - 10.08].
|
||||
However, until now, GPU support has not become a commodity for Genode yet.
|
||||
With the work presented in Section [Advancing GPU driver stack], we hope to
|
||||
change that. For the first time, we identified a clear path to the
|
||||
architectural integration of GPU support in sophisticated Genode scenarios
|
||||
such as Sculpt OS. This outlook prompted us to revive the GPU stack in a
|
||||
holistic way, including our custom Intel GPU multiplexer as well as the Mesa
|
||||
stack.
|
||||
|
||||
Further highlights of the current release are an improved and updated version
|
||||
of VirtualBox 6, refined user-level networking, the maturing integration with
|
||||
host file systems when running Genode on top of Linux, and new media-playback
|
||||
capabilities for our port of the Chromium web engine.
|
||||
|
||||
|
||||
Linux-device-driver environment re-imagined
|
||||
###########################################
|
||||
|
||||
Over more than a decade, the domestication of Linux device drivers for Genode
|
||||
has evolved into a quest of almost epic proportions. This long-winded story
|
||||
has been covered by a recent series of Genodians articles
|
||||
([https://genodians.org/skalk/2021-04-06-dde-linux-experiments - first],
|
||||
[https://genodians.org/skalk/2021-04-08-dde-linux-experiments-1 - second],
|
||||
[https://genodians.org/skalk/2021-06-21-dde-linux-experiments-2 - third]),
|
||||
which also goes into a technical deep dive of our recent developments.
|
||||
|
||||
On the one hand, we draw an enormous value from the device drivers of the
|
||||
Linux kernel. Genode would be nowhere as useful without the Intel wireless
|
||||
stack, USB host-controller drivers, or the Intel graphics driver that we
|
||||
ported over from Linux. On the other hand, those porting efforts are draining
|
||||
a lot of our energy. Linux kernel code is not designed for microkernel-based
|
||||
systems after all. Consequently, the transplantation of such code does not
|
||||
only require a solid understanding of Linux kernel internals, but also ways to
|
||||
overcome the friction between two radically different operating-system-design
|
||||
schools (monolithic and component-based) and friction between implementation
|
||||
languages (C and C++).
|
||||
|
||||
Even though we are not short of evidence of successful driver ports, we are
|
||||
very well aware of several elephants in the room:
|
||||
|
||||
Economically, each driver port must be understood as a distinct project of
|
||||
non-trivial costs. E.g., the port of the i.MX8 graphics driver took us two
|
||||
months. That's certainly minuscule compared to a driver written from scratch.
|
||||
But it is still expensive and we feel that those expenses hold us back.
|
||||
|
||||
Second, once ported, later updates of drivers to a new kernel version are
|
||||
costly and risky. But such updates are unavoidable to keep up with new
|
||||
hardware. The larger the arsenal of device drivers, the bigger this problem
|
||||
becomes.
|
||||
|
||||
Third, the skill set of the porting work is the cross point of Linux kernel
|
||||
competence and Genode competence. In other words, it's rare. To make Genode
|
||||
compatible to a broader spectrum of hardware in the long run, driver porting
|
||||
must become an easily attainable skill rather than black art.
|
||||
|
||||
With the current release, we introduce a vastly improved approach to the reuse
|
||||
of Linux device drivers on Genode. It entails three aspects:
|
||||
|
||||
:Code: Reusable building blocks for crafting custom runtime environments
|
||||
to bring Linux kernel code to fly, and for interfacing Genode's session
|
||||
interfaces with Linux kernel interfaces.
|
||||
|
||||
:Tooling: A custom tool set that automates repetitive work such as generating
|
||||
dummy implementations of Linux kernel functions.
|
||||
|
||||
:Methodology: Consistent patterns and exemplary test scenarios serving as
|
||||
guiding rails for the development work.
|
||||
|
||||
The following illustration maps out the first aspect, the various pieces of
|
||||
code involved in hosting unmodified Linux driver code on Genode.
|
||||
The clear separation of those parts reinforces a degree of formalism - in
|
||||
particular about separating C and C++ - that was absent in our previous takes.
|
||||
|
||||
[image dde_linux_parts]
|
||||
|
||||
A driver is a Genode component. So the outer border of the picture is Genode's
|
||||
bare-bones C++ API. At the lower end, the API provides access to device
|
||||
resources such as interrupts and memory-mapped device registers. At the higher
|
||||
end, the API allows the driver to play the role of a service for other
|
||||
components through one of Genode's session interfaces.
|
||||
|
||||
The lower (blueish) part of the picture is concerned with the runtime
|
||||
environment needed to make the Linux kernel code feel right at home. The gap
|
||||
between Genode's API and Linux kernel interfaces is closed in two steps.
|
||||
First, the so-called *lx_kit* library implements handy mechanisms for building
|
||||
the meaty parts of the runtime in C++. For example, it provides a user-level
|
||||
task scheduling model that satisfies the semantic needs of Linux. The lx_kit
|
||||
is located at _dde_linux/src/include/lx_kit_ and _dde_linux/src/lib/lx_kit/_
|
||||
|
||||
Second, the *lx_emul* (short for Linux emulation) code wraps the lx_kit
|
||||
functionality into C interfaces. The functions of those interfaces are
|
||||
prefixed with 'lx_emul_' and serve as basic primitives for re-implementing
|
||||
(parts of) the original Linux kernel-internal ABI. Although the previous
|
||||
version of DDE Linux already featured the principle lx_kit and lx_emul
|
||||
fragments, the new design applies the underlying idea much more stringent,
|
||||
fostering the almost galvanic separation between C and C++ code. In
|
||||
particular, C++ code never includes any Linux headers. The lx_emul code also
|
||||
comprises driver-specific dummy implementations of unused kernel functions.
|
||||
The handy tool at _tool/dde_linux/create_dummies_ automates the creation of
|
||||
those dummy implementations now. Finally, the lx_emul code drives the startup
|
||||
of the Linux kernel code by executing initcalls in the correct order. The
|
||||
reusable building blocks of lx_emul are located at
|
||||
_dde_linux/src/include/lx_emul/_ and _dde_linux/src/lib/lx_emul/_
|
||||
|
||||
When looking from the upper (greenish) end, the *genode_c_api* library is a
|
||||
thin wrapper around Genode's session interfaces. It enables C code to
|
||||
implement a Genode service such as block driver or network driver. The
|
||||
genode_c_api library is located at _os/include/genode_c_api/_ and
|
||||
_os/src/lib/genode_c_api/_.
|
||||
|
||||
The red area contains sole C code, most of which is unmodified Linux kernel
|
||||
code. It is supplemented with a small *lx_user* part that uses both the
|
||||
genode_c_api as well as Linux kernel interfaces to connect the unmodified
|
||||
Linux kernel code with the Genode universe.
|
||||
|
||||
We address the second aspect - the tooling - by the growing tool set at
|
||||
_tool/dde_linux/_. The biggest time saver is the _create_dummies_ tool, which
|
||||
automates the formerly manual task of implementing dummy functions to quickly
|
||||
attain a linkable binary. It is complemented with the _extract_initcall_order_
|
||||
tool, which supplements lx_emul with the information needed to perform all
|
||||
Linux initialization steps in the exact same order as a Linux kernel would do.
|
||||
|
||||
The third aspect - the methodology - is embodied in two source-code
|
||||
repositories that leverage the new DDE-Linux approach for two distinct ARM
|
||||
SoCs, namely i.MX8MQ and Allwinner A64.
|
||||
|
||||
:Genode support for i.MX8MQ SoC:
|
||||
|
||||
[https://github.com/skalk/genode-imx8mq]
|
||||
|
||||
:Genode support for Allwinner A64 SoC:
|
||||
|
||||
[https://github.com/nfeske/genode-allwinner]
|
||||
|
||||
The most pivotal methodological change is the way how we deal with the
|
||||
Linux-internal API now. In our previous work, we used to mimic the content of
|
||||
kernel headers by a custom-tailored emulation header _lx_emul.h_ per driver.
|
||||
Whereas these driver-specific API flavors catered our urge to keep transitive
|
||||
code complexity at bay, they required significant and boring manual labour.
|
||||
Now we changed our minds to reusing the original Linux headers, thereby
|
||||
greatly reducing the amount of repetitive work while reducing the likelihood
|
||||
for subtle bugs.
|
||||
|
||||
|
||||
Success stories
|
||||
---------------
|
||||
|
||||
Both repositories linked above employ the re-imagined DDE-Linux approach to
|
||||
resounding success. The i.MX8MQ repository features drivers for framebuffer
|
||||
output and SD-card access,
|
||||
[https://genodians.org/skalk/2021-08-02-mnt-reform2-sdcard - targeting the MNT Reform laptop].
|
||||
The Allwinner repository contains a network driver for the Pine-A64-LTS board
|
||||
and a new framebuffer driver for the Pinephone. No single line of Linux code
|
||||
had to be changed.
|
||||
|
||||
We found that the development of those driver components took only a fraction
|
||||
of time compared to our past experiences. The most unnerving aspects of the
|
||||
driver porting work have simply vanished: Subtle incompatibilities between C
|
||||
and C++ are ruled out by design now. The hunt for missing initcalls is no
|
||||
more. No dummy function must be written by hand. The compilation of arbitrary
|
||||
Linux compilation units works instantly without manual labour.
|
||||
This - in turn - brings the experimental addition or removal of kernel
|
||||
subsystems down from hours to seconds, turning the development work into an
|
||||
exploratory experience.
|
||||
|
||||
That said, it is not all roses. Components based on Linux drivers have to
|
||||
carry substantial Linux-specific bureaucracy along with them. The resulting
|
||||
components tend to be somewhat obese given their relatively narrow purpose.
|
||||
E.g., the executable binary of the framebuffer driver for the Pinephone is
|
||||
1.5 MiB in size, most of which is presumably dead weight.
|
||||
|
||||
|
||||
Transition
|
||||
----------
|
||||
|
||||
Our existing and time-tested Linux-based drivers located in the _dde_linux_
|
||||
repository have remained untouched by the current release.
|
||||
We plan to successively update or replace those drivers using the new
|
||||
approach. Until then, the original components refer to the old approach as
|
||||
"legacy". E.g., the former implementation of lx_emul has been moved to
|
||||
_dde_linux/src/include/legacy/lx_emul/_.
|
||||
|
||||
|
||||
Advancing GPU driver stack
|
||||
##########################
|
||||
|
||||
With release 21.08, we take a major leap towards 3D and GPU support on Genode.
|
||||
This topic has been on the slow burner for a while now and we were happy to be
|
||||
able to finally revive this topic. On the Mesa front, we conducted an update
|
||||
to version 21.0.0 (Section [Mesa update]), while adding more features and new
|
||||
platforms to our
|
||||
[https://genode.org/documentation/release-notes/17.08 - Intel GPU multiplexer].
|
||||
On Intel platforms, there exists no hardware distinction between the display
|
||||
controller and 3D acceleration, as both functions are provided by the GPU.
|
||||
Other platforms, e.g. ARM based SoCs, often contain a separate display and a
|
||||
GPU device, making it possible to isolate display configuration within a
|
||||
separate driver. Therefore, we are glad to report that we found a solution on
|
||||
how to separate display and 3D acceleration on Intel systems.
|
||||
|
||||
|
||||
Mesa update
|
||||
-----------
|
||||
|
||||
Genode's port of the
|
||||
[https://www.mesa3d.org - Mesa 3D graphics library] dates back to version
|
||||
11.2.2 that was released in 2016 while the current version is past 21 by now.
|
||||
Because of this version gap, we decided to start with a fresh port of Mesa
|
||||
instead of solely updating from version 11. The more recent version enabled us
|
||||
to switch from Mesa's DRI drivers (i965) to the
|
||||
[https://de.wikipedia.org/wiki/Gallium3D - Gallium] version (Iris) for Intel
|
||||
GPUs.
|
||||
[https://xdc2018.x.org/slides/optimizing-i965-for-the-future.pdf - Iris]
|
||||
is Intel's redesigned version of the dated i965 driver that aims to lower CPU
|
||||
usage and improved performance. It is the only driver that supports Gen 12
|
||||
(Intel's current Xe GPU architecture) while also removing support for old
|
||||
Intel generations. As Genode supports Gen 8 (Broadwell) platforms only, we
|
||||
felt that Iris is the driver of choice for the future.
|
||||
|
||||
|
||||
GPU multiplexer improvements
|
||||
----------------------------
|
||||
|
||||
The GPU multiplexer received stability improvements, new features required by
|
||||
Mesa's Iris driver, i.e. context isolation and sync objects, and bug fixes
|
||||
prompted by supporting newer GPU generations. These generations include Gen 9
|
||||
(Skylake) and Gen 9.5 (Kaby Lake), with more versions to come. Please note
|
||||
that this line of work is not finished and is as of now in a preliminary state
|
||||
with ongoing efforts.
|
||||
|
||||
|
||||
The GPU multiplexer as a platform service
|
||||
-----------------------------------------
|
||||
|
||||
As stated at the beginning of this chapter, Intel PC platforms have no
|
||||
distinction between the display device and the 3D rendering. Both functions
|
||||
are integrated into the GPU as display engine and render engine. This implies
|
||||
that Genode's Intel framebuffer/display driver has to share resources with the
|
||||
GPU multiplexer. The co-location of both drivers in one component, however,
|
||||
violates Genode's core principle of a minimally-complex trusted computing
|
||||
base. Whereas the complex display driver should best be a disposable component
|
||||
([https://fosdem.org/2021/schedule/event/microkernel_pluggable_device_drivers_for_genode/ - FOSDEM talk]),
|
||||
the GPU driver must ideally be realized as a low-complexity resource
|
||||
multiplexer.
|
||||
|
||||
We eventually found a way to solve this contradiction: On Genode, each driver
|
||||
requests the hardware resources to program a device from the platform driver
|
||||
via the platform session. As these resources cannot be shared, we came up with
|
||||
the idea that the GPU multiplexer requests all GPU resources and itself
|
||||
provides a platform service for the display driver. It hands out the subset of
|
||||
resources that are related to display handling and forwards display
|
||||
interrupts. This approach is completely transparent to Genode's Intel display
|
||||
driver.
|
||||
|
||||
[image gpu_architecture]
|
||||
System integration of the GPU driver/multiplexer and the framebuffer driver
|
||||
as distinct components
|
||||
|
||||
We already have implemented this solution for Gen 8 and are working on newer
|
||||
generations.
|
||||
|
||||
|
||||
Future prospects
|
||||
----------------
|
||||
|
||||
In the current state, we are still working on newer Intel (Gen9+) GPU support
|
||||
and are planning to integrate this line of work into Sculpt release 21.09 with
|
||||
a small demo scenario (e.g., [https://github.com/glmark2/glmark2 - Glmark2]
|
||||
that is now available in Genode world).
|
||||
|
||||
Additionally, there is ongoing work to support
|
||||
[https://www.verisilicon.com/en/IPPortfolio/VivanteGPUIP - Vivante] GPUs as
|
||||
utilized by i.MX SoCs. As of now Mesa's etnaviv driver is included in our
|
||||
Mesa update and a GPU multiplexer component based on the Linux DRM driver is
|
||||
available as a preview on
|
||||
[https://github.com/cnuke/genode/commits/21.08-etnaviv - this] topic branch.
|
||||
|
||||
|
||||
Base framework and OS-level infrastructure
|
||||
##########################################
|
||||
|
||||
Revised cache-maintenance interface
|
||||
===================================
|
||||
|
||||
The base library used to expose a single cache-maintenance function to
|
||||
user-level components, namely 'cache_coherent'. It is primarily needed to
|
||||
accommodate self-modifying code, e.g., for JIT compilers, to write back
|
||||
data-cache lines, and invalidate the corresponding instruction-cache lines.
|
||||
However, we found that the proper support for cached DMA buffers in Linux
|
||||
device-driver ports calls for two additional semantic flavours.
|
||||
|
||||
One is needed whenever driver code initially writes data to a DMA buffer
|
||||
before handing over the buffer to the device. Linux driver code usually issues
|
||||
a 'dma_map_*' call in this case to ensure that data gets written out to memory
|
||||
and the data cache is invalidated. This scenario is now covered by the new
|
||||
'cache_clean_invalidate_data' function.
|
||||
|
||||
The other flavor is needed to invalidate data-cache lines before reading
|
||||
device-generated content from a DMA buffer. Linux driver code usually calls a
|
||||
'dma_unmap_*' function in this case. This case is now covered by the new
|
||||
'cache_invalidate_data' function.
|
||||
|
||||
Both functions are provided for the base-hw and Fiasco.OC kernels on the ARM
|
||||
architecture.
|
||||
|
||||
|
||||
Improved host file-system access on Genode/Linux
|
||||
================================================
|
||||
|
||||
Genode has included a component for host file-system access on Linux for
|
||||
years, but the state of the implementation and the feature set limited its
|
||||
application to mere debugging or development scenarios. This release improves
|
||||
*lx_fs* in certain areas to permit common use cases and scenarios.
|
||||
|
||||
First, the file-system server gets support for the unlinking of files, which
|
||||
was left out in the past to prevent accidental deletion of files on the host.
|
||||
The current version includes a robust implementation of the feature, which is
|
||||
confined to the configured sub-directory.
|
||||
Further, sessions track client-specific consumption of resources (namely RAM
|
||||
and capabilities) and also support dynamic resource upgrades. Last, we added
|
||||
file-watching support to lx_fs, which enables monitoring files for changes
|
||||
based on the inotify interface of the Linux kernel. The implementation is
|
||||
prepared to handle bursts of changes by limiting the rate of notifications to
|
||||
the client.
|
||||
|
||||
These improvements were contributed by Pirmin Duss.
|
||||
|
||||
|
||||
New black-hole component
|
||||
========================
|
||||
|
||||
A commonly requested feature for Sculpt OS is that it would be nice to have
|
||||
the ability to wire up various sessions of a deployed component to a dummy
|
||||
version of the required service. This way, the user could easily start an
|
||||
application that would normally require, for example, an audio-out session but
|
||||
connect it to a "black hole" component that simply drops all audio data. This
|
||||
would be especially useful if no hardware driver for a specific device is
|
||||
available on a particular platform, but would also allow for more fine-grained
|
||||
privacy control.
|
||||
|
||||
For this release, we created a first version of the black-hole component,
|
||||
which provides a dummy implementation of the audio-out session when enabled in
|
||||
the configuration:
|
||||
|
||||
! <config>
|
||||
! <audio_out/>
|
||||
! </config>
|
||||
|
||||
More session types are intended to be added in future releases.
|
||||
|
||||
|
||||
NIC router
|
||||
==========
|
||||
|
||||
With this release, the NIC router receives an enhancement of its feature for
|
||||
forwarding DNS configurations via DHCP, a sensible way of dealing with
|
||||
fragmented IPv4 packets, and some minor cleanups regarding its configuration
|
||||
interface. The update changes the configuration interface of the NIC router in
|
||||
a non-compatible way. Hence, systems that integrate the router might require
|
||||
adaptation. At the end of this section, you can find an overview of how to
|
||||
adapt systems properly.
|
||||
|
||||
The NIC router now interprets the IPv4 flags "More Fragments" and "Fragment
|
||||
Offset" in order to determine whether an IPv4 packet is fragmented or not.
|
||||
Fragmented packets are dropped safely while the unfragmented ones are routed
|
||||
as usual. The decision to drop fragmented packets by default is the result of
|
||||
a long discussion among users and developers of the NIC router. That
|
||||
discussion came to the conclusion that the complexity overhead and security
|
||||
risks of routing fragmented IPv4 outrun its relevance in modern world
|
||||
networks. Therefore, we assume that for the common user of the router, a
|
||||
simple rejection of fragmented IPv4 is the better deal.
|
||||
|
||||
The consideration of IPv4 fragmentation is accompanied by several ways of
|
||||
communicating the router's decision to drop fragmented packets. If the config
|
||||
flag 'verbose_packet_drop' is set, the router prints a message "drop packet
|
||||
(fragmented IPv4 not supported)" for each dropped fragment to the log. If the
|
||||
new attribute 'dropped_fragm_ipv4' in the config tag '<report>' is set, the
|
||||
router will report the number of packets dropped due to fragmentation. Last
|
||||
but not least, the NIC router can also be instructed to inform the sender of a
|
||||
dropped IPv4 fragment by sending an ICMP "destination unreachable" reply. Like
|
||||
the other feedback mechanisms, this is deactivated by default and can be
|
||||
activated by setting the new config attribute 'icmp_type_3_code_on_fragm_ipv4'.
|
||||
The attribute must be set to a valid ICMP code number that is then used for
|
||||
the replies.
|
||||
|
||||
The run script 'nic_router_ipv4_fragm' demonstrates the router's behavior
|
||||
regarding fragmented IPv4.
|
||||
|
||||
For many years, the DHCP server of the NIC router is capable of sending DNS
|
||||
configuration attributes with its replies. At first, this was only a single
|
||||
DNS server address. With
|
||||
[https://genode.org/documentation/release-notes/21.02#NIC_router - Genode 21.02],
|
||||
this has been extended to a list of DNS server addresses. Sending such address
|
||||
lists has now been made more conforming to the RFCs in that the server will
|
||||
list them all in one option 6 field instead of adding one option 6 field per
|
||||
address. Consequently, the DHCP client of the router now also considers only
|
||||
the first option 6 field of a reply but may parse multiple addresses from it.
|
||||
|
||||
Another new feature is that the DHCP client of the router now remembers the
|
||||
domain name (option 15) of a DHCP reply that leads to an IPv4 configuration.
|
||||
Analogously, the DHCP server will send a domain name with DHCP replies if such
|
||||
a name is at hand. As with DNS server addresses, the DHCP server can obtain
|
||||
the domain name either statically through its configuration (new config tag
|
||||
'<dns-domain>') or dynamically from the results of a DHCP client of another
|
||||
domain. The latter is achieved by setting the new config attribute
|
||||
'dns_config_from' that replaces the former attribute 'dns_server_from'. If
|
||||
'dns_config_from' is set to the name of another domain, the DHCP server will
|
||||
use both the DNS server addresses and the DNS domain name of the domain.
|
||||
|
||||
DNS domain names that were stored with a dynamic IPv4 configuration in the
|
||||
router are also reported via the new report tag '<dns-domain>' whenever the
|
||||
'config' attribute in the config tag '<report>' is set. As with DNS server
|
||||
addresses, this allows for manual forwarding and filtering through individual
|
||||
management components (see
|
||||
[https://genode.org/documentation/release-notes/21.02#NIC_router - Genode 21.02]).
|
||||
|
||||
As a delayed adaption to the
|
||||
[https://genode.org/documentation/release-notes/21.02#Pluggable_network_device_drivers - introduction of the Uplink session]
|
||||
two Genode releases ago, the term "Uplink", that was used in combination with
|
||||
the NIC router to refer to NIC sessions that the router requested itself, has
|
||||
been re-named more accurately to "NIC client". This is meant to prevent
|
||||
confusion with the new session type and, most notable to users, implies that
|
||||
the tag '<uplink>' in router configurations got re-named to '<nic-client>'.
|
||||
|
||||
|
||||
How to adjust Genode 21.05 systems to the new NIC router
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* At each occurrence of the '<uplink ...>' tag in a NIC router configuration,
|
||||
replace the tag name 'uplink' with 'nic-client'. The rest of the tag stays
|
||||
the same. This does not yield any semantic changes.
|
||||
|
||||
* At each occurrence of the 'dns_server_from' attribute in a NIC router
|
||||
configuration, replace the attribute name with 'dns_config_from'. The
|
||||
attribute value remains unaltered. Be aware that this will add forwarding of
|
||||
DNS domain names to your system. Forwarding DNS server addresses but not DNS
|
||||
domain names is not supported anymore.
|
||||
|
||||
|
||||
RAM framebuffer driver for Qemu
|
||||
===============================
|
||||
|
||||
During graphical application development on ARMv8, it became obvious that
|
||||
Genode still lacked framebuffer-driver support on Qemu for ARMv8, thus
|
||||
rendering test execution on real hardware mandatory. In order to speedup test
|
||||
and development time for graphical applications, we enabled RAM framebuffer
|
||||
support for the "virt_qemu" board by adding a 'driver_interactive-virt_qemu'
|
||||
package. The package contains a 'ram_fb_drv' that configures a RAM framebuffer
|
||||
through Qemu's firmware interface and uses the capture session interface to
|
||||
provide access to the framebuffer.
|
||||
|
||||
To test drive the driver, you can execute any Genode run script that requires
|
||||
graphical applications. The following example shows how to execute the demo
|
||||
run script in Qemu:
|
||||
|
||||
* In _<genode_dir>/build/arm_v8a/etc/build.conf_ change
|
||||
! # use time-tested graphics backend
|
||||
! QEMU_OPT += -display sdl
|
||||
|
||||
to
|
||||
|
||||
! QEMU_OPT += -device ramfb
|
||||
|
||||
* In _<genode_dir>/build/arm_v8a_ execute
|
||||
! make KERNEL=hw BOARD=virt_qemu run/demo
|
||||
|
||||
|
||||
Sandbox API
|
||||
===========
|
||||
|
||||
When using [https://github.com/nfeske/goa - Goa], we noticed that using the os
|
||||
API caused binaries to be always linked against 'sandbox.lib.so' because its
|
||||
symbols were part of the api archive as well. We therefore decided to separate
|
||||
the sandbox API from the os API by moving the header files to
|
||||
_repos/os/include/sandbox/_ and providing them in a distinct api archive along
|
||||
with the library symbols.
|
||||
|
||||
|
||||
Libraries and applications
|
||||
##########################
|
||||
|
||||
Updated and improved VirtualBox
|
||||
===============================
|
||||
|
||||
Our ongoing development efforts with VirtualBox 6.1 extended the
|
||||
implementation in various aspects. With this release, we updated the version
|
||||
to 6.1.26 published in July to stay in sync with upstream developments. This
|
||||
version especially improves the audio back end for the OSS interface and
|
||||
graphics.
|
||||
|
||||
On the integration side, VirtualBox 6 now supports dynamic framebuffer
|
||||
resolutions and the capslock ROM mode. The latter is important to provide the
|
||||
user a consistent system-wide capslock state, which is controlled by a global
|
||||
capslock ROM and virtual KEY_CAPSLOCK events forwarded to guest operating
|
||||
systems. Per default, a raw mode is used and capslock input events are sent
|
||||
unfiltered to the guest. For ROM mode, VirtualBox may be configured like
|
||||
follows.
|
||||
|
||||
!<config capslock="rom">
|
||||
|
||||
The network-device model in VirtualBox 5 uses the MAC address from the
|
||||
connected NIC session. We added this behavior also to VirtualBox 6. During the
|
||||
past months, we also observed significant performance issues with the AHCI
|
||||
model, which we address in this release. The background is that our port of
|
||||
VirtualBox 6 limits changes to the original code and execution model to a bare
|
||||
minimum. This renders updates of the upstream version less expensive, but on
|
||||
the other hand, uncovers some inherent assumptions about the runtime behavior
|
||||
(i.e., scheduling of threads) in the original implementation that must be
|
||||
addressed.
|
||||
|
||||
|
||||
Qt5 and QtWebEngine
|
||||
===================
|
||||
|
||||
In this release, we enabled SSL server certificate validation and support for
|
||||
multimedia playback in our ports of QtWebEngine and the Falkon web browser.
|
||||
|
||||
More specifically, we ported the 'nss' library for the SSL certificate
|
||||
validation and the 'sndio' library as back end for the audio playback
|
||||
functionality and enhanced our OSS audio VFS plugin accordingly.
|
||||
|
||||
The following screenshot shows an example use case of Falkon as a private
|
||||
multimedia browser, which stores all session data, like cookies, in RAM only.
|
||||
In the future, we also want to enable support for multimedia input and,
|
||||
consequently, private video conferences.
|
||||
|
||||
[image falkon_youtube]
|
||||
|
||||
|
||||
Modular integration of LTE modem stack in Sculpt OS
|
||||
===================================================
|
||||
|
||||
In version [https://genode.org/documentation/release-notes/21.02#LTE_modem_stack - 21.02],
|
||||
we announced the LTE modem support as a prerequisite for using Genode on the
|
||||
Pinephone. Since most of our development laptops also come with LTE modems or
|
||||
an extension slot for installing one, we explored ways to augment the Sculpt
|
||||
scenario with mobile networking on demand, i.e., by the installation of
|
||||
additional components. The result is documented by means of an
|
||||
[https://genodians.org/jschlatow/2021-07-21-mobile-network - article on genodians.org].
|
||||
|
||||
|
||||
Webcam improvements using libuvc
|
||||
================================
|
||||
|
||||
With webcam support added by the previous release, we discovered some
|
||||
complications with devices that implement the UVC spec in version 1.5. We
|
||||
found one of those devices in a Thinkpad T490s. Since
|
||||
[https://ken.tossell.net/libuvc/doc - libuvc] did not fully implement this
|
||||
version of the spec, we added a patch for this. The main issue was the
|
||||
different size of the video probe and commit control messages. Interestingly,
|
||||
the problematic device is quite picky in this regard and only responds when
|
||||
the size was set correctly. In connection with this, we fixed a bug in our
|
||||
[https://libusb.info - libusb] back end, which caused the size of USB control
|
||||
messages being wrongly calculated.
|
||||
|
||||
Apart from these device-specific issues, the webcam driver now enables auto
|
||||
exposure in order to adapt to different lighting conditions.
|
||||
|
||||
|
||||
Sndio audio library
|
||||
===================
|
||||
|
||||
To complement the VFS OSS-plugin introduced in release
|
||||
[https://genode.org/documentation/release-notes/20.11 - 20.11], we ported the
|
||||
[https://sndio.org - sndio] library to Genode. It contains an OSS back end
|
||||
that prompted us to broaden the functionality of our VFS plugin to satisfy
|
||||
the requirements of the library. This is in line with the envisioned plan to
|
||||
extend the OSS plugin incrementally to cover more use cases.
|
||||
|
||||
The sndio framework features a server component besides the library but for
|
||||
the moment, we focus solely on using sndio in a client context. Here the
|
||||
component, e.g., cmus and Falkon, uses the library to access the sound device
|
||||
directly.
|
||||
|
||||
|
||||
Build system and tools
|
||||
######################
|
||||
|
||||
Tool-chain support for RISC-V
|
||||
=============================
|
||||
|
||||
As one might have noticed, Genode's RISC-V tool chain is absent in tool-chain
|
||||
release
|
||||
[https://sourceforge.net/projects/genode/files/genode-toolchain/21.05/genode-toolchain-21.05-x86_64.tar.xz/download - 21.05]
|
||||
because it still had issues at the release time. These issues, namely the
|
||||
problem of the dynamic linker's self relocation during program startup have
|
||||
been resolved during this release cycle. The RISC-V tool chain can now be
|
||||
built manually using Genode's regular 'tool_chain' script:
|
||||
|
||||
! <genode-dir>/tool/tool_chain riscv ENABLE_FEATURES="c c++ gdb"
|
||||
|
||||
|
||||
Run tool
|
||||
========
|
||||
|
||||
Genode's custom workflow automation tool called 'run' received the following
|
||||
enhancements.
|
||||
|
||||
To ease the hosting of driver packages outside of Genode's main repository -
|
||||
an emerging pattern for supporting new SoCs - we replaced the formerly
|
||||
built-in names of board-specific 'drivers_nic' and 'drivers_interactive' depot
|
||||
packages by the convention of appending the board name as a suffix, e.g.,
|
||||
'drivers_nic-pine_a64lts'. Hence, new hardware support can now be added
|
||||
without touching the run tool.
|
||||
|
||||
The ARM fastboot plugin can now be used on 64-bit ARM platforms in addition to
|
||||
32-bit ARM. Its formerly mandatory parameter '--load-fastboot-device' has
|
||||
become optional and can be omitted if only one device is present.
|
||||
|
||||
A new _image/uboot_fit_ plugin enables the use of U-Boot's new FIT (flattened
|
||||
image tree) image format (carrying the extension 'itb'), which supersedes the
|
||||
uImage format. The new format simplifies the booting of a Linux system, which
|
||||
typically requires not only a kernel image but also a device-tree binary and a
|
||||
RAM disk. A FIT image combines all ingredients into a single file and adds
|
||||
some metadata like checksums. Note, however, that booting an _image.itb_,
|
||||
which doesn't contain a device-tree binary may cause U-Boot's 'bootm' command
|
||||
to fail. A workaround for this is to execute the individual boot steps
|
||||
separately, which skips the Linux-specific preparatory steps that depend on
|
||||
the device-tree binary:
|
||||
|
||||
! bootm start
|
||||
! bootm loados
|
||||
! bootm go
|
||||
|
||||
|
||||
Removal of deprecated components
|
||||
################################
|
||||
|
||||
In the release notes of version
|
||||
[https://genode.org/documentation/release-notes/20.11#Retiring_the_monolithic_USB_driver - 20.11],
|
||||
we announced the retirement of our traditional monolithic USB-driver
|
||||
component, which used to combine host-controller drivers together with USB
|
||||
storage, HID, and networking drivers in a single component. With the current
|
||||
release, we ultimately completed the transition to our multi-component USB
|
||||
stack and removed the deprecated monolithic USB driver.
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 d8e59b010b60eba516a0e20b3aab18e05c85a977
|
||||
2021-08-28 eec6b1e516691434c54196615af980b54428eb7e
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 8cfe2fe4913b79b6b58ae5dc1e47e4c96881b9fb
|
||||
2021-08-28 29757bf5413bf396d085bafbc700268e2d1156c4
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 af377c6c3dcc0adcd59cd2e8668f47bdcc12d4c1
|
||||
2021-08-28 60c1ff4c8efe8caa105ff16fdd7fd09ef1ef6991
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 475462d2565c1eb0cb0df6c3ba4f58007f73ac04
|
||||
2021-08-28 038ab57adceb64cf49000518343c3e14b8481851
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 778e2a540f54b8164db8f459931211964cafeb58
|
||||
2021-08-28 ba949187f071c5af50467ab054d8841788e48548
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 d977d90dd21a266a9325b355da80def7bf26cd0f
|
||||
2021-08-28 52379c07bda990554cf5e18e81d3c3de449b9197
|
||||
|
||||
@@ -21,3 +21,15 @@ void Genode::cache_coherent(addr_t addr, size_t size)
|
||||
{
|
||||
Foc::l4_cache_coherent(addr, addr + size);
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_clean_invalidate_data(Genode::addr_t addr, Genode::size_t size)
|
||||
{
|
||||
Foc::l4_cache_flush_data(addr, addr + size);
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_invalidate_data(Genode::addr_t addr, Genode::size_t size)
|
||||
{
|
||||
Foc::l4_cache_inv_data(addr, addr + size);
|
||||
}
|
||||
|
||||
@@ -37,13 +37,15 @@ namespace Kernel {
|
||||
constexpr Call_arg call_id_ack_signal() { return 11; }
|
||||
constexpr Call_arg call_id_print_char() { return 12; }
|
||||
constexpr Call_arg call_id_cache_coherent_region() { return 13; }
|
||||
constexpr Call_arg call_id_ack_cap() { return 14; }
|
||||
constexpr Call_arg call_id_delete_cap() { return 15; }
|
||||
constexpr Call_arg call_id_timeout() { return 16; }
|
||||
constexpr Call_arg call_id_timeout_max_us() { return 17; }
|
||||
constexpr Call_arg call_id_time() { return 18; }
|
||||
constexpr Call_arg call_id_run_vm() { return 19; }
|
||||
constexpr Call_arg call_id_pause_vm() { return 20; }
|
||||
constexpr Call_arg call_id_cache_clean_inv_region() { return 14; }
|
||||
constexpr Call_arg call_id_cache_inv_region() { return 15; }
|
||||
constexpr Call_arg call_id_ack_cap() { return 16; }
|
||||
constexpr Call_arg call_id_delete_cap() { return 17; }
|
||||
constexpr Call_arg call_id_timeout() { return 18; }
|
||||
constexpr Call_arg call_id_timeout_max_us() { return 19; }
|
||||
constexpr Call_arg call_id_time() { return 20; }
|
||||
constexpr Call_arg call_id_run_vm() { return 21; }
|
||||
constexpr Call_arg call_id_pause_vm() { return 22; }
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
@@ -188,6 +190,32 @@ namespace Kernel {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean and invalidate D-Cache lines of the given memory region
|
||||
*
|
||||
* \param base base of the region within the current domain
|
||||
* \param size size of the region
|
||||
*/
|
||||
inline void cache_clean_invalidate_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
call(call_id_cache_clean_inv_region(), (Call_arg)base, (Call_arg)size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Invalidate D-Cache lines of the given memory region
|
||||
*
|
||||
* \param base base of the region within the current domain
|
||||
* \param size size of the region
|
||||
*/
|
||||
inline void cache_invalidate_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
call(call_id_cache_inv_region(), (Call_arg)base, (Call_arg)size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send request message and await receipt of corresponding reply message
|
||||
*
|
||||
|
||||
@@ -15,6 +15,7 @@ SRC_CC += spec/arm/kernel/cpu.cc
|
||||
SRC_CC += spec/arm/kernel/pd.cc
|
||||
SRC_CC += spec/arm/cpu.cc
|
||||
SRC_CC += spec/arm/kernel/thread.cc
|
||||
SRC_CC += spec/arm/kernel/thread_caches.cc
|
||||
SRC_CC += spec/arm/platform_support.cc
|
||||
|
||||
# add assembly sources
|
||||
|
||||
@@ -7,6 +7,7 @@ SRC_CC += kernel/cpu_mp.cc
|
||||
SRC_CC += spec/64bit/memory_map.cc
|
||||
SRC_CC += spec/arm/generic_timer.cc
|
||||
SRC_CC += spec/arm/kernel/lock.cc
|
||||
SRC_CC += spec/arm/kernel/thread_caches.cc
|
||||
SRC_CC += spec/arm/platform_support.cc
|
||||
SRC_CC += spec/arm_v8/cpu.cc
|
||||
SRC_CC += spec/arm_v8/kernel/cpu.cc
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-02-22 8418c32c327c1c69414891ae813d904cbf7f9c64
|
||||
2021-06-24 5626884aba14848b98e9aad4d00714fa5ea7c84a
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 602a4250ab4812d355255f87600ae5b2d058ff6c
|
||||
2021-08-28 7bb57a2e769700abf6fd2057d9e003abfa98299b
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 5a92bddc377068791d0eb704411e8f64f408b7a3
|
||||
2021-08-28 76c6eeb920f7d892be4ed670b8ee88f1ddb6706d
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 03207ecbb46d304aecf94b491dd7f5f18434a3ba
|
||||
2021-08-28 2ff3b759c6df9a5c461e9c259909e9804ad17ed7
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 e561b3c3024c5e66fc47a14741ad51f94772023d
|
||||
2021-08-28 a78c91c4f6fbcdad8e5cb77c4995c306f6e7f383
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 a45306f7af1fbe6b5414fc79d6d7df72d90cc051
|
||||
2021-08-28 f1a2ea4fa36605cc76483a40040c7e0bd1921695
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 0e52b14f12fb8387836c1d282c5b3bdd43308a33
|
||||
2021-08-28 c0c4cabd03be175d380f036de30106881eeb6651
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 04b1d602e9705d398191f25bd5650df55e02d15e
|
||||
2021-08-28 a8c4f0782c8653dc18e5ecd20bb3eb11a8d2984b
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 6a261650e7781a3fe05b2884c3222c4a684989b9
|
||||
2021-08-28 67253c6a4c652664896221c8b79fb82fff01dc57
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 6a7d93057760db316c708ed862f57552e1d30076
|
||||
2021-08-28 d0b3d729f5a549c885dab4dd7b4bc930daa5f6dc
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 f297a9e79ff7645be095431c9b4d8a6caeea84e3
|
||||
2021-08-28 c850168cfba0ff5bbfb1048c2a58552dd36dfb0f
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 a461ab6e948dd5d96a908bec57a9eecbf7088f3b
|
||||
2021-08-28 e4de82cc87762b272d28d6d632c967a575197e11
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 f2aa981b5a6eee8a4f246b2f03c785558e001f09
|
||||
2021-08-28 0e5bcaca15c5738839c7bae0bcdc1cbace99018b
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 c2d6204ae3de07ef6bca3aceacb7cc0df6b8939a
|
||||
2021-08-28 2e6f58ac4d73642b0241f211c0738ad2b47b5f6a
|
||||
|
||||
@@ -726,6 +726,8 @@ void Thread::_call()
|
||||
unsigned const call_id = user_arg_0();
|
||||
switch (call_id) {
|
||||
case call_id_cache_coherent_region(): _call_cache_coherent_region(); return;
|
||||
case call_id_cache_clean_inv_region(): _call_cache_clean_invalidate_data_region(); return;
|
||||
case call_id_cache_inv_region(): _call_cache_invalidate_data_region(); return;
|
||||
case call_id_stop_thread(): _call_stop_thread(); return;
|
||||
case call_id_restart_thread(): _call_restart_thread(); return;
|
||||
case call_id_yield_thread(): _call_yield_thread(); return;
|
||||
|
||||
@@ -225,6 +225,8 @@ class Kernel::Thread : private Kernel::Object, public Cpu_job, private Timeout
|
||||
void _call_send_reply_msg();
|
||||
void _call_invalidate_tlb();
|
||||
void _call_cache_coherent_region();
|
||||
void _call_cache_clean_invalidate_data_region();
|
||||
void _call_cache_invalidate_data_region();
|
||||
void _call_print_char();
|
||||
void _call_await_signal();
|
||||
void _call_pending_signal();
|
||||
|
||||
@@ -152,16 +152,24 @@ void Arm_cpu::cache_coherent_region(addr_t const base,
|
||||
}
|
||||
|
||||
|
||||
void Arm_cpu::clean_data_cache_by_virt_region(addr_t const base,
|
||||
size_t const size)
|
||||
void Arm_cpu::cache_invalidate_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
auto lambda = [] (addr_t const base) { Dcimvac::write(base); };
|
||||
cache_maintainance(base, size, Cpu::data_cache_line_size(), lambda);
|
||||
}
|
||||
|
||||
|
||||
void Arm_cpu::cache_clean_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
auto lambda = [] (addr_t const base) { Dccmvac::write(base); };
|
||||
cache_maintainance(base, size, Cpu::data_cache_line_size(), lambda);
|
||||
}
|
||||
|
||||
|
||||
void Arm_cpu::clean_invalidate_data_cache_by_virt_region(addr_t const base,
|
||||
size_t const size)
|
||||
void Arm_cpu::cache_clean_invalidate_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
auto lambda = [] (addr_t const base) { Dccimvac::write(base); };
|
||||
cache_maintainance(base, size, Cpu::data_cache_line_size(), lambda);
|
||||
@@ -197,7 +205,7 @@ void Arm_cpu::clear_memory_region(addr_t const addr,
|
||||
* DMA memory, which needs to be evicted from the D-cache
|
||||
*/
|
||||
if (changed_cache_properties) {
|
||||
Cpu::clean_invalidate_data_cache_by_virt_region(addr, size);
|
||||
Cpu::cache_clean_invalidate_data_region(addr, size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -70,19 +70,6 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
|
||||
static void invalidate_instr_cache() {
|
||||
asm volatile ("mcr p15, 0, %0, c7, c5, 0" :: "r" (0) : ); }
|
||||
|
||||
/**
|
||||
* Clean data-cache for virtual region 'base' - 'base + size'
|
||||
*/
|
||||
static void clean_data_cache_by_virt_region(addr_t const base,
|
||||
size_t const size);
|
||||
|
||||
/**
|
||||
* Clean and invalidate data-cache for virtual region
|
||||
* 'base' - 'base + size'
|
||||
*/
|
||||
static void clean_invalidate_data_cache_by_virt_region(addr_t const base,
|
||||
size_t const size);
|
||||
|
||||
static void clear_memory_region(addr_t const addr,
|
||||
size_t const size,
|
||||
bool changed_cache_properties);
|
||||
@@ -90,6 +77,15 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu
|
||||
static void cache_coherent_region(addr_t const addr,
|
||||
size_t const size);
|
||||
|
||||
static void cache_clean_data_region(addr_t const base,
|
||||
size_t const size);
|
||||
|
||||
static void cache_clean_invalidate_data_region(addr_t const addr,
|
||||
size_t const size);
|
||||
|
||||
static void cache_invalidate_data_region(addr_t const addr,
|
||||
size_t const size);
|
||||
|
||||
/**
|
||||
* Invalidate TLB regarding the given address space id
|
||||
*/
|
||||
|
||||
@@ -55,36 +55,6 @@ void Thread::exception(Cpu & cpu)
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_coherent_region()
|
||||
{
|
||||
addr_t base = (addr_t) user_arg_1();
|
||||
size_t const size = (size_t) user_arg_2();
|
||||
|
||||
/**
|
||||
* sanity check that only one small page is affected,
|
||||
* because we only want to lookup one page in the page tables
|
||||
* to limit execution time within the kernel
|
||||
*/
|
||||
if (Hw::trunc_page(base) != Hw::trunc_page(base+size-1)) {
|
||||
Genode::raw(*this, " tried to make cross-page region cache coherent ",
|
||||
(void*)base, " ", size);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup whether the page is backed, and if so make the memory coherent
|
||||
* in between I-, and D-cache
|
||||
*/
|
||||
addr_t phys = 0;
|
||||
if (pd().platform_pd().lookup_translation(base, phys)) {
|
||||
Cpu::cache_coherent_region(base, size);
|
||||
} else {
|
||||
Genode::raw(*this, " tried to make invalid address ",
|
||||
base, " cache coherent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* on ARM with multiprocessing extensions, maintainance operations on TLB,
|
||||
* and caches typically work coherently across CPUs when using the correct
|
||||
|
||||
74
repos/base-hw/src/core/spec/arm/kernel/thread_caches.cc
Normal file
74
repos/base-hw/src/core/spec/arm/kernel/thread_caches.cc
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* \brief Kernel backend for threads - cache maintainance
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-06-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <cpu.h>
|
||||
#include <platform_pd.h>
|
||||
#include <kernel/pd.h>
|
||||
#include <kernel/thread.h>
|
||||
|
||||
using namespace Kernel;
|
||||
|
||||
|
||||
template <typename FN>
|
||||
static void for_cachelines(addr_t base,
|
||||
size_t const size,
|
||||
Kernel::Thread & thread,
|
||||
FN const & fn)
|
||||
{
|
||||
/**
|
||||
* sanity check that only one small page is affected,
|
||||
* because we only want to lookup one page in the page tables
|
||||
* to limit execution time within the kernel
|
||||
*/
|
||||
if (Hw::trunc_page(base) != Hw::trunc_page(base+size-1)) {
|
||||
Genode::raw(thread, " tried to make cross-page region cache coherent ",
|
||||
(void*)base, " ", size);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup whether the page is backed, and if so make the memory coherent
|
||||
* in between I-, and D-cache
|
||||
*/
|
||||
addr_t phys = 0;
|
||||
if (thread.pd().platform_pd().lookup_translation(base, phys)) {
|
||||
fn(base, size);
|
||||
} else {
|
||||
Genode::raw(thread, " tried to make invalid address ",
|
||||
(void*)base, " cache coherent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_coherent_region()
|
||||
{
|
||||
for_cachelines((addr_t)user_arg_1(), (size_t)user_arg_2(), *this,
|
||||
[] (addr_t addr, size_t size) {
|
||||
Genode::Cpu::cache_coherent_region(addr, size); });
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_clean_invalidate_data_region()
|
||||
{
|
||||
for_cachelines((addr_t)user_arg_1(), (size_t)user_arg_2(), *this,
|
||||
[] (addr_t addr, size_t size) {
|
||||
Genode::Cpu::cache_clean_invalidate_data_region(addr, size); });
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_invalidate_data_region()
|
||||
{
|
||||
for_cachelines((addr_t)user_arg_1(), (size_t)user_arg_2(), *this,
|
||||
[] (addr_t addr, size_t size) {
|
||||
Genode::Cpu::cache_invalidate_data_region(addr, size); });
|
||||
}
|
||||
@@ -29,7 +29,7 @@ constexpr bool Hw::Page_table::Descriptor_base::_smp() { return false; }
|
||||
|
||||
void Hw::Page_table::_table_changed(unsigned long addr, unsigned long size)
|
||||
{
|
||||
Genode::Arm_cpu::clean_data_cache_by_virt_region(addr, size);
|
||||
Genode::Arm_cpu::cache_clean_data_region(addr, size);
|
||||
}
|
||||
|
||||
#endif /* _CORE__SPEC__ARM_V6__TRANSLATION_TABLE_H_ */
|
||||
|
||||
@@ -101,7 +101,7 @@ static inline void cache_maintainance(Genode::addr_t const base,
|
||||
|
||||
|
||||
void Genode::Cpu::cache_coherent_region(addr_t const base,
|
||||
size_t const size)
|
||||
size_t const size)
|
||||
{
|
||||
Genode::memory_barrier();
|
||||
|
||||
@@ -117,6 +117,36 @@ void Genode::Cpu::cache_coherent_region(addr_t const base,
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cpu::cache_clean_invalidate_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
Genode::memory_barrier();
|
||||
|
||||
auto lambda = [] (addr_t const base) {
|
||||
asm volatile("dc civac, %0" :: "r" (base));
|
||||
asm volatile("dsb ish");
|
||||
asm volatile("isb");
|
||||
};
|
||||
|
||||
cache_maintainance(base, size, lambda);
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cpu::cache_invalidate_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
Genode::memory_barrier();
|
||||
|
||||
auto lambda = [] (addr_t const base) {
|
||||
asm volatile("dc ivac, %0" :: "r" (base));
|
||||
asm volatile("dsb ish");
|
||||
asm volatile("isb");
|
||||
};
|
||||
|
||||
cache_maintainance(base, size, lambda);
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cpu::clear_memory_region(addr_t const addr,
|
||||
size_t const size,
|
||||
bool changed_cache_properties)
|
||||
|
||||
@@ -56,7 +56,8 @@ struct Genode::Cpu : Hw::Arm_64_cpu
|
||||
struct alignas(16) Fpu_state
|
||||
{
|
||||
Genode::uint128_t q[32];
|
||||
Genode::uint32_t fpsr;
|
||||
Genode::uint64_t fpsr;
|
||||
Genode::uint64_t fpcr;
|
||||
};
|
||||
|
||||
struct alignas(8) Context : Cpu_state
|
||||
@@ -95,6 +96,10 @@ struct Genode::Cpu : Hw::Arm_64_cpu
|
||||
|
||||
static void cache_coherent_region(addr_t const addr,
|
||||
size_t const size);
|
||||
static void cache_clean_invalidate_data_region(addr_t const addr,
|
||||
size_t const size);
|
||||
static void cache_invalidate_data_region(addr_t const addr,
|
||||
size_t const size);
|
||||
};
|
||||
|
||||
#endif /* _CORE__SPEC__ARM_V8__CPU_H_ */
|
||||
|
||||
@@ -60,8 +60,9 @@ _kernel_entry:
|
||||
stp q26, q27, [x0], #32
|
||||
stp q28, q29, [x0], #32
|
||||
stp q30, q31, [x0], #32
|
||||
mrs x1, fpcr
|
||||
mrs x2, fpsr
|
||||
str x2, [x0]
|
||||
stp x1, x2, [x0], #16
|
||||
msr fpsr, xzr
|
||||
ldr x0, [sp, #-16]
|
||||
ldr x1, [sp, #-32]
|
||||
@@ -111,8 +112,9 @@ _kernel_entry:
|
||||
ldp q26, q27, [x1], #32
|
||||
ldp q28, q29, [x1], #32
|
||||
ldp q30, q31, [x1], #32
|
||||
ldr x1, [x1]
|
||||
msr fpsr, x1
|
||||
ldp x2, x3, [x1], #16
|
||||
msr fpcr, x2
|
||||
msr fpsr, x3
|
||||
add x0, x0, #8
|
||||
ldp x1, x2, [x0], #16
|
||||
ldp x3, x4, [x0], #16
|
||||
|
||||
@@ -107,36 +107,6 @@ bool Kernel::Pd::invalidate_tlb(Cpu &, addr_t addr, size_t size)
|
||||
}
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_coherent_region()
|
||||
{
|
||||
addr_t base = (addr_t) user_arg_1();
|
||||
size_t const size = (size_t) user_arg_2();
|
||||
|
||||
/**
|
||||
* sanity check that only one small page is affected,
|
||||
* because we only want to lookup one page in the page tables
|
||||
* to limit execution time within the kernel
|
||||
*/
|
||||
if (Hw::trunc_page(base) != Hw::trunc_page(base+size-1)) {
|
||||
Genode::raw(*this, " tried to make cross-page region cache coherent ",
|
||||
(void*)base, " ", size);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup whether the page is backed, and if so make the memory coherent
|
||||
* in between I-, and D-cache
|
||||
*/
|
||||
addr_t phys = 0;
|
||||
if (pd().platform_pd().lookup_translation(base, phys)) {
|
||||
Cpu::cache_coherent_region(base, size);
|
||||
} else {
|
||||
Genode::raw(*this, " tried to make invalid address ",
|
||||
base, " cache coherent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Thread::proceed(Cpu & cpu)
|
||||
{
|
||||
cpu.switch_to(*regs, pd().mmu_regs);
|
||||
|
||||
@@ -37,7 +37,7 @@ void Hw::Page_table::_table_changed(unsigned long addr, unsigned long size)
|
||||
* page table entry is added. We only do this as core as the kernel
|
||||
* adds translations solely before MMU and caches are enabled.
|
||||
*/
|
||||
Genode::Cpu::clean_data_cache_by_virt_region(addr, size);
|
||||
Genode::Cpu::cache_clean_data_region(addr, size);
|
||||
}
|
||||
|
||||
#endif /* _CORE__SPEC__CORTEX_A8__TRANSLATION_TABLE_H_ */
|
||||
|
||||
@@ -28,10 +28,10 @@ struct Genode::Cpu : Arm_v7_cpu
|
||||
* Clean and invalidate data-cache for virtual region
|
||||
* 'base' - 'base + size'
|
||||
*/
|
||||
static void clean_invalidate_data_cache_by_virt_region(addr_t const base,
|
||||
size_t const size)
|
||||
static void cache_clean_invalidate_data_region(addr_t const base,
|
||||
size_t const size)
|
||||
{
|
||||
Arm_cpu::clean_invalidate_data_cache_by_virt_region(base, size);
|
||||
Arm_cpu::cache_clean_invalidate_data_region(base, size);
|
||||
Board::l2_cache().clean_invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,12 @@ void Thread::exception(Cpu & cpu)
|
||||
void Thread::_call_cache_coherent_region() { }
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_clean_invalidate_data_region() { }
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_invalidate_data_region() { }
|
||||
|
||||
|
||||
void Kernel::Thread::proceed(Cpu & cpu)
|
||||
{
|
||||
cpu.switch_to(_pd->mmu_regs);
|
||||
|
||||
@@ -35,6 +35,12 @@ void Kernel::Thread::Tlb_invalidation::execute()
|
||||
void Kernel::Thread::_call_cache_coherent_region() { }
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_clean_invalidate_data_region() { }
|
||||
|
||||
|
||||
void Kernel::Thread::_call_cache_invalidate_data_region() { }
|
||||
|
||||
|
||||
void Kernel::Thread::proceed(Cpu & cpu)
|
||||
{
|
||||
cpu.switch_to(*regs, pd().mmu_regs);
|
||||
|
||||
@@ -206,6 +206,9 @@ struct Hw::Arm_cpu
|
||||
/* Branch predictor invalidate all */
|
||||
ARM_CP15_REGISTER_32BIT(Bpimva, c7, c5, 0, 7);
|
||||
|
||||
/* Data Cache Invalidate by MVA to PoC */
|
||||
ARM_CP15_REGISTER_32BIT(Dcimvac, c7, c6, 0, 1);
|
||||
|
||||
/* Data Cache Clean by MVA to PoC */
|
||||
ARM_CP15_REGISTER_32BIT(Dccmvac, c7, c10, 0, 1);
|
||||
|
||||
|
||||
@@ -17,22 +17,44 @@
|
||||
#include <cpu/cache.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
void Genode::cache_coherent(Genode::addr_t addr, Genode::size_t size)
|
||||
|
||||
template <typename FN>
|
||||
static void for_cachelines(addr_t addr, size_t size, FN const & fn)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/**
|
||||
* The kernel accepts the 'cache_coherent_region' call for one designated
|
||||
* The kernel accepts the cache maintainance calls for one designated
|
||||
* page only. Otherwise, it just ignores the call to limit the time being
|
||||
* uninteruppptible in the kernel. Therefor, we have to loop if more than
|
||||
* uninteruppptible in the kernel. Therefore, we have to loop if more than
|
||||
* one page is affected by the given region.
|
||||
*/
|
||||
while (size) {
|
||||
addr_t next_page = align_addr(addr+1, get_page_size_log2());
|
||||
size_t s = min(size, next_page - addr);
|
||||
Kernel::cache_coherent_region(addr, s);
|
||||
fn(addr, s);
|
||||
addr += s;
|
||||
size -= s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_coherent(addr_t addr, size_t size)
|
||||
{
|
||||
for_cachelines(addr, size, [] (addr_t addr, size_t size) {
|
||||
Kernel::cache_coherent_region(addr, size); });
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_clean_invalidate_data(addr_t addr, size_t size)
|
||||
{
|
||||
for_cachelines(addr, size, [] (addr_t addr, size_t size) {
|
||||
Kernel::cache_clean_invalidate_data_region(addr, size); });
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_invalidate_data(addr_t addr, size_t size)
|
||||
{
|
||||
for_cachelines(addr, size, [] (addr_t addr, size_t size) {
|
||||
Kernel::cache_invalidate_data_region(addr, size); });
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-09 e5ecbb3c8bdace835f144f0084c9aa91649e0bab
|
||||
2021-08-17 c3bcd7753faa8b48d9013a45b69edfa2a16695e4
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 9534bb2a4c39f66505bdbbad8ccb9da9506617c5
|
||||
2021-08-28 6b854a47a41ca0e70bf06c52f158f50a444e6a18
|
||||
|
||||
@@ -51,9 +51,10 @@ install_config {
|
||||
}
|
||||
|
||||
#
|
||||
# Create test-directory structure
|
||||
# Create test-directory structure and ensure it is empty
|
||||
#
|
||||
|
||||
exec rm -rf bin/libc_vfs
|
||||
exec mkdir -p bin/libc_vfs
|
||||
|
||||
#
|
||||
|
||||
436
repos/base-linux/run/lx_fs_notify.run
Normal file
436
repos/base-linux/run/lx_fs_notify.run
Normal file
@@ -0,0 +1,436 @@
|
||||
#
|
||||
# \brief Test for using the lx_fs_notify plugin with the Linux file system
|
||||
# \author Pirmin Duss
|
||||
# \date 2019-12-05
|
||||
#
|
||||
|
||||
assert_spec linux
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
create_boot_directory
|
||||
|
||||
import_from_depot [depot_user]/src/[base_src]
|
||||
import_from_depot [depot_user]/src/chroot
|
||||
import_from_depot [depot_user]/src/fs_rom
|
||||
import_from_depot [depot_user]/src/init
|
||||
import_from_depot [depot_user]/src/libc
|
||||
import_from_depot [depot_user]/src/stdcxx
|
||||
import_from_depot [depot_user]/src/posix
|
||||
import_from_depot [depot_user]/src/vfs
|
||||
|
||||
build {
|
||||
server/lx_fs
|
||||
test/lx_fs_notify/rom_log
|
||||
test/lx_fs_notify/file_writer
|
||||
}
|
||||
|
||||
#
|
||||
# init config
|
||||
#
|
||||
install_config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
|
||||
<start name="lx_fs" caps="200" ld="no">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides> <service name="File_system"/> </provides>
|
||||
<config>
|
||||
<policy label_prefix="fs_rom_config" root="/lx_fs_notify" writeable="no"/>
|
||||
<policy label_prefix="fs_rom_test" root="/lx_fs_notify/test" writeable="no"/>
|
||||
<policy label_suffix="templates" root="/lx_fs_notify/templates" writeable="yes"/>
|
||||
<policy label_suffix="test" root="/lx_fs_notify/test" writeable="yes"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="fs_rom_config">
|
||||
<binary name="fs_rom"/>
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<provides> <service name="ROM"/> </provides>
|
||||
<route>
|
||||
<service name="File_system"> <child name="lx_fs"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="fs_rom_test">
|
||||
<binary name="fs_rom"/>
|
||||
<resource name="RAM" quantum="40M"/>
|
||||
<provides> <service name="ROM"/> </provides>
|
||||
<route>
|
||||
<service name="File_system"> <child name="lx_fs"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="test-rom_log">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<route>
|
||||
<service name="ROM" label="outfile.txt"> <child name="fs_rom_test"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="init" caps="4000">
|
||||
<resource name="RAM" quantum="300M"/>
|
||||
<route>
|
||||
<service name="File_system"> <child name="lx_fs"/> </service>
|
||||
<service name="ROM" label="config"> <child name="fs_rom_config" label="init.config"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
</config>
|
||||
}
|
||||
|
||||
#
|
||||
# configurations for the sub init
|
||||
#
|
||||
set init_run_fwrite_test {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
<service name="Timer"/>
|
||||
<service name="File_system"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
|
||||
<start name="test-file_writer" caps="300" version="1">
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<config>
|
||||
<libc stdout="/dev/log" stderr="/dev/log"/>
|
||||
<vfs>
|
||||
<dir name="dev">
|
||||
<log/>
|
||||
<null/>
|
||||
</dir>
|
||||
<dir name="templates"> <fs label="templates"/> </dir>
|
||||
<dir name="test"> <fs label="test"/> </dir>
|
||||
</vfs>
|
||||
<arg value="test-file_writer"/>
|
||||
<arg value="--fwrite"/>
|
||||
<arg value="templates/infile.txt"/>
|
||||
<arg value="test/outfile.txt"/>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
set init_run_write_test {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
<service name="Timer"/>
|
||||
<service name="File_system"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
|
||||
<start name="test-file_writer" caps="300" version="2">
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<config>
|
||||
<libc stdout="/dev/log" stderr="/dev/log"/>
|
||||
<vfs>
|
||||
<dir name="dev">
|
||||
<log/>
|
||||
<null/>
|
||||
</dir>
|
||||
<dir name="templates"> <fs label="templates"/> </dir>
|
||||
<dir name="test"> <fs label="test"/> </dir>
|
||||
</vfs>
|
||||
<arg value="test-file_writer"/>
|
||||
<arg value="--write"/>
|
||||
<arg value="templates/infile.txt"/>
|
||||
<arg value="test/outfile.txt"/>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
set test_iterations 10
|
||||
set input_file_name "bin/lx_fs_notify/templates/infile.txt"
|
||||
set output_file_name "bin/lx_fs_notify/test/outfile.txt"
|
||||
|
||||
#
|
||||
# print text in colors
|
||||
#
|
||||
proc color {foreground text} {
|
||||
# tput is a little Unix utility that lets you use the termcap database
|
||||
# *much* more easily...
|
||||
return [exec tput setaf $foreground]$text[exec tput sgr0]
|
||||
}
|
||||
|
||||
#
|
||||
# write the desired config for the sub init
|
||||
#
|
||||
proc write_init_config { config } {
|
||||
set fd [open "bin/lx_fs_notify/init.config" "w"]
|
||||
puts $fd $config
|
||||
close $fd
|
||||
}
|
||||
|
||||
#
|
||||
# clear the content of the init config
|
||||
#
|
||||
proc write_empty_init_config { } {
|
||||
set fd [open "bin/lx_fs_notify/init.config" "w"]
|
||||
puts $fd ""
|
||||
close $fd
|
||||
}
|
||||
|
||||
#
|
||||
# wait for an update to the test file and check
|
||||
#
|
||||
proc wait_file_changed { file_size additional_filter } {
|
||||
global spawn_id
|
||||
|
||||
puts [color 3 "wait for file change with size=$file_size"]
|
||||
set timeout 5
|
||||
expect {
|
||||
-i $spawn_id -re ".*init -> test-rom_log.*updated ROM content: size=$file_size.*\n" { }
|
||||
timeout {
|
||||
puts [color 1 "ERROR no file change or wrong file size reported. expected size was $file_size"]
|
||||
exit -4
|
||||
}
|
||||
}
|
||||
|
||||
if { $additional_filter != {} } {
|
||||
set wait_re ".*$additional_filter\n"
|
||||
set timeout 3
|
||||
expect {
|
||||
-i $spawn_id -re $wait_re { }
|
||||
timeout { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# wait for a defined time
|
||||
#
|
||||
proc wait_and_consume_log { delay_sec } {
|
||||
global spawn_id
|
||||
|
||||
set timeout $delay_sec
|
||||
expect {
|
||||
-i $spawn_id -re { text that never is printed during the test } { }
|
||||
timeout { }
|
||||
}
|
||||
after 10
|
||||
}
|
||||
|
||||
#
|
||||
# create the input file for a test
|
||||
#
|
||||
proc create_test_file { input_file_name } {
|
||||
exec seq -w [expr int(rand()*4000)+1] > $input_file_name
|
||||
set file_size [exec stat -c%s $input_file_name]
|
||||
return $file_size
|
||||
}
|
||||
|
||||
#
|
||||
# create output file
|
||||
#
|
||||
proc create_output_file { output_file_name } {
|
||||
exec seq -w [expr int(rand()*400)+1] > $output_file_name
|
||||
set file_size [exec stat -c%s $output_file_name]
|
||||
return $file_size
|
||||
}
|
||||
|
||||
#
|
||||
# compute the size of the ROM from the file size
|
||||
#
|
||||
proc rom_size { file_size } {
|
||||
if { [expr $file_size % 4096] == 0 } {
|
||||
return $file_size
|
||||
} else {
|
||||
return [expr $file_size + (4096 - ($file_size % 4096))]
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Create test-directory structure
|
||||
#
|
||||
exec rm -Rf bin/lx_fs_notify
|
||||
exec mkdir -p bin/lx_fs_notify/templates
|
||||
exec mkdir -p bin/lx_fs_notify/test
|
||||
exec mkdir -p bin/lx_fs_notify/mnt
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
build_boot_image { lx_fs test-rom_log test-file_writer lx_fs_notify }
|
||||
|
||||
#
|
||||
# build the test program for Linux
|
||||
# this wil bel located in /tmp/bin
|
||||
#
|
||||
exec make -C [genode_dir]/repos/os/src/test/lx_fs_notify/file_writer/
|
||||
|
||||
#
|
||||
# Test cases
|
||||
#
|
||||
proc test_libc_fwrite_in_genode { test_iterations init_run_fwrite_test input_file_name output_file_name } {
|
||||
puts [color 2 ">>> run libc fwrite test in Genode ($test_iterations iterations)"]
|
||||
set size [create_output_file $output_file_name]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
set size [create_test_file $input_file_name]
|
||||
wait_and_consume_log 1
|
||||
write_init_config $init_run_fwrite_test
|
||||
wait_file_changed $size {child "test-file_writer" exited with exit value 0}
|
||||
write_empty_init_config
|
||||
}
|
||||
}
|
||||
|
||||
proc test_libc_write_in_genode { test_iterations init_run_write_test input_file_name output_file_name } {
|
||||
puts [color 2 ">>> run libc write test in Genode ($test_iterations iterations)"]
|
||||
set size [create_output_file $output_file_name]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
set size [expr max([create_test_file $input_file_name], $size)]
|
||||
wait_and_consume_log 1
|
||||
write_init_config $init_run_write_test
|
||||
wait_file_changed $size {child "test-file_writer" exited with exit value 0}
|
||||
write_empty_init_config
|
||||
}
|
||||
}
|
||||
|
||||
proc test_libc_fwrite_on_linux { test_iterations input_file_name output_file_name } {
|
||||
puts [color 2 ">>> run libc fwrite test on Linux ($test_iterations iterations)"]
|
||||
write_empty_init_config
|
||||
create_output_file $output_file_name
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
set size [create_test_file $input_file_name]
|
||||
wait_and_consume_log 1
|
||||
exec /tmp/bin/file_writer --fwrite [run_dir]/genode/lx_fs_notify/templates/infile.txt [run_dir]/genode/lx_fs_notify/test/outfile.txt
|
||||
wait_file_changed $size {}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_libc_write_on_linux { test_iterations input_file_name output_file_name } {
|
||||
puts [color 2 ">>> run libc write test on Linux ($test_iterations iterations)"]
|
||||
write_empty_init_config
|
||||
set size [create_output_file $output_file_name]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
set size [expr max([create_test_file $input_file_name], $size)]
|
||||
wait_and_consume_log 1
|
||||
exec /tmp/bin/file_writer --write [run_dir]/genode/lx_fs_notify/templates/infile.txt [run_dir]/genode/lx_fs_notify/test/outfile.txt
|
||||
wait_file_changed $size {}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_tcl_file_copy { test_iterations input_file_name output_file_name} {
|
||||
puts [color 2 ">>> run TCL 'file copy' test ($test_iterations iterations)"]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
set size [create_test_file $input_file_name]
|
||||
file copy -force $input_file_name $output_file_name
|
||||
wait_file_changed $size {}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_shell_cp { test_iterations input_file_name output_file_name } {
|
||||
puts [color 2 ">>> run shell 'cp' test ($test_iterations iterations)"]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
set size [create_test_file $input_file_name]
|
||||
exec cp -f $input_file_name $output_file_name
|
||||
wait_file_changed $size {}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_shell_mv_overwrite { test_iterations input_file_name output_file_name } {
|
||||
create_output_file $output_file_name
|
||||
puts [color 2 ">>> run shell 'mv' overwrite test ($test_iterations iterations)"]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
set size [create_test_file $input_file_name]
|
||||
exec mv $input_file_name $output_file_name
|
||||
wait_file_changed $size {}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_shell_mv_rename { test_iterations } {
|
||||
global output_file_name
|
||||
puts [color 2 ">>> run 'mv' rename watched file test ($test_iterations iterations)"]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
puts "create watched file"
|
||||
set size [create_output_file $output_file_name]
|
||||
wait_file_changed $size {}
|
||||
puts "move watched file away"
|
||||
exec mv $output_file_name $output_file_name.out
|
||||
wait_file_changed 0 {}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_shell_mv_move_other_dir { test_iterations } {
|
||||
global input_file_name
|
||||
global output_file_name
|
||||
puts [color 2 ">>> run 'mv' move watched file to other directory test ($test_iterations iterations)"]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
puts "create watched file"
|
||||
set size [create_output_file $output_file_name]
|
||||
wait_file_changed $size {}
|
||||
puts "move watched file away"
|
||||
exec mv $output_file_name $input_file_name
|
||||
wait_file_changed 0 {}
|
||||
}
|
||||
}
|
||||
|
||||
proc test_shell_rm { test_iterations output_file_name } {
|
||||
puts [color 2 ">>> run 'rm' remove watched file test ($test_iterations iterations)"]
|
||||
for { set it 0 } { $it < $test_iterations } { incr it } {
|
||||
puts "create watched file"
|
||||
set size [create_output_file $output_file_name]
|
||||
wait_file_changed $size {}
|
||||
puts "remove watched file"
|
||||
exec rm -f $output_file_name
|
||||
wait_file_changed 0 {}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Execute test cases
|
||||
#
|
||||
# wait until the test program has started
|
||||
run_genode_until ".*wait for ROM update.*\n" 6
|
||||
set spawn_id [output_spawn_id]
|
||||
wait_and_consume_log 3
|
||||
|
||||
test_libc_fwrite_in_genode $test_iterations $init_run_fwrite_test $input_file_name $output_file_name
|
||||
test_libc_write_in_genode $test_iterations $init_run_write_test $input_file_name $output_file_name
|
||||
test_libc_fwrite_on_linux $test_iterations $input_file_name $output_file_name
|
||||
test_libc_write_on_linux $test_iterations $input_file_name $output_file_name
|
||||
test_tcl_file_copy $test_iterations $input_file_name $output_file_name
|
||||
test_shell_cp $test_iterations $input_file_name $output_file_name
|
||||
test_shell_mv_overwrite $test_iterations $input_file_name $output_file_name
|
||||
test_shell_mv_rename $test_iterations
|
||||
test_shell_mv_move_other_dir $test_iterations
|
||||
test_shell_rm $test_iterations $output_file_name
|
||||
|
||||
#
|
||||
# Cleanup test-directory structure
|
||||
#
|
||||
exec rm -Rf bin/lx_fs_notify
|
||||
|
||||
# vi: set ft=tcl :
|
||||
@@ -13,9 +13,22 @@
|
||||
|
||||
#include <linux_syscalls.h>
|
||||
|
||||
#include <base/log.h>
|
||||
#include <cpu/cache.h>
|
||||
|
||||
void Genode::cache_coherent(Genode::addr_t addr, Genode::size_t size)
|
||||
{
|
||||
lx_syscall(__ARM_NR_cacheflush, addr, addr + size, 0);
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_clean_invalidate_data(Genode::addr_t, Genode::size_t)
|
||||
{
|
||||
error(__func__, " not implemented for this kernel!");
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_invalidate_data(Genode::addr_t, Genode::size_t)
|
||||
{
|
||||
error(__func__, " not implemented for this kernel!");
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 8ae888b469b89a1a4ca3e4f8334967e2144f2f7d
|
||||
2021-08-28 24d733ac8ed44fcb226b46fee0054b9d237e0499
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 4394ee99a7779bcaf5f1ca8fe9e7f2f82ade9fdb
|
||||
2021-08-28 08ba0ce73e3c25969c358fae3d39d9924e695085
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 9ee95aaf8ec2c51eb6e3fec9d1bfcc7a14ddf4ae
|
||||
2021-08-28 a853b019d9fa8d4bc824c36385f90c0081606492
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
LIBS += timeout-arm
|
||||
|
||||
vpath cache.cc $(REP_DIR)/src/lib/base/arm
|
||||
|
||||
include $(REP_DIR)/lib/mk/base-sel4.inc
|
||||
|
||||
@@ -12,6 +12,12 @@ else
|
||||
all:
|
||||
endif
|
||||
|
||||
ifeq ($(CCACHE),yes)
|
||||
SEL4_CCACHE=ccache
|
||||
else
|
||||
SEL4_CCACHE=
|
||||
endif
|
||||
|
||||
elfloader/elfloader.o:
|
||||
$(VERBOSE)cp -r $(TOOLS_DIR)/elfloader-tool $(LIB_CACHE_DIR)/$(LIB)/elfloader
|
||||
$(VERBOSE)mkdir -p $(LIB_CACHE_DIR)/$(LIB)/elfloader/tools/kbuild
|
||||
@@ -25,7 +31,8 @@ elfloader/elfloader.o:
|
||||
ARCH=arm PLAT=$(PLAT) ARMV=armv7-a __ARM_32__="y" \
|
||||
CPU=$(CPU) ASFLAGS="-march=armv7-a" \
|
||||
CFLAGS="-march=armv7-a -D__KERNEL_32__ -fno-builtin" \
|
||||
SEL4_COMMON=. SOURCE_DIR=. STAGE_DIR=. srctree=.
|
||||
SEL4_COMMON=. CCACHE=$(SEL4_CCACHE) SOURCE_DIR=. STAGE_DIR=. \
|
||||
srctree=.
|
||||
|
||||
build_kernel: elfloader/elfloader.o
|
||||
$(VERBOSE)$(MAKE) \
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 18a6627656ebbcd8dd3894eeaf4438f96fe4ce3f
|
||||
2021-08-28 577cfeb32e48ca34ce7289cfe0d2b6cc7468cad2
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 a0f16c97c898f1017fb49cdedb497f6c679e084e
|
||||
2021-08-28 26eb1066991852529a0055222c64ccc3193f4f74
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 6042b84f2db1380db94fa006a8ced88b7838ea9f
|
||||
2021-08-28 c0b6d79615696f1ee1ee5b4c748c1c44b7eb636d
|
||||
|
||||
32
repos/base-sel4/src/lib/base/arm/cache.cc
Normal file
32
repos/base-sel4/src/lib/base/arm/cache.cc
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* \brief Implementation of the cache operations
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2021-06-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <cpu/cache.h>
|
||||
|
||||
void Genode::cache_coherent(Genode::addr_t, Genode::size_t)
|
||||
{
|
||||
error(__func__, " not implemented for this kernel!");
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_clean_invalidate_data(Genode::addr_t, Genode::size_t)
|
||||
{
|
||||
error(__func__, " not implemented for this kernel!");
|
||||
}
|
||||
|
||||
|
||||
void Genode::cache_invalidate_data(Genode::addr_t, Genode::size_t)
|
||||
{
|
||||
error(__func__, " not implemented for this kernel!");
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Cache operations
|
||||
* \author Christian Prochaska
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-05-13
|
||||
*/
|
||||
|
||||
@@ -20,8 +21,20 @@ namespace Genode {
|
||||
|
||||
/*
|
||||
* Make D-Cache and I-Cache coherent
|
||||
*
|
||||
* That means write back the D-Cache lines, and invalidate the I-Cache lines
|
||||
*/
|
||||
void cache_coherent(Genode::addr_t addr, Genode::size_t size);
|
||||
|
||||
/*
|
||||
* Write back and delete D-Cache (commonly known as flush)
|
||||
*/
|
||||
void cache_clean_invalidate_data(Genode::addr_t addr, Genode::size_t size);
|
||||
|
||||
/*
|
||||
* Delete D-Cache lines only
|
||||
*/
|
||||
void cache_invalidate_data(Genode::addr_t addr, Genode::size_t size);
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__CPU__CACHE_H_ */
|
||||
|
||||
@@ -26,16 +26,19 @@ namespace Genode { namespace Trace {
|
||||
{
|
||||
uint64_t t;
|
||||
__asm__ __volatile__ (
|
||||
"pushl %%ebx\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"cpuid\n\t"
|
||||
"pushl %%ebx\n\t" /* ebx is reserved in PIC mode, but clobbered by cpuid */
|
||||
"xorl %%eax,%%eax\n\t" /* provide constant argument to cpuid to reduce variance */
|
||||
"cpuid\n\t" /* synchronise, i.e. finish all preceeding instructions */
|
||||
"popl %%ebx\n\t"
|
||||
:
|
||||
:
|
||||
: "%eax", "%ecx", "%edx"
|
||||
);
|
||||
__asm__ __volatile__ (
|
||||
"rdtsc" : "=A" (t)
|
||||
"rdtsc"
|
||||
: "=A" (t)
|
||||
:
|
||||
: "memory" /* prevent reordering of asm statements */
|
||||
);
|
||||
|
||||
return t;
|
||||
|
||||
@@ -27,14 +27,17 @@ namespace Genode { namespace Trace {
|
||||
{
|
||||
uint32_t lo, hi;
|
||||
__asm__ __volatile__ (
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"cpuid\n\t"
|
||||
"xorl %%eax,%%eax\n\t" /* provide constant argument to cpuid to reduce variance */
|
||||
"cpuid\n\t" /* synchronise, i.e. finish all preceeding instructions */
|
||||
:
|
||||
:
|
||||
: "%rax", "%rbx", "%rcx", "%rdx"
|
||||
);
|
||||
__asm__ __volatile__ (
|
||||
"rdtsc" : "=a" (lo), "=d" (hi)
|
||||
"rdtsc"
|
||||
: "=a" (lo), "=d" (hi)
|
||||
:
|
||||
: "memory" /* prevent reordering of asm statements */
|
||||
);
|
||||
|
||||
return (uint64_t)hi << 32 | lo;
|
||||
|
||||
@@ -149,7 +149,15 @@ struct Genode::Register
|
||||
/**
|
||||
* Get an unshifted mask of this field
|
||||
*/
|
||||
static constexpr access_t mask() { return ((access_t)1 << WIDTH) - 1; }
|
||||
static constexpr access_t mask()
|
||||
{
|
||||
/* prevent compile error "left shift count >= width of type" */
|
||||
if (_WIDTH < _ACCESS_WIDTH) {
|
||||
return ((access_t)1 << _WIDTH) - 1;
|
||||
} else {
|
||||
return ~(access_t)0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mask of this field shifted by its shift in the register
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#
|
||||
# Force to build -O2 on RISC-V in order to get proper inlining during self
|
||||
# relocation
|
||||
#
|
||||
override CC_OLEVEL = -O2
|
||||
|
||||
include $(BASE_DIR)/lib/mk/ld-platform.inc
|
||||
|
||||
INC_DIR += $(DIR)/spec/riscv
|
||||
|
||||
@@ -125,6 +125,8 @@ _ZN6Genode14Signal_contextD0Ev T
|
||||
_ZN6Genode14Signal_contextD1Ev T
|
||||
_ZN6Genode14Signal_contextD2Ev T
|
||||
_ZN6Genode14cache_coherentEmm T
|
||||
_ZN6Genode21cache_invalidate_dataEmm T
|
||||
_ZN6Genode27cache_clean_invalidate_dataEmm T
|
||||
_ZN6Genode14env_deprecatedEv T
|
||||
_ZN6Genode14ipc_reply_waitERKNS_17Native_capabilityENS_18Rpc_exception_codeERNS_11Msgbuf_baseES5_ T
|
||||
_ZN6Genode15Connection_baseC1Ev T
|
||||
|
||||
@@ -26,7 +26,12 @@ $(SUB_DIRS):
|
||||
#
|
||||
# Make sure that we rebuild object files and host tools after Makefile changes
|
||||
#
|
||||
$(wildcard $(OBJECTS)) $(HOST_TOOLS): $(filter-out $(LIB_PROGRESS_LOG),$(MAKEFILE_LIST))
|
||||
# The 'GLOBAL_DEPS' variable contains a list of files with side effects on the
|
||||
# build result that not captured by the regular .d-file mechanism. Changes of
|
||||
# such files - in particular build-description files - trigger a whole rebuild.
|
||||
#
|
||||
GLOBAL_DEPS += $(filter-out $(LIB_PROGRESS_LOG),$(MAKEFILE_LIST))
|
||||
$(wildcard $(OBJECTS)) $(HOST_TOOLS): $(GLOBAL_DEPS)
|
||||
|
||||
INCLUDES := $(addprefix -I,$(wildcard $(ALL_INC_DIR)))
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ CXX_LINK_OPT += $(LD_OPT_NOSTDLIB)
|
||||
#
|
||||
# Linker script for dynamically linked programs
|
||||
#
|
||||
LD_SCRIPT_DYN = $(BASE_DIR)/src/ld/genode_dyn.ld
|
||||
LD_SCRIPT_DYN ?= $(BASE_DIR)/src/ld/genode_dyn.ld
|
||||
|
||||
#
|
||||
# Linker script for shared libraries
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 84140f487073d2e7c49a6ae785d4647bcbdfe9d9
|
||||
2021-08-28 fd9f7f1e21d3adfd6225b083166f0fa143a9df73
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 48fda6a6876070847579508e8e2c5bac99005286
|
||||
2021-08-28 28dfe62302c4272b73018eccb421a14955670d55
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 8bdae508d2ba50d839d6901b209a79918a461297
|
||||
2021-08-28 e436304d18c4a612c5f5bbebe5eb3c78c480c4da
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 0af01d3672b0e8383a9bb7788fa3354355f70de9
|
||||
2021-08-28 2d297f695b7f7a0184607342384477b9f3084e78
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 f141a82bc32c7f99987cd9e67eb29cc8bcdb3c3e
|
||||
2021-08-28 11c0ea3bd8c95efcafef30845f53344e972ccd02
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 e2ba89a1f7ccca3ae8ab2154884071f98b536f0e
|
||||
2021-08-28 bacb191a29ffb71543bed8d3676c1fa50fe2af32
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 dda2166e87254d4839373b446671f9d1d081beef
|
||||
2021-08-28 df8c46b9ca370682fb734e4b174860d4014696c5
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 27d522e6adb772b93d7c7fc459c5dc1d9c4bd26f
|
||||
2021-08-28 847a6c631b2d76cbbc84240dd327536bc45a8a97
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 462af638f0f14ce1a26448067d0890b0ba9cc9a7
|
||||
2021-08-28 e362e16436aab7442d513e333209ef6da43a1ca1
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 676ffb791f91a317d29ed57d74a4c09e37ca778e
|
||||
2021-08-28 55363f9dd6006ae1b43aa2408f29bee978c4656d
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 4dd84d113033f6faf23bbe6f17b9ad3ff92ad70f
|
||||
2021-08-28 757a56abc4141d60fd5f7c430f66c06d6b1d1024
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 7e03ebe9de53c0b5ed4ccc516cc6f4ed5e278439
|
||||
2021-08-28 88164316c9f1ca0cb08ba8bdfcf548b9b62a1eba
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 8838a9217e489c7bc630be21deec00d2c8b5c492
|
||||
2021-08-28 405f18b3885abd88e3fb7b277ba71ceb1290410b
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 6e573ede882dfc47cffe5a2b3ae50e2c7fde2d3e
|
||||
2021-08-28 9ace2cb6c94873d67b040be437a0bc524a458f5c
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 6ca5a50d0a9a15ddf81922351b2dcfd5019fb35d
|
||||
2021-08-28 6eff9fc4d3e2740901ab3857f9e6fdbcae4b1cb8
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 5afef9d2b3c187c0aa5d2006e4ee36c7f6d3ade8
|
||||
2021-08-28 f1cf33711c233d2c25fee4815c51493c77bd8f50
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 a175abfa75e2334ffe4fa88fd9d7e32ec818e4ed
|
||||
2021-08-28 76edcc1e227123c5b43c2a5a4f1f54da47cc42c2
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 b6df37beb9715413a9d01b3d9a41b9dbde3364c0
|
||||
2021-08-28 b91292b64c999c3dbb6e1c603f809e5cb2a5bfb7
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 2254c1a8caef6d8ca766e76e079446cd21a665e7
|
||||
2021-08-28 9f3c95e147f2a9ad191aa3d3796b6ebbccd856c2
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 45b9443834f32609efd225f2579b74951c9b23ed
|
||||
2021-08-28 f9e25e023b1ccb9e3bc8ee69f2550a94f98a92ba
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 eab9e2a5476d7aaad220c3e67229f70fdda72756
|
||||
2021-08-28 9bcb8324d7662b0e9e2f3040c159fbfe5075b2cc
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 21fcf822b2df293f568fd81e29f15f526bfe648c
|
||||
2021-08-28 751bb2bf2b61bd80cffc69f49e2c5449e42894e1
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 54b96912154ae27a45233a69eb9f9c0c597407d9
|
||||
2021-08-28 5bcaa440962e00206480f819f120ae6b5365b20b
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 0b67a1988da440058443f2d4e58c933496b5e761
|
||||
2021-08-28 bb30e7042b2358201de2ecc39a56f8885c84573e
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 fb3c0199d3153925b761c87c3bf91d1203c935ed
|
||||
2021-08-28 d03f63e0c1a901fbe9c1ea7b118f2eeb976c1394
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 9965ec22cf8aa16c363b1d47322cf58824322fc0
|
||||
2021-08-28 338ba86f3f3d65a5d49ba5c36e317c8ee9e889cb
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 17913bd83430cf39efbe0a9bdece9c5a54707647
|
||||
2021-08-28 3ec94c047a1c5ee47af39f5e7bd9952feb00370b
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 dd48baf5ebb8a7087758b5661ccb43586b99b1cf
|
||||
2021-08-28 63a03d087401a8687a229af9ede07d6ff5fd5952
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 25018c0f7f0c1f24c8a6dc9e70a036252c247968
|
||||
2021-08-28 8805c7614800810ee4a04349c7a9e47d9978fdf7
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 1b90997495a0cffd7bf917ed4fc1ede8aed28c3a
|
||||
2021-08-28 48268d2c6b8eaa9e58a05c6bb3c9510979346569
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-05-27 2eece9f1263e2d49659596e94cd7dd9841b1f737
|
||||
2021-08-28 a6f9911fa40b73378b19fb3878c4cae8cb0c65d9
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user