diff options
Diffstat (limited to 'host/rootfs')
68 files changed, 1230 insertions, 0 deletions
diff --git a/host/rootfs/.gitignore b/host/rootfs/.gitignore new file mode 100644 index 0000000..2849946 --- /dev/null +++ b/host/rootfs/.gitignore @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +/build +result +result-* diff --git a/host/rootfs/LICENSES/CC0-1.0.txt b/host/rootfs/LICENSES/CC0-1.0.txt new file mode 100644 index 0000000..0e259d4 --- /dev/null +++ b/host/rootfs/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/host/rootfs/LICENSES/EUPL-1.2.txt b/host/rootfs/LICENSES/EUPL-1.2.txt new file mode 100644 index 0000000..4153cd3 --- /dev/null +++ b/host/rootfs/LICENSES/EUPL-1.2.txt @@ -0,0 +1,287 @@ + EUROPEAN UNION PUBLIC LICENCE v. 1.2 + EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined +below) which is provided under the terms of this Licence. Any use of the Work, +other than as authorised under this Licence is prohibited (to the extent such +use is covered by a right of the copyright holder of the Work). + +The Work is provided under the terms of this Licence when the Licensor (as +defined below) has placed the following notice immediately following the +copyright notice for the Work: + + Licensed under the EUPL + +or has expressed by any other means his willingness to license under the EUPL. + +1. Definitions + +In this Licence, the following terms have the following meaning: + +- ‘The Licence’: this Licence. + +- ‘The Original Work’: the work or software distributed or communicated by the + Licensor under this Licence, available as Source Code and also as Executable + Code as the case may be. + +- ‘Derivative Works’: the works or software that could be created by the + Licensee, based upon the Original Work or modifications thereof. This Licence + does not define the extent of modification or dependence on the Original Work + required in order to classify a work as a Derivative Work; this extent is + determined by copyright law applicable in the country mentioned in Article 15. + +- ‘The Work’: the Original Work or its Derivative Works. + +- ‘The Source Code’: the human-readable form of the Work which is the most + convenient for people to study and modify. + +- ‘The Executable Code’: any code which has generally been compiled and which is + meant to be interpreted by a computer as a program. + +- ‘The Licensor’: the natural or legal person that distributes or communicates + the Work under the Licence. + +- ‘Contributor(s)’: any natural or legal person who modifies the Work under the + Licence, or otherwise contributes to the creation of a Derivative Work. + +- ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of + the Work under the terms of the Licence. + +- ‘Distribution’ or ‘Communication’: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, online or offline, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. + +2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +sublicensable licence to do the following, for the duration of copyright vested +in the Original Work: + +- use the Work in any circumstance and for all usage, +- reproduce the Work, +- modify the Work, and make Derivative Works based upon the Work, +- communicate to the public, including the right to make available or display + the Work or copies thereof to the public and perform publicly, as the case may + be, the Work, +- distribute the Work or copies thereof, +- lend and rent the Work or copies thereof, +- sublicense rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether now +known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make effective +the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to +any patents held by the Licensor, to the extent necessary to make use of the +rights granted on the Work under this Licence. + +3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as +Executable Code. If the Work is provided as Executable Code, the Licensor +provides in addition a machine-readable copy of the Source Code of the Work +along with each copy of the Work that the Licensor distributes or indicates, in +a notice following the copyright notice attached to the Work, a repository where +the Source Code is easily and freely accessible for as long as the Licensor +continues to distribute or communicate the Work. + +4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits from +any exception or limitation to the exclusive rights of the rights owners in the +Work, of the exhaustion of those rights or of other applicable limitations +thereto. + +5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the +disclaimer of warranties. The Licensee must include a copy of such notices and a +copy of the Licence with every copy of the Work he/she distributes or +communicates. The Licensee must cause any Derivative Work to carry prominent +notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the +Original Works or Derivative Works, this Distribution or Communication will be +done under the terms of this Licence or of a later version of this Licence +unless the Original Work is expressly distributed only under this version of the +Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee +(becoming Licensor) cannot offer or impose any additional terms or conditions on +the Work or Derivative Work that alter or restrict the terms of the Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative +Works or copies thereof based upon both the Work and another work licensed under +a Compatible Licence, this Distribution or Communication can be done under the +terms of this Compatible Licence. For the sake of this clause, ‘Compatible +Licence’ refers to the licences listed in the appendix attached to this Licence. +Should the Licensee's obligations under the Compatible Licence conflict with +his/her obligations under this Licence, the obligations of the Compatible +Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the Work, +the Licensee will provide a machine-readable copy of the Source Code or indicate +a repository where this Source will be easily and freely available for as long +as the Licensee continues to distribute or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade names, +trademarks, service marks, or names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she brings +to the Work are owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent +Contributors grant You a licence to their contributions to the Work, under the +terms of this Licence. + +7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +Contributors. It is not a finished work and may therefore contain defects or +‘bugs’ inherent to this type of development. + +For the above reason, the Work is provided under the Licence on an ‘as is’ basis +and without warranties of any kind concerning the Work, including without +limitation merchantability, fitness for a particular purpose, absence of defects +or errors, accuracy, non-infringement of intellectual property rights other than +copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a condition +for the grant of any rights to the Work. + +8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the use +of the Work, including without limitation, damages for loss of goodwill, work +stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such damage. +However, the Licensor will be liable under statutory product liability laws as +far such laws apply to the Work. + +9. Additional agreements + +While distributing the Work, You may choose to conclude an additional agreement, +defining obligations or services consistent with this Licence. However, if +accepting obligations, You may act only on your own behalf and on your sole +responsibility, not on behalf of the original Licensor or any other Contributor, +and only if You agree to indemnify, defend, and hold each Contributor harmless +for any liability incurred by, or claims asserted against such Contributor by +the fact You have accepted any warranty or additional liability. + +10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ +placed under the bottom of a window displaying the text of this Licence or by +affirming consent in any other similar way, in accordance with the rules of +applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and +conditions by exercising any rights granted to You by Article 2 of this Licence, +such as the use of the Work, the creation by You of a Derivative Work or the +Distribution or Communication by You of the Work or copies thereof. + +11. Information to the public + +In case of any Distribution or Communication of the Work by means of electronic +communication by You (for example, by offering to download the Work from a +remote location) the distribution channel or media (for example, a website) must +at least provide to the public the information requested by the applicable law +regarding the Licensor, the Licence and the way it may be accessible, concluded, +stored and reproduced by the Licensee. + +12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically upon +any breach by the Licensee of the terms of the Licence. + +Such a termination will not terminate the licences of any person who has +received the Work from the Licensee under the Licence, provided such persons +remain in full compliance with the Licence. + +13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as a +whole. Such provision will be construed or reformed so as necessary to make it +valid and enforceable. + +The European Commission may publish other linguistic versions or new versions of +this Licence or updated versions of the Appendix, so far this is required and +reasonable, without reducing the scope of the rights granted by the Licence. New +versions of the Licence will be published with a unique version number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version of +their choice. + +14. Jurisdiction + +Without prejudice to specific agreement between parties, + +- any litigation resulting from the interpretation of this License, arising + between the European Union institutions, bodies, offices or agencies, as a + Licensor, and any Licensee, will be subject to the jurisdiction of the Court + of Justice of the European Union, as laid down in article 272 of the Treaty on + the Functioning of the European Union, + +- any litigation arising between other parties and resulting from the + interpretation of this License, will be subject to the exclusive jurisdiction + of the competent court where the Licensor resides or conducts its primary + business. + +15. Applicable Law + +Without prejudice to specific agreement between parties, + +- this Licence shall be governed by the law of the European Union Member State + where the Licensor has his seat, resides or has his registered office, + +- this licence shall be governed by Belgian law if the Licensor has no seat, + residence or registered office inside a European Union Member State. + +Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: + +- GNU General Public License (GPL) v. 2, v. 3 +- GNU Affero General Public License (AGPL) v. 3 +- Open Software License (OSL) v. 2.1, v. 3.0 +- Eclipse Public License (EPL) v. 1.0 +- CeCILL v. 2.0, v. 2.1 +- Mozilla Public Licence (MPL) v. 2 +- GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +- Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for + works other than software +- European Union Public Licence (EUPL) v. 1.1, v. 1.2 +- Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong + Reciprocity (LiLiQ-R+). + +The European Commission may update this Appendix to later versions of the above +licences without producing a new version of the EUPL, as long as they provide +the rights granted in Article 2 of this Licence and protect the covered Source +Code from exclusive appropriation. + +All other changes or additions to this Appendix require the production of a new +EUPL version. diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile new file mode 100644 index 0000000..abbb5ba --- /dev/null +++ b/host/rootfs/Makefile @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +# qemu-kvm is non-standard, but is present in at least Fedora and +# Nixpkgs. If you don't have qemu-kvm, you'll need to set e.g. +# QEMU_KVM = qemu-system-x86_64 -enable-kvm. +QEMU_KVM = qemu-kvm +SCREEN = screen + +# tar2ext4 will leave half a filesystem behind if it's interrupted +# half way through. +build/rootfs.ext4: build/rootfs.tar + tar2ext4 -i build/rootfs.tar -o $@.tmp + mv $@.tmp $@ + +build/test.img: scripts/make-gpt.sh build/rootfs.ext4 $(EXT_FS) + scripts/make-gpt.sh $@.tmp \ + build/rootfs.ext4:4f68bce3-e8cd-4db1-96e7-fbcaf984b709 \ + $(EXT_FS):9293e1ff-cee4-4658-88be-898ec863944f + mv $@.tmp $@ + +FILES = \ + etc/fonts/fonts.conf \ + etc/fstab \ + etc/group \ + etc/init \ + etc/login \ + etc/mdev.conf \ + etc/mdev/listen \ + etc/mdev/net/add \ + etc/mdev/wait \ + etc/parse-devname \ + etc/passwd \ + etc/service/getty-tty1/run \ + etc/service/getty-tty2/run \ + etc/service/getty-tty3/run \ + etc/service/getty-tty4/run \ + etc/service/getty-ttyS0/run \ + etc/xdg/weston/autolaunch \ + etc/xdg/weston/weston.ini + +# These are separate because they need to be included, but putting +# them as make dependencies would confuse make. +LINKS = bin sbin + +BUILD_FILES = build/etc/mdev/modalias.sh build/etc/s6-rc +MOUNTPOINTS = dev ext run proc sys + +build/rootfs.tar: $(PACKAGES_TAR) $(FILES) $(BUILD_FILES) + cp --no-preserve=mode -f $(PACKAGES_TAR) $@ + tar $(TARFLAGS) --append -f $@ $(FILES) $(LINKS) + echo $(BUILD_FILES) | cut -d/ -f2 | \ + tar $(TARFLAGS) --append -f $@ -C build -T - + for m in $(MOUNTPOINTS); do \ + tar $(TARFLAGS) --append -hf $@ --xform="s,.*,$$m," /var/empty ; \ + done + tar $(TARFLAGS) --append -hf $@ --xform='s,.*,etc/service,' /var/empty + +build/etc/mdev/modules.map: scripts/modprobe/gen_modules.map.awk + mkdir -p $$(dirname $@) + awk -f scripts/modprobe/gen_modules.map.awk \ + $(MODULES_ORDER) > $@ || rm -f $@ + +build/etc/mdev/modalias.sh: scripts/modprobe/gen_modalias.sh.awk build/etc/mdev/modules.map + mkdir -p $$(dirname $@) + awk -v modmap=build/etc/mdev/modules.map \ + -f scripts/modprobe/gen_modalias.sh.awk \ + $(MODULES_ALIAS) > $@ || rm -f $@ + chmod +x $@ + +S6_RC_FILES = \ + etc/s6-rc/card0/up \ + etc/s6-rc/card0/type \ + etc/s6-rc/ext-rc-init/dependencies \ + etc/s6-rc/ext-rc-init/type \ + etc/s6-rc/ext-rc-init/up \ + etc/s6-rc/ext-rc/dependencies \ + etc/s6-rc/ext-rc/type \ + etc/s6-rc/ext-rc/up \ + etc/s6-rc/ext/type \ + etc/s6-rc/ext/up \ + etc/s6-rc/mdevd-coldplug/dependencies \ + etc/s6-rc/mdevd-coldplug/type \ + etc/s6-rc/mdevd-coldplug/up \ + etc/s6-rc/mdevd/notification-fd \ + etc/s6-rc/mdevd/run \ + etc/s6-rc/mdevd/type \ + etc/s6-rc/ok-all/contents \ + etc/s6-rc/ok-all/type \ + etc/s6-rc/static-nodes/type \ + etc/s6-rc/static-nodes/up \ + etc/s6-rc/weston/dependencies \ + etc/s6-rc/weston/notification-fd \ + etc/s6-rc/weston/type \ + etc/s6-rc/weston/run + +# s6-rc-compile's input is a directory, but that doesn't play nice +# with Make, because it won't know to update if some file in the +# directory is changed, or a file is created or removed in a +# subdirectory. Using the whole source directory could also end up +# including files that aren't intended to be part of the input, like +# temporary editor files or .license files. So for all these reasons, +# only explicitly listed files are made available to s6-rc-compile. +build/etc/s6-rc: $(S6_RC_FILES) + mkdir -p $$(dirname $@) + rm -rf $@ + + dir=$$(mktemp -d) && \ + tar -c $(S6_RC_FILES) | tar -C $$dir -x --strip-components 2 && \ + s6-rc-compile $@ $$dir; \ + exit=$$?; rm -r $$dir; exit $$exit + +clean: + rm -rf build +.PHONY: clean + +run: build/test.img + $(QEMU_KVM) -cpu host -m 2G \ + -machine q35,kernel=$(KERNEL),kernel-irqchip=split \ + -display gtk,gl=on \ + -qmp unix:vmm.sock,server,nowait \ + -monitor vc \ + -parallel none \ + -drive file=build/test.img,if=virtio,format=raw,readonly=on \ + -append "console=ttyS0 root=/dev/vda1 intel_iommu=on" \ + -device intel-iommu,intremap=on \ + -device virtio-vga-gl +.PHONY: run + +console: + @$(SCREEN) "$$(scripts/qemu-pty.sh vmm.sock virtiocon0)" +.PHONY: console diff --git a/host/rootfs/bin b/host/rootfs/bin new file mode 120000 index 0000000..1e881ed --- /dev/null +++ b/host/rootfs/bin @@ -0,0 +1 @@ +usr/bin \ No newline at end of file diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix new file mode 100644 index 0000000..fc347aa --- /dev/null +++ b/host/rootfs/default.nix @@ -0,0 +1,140 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +{ pkgs ? import <nixpkgs> {} }: pkgs.pkgsStatic.callPackage ( + +{ lib, stdenv, runCommand, writeReferencesToFile, s6-rc, tar2ext4 +, busybox, cloud-hypervisor, curl, execline, jq, mdevd, mktuntap, s6 +, s6-linux-utils, s6-portable-utils, screen, util-linux, xorg +}: + +let + inherit (lib) cleanSource cleanSourceWith concatMapStringsSep; + + pkgsGui = pkgs.pkgsMusl.extend (final: super: { + systemd = final.libudev-zero; + }); + + foot = pkgsGui.foot.override { allowPgo = false; }; + + packages = [ + cloud-hypervisor curl execline jq mdevd mktuntap s6 s6-linux-utils + s6-portable-utils s6-rc screen + pkgs.pkgsMusl.cryptsetup + (busybox.override { + extraConfig = '' + CONFIG_INIT n + ''; + }) + ] ++ (with pkgsGui; [ foot westonLite ]); + + kernel = pkgs.linux_latest.override { + structuredExtraConfig = with lib.kernel; { + VIRTIO = yes; + VIRTIO_PCI = yes; + VIRTIO_BLK = yes; + EXT4_FS = yes; + MODPROBE_PATH = freeform "/sbin/modprobe"; + }; + }; + + packagesSysroot = runCommand "packages-sysroot" { + nativeBuildInputs = [ xorg.lndir ]; + } '' + mkdir -p $out/usr/bin + ln -s ${concatMapStringsSep " " (p: "${p}/bin/*") packages} $out/usr/bin + + for pkg in ${lib.escapeShellArgs [ pkgsGui.mesa.drivers pkgsGui.dejavu_fonts ]}; do + lndir -silent "$pkg" "$out/usr" + done + + ln -s ${kernel}/lib $out/lib + + # TODO: this is a hack and we should just build the util-linux + # programs we want. + # https://lore.kernel.org/util-linux/87zgrl6ufb.fsf@alyssa.is/ + ln -s ${util-linux.override { systemd = null; }}/bin/lsblk $out/usr/bin + ''; + + packagesTar = runCommand "packages.tar" {} '' + cd ${packagesSysroot} + tar -cf $out --sort=name --mtime=@0 --verbatim-files-from \ + -T ${writeReferencesToFile packagesSysroot} . + ''; + + netvm = import ../spectrum-netvm { + inherit pkgs; + inherit (foot) terminfo; + }; + + appvm-catgirl = import ../spectrum-appvm-catgirl { + inherit pkgs; + inherit (foot) terminfo; + }; + + appvm-lynx = import ../spectrum-appvm-lynx { + inherit pkgs; + inherit (foot) terminfo; + }; + + extFs = runCommand "ext.ext4" { + nativeBuildInputs = [ tar2ext4 s6-rc ]; + } '' + mkdir s6-rc svc + + tar -C ${netvm}/s6-rc -c . | tar -C s6-rc -x + chmod +w s6-rc + tar -C ${appvm-catgirl}/s6-rc -c . | tar -C s6-rc -x + chmod +w s6-rc + tar -C ${appvm-lynx}/s6-rc -c . | tar -C s6-rc -x + chmod +w s6-rc + mkdir s6-rc/default + echo bundle > s6-rc/default/type + printf "appvm-catgirl\nappvm-lynx\n" > s6-rc/default/contents + s6-rc-compile svc/s6-rc s6-rc + + tar -C ${netvm} -c data | tar -C svc -x + chmod +w svc/data + tar -C ${appvm-catgirl} -c data | tar -C svc -x + chmod +w svc/data + tar -C ${appvm-lynx} -c data | tar -C svc -x + + tar -cf ext.tar svc + tar2ext4 -i ext.tar -o $out + ''; +in + +stdenv.mkDerivation { + name = "spectrum-rootfs"; + + src = cleanSourceWith { + filter = name: _type: name != "${toString ./.}/build"; + src = cleanSource ./.; + }; + + nativeBuildInputs = [ s6-rc tar2ext4 ]; + + EXT_FS = extFs; + MODULES_ALIAS = "${kernel}/lib/modules/${kernel.modDirVersion}/modules.alias"; + MODULES_ORDER = "${kernel}/lib/modules/${kernel.modDirVersion}/modules.order"; + PACKAGES_TAR = packagesTar; + + postPatch = '' + mkdir $NIX_BUILD_TOP/empty + substituteInPlace Makefile --replace /var/empty $NIX_BUILD_TOP/empty + ''; + + installPhase = '' + cp build/rootfs.ext4 $out + ''; + + enableParallelBuilding = true; + + passthru = { inherit kernel; }; + + meta = with lib; { + license = licenses.eupl12; + platforms = platforms.linux; + }; +} +) {} diff --git a/host/rootfs/etc/fonts/fonts.conf b/host/rootfs/etc/fonts/fonts.conf new file mode 100644 index 0000000..0dcde54 --- /dev/null +++ b/host/rootfs/etc/fonts/fonts.conf @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- SPDX-License-Identifier: CC0-1.0 --> +<!-- SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> --> +<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> +<fontconfig> + <alias binding="same"> + <family>monospace</family> + <prefer> + <family>DejaVu Sans Mono</family> + </prefer> + </alias> + + <alias binding="same"> + <family>sans-serif</family> + <prefer> + <family>DejaVu Sans</family> + </prefer> + </alias> + + <dir>/usr/share/fonts</dir> +</fontconfig> diff --git a/host/rootfs/etc/fstab b/host/rootfs/etc/fstab new file mode 100644 index 0000000..ceb1087 --- /dev/null +++ b/host/rootfs/etc/fstab @@ -0,0 +1,4 @@ +proc /proc proc defaults +devpts /dev/pts devpts defaults,gid=4,mode=620 +tmpfs /dev/shm tmpfs defaults +sysfs /sys sysfs defaults diff --git a/host/rootfs/etc/fstab.license b/host/rootfs/etc/fstab.license new file mode 100644 index 0000000..fcbd585 --- /dev/null +++ b/host/rootfs/etc/fstab.license @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/group b/host/rootfs/etc/group new file mode 100644 index 0000000..18acc30 --- /dev/null +++ b/host/rootfs/etc/group @@ -0,0 +1 @@ +root:x:0:root diff --git a/host/rootfs/etc/group.license b/host/rootfs/etc/group.license new file mode 100644 index 0000000..2b3b032 --- /dev/null +++ b/host/rootfs/etc/group.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/init b/host/rootfs/etc/init new file mode 100755 index 0000000..4f3ed66 --- /dev/null +++ b/host/rootfs/etc/init @@ -0,0 +1,27 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +/bin/export PATH /bin +/bin/s6-setsid -qb -- + +umask 022 +if { mount -t tmpfs -o mode=0755 tmpfs /run } +if { s6-hiercopy /etc/service /run/service } +emptyenv -p + +background { + s6-setsid -- + + if { s6-rc-init -c /etc/s6-rc /run/service } + + if { s6-mkdir -p /dev/pts /dev/shm } + + if { mount -a } + + s6-rc change ok-all +} + +unexport ! +cd /run/service +s6-svscan diff --git a/host/rootfs/etc/login b/host/rootfs/etc/login new file mode 100755 index 0000000..4d482f5 --- /dev/null +++ b/host/rootfs/etc/login @@ -0,0 +1,16 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +backtick USER { id -un } +backtick HOME { + importas -i user USER + homeof $user +} + +importas -i home HOME +cd $home + +export PATH /bin # Clear out execlineb wrapper path +/bin/exec -l +sh diff --git a/host/rootfs/etc/mdev.conf b/host/rootfs/etc/mdev.conf new file mode 100644 index 0000000..0882ee5 --- /dev/null +++ b/host/rootfs/etc/mdev.conf @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +-$MODALIAS=.* 0:0 660 +/etc/mdev/modalias.sh +kvm 0:0 660 +dri/card0 0:0 660 +/etc/mdev/listen card0 diff --git a/host/rootfs/etc/mdev/listen b/host/rootfs/etc/mdev/listen new file mode 100755 index 0000000..3364e0a --- /dev/null +++ b/host/rootfs/etc/mdev/listen @@ -0,0 +1,12 @@ +#!/bin/execlineb -s1 +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +foreground { + redirfd -w 2 /dev/null + foreground { mkdir /run/wait } + mkfifo /run/wait/${1} +} + +redirfd -w 1 /run/wait/${1} +echo diff --git a/host/rootfs/etc/mdev/net/add b/host/rootfs/etc/mdev/net/add new file mode 100755 index 0000000..e7a5fab --- /dev/null +++ b/host/rootfs/etc/mdev/net/add @@ -0,0 +1,41 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +# Assign the whole IOMMU group containing this device to the network +# VM. + +if { + forx -pE module { vfio-pci vfio_iommu_type1 } + modprobe $module +} + +importas -i devpath DEVPATH + +foreground { + pipeline { ls -1 /sys${devpath}/iommu_group/devices } + forstdin -pE device + foreground { + redirfd -w 2 /dev/null + redirfd -w 1 /sys/bus/pci/devices/${device}/driver/unbind + printf "%s" $device + } + foreground { + redirfd -w 1 /sys/bus/pci/devices/${device}/driver_override + printf vfio-pci + } + redirfd -w 1 /sys/bus/pci/drivers/vfio-pci/bind + printf "%s" $device +} + +# We have to background here before running s6-rc, because if we're +# running from inside mdevd-coldplug trying to start another service +# will deadlock. +background { + # Wait for the VM to be up. + foreground { s6-rc -bu change ext-rc-init } + if { s6-svwait -U /run/service/ext-netvm-vmm } + + ch-remote --api-socket /run/service/ext-netvm-vmm/env/cloud-hypervisor.sock + add-device path=/sys${devpath} +} diff --git a/host/rootfs/etc/mdev/wait b/host/rootfs/etc/mdev/wait new file mode 100755 index 0000000..b7de5f8 --- /dev/null +++ b/host/rootfs/etc/mdev/wait @@ -0,0 +1,15 @@ +#!/bin/execlineb -s1 +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +foreground { + redirfd -w 2 /dev/null + foreground { mkdir /run/wait } + mkfifo /run/wait/${1} +} + +foreground { + redirfd -w 1 /dev/null + head -1 /run/wait/${1} +} +rm /run/wait/${1} diff --git a/host/rootfs/etc/parse-devname b/host/rootfs/etc/parse-devname new file mode 100755 index 0000000..ce97491 --- /dev/null +++ b/host/rootfs/etc/parse-devname @@ -0,0 +1,10 @@ +#!/bin/awk -f +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +# Parses modules.devname into space-separated arguments suitable for mknod(1). + +!/^#/ { + sub(":", " ", $3); + print $2 " " substr($3, 1, 1) " " substr($3, 2); +} diff --git a/host/rootfs/etc/passwd b/host/rootfs/etc/passwd new file mode 100644 index 0000000..29f3b25 --- /dev/null +++ b/host/rootfs/etc/passwd @@ -0,0 +1 @@ +root:x:0:0:System administrator:/:/bin/sh diff --git a/host/rootfs/etc/passwd.license b/host/rootfs/etc/passwd.license new file mode 100644 index 0000000..2b3b032 --- /dev/null +++ b/host/rootfs/etc/passwd.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/card0/type b/host/rootfs/etc/s6-rc/card0/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/host/rootfs/etc/s6-rc/card0/type @@ -0,0 +1 @@ +oneshot diff --git a/host/rootfs/etc/s6-rc/card0/type.license b/host/rootfs/etc/s6-rc/card0/type.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/card0/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/card0/up b/host/rootfs/etc/s6-rc/card0/up new file mode 100644 index 0000000..70907f4 --- /dev/null +++ b/host/rootfs/etc/s6-rc/card0/up @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +/etc/mdev/wait card0 diff --git a/host/rootfs/etc/s6-rc/ext-rc-init/dependencies b/host/rootfs/etc/s6-rc/ext-rc-init/dependencies new file mode 100644 index 0000000..ee3e8f0 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc-init/dependencies @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +# +ext diff --git a/host/rootfs/etc/s6-rc/ext-rc-init/type b/host/rootfs/etc/s6-rc/ext-rc-init/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc-init/type @@ -0,0 +1 @@ +oneshot diff --git a/host/rootfs/etc/s6-rc/ext-rc-init/type.license b/host/rootfs/etc/s6-rc/ext-rc-init/type.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc-init/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/ext-rc-init/up b/host/rootfs/etc/s6-rc/ext-rc-init/up new file mode 100644 index 0000000..a4470c2 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc-init/up @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +s6-rc-init -c /ext/svc/s6-rc -l /run/s6-rc.ext -p ext- /run/service diff --git a/host/rootfs/etc/s6-rc/ext-rc/dependencies b/host/rootfs/etc/s6-rc/ext-rc/dependencies new file mode 100644 index 0000000..288421f --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc/dependencies @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +# +ext-rc-init +static-nodes +weston diff --git a/host/rootfs/etc/s6-rc/ext-rc/type b/host/rootfs/etc/s6-rc/ext-rc/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc/type @@ -0,0 +1 @@ +oneshot diff --git a/host/rootfs/etc/s6-rc/ext-rc/type.license b/host/rootfs/etc/s6-rc/ext-rc/type.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/ext-rc/up b/host/rootfs/etc/s6-rc/ext-rc/up new file mode 100644 index 0000000..bed07a2 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext-rc/up @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +s6-rc -l /run/s6-rc.ext -u change default diff --git a/host/rootfs/etc/s6-rc/ext/type b/host/rootfs/etc/s6-rc/ext/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext/type @@ -0,0 +1 @@ +oneshot diff --git a/host/rootfs/etc/s6-rc/ext/type.license b/host/rootfs/etc/s6-rc/ext/type.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/ext/up b/host/rootfs/etc/s6-rc/ext/up new file mode 100644 index 0000000..4400814 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ext/up @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +# For now, we only support ext partitions on the same disk as the +# rootfs. This could be relaxed in future, but probably requires some +# careful thought, including support for doing it asynchronously +# e.g. if the ext partition is on a USB device. + +backtick -E rootpart { + pipeline { veritysetup status root-verity } + awk -F ":[[:blank:]]*" "$1 ~ /^[[:blank:]]*data device$/ {print $2; exit}" +} + +backtick -E diskpath { + pipeline { lsblk -lnpo KNAME,PKNAME } + awk -v rootpart=${rootpart} "$1 == rootpart {print $2; exit}" +} + +backtick -E extpart { + pipeline { lsblk -lnpo PARTTYPE,NAME $diskpath } + awk "$1 == \"9293e1ff-cee4-4658-88be-898ec863944f\" {print $2; exit}" +} + +mount $extpart /ext diff --git a/host/rootfs/etc/s6-rc/mdevd-coldplug/dependencies b/host/rootfs/etc/s6-rc/mdevd-coldplug/dependencies new file mode 100644 index 0000000..59b02b7 --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd-coldplug/dependencies @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is> +# +mdevd diff --git a/host/rootfs/etc/s6-rc/mdevd-coldplug/type b/host/rootfs/etc/s6-rc/mdevd-coldplug/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd-coldplug/type @@ -0,0 +1 @@ +oneshot diff --git a/host/rootfs/etc/s6-rc/mdevd-coldplug/type.license b/host/rootfs/etc/s6-rc/mdevd-coldplug/type.license new file mode 100644 index 0000000..2b3b032 --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd-coldplug/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/mdevd-coldplug/up b/host/rootfs/etc/s6-rc/mdevd-coldplug/up new file mode 100644 index 0000000..a5d4dc1 --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd-coldplug/up @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +mdevd-coldplug diff --git a/host/rootfs/etc/s6-rc/mdevd/notification-fd b/host/rootfs/etc/s6-rc/mdevd/notification-fd new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd/notification-fd @@ -0,0 +1 @@ +3 diff --git a/host/rootfs/etc/s6-rc/mdevd/notification-fd.license b/host/rootfs/etc/s6-rc/mdevd/notification-fd.license new file mode 100644 index 0000000..2b3b032 --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd/notification-fd.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/mdevd/run b/host/rootfs/etc/s6-rc/mdevd/run new file mode 100644 index 0000000..03ad5e3 --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd/run @@ -0,0 +1,5 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +mdevd -D3 diff --git a/host/rootfs/etc/s6-rc/mdevd/type b/host/rootfs/etc/s6-rc/mdevd/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd/type @@ -0,0 +1 @@ +longrun diff --git a/host/rootfs/etc/s6-rc/mdevd/type.license b/host/rootfs/etc/s6-rc/mdevd/type.license new file mode 100644 index 0000000..2b3b032 --- /dev/null +++ b/host/rootfs/etc/s6-rc/mdevd/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2020 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/ok-all/contents b/host/rootfs/etc/s6-rc/ok-all/contents new file mode 100644 index 0000000..dfe7022 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ok-all/contents @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +# +ext-rc +mdevd-coldplug diff --git a/host/rootfs/etc/s6-rc/ok-all/type b/host/rootfs/etc/s6-rc/ok-all/type new file mode 100644 index 0000000..757b422 --- /dev/null +++ b/host/rootfs/etc/s6-rc/ok-all/type @@ -0,0 +1 @@ +bundle diff --git a/host/rootfs/etc/s6-rc/ok-all/type.license b/host/rootfs/etc/s6-rc/ok-all/type.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/ok-all/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/static-nodes/type b/host/rootfs/etc/s6-rc/static-nodes/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/host/rootfs/etc/s6-rc/static-nodes/type @@ -0,0 +1 @@ +oneshot diff --git a/host/rootfs/etc/s6-rc/static-nodes/type.license b/host/rootfs/etc/s6-rc/static-nodes/type.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/static-nodes/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/static-nodes/up b/host/rootfs/etc/s6-rc/static-nodes/up new file mode 100644 index 0000000..3020681 --- /dev/null +++ b/host/rootfs/etc/s6-rc/static-nodes/up @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +pipeline { + elglob modules_devname /lib/modules/*/modules.devname + /etc/parse-devname $modules_devname +} + +cd /dev +forstdin -p line + +foreground { + backtick -E dirname { + backtick -E path { + importas -i line line + heredoc 0 $line + cut -d " " -f 1 + } + dirname $path + } + redirfd -w 2 /dev/null + mkdir $dirname +} + +importas -siu args line +mknod -- $args diff --git a/host/rootfs/etc/s6-rc/weston/dependencies b/host/rootfs/etc/s6-rc/weston/dependencies new file mode 100644 index 0000000..8470c0f --- /dev/null +++ b/host/rootfs/etc/s6-rc/weston/dependencies @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +# +card0 diff --git a/host/rootfs/etc/s6-rc/weston/notification-fd b/host/rootfs/etc/s6-rc/weston/notification-fd new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/host/rootfs/etc/s6-rc/weston/notification-fd @@ -0,0 +1 @@ +3 diff --git a/host/rootfs/etc/s6-rc/weston/notification-fd.license b/host/rootfs/etc/s6-rc/weston/notification-fd.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/weston/notification-fd.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/s6-rc/weston/run b/host/rootfs/etc/s6-rc/weston/run new file mode 100644 index 0000000..df765cb --- /dev/null +++ b/host/rootfs/etc/s6-rc/weston/run @@ -0,0 +1,27 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +foreground { + redirfd -w 2 /dev/null + ln -ns /usr /run/opengl-driver +} +foreground { mkdir /run/user } +foreground { + umask 077 + mkdir /run/user/0 +} +unexport ? + +backtick USER { id -un } +backtick HOME { + importas -i user USER + homeof $user +} + +export XDG_RUNTIME_DIR /run/user/0 +redirfd -r 0 /dev/tty1 + +importas -i home HOME +cd $home +weston diff --git a/host/rootfs/etc/s6-rc/weston/type b/host/rootfs/etc/s6-rc/weston/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/host/rootfs/etc/s6-rc/weston/type @@ -0,0 +1 @@ +longrun diff --git a/host/rootfs/etc/s6-rc/weston/type.license b/host/rootfs/etc/s6-rc/weston/type.license new file mode 100644 index 0000000..c49c11b --- /dev/null +++ b/host/rootfs/etc/s6-rc/weston/type.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> diff --git a/host/rootfs/etc/service/getty-tty1/run b/host/rootfs/etc/service/getty-tty1/run new file mode 100755 index 0000000..c6da707 --- /dev/null +++ b/host/rootfs/etc/service/getty-tty1/run @@ -0,0 +1,5 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +getty -i -n -l /etc/login 0 tty1 linux diff --git a/host/rootfs/etc/service/getty-tty2/run b/host/rootfs/etc/service/getty-tty2/run new file mode 100755 index 0000000..5af93e3 --- /dev/null +++ b/host/rootfs/etc/service/getty-tty2/run @@ -0,0 +1,5 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +getty -i -n -l /etc/login 0 tty2 linux diff --git a/host/rootfs/etc/service/getty-tty3/run b/host/rootfs/etc/service/getty-tty3/run new file mode 100755 index 0000000..fc4ec34 --- /dev/null +++ b/host/rootfs/etc/service/getty-tty3/run @@ -0,0 +1,5 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +getty -i -n -l /etc/login 0 tty3 linux diff --git a/host/rootfs/etc/service/getty-tty4/run b/host/rootfs/etc/service/getty-tty4/run new file mode 100755 index 0000000..e32196b --- /dev/null +++ b/host/rootfs/etc/service/getty-tty4/run @@ -0,0 +1,5 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +getty -i -n -l /etc/login 0 tty4 linux diff --git a/host/rootfs/etc/service/getty-ttyS0/run b/host/rootfs/etc/service/getty-ttyS0/run new file mode 100755 index 0000000..d93e03f --- /dev/null +++ b/host/rootfs/etc/service/getty-ttyS0/run @@ -0,0 +1,5 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2020-2021 Alyssa Ross <hi@alyssa.is> + +getty -i -n -l /etc/login 0,115200,57600,38400,9600 ttyS0 dumb diff --git a/host/rootfs/etc/xdg/weston/autolaunch b/host/rootfs/etc/xdg/weston/autolaunch new file mode 100755 index 0000000..4506e0c --- /dev/null +++ b/host/rootfs/etc/xdg/weston/autolaunch @@ -0,0 +1,7 @@ +#!/bin/execlineb -P +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +# Notify readiness +fdmove 1 3 +echo diff --git a/host/rootfs/etc/xdg/weston/weston.ini b/host/rootfs/etc/xdg/weston/weston.ini new file mode 100644 index 0000000..cdf8666 --- /dev/null +++ b/host/rootfs/etc/xdg/weston/weston.ini @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +[autolaunch] +path=/etc/xdg/weston/autolaunch diff --git a/host/rootfs/sbin b/host/rootfs/sbin new file mode 120000 index 0000000..1e881ed --- /dev/null +++ b/host/rootfs/sbin @@ -0,0 +1 @@ +usr/bin \ No newline at end of file diff --git a/host/rootfs/scripts/make-gpt.sh b/host/rootfs/scripts/make-gpt.sh new file mode 100755 index 0000000..00042d3 --- /dev/null +++ b/host/rootfs/scripts/make-gpt.sh @@ -0,0 +1,58 @@ +#!/bin/sh -eu +# +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +# SPDX-License-Identifier: EUPL-1.2 +# +# usage: make-gpt.sh GPT_PATH PATH:UUID... + +ONE_MiB=1048576 +TWO_MiB=2097152 + +# Prints the number of 1MiB blocks required to store the file named +# $1. We use 1MiB blocks because that's what sfdisk uses for +# alignment. It would be possible to get a slightly smaller image +# using actual normal-sized 512-byte blocks, but it's probably not +# worth it to configure sfdisk to do that. +sizeMiB() { + wc -c "$1" | awk -v ONE_MiB=$ONE_MiB \ + '{printf "%d\n", ($1 + ONE_MiB - 1) / ONE_MiB}' +} + +# Copies from path $3 into partition number $2 in partition table $1. +fillPartition() { + sfdisk -J "$1" | jq -r --argjson index "$2" \ + '.partitiontable.partitions[$index] | "\(.start) \(.size)"' | + (read start size; + dd if="$3" of="$1" seek="$start" count="$size" conv=notrunc) +} + +# Prints the partition path from a PATH:UUID string. +partitionPath() { + printf "%s" "$1" | awk -F: '{NF--; print}' +} +# Prints the partition UUID from a PATH:UUID string. +partitionUuid() { + printf "%s" "$1" | awk -F: '{print $NF}' +} + +out="$1" +shift + +# Keep 1MiB free at the start, and 1MiB free at the end. +gptBytes=$TWO_MiB +for partition; do + sizeMiB="$(sizeMiB "$(partitionPath "$partition")")" + gptBytes="$(expr "$gptBytes" + "$sizeMiB" \* $ONE_MiB)" +done + +truncate -s "$gptBytes" "$out" +(printf "label: gpt\n"; for partition; do + sizeMiB="$(sizeMiB "$(partitionPath "$partition")")" + printf "%s\n" "- ${sizeMiB}MiB $(partitionUuid "$partition") -" +done) | tee /dev/stderr | sfdisk "$out" + +n=0 +for partition; do + fillPartition "$out" "$n" "$(partitionPath "$partition")" + n="$(expr "$n" + 1)" +done diff --git a/host/rootfs/scripts/modprobe/gen_modalias.sh.awk b/host/rootfs/scripts/modprobe/gen_modalias.sh.awk new file mode 100755 index 0000000..0546cd4 --- /dev/null +++ b/host/rootfs/scripts/modprobe/gen_modalias.sh.awk @@ -0,0 +1,79 @@ +#!/usr/bin/awk -f +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +# +# This program generates a shell script expected to be run with a +# kernel uevent in its environment, for example from mdev.conf. The +# shell script will match on the modalias from the event, and choose a +# command to run based on what driver would be loaded by the kernel's +# modules.alias file. By default, it will run modprobe -q "$MODALIAS". +# +# Matching on default drivers instead of modalias patterns directly is +# a much friendlier and more maintainable way to configure a system. +# The mappings from default drivers to commands is configured in a +# file, the path to which is passed to this script in the modmap +# variable. Each line of the file should contain a driver name, then +# some blanks, and then a command to run. Empty lines, as well as +# lines starting with optional blanks followed by a # character, are +# ignored. + +function normalize_driver_name(name) { + return gsub("-", "_", name) +} + +BEGIN { + while (getline line < modmap) { + if (line == "" || match(line, "^[[:blank:]]*#")) + continue + + if (!match(line, "[[:blank:]]+")) + exit 1 + + driver = substr(line, 1, RSTART - 1) + command = substr(line, RSTART + RLENGTH) + + normalize_driver_name(driver) + + remap[driver] = command + } + + print "#!/bin/sh -x" + # Break this up to avoid confusing reuse lint. + print "# SPDX-License-Identifier" ": CC0-1.0" + print "#" + print "# Generated by gen_modalias.sh.awk." + print "# Rules file: " modmap +} + +FNR == 1 { + print "# Input file: " FILENAME +} + +$1 == "alias" && $3 in remap { + normalize_driver_name($3) + command = remap[$3] + patterns[command][patterns_lengths[command]++] = $2 +} + +END { + for (_ in patterns) { + print "" + print "case \"$MODALIAS\" in" + break + } + + for (exec in patterns) { + printf "\t" + for (n in patterns[exec]) { + if (n > 0) + printf "|" + printf "%s", patterns[exec][n] + } + printf ")\n\t\texec %s\n\t\t;;\n", exec + } + + for (_ in patterns) { + printf "\t*)\n\t\texec modprobe -q \"$MODALIAS\"\n\t\t;;\nesac" + break + } +} diff --git a/host/rootfs/scripts/modprobe/gen_modules.map.awk b/host/rootfs/scripts/modprobe/gen_modules.map.awk new file mode 100755 index 0000000..d4f8abf --- /dev/null +++ b/host/rootfs/scripts/modprobe/gen_modules.map.awk @@ -0,0 +1,25 @@ +#!/usr/bin/awk -f +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +function driver(type) { + sub("\\.ko$", "") + print $NF, "\"/etc/mdev/" type "/$ACTION\"" +} + +BEGIN { + FS = "/" + OFS = "\t" + + # Break this up to avoid confusing reuse lint. + print "# SPDX-License-Identifier" ": CC0-1.0" + print "#" + print "# Generated by gen_modalias.sh.awk." +} + +FNR == 1 { + print "" + print "# Input file: " FILENAME +} + +/^kernel\/drivers\/net\/ethernet\// { driver("net") } diff --git a/host/rootfs/scripts/qemu-pty.sh b/host/rootfs/scripts/qemu-pty.sh new file mode 100755 index 0000000..2a27341 --- /dev/null +++ b/host/rootfs/scripts/qemu-pty.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> +# SPDX-License-Identifier: EUPL-1.2 +# +# usage: qemu-pty.sh socket-path chardev-name + +nc -U "$1" <<IN | jq -rn --arg name "$2" 'first(inputs | .return | arrays)[] | + select(.label == $name) | .filename | ltrimstr("pty:")' +{"execute":"qmp_capabilities"} +{"execute":"query-chardev"} +IN diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix new file mode 100644 index 0000000..16f443c --- /dev/null +++ b/host/rootfs/shell.nix @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: EUPL-1.2 +# SPDX-FileCopyrightText: 2021 Alyssa Ross <hi@alyssa.is> + +{ pkgs ? import <nixpkgs> {} }: + +with pkgs; + +(import ./. { inherit pkgs; }).overrideAttrs ( +{ passthru ? {}, nativeBuildInputs ? [], ... }: + +{ + nativeBuildInputs = nativeBuildInputs ++ [ + jq netcat qemu_kvm reuse screen util-linux + ]; + + KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}"; +}) |