commit 13c231ee0d0ff477969e14b47332ec94329bf80c
Author: vin <git@vineetk.net>
Date: Tue, 22 Oct 2024 14:23:15 -0400
initial commit with converted pages
Diffstat:
21 files changed, 1868 insertions(+), 0 deletions(-)
diff --git a/archetypes/default.md b/archetypes/default.md
@@ -0,0 +1,5 @@
++++
+title = '{{ replace .File.ContentBaseName "-" " " | title }}'
+date = {{ .Date }}
+draft = true
++++
diff --git a/assets/main.scss b/assets/main.scss
@@ -0,0 +1,248 @@
+$background: #0e0c06;
+$foreground: #d4b782;
+$black: #1b1918;
+$brblack: #544b44;
+$red: #d42215;
+$green: #358c15;
+$yellow: #9a6200;
+$blue: #00458d;
+$magenta: #773dbf;
+$cyan: #008a7b;
+$white: #cfb688;
+
+html {
+ font-family: sans-serif;
+ color: $foreground;
+ background-color: $background;
+}
+
+body {
+ max-width: 920px;
+ margin: 0 auto;
+ padding: 1rem;
+ font-family: monospace;
+}
+
+h1 {
+ margin-top: 0;
+ font-size: 1.5rem;
+
+ small {
+ display: block;
+ font-size: 1rem;
+ }
+}
+
+a {
+ color: $yellow;
+ text-decoration: none;
+}
+
+a:hover {
+ color: $yellow;
+ text-decoration: underline;
+}
+
+a:visited {
+ color: $green;
+}
+
+.index {
+ display: flex;
+ flex-direction: row;
+
+ .article-list {
+ flex-grow: 1;
+ margin: auto;
+ max-width: 600px;
+
+ .article {
+ margin-bottom: 1rem;
+ }
+
+ .date {
+ display: block;
+ color: $brblack;
+ }
+ }
+
+ aside {
+ width: 40%;
+
+ img {
+ display: block;
+ margin: 0 auto 1rem;
+ border-radius: 5px;
+ }
+
+ dt {
+ font-size: 0.9rem;
+ }
+
+ dd {
+ margin-left: 0;
+
+ &:not(:last-child) {
+ margin-bottom: 0.5rem;
+ }
+ }
+ }
+
+ @media(max-width: 640px) {
+ aside {
+ display: none;
+ }
+ }
+}
+
+article {
+ margin: 0 auto;
+ max-width: 720px;
+ line-height: 1.3;
+
+ img, video, iframe {
+ // !important for asciinema frames
+ display: block !important;
+ margin: 0 auto !important;
+ max-width: 90%;
+
+ @media(max-width: 640px) {
+ max-width: calc(100% - 2rem);
+ }
+ }
+
+ .comment {
+ margin: 2rem auto 0;
+ max-width: 80%;
+ color: #333;
+ }
+}
+
+.footnotes {
+ font-size: 0.85rem;
+}
+
+footer {
+ margin-top: 2rem;
+ text-align: center;
+ font-size: 0.8rem;
+ color: #333;
+}
+
+.float-img {
+ float: right;
+ display: inline;
+ padding-left: 1rem;
+
+ @media(max-width: 640px) {
+ display: block;
+ float: none;
+ padding-left: inherit;
+ }
+}
+
+pre {
+ background-color: $black;
+ padding: 0.25rem 1rem;
+ margin: 0 -1rem;
+ max-width: 100%;
+ overflow-x: auto;
+
+ .cp {
+ color: #800;
+ }
+
+ .k {
+ color: #008;
+ }
+
+ .kt, .kd, .kc {
+ color: #44F;
+ }
+
+ .s {
+ color: #484;
+ font-style: italic;
+ }
+
+ .cm, .c1 {
+ color: #333;
+ font-style: italic;
+ }
+
+ .gi {
+ color: $green;
+ }
+
+ .gd {
+ color: $red;
+ }
+
+ .gu {
+ color: $blue;
+ }
+}
+
+summary {
+ cursor: pointer;
+ background-color: $black;
+ padding: 0.25rem 1rem;
+ margin: 0 -1rem;
+}
+
+details[open] {
+ border-bottom: 1rem solid $black;
+ margin: 0 -1rem 1rem;
+ padding: 0 1rem;
+}
+
+.text-center {
+ text-align: center;
+}
+
+blockquote {
+ border-left: 5px solid #bbb;
+ background-color: $black;
+ padding: 0 1rem;
+ margin-left: calc(-1rem - 5px);
+ margin-right: -1rem;
+
+ blockquote {
+ margin-right: 0;
+ margin-left: 0;
+ }
+}
+
+dl {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ grid-gap: 0.2rem 1rem;
+
+ dt {
+ font-weight: bold;
+ grid-column-start: 1;
+ }
+
+ dd {
+ grid-column-start: 2;
+ margin: 0;
+ }
+}
+
+.alert {
+ padding: 0.5rem;
+ border: 1px solid transparent;
+ margin-bottom: 1rem;
+
+ &.alert-danger {
+ background: #f8d7da;
+ color: #721c24;
+ border-color: #f5c6cb;
+ }
+
+ &.alert-info {
+ background: #d1ecf1;
+ color: #0c5460;
+ border-color: #bee5eb;
+ }
+}
diff --git a/config.toml b/config.toml
@@ -0,0 +1,14 @@
+baseURL = "https://vineetk.net/"
+title = "Vineet's site"
+pygmentsUseClasses = true
+uglyurls = true
+disablePathToLower = true
+
+[permalinks]
+blog = "/:year/:month/:day/:filename"
+
+[markup.goldmark.renderer]
+unsafe = true
+
+[markup.tableOfContents]
+ordered = true
diff --git a/content/_index.html b/content/_index.html
@@ -0,0 +1,3 @@
+---
+title: Vineet's site
+---
diff --git a/content/blog/kobo_clara-custom-distro.md b/content/blog/kobo_clara-custom-distro.md
@@ -0,0 +1,265 @@
++++
+title = "Kobo Clara HD Custom Linux Distro/RootFS"
+date = 2021-07-22
+draft = false
++++
+
+These are just some notes I made when creating my own mini-distro after
+wanting something more custom than just using buildroot or making the
+official firmware more slim. For people other than me, I suggest
+looking through (C)LFS or running postmarketOS instead once this
+reader's pull request[1] gets integrated into upstream.
+
+Two things that'll greatly help with this is having serial terminal
+access with the four uart pins near the top right in the back of the
+reader, near the uSD card slot (I don't connect the 5V pin as my reader
+doesn't really turn on anything other than the power LED). I suggest
+maybe soldering female pin headers to there to make your life easier
+(you can later cut out a hole in the back cover or desolder the headers
+once you're done). Other than that, I suggest installing QEMU with ARM
+userspace to test programs that you have built or running them on a
+separate ARM device like a Raspberry Pi.
+
+## Prelude
+Ever since I learnt that the official firmware for the Clara was just
+using a modified Linux kernel with busybox as coreutils and many other
+libraries, I just knew that I had to minimize it. I also saw that it
+was using glibc for it's libc, which I really dislike as statically
+linking C programs against it was a pain in my experience, compared to
+something like musl and uclibc. It's also much larger than them and I
+don't use any of glibc extensions so it seemed like a waste of space to
+me.
+
+Initially when I replaced Nickel with Plato, I was able to shave about
+100 MiB after I removed /usr/local (which contains Nickel, Qt and a few
+other things), from 189 MiB to 74 MiB, but I still wanted to make it
+smaller.
+
+Using buildroot, I was able to get it under 2 MiB (!!) which was a
+little less than half the size of an uncompressed armhf Alpine Linux
+minirootfs (4.9M for 3.14). With Busybox, it was pretty much working
+out of the box, with serial terminal access! But waiting around 15
+minutes for the toolchain to build each time I wanted to change
+something in the rootfs took way too long, although it could've been
+minimized if I used ccache with a fairly large cache size. I still
+found that it compiled and installed a lot of things I wouldn't be
+using (particularly in /usr) even after disabling almost all of the
+third-party packages.
+
+I've uploaded the config file and the resulting rootfs for
+buildroot 2021.05. The root password by default is changeme.
+EDIT 2022-10-21: gone, build it yourself
+
+Of course the rootfs I got from buildroot nor me making the official
+firmware smaller is the point of this article, and the actual point is
+making one yourself! (or rather what I did to make my own)
+
+## Cross-toolchain
+For now as of July 22, 2021, I'm using my distro (Void Linux)'s
+packaged cross toolchain for armhf musl, but eventually I would be
+using my own.
+
+I'm not compiling off of the device itself as it would be somewhat slow
+for bigger programs, which is currently primarily the Linux kernel,
+U-Boot, and the toolchain itself, considering that the ereader's CPU
+(Freescale i.MX 6SLL) is a single core running up to 1 GHz. Including
+the development tools and headers would also take up more space on the
+device itself, and since the terminal can currently only be accessed
+through it's serial/uart pins, I don't think it's ideal.
+
+TODO: include steps to create own toolchain (probably based off of gcc
+4.7.3 as that doesn't require c++)
+
+## Building the rootfs
+Assuming you made a new filesystem on your rootfs's partition, it'll
+likely be empty with no directories you'd expect to find on a regular
+distro. So you'll just have to make them.
+cd /path/to/rootfs
+mkdir bin dev etc proc sbin
+
+Your binaries would usually go in /bin, the uSD card, ttymxc0, and
+other devices would go in /dev, felker init's default program/script to
+execute is usually in /etc/rc, /proc is optional but I have it mounted
+to see what is currently mounted through /proc/mounts (or mount(1)
+without any arguments) as well as to see my disk usage through df(1).
+/sbin is there to place the init in as /sbin/init is the default init
+path the kernel looks at.
+
+## toybox
+Now on to the main part of the distro, the userspace. I intend to keep
+it fairly minimal so I've chosen to use toybox along with a slightly
+modified version of felker (musl dev)'s init[2], as well as dash[3] as
+the main shell since toybox doesn't include one as of 0.8.5 (though
+it'll probably be there by 1.0). I'll also be statically linking all
+the programs that'll be used so I wouldn't have to worry about shared
+libraries not being included/copied over, and also including LTO for
+slightly faster binaries. Originally, I tried going with sinit, sbase,
+and ubase but I was having trouble getting serial terminal access with
+getty to /dev/ttymxc0 (the default serial tty, at least with the
+vendor kernel). I didn't have this problem with busybox's and toybox's
+getty however. My config for toybox was also about 81K smaller than my
+trimmed sbase-box and ubase-box (352K compared to 267K+166K) where I
+removed programs that I won't use from ${BIN} in their respective
+Makefiles.
+EDIT 2022-10-21: also gone
+
+First I suggest exporting some environment variables to set the
+toolchain used as well as enabling static linking and LTO.
+
+ export CROSS_COMPILE="arm-linux-musleabihf-" # change to your cross-tc
+ export CC="${CROSS_COMPILE}gcc"
+ export LDFLAGS="--static"
+ export CFLAGS="-flto -static"
+ export ARCH=arm # for compiling the linux kernel
+
+To compile toybox, get the source from
+https://landley.net/toybox/downloads/ (or clone the upstream repo).
+Then run make menuconfig (optionally with make defconfig before it) and
+change it as you see fit. Personally, I disabled most of the programs I
+wouldn't use and kept only the ones that'll help with fixing a problem.
+Finally, make sure to run make.
+
+ make defconfig
+ make menuconfig
+ make
+
+To move it to your rootfs and set it's symlinks, you could probably run
+make install after setting PREFIX to your rootfs's /bin directory, but
+I did it manually.
+
+ # automatic (didn't test, check README)
+ make PREFIX=/path/to/rootfs/bin/ install
+
+ # (semi?) manual
+ cp toybox /path/to/rootfs/bin
+
+ # add symlinks if doing manual and you want them
+ cd /path/to/rootfs/bin
+ for prog in $(qemu-arm ./toybox); do ln -s toybox "$prog"; done
+
+## dash
+Also as of toybox 0.8.5, a shell still isn't included (probably would
+be included by 1.0 according to scripts/install.sh as well as a few
+other programs like gzip), so a separate shell would need to be built.
+Any can be used but dash would be shown as an example as I was able to
+get a static binary without too much trouble.
+
+First obtain the source[3] and cd into its
+untarred directory. Assuming your CC and CFLAGS are set, you can run
+these steps:
+
+ autoreconf -fiv
+ ./configure --host=$CROSS_COMPILE --with-libedit
+ make
+ ${CROSS_COMPILE}strip src/dash
+
+As this is going to be used as the main shell, I've decided to just
+copy it to /bin/sh in the rootfs directory, though copying it there but
+as /bin/dash and /bin/sh being symlinked to dash is also an option.
+
+ cp src/dash /path/to/rootfs/bin/sh
+ # or
+ cp src/dash /path/to/rootfs/bin
+ cd /path/to/rootfs/bin
+ ln -s dash sh
+
+## felker's init
+The init is just a single file that you can get from felker's site[2]
+or the gist on github[7]. I haven't had a good experience with the
+default startup program (/etc/rc) as a shell script with execve() run
+on it so I'd change it to execvp() and remove the third (specifies
+environment). To compile and install the init, all you need to do is
+run:
+
+ $CC $CFLAGS -o init init.c
+ cp init /path/to/rootfs/sbin
+
+Instead of /etc/rc being a shell script, you can also make a C program
+that does whatever you think is needed for a proper startup. I'll still
+use a shell script though which is linked here.
+EDIT 2022-10-21: you get the idea, it's gone.
+
+## /etc/passwd
+Copying the rootfs's contents to your device's/uSD card's root
+partition and then turning the device on should now work with a login
+prompt shown in the serial terminal. However, you probably wouldn't be
+able to login to any user. So you'll have to create a file at
+/path/to/rootfs/etc/passwd. For an empty password to root, you can use
+this, though I suggest setting a password as soon as you login:
+
+ # in rootfs's /etc/passwd
+ root::0:0:root:/root:/bin/sh
+
+With the passwd file created/updated, you should now be able to login
+to root after the rootfs is copied to your uSD card. Your rootfs so far
+should now be around 550-560K, which is much much smaller than the
+original firmware's, though it'll likely be much larger to maybe a few
+megabytes once a proper reader software is added.
+
+## Custom Linux Kernel
+WARNING: I haven't actually gotten the kernel to load in u-boot yet. It
+just hangs in the "Starting kernel ..." step and the init doesn't get
+loaded, so I'm assuming the kernel itself isn't either. If anyone out
+there has gotten a custom kernel working in the Kobo Clara HD, please
+send me an email or message on xmpp.
+
+UPDATE Jul 28, 2021: Gave up on it as I just couldn't get any kernels I
+built (both vendor and akemnade's mainline) to boot. But neither did
+postmarketOS boot beyond the initial initramfs messages without the log
+file being created. So I'll revisit this for later.
+
+EDIT 2022-10-21: I have gotten this working, but have been unable to
+get Plato build for musl, so I will have to either continue fighting
+with the crab or create my own with fbink, as that still works.
+Separate article on this later.
+
+My next big step is compiling my own kernel for the Clara HD. With the
+default configuration built for the vendor kernel, it appears to be
+about 3M, so my goal is to build a kernel that is smaller than that
+while retaining only the functionality that I need. I'm also not going
+to include networking support as that is unneeded for my purposes, but
+I suggest just keeping it if you're unsure. The wifi driver for the
+Kobo Clara HD is available as an out-of-tree driver[8].
+
+You should first obtain the kernel source, with two main options, the
+vendor kernel[9] and the mainline kernel (with akemnade's
+patches)[10]. For the latter, you need to clone the repo and switch to
+the latest kobo/drm-merged branch (kobo/merged-5.13 as of July 25,
+2021).
+
+After you've got them and assuming the CROSS_COMPILE and ARCH
+environment variables are set, you'd want to configure the kernel.
+
+I had a hard time compiling the vendor kernel with many things
+disabled, so I've kept my config somewhat similar to the default
+config. The config I used is available here (EDIT: dead).
+
+ make menuconfig
+ make zImage
+
+Assuming it compiles properly and arch/arm/boot/zImage exists, all
+that's needed to is to write it to your uSD card at the 1M offset.
+dd if=/path/to/kernel/zImage of=/path/to/uSDdev bs=512 seek=2048
+
+## Custom U-Boot
+I have not done this yet, nor really plan to, but if you do manage to
+compile the Kobo's vendored u-boot source, then all you'd have to do to
+install it is:
+
+ dd if=u-boot-file of=/dev/mmcblk0 bs=128k count=1 seek=6
+
+If I remember correctly, this command was included in an older
+firmware's startup script/rcS for updating udev, and it should still
+work.
+
+## Links
+[1]: https://gitlab.com/postmarketOS/pmaports/-/merge_requests/2334
+[2]: https://ewontfix.com/14
+[3]: https://git.kernel.org/pub/scm/utils/dash/dash.git
+[4]: https://github.com/akemnade/linux/tree/kobo/merged-5.13
+[5]: https://misc.andi.de1.cc/kobo/uboot-env.txt
+[6]: https://misc.andi.de1.cc/kobo/
+[7]: https://gist.github.com/rofl0r/6168719/raw/183525e0f0007169a49392b21ceee5b507e3aee8/init.c
+[8]: https://github.com/jwrdegoede/rtl8189ES_linux/tree/rtl8189fs
+[9]: https://github.com/kobolabs/Kobo-Reader/blob/master/hw/imx6sll-clara/kernel.tar.bz2
+[10]: https://github.com/akemnade/linux/tree/kobo/drm-merged-5.12
diff --git a/content/blog/kobo_clara-nickel.md b/content/blog/kobo_clara-nickel.md
@@ -0,0 +1,245 @@
++++
+title = 'Kobo Clara HD Notes for Nickel'
+date = 2021-01-13
+draft = false
+layout = "post"
++++
+
+My ereader of choice is the Kobo Clara HD and I particularly like it
+because my eyes hurt less when reading for long periods of time
+compared to when I read on my phone or when I still had my iPad. It
+also had much longer battery life and only need to charge it about once
+every two weeks when I read for about 4 hours on average daily.
+
+However, the two notable things I don't like about it is it's included
+telemetry, like using Google Analytics by default and keeping a unique
+salt
+
+Spyware/Anti-Features:
+- Google Analytics (a lot of actions, if not everything, is sent to
+Google)
+- Auto-update by default
+ - I prefer being able to review what the new update provides and
+ choose not to apply it
+ - I don't like the new redesign in firmware v4.23.15505
+
+I'm also assuming your Kobo reader and it's SD card's device file would
+be would located at `/dev/sdf` and be mounted at `/mnt/kobo`.
+
+If you're going to not be using Nickel and instead be using something
+like [Plato](https://github.com/baskerville/plato), there's a newer version of this article available
+[here](./kobo-clara-plato.html), but the notes are for ~KSM~ loading Plato directly and not
+though k/fmon because I don't want to load Nickel if I'm already using
+a different reader.
+
+## Upgrade/Backup Included SD Card
+While the included 8GB microSD card is decent for storing your ebook
+library that may not have a lot of images, that would likely not be
+enough if you were aiming to read some comics on your ereader as they
+can be pretty big (quite a few of mine are over a gigabyte, with some
+over. Luckily, you can replace the microSD card with another one.
+
+Before upgrading, you should backup the SD card to into an image file
+so the filesystem would be preserved when putting the contents of the
+image on the new SD card. I'm using the command dd but there might be
+another program doing the same thing. Even if you're not going to
+upgrade, I still suggest to backup the SD card in case something goes
+wrong.
+```sh
+dd if=/dev/sdf of=kobo_sd.img conv=sync
+```
+
+After this is done, you can plug in your new SD card and reimage
+kobo_sd.img onto it. With dd, you can do something like:
+```sh
+dd if=kobo_sd.img of=/dev/sdf conv=sync
+```
+
+Checking it's partition table via lsblk or fdisk -l should show three
+partitions. If you replaced the SD card with something bigger, than you
+should resize the third partition.
+
+## Bypassing Registration On Setup
+When setting up your Kobo, you will be asked to sign into a Kobo
+account. There are other options like logging in via Google, Walmart,
+and other stores, but I don't like having to login to a device that
+would likely not be connected to the public internet. Fortunately, you
+can bypass this by choosing that you cannot connect to a Wi-Fi network
+and mount your Kobo to your computer. In, `.kobo/KoboReader.sqlite`, you
+can run:
+```sh
+echo "INSERT INTO user(UserID,UserKey) VALUES('1','');" \
+ | sqlite3 KoboReader.sqlite
+```
+
+This way you don't have to install their application just to be able to
+use your device.
+
+Note: Do not try doing this when you still have your SD card mounted
+before you setup your device. The device's screen would likely not
+update, at least on an early firmware version like v4.7.10733.
+
+## Blocking Google Analytics and other Telemetry
+Just adding 0.0.0.0 analytics.google.com to `/etc/hosts` may be enough to
+block most of the telemetry from being sent. However, you can try
+intercepting what connections your Kobo is making via mitmproxy set to
+transparent mode or using a hosts file that blocks all connections to
+Google (but not necessarily to Kobo's servers) like [Baobab's hosts file](https://codeberg.org/baobab/hosts)
+[(raw)](https://codeberg.org/baobab/hosts/raw/branch/master/hosts).
+EDIT 2022-10-21: Baobab has deleted his account from Codeberg for quite a
+while, so these two links are dead. Instead, I now recommend [Steven Black's](https://github.com/StevenBlack/hosts)
+instead [(raw)](https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts).
+
+To put the hosts file without root (which will be detailed in another
+section), you can make a directory called etc, put the hosts file in
+there, and tar it into a file called KoboRoot.tgz.
+```sh
+mkdir etc
+wget -O etc/hosts https://codeberg.org/baobab/hosts/raw/branch/master/hosts
+tar czvf KoboRoot.tgz etc
+cp KoboRoot.tgz /mnt/kobo/.kobo/
+```
+
+When you move a tar file with that name into your Kobo's .kobo folder,
+it's contents gets untarred into it's root at `/` when the device is
+turned on again, which is usually done for their updates but can be
+used for custom files like this and gaining root access.
+
+## Gaining Root Access via Telnet
+To gain root access, we first need to get the `/etc/inittab` and
+`/etc/inetd.conf` which you can get from mounting the SD card's first
+partition into your computer (the second partition seems to be like a
+backup). You should copy those two files into a folder called etc
+somewhere (probably not on the SD card).
+
+In the `etc/inittab` file, you should add these two lines:
+```
+::sysinit:/etc/custominit.sh
+::respawn:/usr/sbin/inetd -f /etc/inetd2.conf
+```
+
+You would want to rename the `etc/inetd.conf` file you copied into
+`etc/inetd2.conf` (or whatever the custom inetd.conf's filename is) and
+when editing that, you should add:
+```
+23 stream tcp nowait root /bin/busybox telnetd -i
+```
+
+However, if there is already a commented line for root telnet in the
+inetd2.conf, you should probably still add the above line and ignore
+the commented line as that may or may not work (didn't for me).
+
+To actually start inetd, you should add these lines somewhere in
+`/etc/custominit.sh`:
+```sh
+mkdir -p /dev/pts
+mount -t devpts devpts /dev/pts
+/usr/sbin/inetd /etc/inetd2.conf
+```
+
+After that, you just have to tar the `etc/` folder again and copy it to
+your Kobo's onboard/third partition's `.kobo` folder.
+```sh
+tar czvf KoboRoot.tgz etc
+cp KoboRoot.tgz /mnt/kobo/.kobo/
+```
+
+Now you could put your SD card back into your Kobo provided that they
+are already unmounted and turn your Kobo back on.
+
+After connecting to the WiFi, simplying telnetting (?) into your Kobo
+and logging in as root should give you a root shell. :D
+```sh
+telnet $KOBO_IP
+```
+
+By default, root has no password so you should change it with passwd.
+
+## Getting SSH and SFTP access via Dropbear
+I'm using Dropbear instead of OpenSSH because it's better suited for
+embedded hardware like the Kobo Clara HD. Obviously we can't copy a
+binary compiled for amd64 or whatever architecture your compiling
+computer is running so we would have to cross-compile for our ereader.
+
+Fortunately, we are not required to cross-compile `gcc`/`clang` and friends
+as we can simply download the linaro arm toolchain which has the
+binaries for gcc and others included. You could get the toolchain
+[here](https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/) and you should get the release that matches your host's
+
+architecture. After untarring the file, you should also set your PATH
+variable to the toolchain's `bin/` folder so you don't have to manually
+set the CC and CXX variables when building Dropbear.
+
+```sh
+wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
+tar xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
+export PATH=$(pwd)/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin:$PATH
+```
+
+Now you could get the source for Dropbear and cross-compile it. The
+source can be found on their [homepage](https://matt.ucc.asn.au/dropbear/dropbear.html) or [github](https://github.com/mkj/dropbear/releases) repo.
+```sh
+wget https://matt.ucc.asn.au/dropbear/releases/dropbear-2020.81.tar.bz2
+tar xvf dropbear-2020.81.tar.bz2
+cd dropbear-2020.81
+./configure --enable-static --host=arm-linux-gnueabihf
+# MULTI=1 combines the binaries like busybox does and is also smaller in size
+make MULTI=1 PROGRAMS="dropbear dropbearkey"
+```
+
+Now you only need to copy the dropbearmulti binary over to your Kobo.
+What I've done is running `python3 -m http.server` and downloading the
+file onto my Kobo but you could also just copy it onto the microSD
+card.
+```sh
+wget your.computer.ip:8000/dropbearmulti
+chmod +x dropbearmulti
+mv dropbearmulti /usr/bin
+cd /usr/bin
+# below are optional but dropbear(key) would be an argument for dropbearmulti
+ln -s dropbearmulti dropbear
+ln -s dropbearmulti dropbearkey
+```
+
+Now you only need to generate the host keys. My client key is ed25519
+so I'm not going to generate the others.
+```sh
+mkdir /etc/dropbear
+dropbearkey -t ed25519 -f /etc/dropbear/dropbear_ed25519_host_key
+dropbear -F -r /etc/dropbear/dropbear_ed25519_key
+```
+
+Now you could `ssh` into your Kobo and login as `root`. Remember to change
+`root`'s password beforehand though if you haven't already! I suggest
+copying your public key to your Kobo via `ssh-copy-id` so you don't have
+to enter root's password all the time and so password-based logins can
+be disabled in dropbear.
+
+To start it on boot, you could add the following line to
+`/etc/inetd2.conf`:
+```
+22 stream tcp nowait root /usr/bin/dropbearmulti dropbear -i -r /etc/dropbear/dropbear_ed25519_key
+```
+
+For some reason, the symlink wasn't resolving for me inetd so I had to
+call the multi-binary directly. You could also add the command/args
+into `/etc/custominit.sh`.
+
+## FTP Access
+If you don't or can't use sftp or scp for some reason, there's always ftp :D
+There's a ftp daemon included in busybox so all we have to do is enable it
+in `/etc/inetd2.conf`:
+```
+21 stream tcp nowait root /bin/busybox ftpd -w -S /
+```
+
+This would share the entire filesystem so you may or may not want to
+restrict the shared directory to maybe just your ebook directory
+(`/mnt/onboard`) and move the files out via `telnet` or `ssh`.
+EDIT 2022-10-21: A chroot would also work.
+
+## References and Other Links
+- [Rémy's notes on hacking a Kobo Aura H2O](https://remy.grunblatt.org/kobo-aura-h2o-electronic-reader-hacking.html)
+- [Ying's notes on bypassing registration and setting up telnet, ssh, etc.](https://yingtongli.me/blog/2018/07/30/kobo-rego.html)
+- [MobileRead forum thread on disabling Google Analytics on the Kobo Touch](https://www.mobileread.com/forums/showthread.php?t=162713)
+- [MobileRead wiki on hacking the Kobo Touch](https://wiki.mobileread.com/wiki/Kobo_Touch_Hacking)
diff --git a/content/blog/kobo_clara-plato.md b/content/blog/kobo_clara-plato.md
@@ -0,0 +1,129 @@
++++
+title = "Kobo Clara HD Notes for Plato (and KSM)"
+date = 2021-03-27
++++
+
+These are my notes for getting Plato on the Kobo Clara HD from scratch
+as well as some notes for getting KSM to work, but I now boot directly
+into Plato instead of through KSM.
+
+Previously, I didn't really like using KOReader because it was kind of
+slow and was written in Lua. At the time of using Plato, it seemed nice
+but it didn't cover thumbnails for books, which while it is a minor
+detail, I find books easier to be recognized with a cover thumbnail in
+addition to their title. This was added in release 0.9.10 but as an
+optional feature which I didn't somehow see until recently when I
+retried it. HOWEVER again, I didn't like using k/fmon as I had to still
+use Nickel to get back into KOReader/Plato/whatever alternate reader
+when I wanted to go away from using Nickel.
+
+<ignore>
+That was when I found out about KSM and how there was a working version
+for the Clara HD. KSM is like an alternate bootloader for the Kobo
+readers and it apparently doesn't work very well with newer models like
+the Clara HD and up, but someone got it to work with those devices.
+[KSM 09](https://www.mobileread.com/forums/showthread.php?s=c34e41df391c61810a6b06f991c29168&t=293804) is apparently not maintained anymore and I'm not sure if KSM
+10 is being developed or not since I'm pretty sure it's closed source.
+
+> Development and support for KSM stopped some time ago. Therefore, do
+> not use it!
+
+"That sign can't stop me because I can't read!" - Me imitating D.W.
+from the PBS Kids cartoon Arthur on Mar. 26, 2021 when I saw that it
+can be used on my Kobo
+
+The latest firmware version that KSM sort of supports is v4.25.15875
+but it can probably work with a newer version like v4.26+ that would
+likely only need a couple changes to /etc/init.d/rcS, if any changes
+were needed at all. I'll be using v4.26 for the rest of this
+article/guide.
+</ignore>
+
+Recently, after seeing how my Kobo boots into KSM and Nickel through
+the rcS file, I realized that I could've instead just booted directly
+into Plato, and plato.sh (the script that runs Plato) has a standalone
+option that supports just that! The KSM notes are still going to be
+here in case someone still wants to use KSM.
+
+## Installing Plato (or probably any other reader like KOReader)
+This part probably applies to any other reader other than Plato like
+KOReader but I haven't personally tested them. All you have to do is
+[get the latest release](https://github.com/baskerville/plato/releases/latest) at Plato's repo and unzip it's contents into
+a folder called plato in /path/to/kobo/mount/.adds, the latter folder
+of which should have already been created by KSM if you are using that.
+If you are using KSM, there should be a new option below "start nickel"
+called "start plato" when you have rebooted the device. Read below if
+you aren't using KSM.
+
+## Loading Plato on Boot
+Since I don't want to load Nickel only to load into another reader like
+the recommended options in Plato's forum thread (kfmon, fmon, and
+NickelMenu) suggest, I noticed that I could have booted into Plato
+directly. The only requirements for doing this having access to the
+rootfs, so either through a telnet/ssh session, or having the sd card's
+root/first partition mounted to your computer, or just ftp/rsyncing the
+files to your Kobo.
+
+First I suggest making a copy of rcS if you haven't already in case an
+update overwrites it. My copy is named custominit.sh. Next you'll want
+the Kobo's /etc/inittab to boot with custominit.sh instead of rcS:
+/etc/inittab:
+
+```
+#::sysinit:/etc/init.d/rcS
+::sysinit:/etc/custominit.sh
+```
+
+The rest of the lines don't need to change. Then you should open
+custominit.sh in your favourite editor to add the lines at the bottom
+but before hindenburg is executed:
+
+```
+cd /mnt/onboard/.adds/plato # or whereever Plato is
+PLATO_STANDALONE=1 ./plato.sh
+```
+
+You would probably also want to remove the lines where Nickel-specific
+programs/scripts are running like nickel, hindenburg, pickel, sickel,
+etc.
+
+Now on subsequent boots, Plato should automatically have been loaded.
+Boot times may also be slightly faster! :D
+
+## Installing KSM 09 (not doing anymore)
+First you would want to [download the Clara HD version of KSM 09](https://www.mobileread.com/forums/attachment.php?s=902078ac2e6fe8ff7a0947b56cbcade6&attachmentid=166556&d=1538176531) and
+[the fix for v4.25](https://www.mobileread.com/forums/attachment.php?s=902078ac2e6fe8ff7a0947b56cbcade6&attachmentid=184756&d=1610745905). Then, you would want to unzip the KoboRoot.tgz
+with separate filenames so they don't replace each other and we would
+untar those into the same directory. After that, we would cd into the
+directory and tar it's contents into a new KoboRoot.tgz and place it in
+/path/to/kobo/mount/.kobo/.
+
+An example of what I did after downloading and unzipping the files are
+below:
+
+```
+mkdir koboroot
+tar -xvf KoboRoot-main.tgz -C koboroot
+tar -xvf KoboRoot-v4.25-darkmodefix.tgz -C koboroot
+cd koboroot
+tar -czvf ../KoboRoot.tgz .
+cd ..
+rm -r koboroot
+```
+
+After your Kobo untars it and you wait a while, you should be presented
+with KSM's main screen :D ksm09's main screen running on the kobo clara
+hd
+
+## Auto-Boot into Plato instead of Nickel via KSM (not doing anymore)
+First make sure USB support is enabled in KSM and then mount your Kobo
+to your computer. Once mounted, go to
+/path/to/kobo/mount/.adds/kbmenu_user/confoptions and edit
+ksm_ini_options.txt in your favourite editor. You should see many
+options that are listed but the one that we're interested in is
+ksmAutoselectoption which may have start_nickel and start_koreader
+already and what we want to do is add ksmAutoselectoption=start_plato.
+After a quick restart to reload the options file, you should be able to
+see the new option in KSM's settings under [general] and add item if it
+wasn't already added. Now Plato should auto-boot on subsequent
+powerons.
diff --git a/content/blog/st-bitmap-font-fix.md b/content/blog/st-bitmap-font-fix.md
@@ -0,0 +1,37 @@
++++
+title = "Fixing bitmap font fallbacks in the st terminal"
+date = 2023-11-24
+draft = false
++++
+tldr, change FC_SCALABLE in x.c from 1 to 0. (comes from the font2 patch)
+
+For some context, I have been using xterm for a long while when I'm on OpenBSD
+since it is included by default in Xenocara with Terminus as my default font,
+and the main reason why I did not use st again was that my bitmap fallback font
+for CJK was not loading. Instead, I get an ugly sans-serif scaled font that
+looked very out of place in my otherwise clean and crisp bitmap terminal.
+
+Yes, I did make sure that the font2 patch for st was applied correctly.
+
+The X11 font string for reference is Fixed:
+-misc-fixed-medium-r-normal-ja-18-120-100-100-c-180-iso10646-1
+
+It also didn't help that fontconfig was unable to find the font either no
+matter how much I looked for it with fc-list and fc-match. The weirder thing is
+that when I installed GNU Unifont to my fonts directory, fontconfig was able to
+find it and st loaded it (I put a printf in the xloadfonts() function in x.c),
+but the same old ugly scaled font was still being shown for CJK. The weirderer
+thing was that Unifont was rendering just fine when being used as the main font
+instead of in font2.
+
+I thought to myself why this was happening and wasn't able to find out, until I
+reread the font loading portion in x.c's xloadsparefonts() function that came
+part of the font2 patch.
+
+It had set the FC_SCALABLE boolean to 1 (true). That explained why the fallback
+font rendered fine as the main font and not fallback. Setting that boolean to
+0 (false) fixed my fallback font not matching issue, and now I have clean and
+crisp looking text that I can read more easily.
+
+I already disliked fontconfig, freetype, xft, and friends (don't get me started
+on pango and harfbuzz), but this incident made me dislike it further.
diff --git a/content/blog/tmpfilehost.md b/content/blog/tmpfilehost.md
@@ -0,0 +1,73 @@
++++
+title = "Creating a Temporary File Hoster"
+date = 2022-04-27
+draft = false
++++
+For the past couple years, whenever I wanted to upload a file, I would
+curl the file to [lainsafe](https://git.qorg11.net/lainsafe.git/), [i/u.kalli.st](https://gt.kalli.st/kallist/uploader), and recently [ttm.sh](https://tildegit.org/tildeverse/ttm.sh).
+
+Since I want to selfhost, I thought i can just use either of what those
+three used. Earlier today though, I realized I could just copy the
+file(s) I want to upload via rsync/scp to a public directory that gets
+served by an httpd or gopherd.
+
+From what I understand, the previous file hosters had a program running
+that read the file that the user uploads to them, does some renaming,
+and writes that to a directory that is served. After some time, that
+file is deleted. The first part can be handled via rsync/scp like
+mentioned previously. For automatic deletion, I recently saw in find's
+man page that it can list that haven't been modified via the -mtime
+flag, so that can be used with a cron job.
+
+But while thinking of this idea, I got stumped by how to print back the
+url to this file that is uploaded since printing the filename as is
+appended to its baseurl, there could be spaces and other invalid
+unescaped characters which programs trying to download it may not like.
+
+I thought I could just create a separate program for this. However,
+doing this seemed more complicated than just copying the file to the
+server. So, with the help of awk and some StackExchanging, I've been
+able to do it.
+
+`upfile.sh`:
+```sh
+#!/bin/sh
+urlencode() {
+ awk '
+BEGIN { for (i = 1; i < 256; i++) hex[sprintf("%c", i)] = sprintf("%%%02X", i) }
+{
+ for (i = 1; i <= length($0); i++) {
+ c = substr($0, i, 1)
+ printf("%s", c ~ /^[-._~0-9a-zA-Z]$/ ? c : hex[c])
+ }
+ printf "\n"
+}
+'
+}
+
+FILE="$1"
+SERVER="REPLACEME"
+BASEURL="https://u.$SERVER"
+
+[ -z "$1" ] && exit 1
+
+scp "$FILE" "$SERVER":files/ || exit 1
+printf "%s/" "$BASEURL"
+basename "$FILE" | urlencode
+```
+
+Then to purge these files after they become too old (e.g. 3 days), you
+can put something like this in a cron job to run daily (replace file
+directory):
+
+```
+0 0 * * * find /path/to/dir/ -mtime +3 -exec rm {} \;
+```
+
+You can also put this command in /etc/daily.local or /etc/cron/daily,
+or whatever file your root crontab's @daily runs (if there is one).
+
+And that's it! The only difficult part that I experienced was encoding
+the name of the file and originally did that in C. However, having a
+mixed C and shell program just for file uploading didn't sit right with
+me. It seems like whenever you're in doubt, you can rely on awk huh.
diff --git a/content/blog/vfio-win10.md b/content/blog/vfio-win10.md
@@ -0,0 +1,318 @@
++++
+title = "VFIO Install Notes"
+date = 2020-10-17
+draft = false
++++
+You should first go look at [the Arch Wiki on it](https://wiki.archlinux.org/index.php/PCI%20passthrough%20via%20OVMF) or [Yuri Alek's guide on Single GPU passthrough](https://gitlab.com/YuriAlek/vfio) or [4chan's /g/ wiki on it](https://wiki.installgentoo.com/index.php/PCI_passthrough) as these assume prior knowledge.
+
+# Prerequisites
+## UEFI Options
+Enable VT-d and VT-x (or AMD equivalent)
+
+## Kernel Config
+Enable KVM and VFIO
+> you can set VFIO as builtin but as a module is more flexible
+Also add `"iommu=pt intel_iommu=on"` to your kernel command line (or in CONFIG\_CMDLINE)
+
+### Current Options
+```
+...
+CONFIG_IOMMU_IOVA=y
+CONFIG_IOMMU_API=y
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y
+# use the respective AMD options if using an AMD CPU
+CONFIG_INTEL_IOMMU=y
+CONFIG_INTEL_IOMMU_SVM=y
+CONFIG_INTEL_IOMMU_DEFAULT_ON=y
+CONFIG_INTEL_IOMMU_FLOPPY_WA=y
+
+CONFIG_KVM_VFIO=y
+CONFIG_VFIO_IOMMU_TYPE1=m
+CONFIG_VFIO_VIRQFD=m
+CONFIG_VFIO=m
+CONFIG_VFIO_PCI=m
+CONFIG_VFIO_PCI_VGA=y
+CONFIG_VFIO_PCI_MMAP=y
+CONFIG_VFIO_PCI_INTX=y
+CONFIG_VFIO_PCI_IGD=y
+CONFIG_VFIO_MDEV=m
+CONFIG_VFIO_MDEV_DEVICE=m
+...
+```
+
+## Packages Required
+```
+app-emulation/qemu (actual program)
+sys-firmware/edk2-ovmf (UEFI firmware for Nvidia GPU)
+media-sound/scream (audio)
+looking-glass-client (compile from source if no package, or make your own)
+```
+
+`app-emulation/libvirt` can be used as well for easier configuration and autostart
+but I have had problems with it:
+- Service not starting properly, workaround is restarting service after it starts (Gentoo)
+- Networks and domains not autostarting, workaround is starting them manually (CRUX)
+
+### Gentoo USE Flags
+```
+app-emulation/qemu gtk opengl sdl sdl-image usb # (spice, ssh, vhost-user-fs, virgl, and virtfs are optional I think)
+media-libs/libsdl2 X gles opengl # for Looking Glass
+```
+note to self (2020-10-17): check how minimal you can make qemu to run vfio
+
+# IOMMU
+Run `dmesg | grep -E 'DMAR'` and see if `DMAR: IOMMU enabled` or something similar is in output
+
+# QEMU Script
+All code blocks in this section go in the qemu script file unless specified otherwise
+
+## Environment Variables
+```sh
+IMG=/path/to/windows-image-file
+VIRTIO=/path/to/virtio-iso
+WINDOWS=/path/to/windows-install-iso
+OVMF=/usr/share/edk2-ovmf/OVMF_CODE.fd
+RAM=16G
+ULIMIT=$(ulimit -l)
+ULIMIT_TARGET=$(( $(echo $RAM | tr -d 'G')*1048576+100000 ))
+
+GPU_VIDEO=01:00.0
+GPU_AUDIO=01:00.1
+VIDEOID="10de 13c0"
+AUDIOID="10de 0fbb"
+VIDEOBUSID="0000:${GPU_VIDEO}"
+AUDIOBUSID="0000:${GPU_AUDIO}"
+```
+
+## VFIO Detaching and Attaching
+```sh
+vfio_on() {
+ # for nvidia card with proprietary drivers
+ rmmod nvidia_drm
+ rmmod nvidia_modeset
+ rmmod nvidia
+
+ # disable bumblebee service or use bbswitch to detach card if using bumblebee
+
+ modprobe vfio-pci
+
+ echo $VIDEOID > /sys/bus/pci/drivers/vfio-pci/new_id
+ echo $VIDEOBUSID > /sys/bus/pci/devices/$VIDEOBUSID/driver/unbind
+ echo $VIDEOBUSID > /sys/bus/pci/drivers/vfio-pci/bind
+ echo $VIDEOID > /sys/bus/pci/drivers/vfio-pci/remove_id
+
+ echo $AUDIOID > /sys/bus/pci/drivers/vfio-pci/new_id
+ echo $AUDIOBUSID > /sys/bus/pci/devices/$AUDIOBUSID/driver/unbind
+ echo $AUDIOBUSID > /sys/bus/pci/drivers/vfio-pci/bind
+ echo $AUDIOID > /sys/bus/pci/drivers/vfio-pci/remove_id
+
+ # add rest of gpu devices if they are in the same group (I think 4 devices in 1000 or 2000 series nvidia)
+}
+
+vfio_off() {
+ rmmod vfio_iommu_type1
+ rmmod vfio_pci
+ rmmod vfio_virqfd
+ rmmod vfio
+
+ modprobe nvidia
+}
+```
+
+## Networking
+```sh
+net_on() {
+ ip tuntap add dev tap0 mode tap group kvm
+ ip link set dev tap0 up promisc on
+ ip addr add 0.0.0.0 dev tap0
+
+ ip link add br0 type bridge
+ ip link set br0 up
+ ip link set tap0 master br0
+ echo 0 > /sys/class/net/br0/bridge/stp_state
+ ip addr add 192.168.123.1/24 dev br0
+
+ sysctl net.ipv4.conf.tap0.proxy_arp=1 > /dev/null
+ sysctl net.ipv4.conf.enp0s31f6.proxy_arp=1 > /dev/null
+ sysctl net.ipv4.ip_forward=1 > /dev/null
+
+ iptables -t nat -A POSTROUTING -o enp0s31f6 -j MASQUERADE > /dev/null
+ iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT > /dev/null
+ iptables -A FORWARD -i br0 -o enp0s31f6 -j ACCEPT > /dev/null
+}
+
+net_off() {
+ sysctl net.ipv4.conf.tap0.proxy_arp=0 > /dev/null
+ sysctl net.ipv4.conf.enp0s31f6.proxy_arp=0 > /dev/null
+ sysctl net.ipv4.ip_forward=0 > /dev/null
+
+ ip link set dev br0 down
+ ip link del br0
+
+ ip link set dev tap0 down
+ ip tuntap del mode tap name tap0
+}
+```
+
+Also add this to /etc/conf.d/net if using Gentoo ([source](https://wiki.gentoo.org/wiki/QEMU/Options#Network_bridge))
+> replace `enp0s31f6` with the host/master interface
+```sh
+...
+tuntap_tap0="tap"
+config_tap0="null"
+bridge_br0="enp0s31f6 tap0"
+
+config_br0="192.168.123.2 netmask 255.255.255.0"
+routes_br0="default via 192.168.123.1"
+bridge_forward_delay_br0=0
+bridge_hello_time_br0=10
+
+depend_br0() {
+ need net.enp0s31f6
+ need net.tap0
+}
+...
+```
+
+## Hugepages
+```sh
+hugepages_on() {
+ PAGES=$(( $(echo $RAM | tr -d 'G') * 1048576 / 2048))
+ mkdir -p /dev/hugepages
+ mount -t hugetlbfs hugetlbfs /dev/hugepages
+ echo $PAGES > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
+}
+
+hugepages_off() {
+ echo 0 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
+ umount /dev/hugepages
+}
+```
+
+## QEMU Command
+### Before installing guest OS (Windows 10 used as example)
+```sh
+ulimit -l $ULIMIT_TARGET
+
+qemu-system-x86_64 \
+ -name 'vfio-vm' \
+ -vga qxl \
+ -nodefaults -enable-kvm -machine q35 \
+ -m $RAM -mem-path /dev/hugepages \
+ -cpu host,kvm=off,svm=off,topoext,hv_relaxed,hv_spinlocks=0x1fff,hv_time,hv_vapic,hv_vendor_id=novideobad43,hv_vpindex,hv_synic,hv_stimer,hv_frequencies \
+ -smp 8,sockets=1,cores=4,threads=2 \
+ -rtc clock=host,base=localtime \
+ -boot menu=on -boot d \
+ -nic tap,ifname=tap0,script=no,downscript=0,model=virtio-net-pci \
+ -drive if=pflash,format=raw,readonly,file=$OVMF \
+ -drive file="$VIRTIO",id=cd1,media=cdrom \
+ -drive file="$WINDOWS",id=cd2,media=cdrom \
+ -device virtio-scsi-pci,id=scsi0 \
+ -device scsi-hd,bus=scsi0.0,drive=rootfs \
+ -drive file="$IMG",id=rootfs,index=0,format=qcow2,media=disk,if=none
+
+ulimit -l $ULIMIT
+```
+### After installing guest OS
+```sh
+ulimit -l $ULIMIT_TARGET
+
+qemu-system-x86_64 \
+ -name 'vfio-vm' \
+ -vga none -nographic \
+ -nodefaults -enable-kvm -machine q35 \
+ -m $RAM -mem-path /dev/hugepages \
+ -cpu host,kvm=off,svm=off,topoext,hv_relaxed,hv_spinlocks=0x1fff,hv_time,hv_vapic,hv_vendor_id=novideobad43,hv_vpindex,hv_synic,hv_stimer,hv_frequencies \
+ -smp 8,sockets=1,cores=4,threads=2 \
+ -rtc clock=host,base=localtime \
+ -boot menu=on -boot c \
+ -nic tap,ifname=tap0,script=no,downscript=0,model=virtio-net-pci \
+ -device vfio-pci,host=$GPU_VIDEO,multifunction=on,x-vga=on \
+ -device vfio-pci,host=$GPU_AUDIO \
+ -device ivshmem-plain,memdev=ivshmem,bus=pcie.0 \
+ -object memory-backend-file,id=ivshmem,share=on,mem-path=/dev/shm/looking-glass,size=32M \
+ -device virtio-keyboard-pci \
+ -device virtio-mouse-pci \
+ -object input-linux,id=kbd0,evdev=/dev/input/by-id/usb-Corsair_Corsair_K70R_Gaming_Keyboard-if02-event-kbd,grab_all=on,repeat=on \
+ -object input-linux,id=mouse0,evdev=/dev/input/by-id/usb-Logitech_Gaming_Mouse_G502_0E5F335C3236-event-mouse \
+ -object input-linux,id=mouse1,evdev=/dev/input/by-id/usb-Logitech_Gaming_Mouse_G502_0E5F335C3236-if01-event-kbd,grab_all=on,repeat=on \
+ -drive if=pflash,format=raw,readonly,file=$OVMF \
+ -drive file="$VIRTIO",id=cd1,media=cdrom \
+ -device virtio-scsi-pci,id=scsi0 \
+ -device scsi-hd,bus=scsi0.0,drive=rootfs \
+ -drive file="$IMG",id=rootfs,index=0,format=qcow2,media=disk,if=none
+
+ulimit -l $ULIMIT
+```
+
+# Extra
+## Adding USB Devices
+Get vendor and product id from `lsusb` and add them to your QEMU command arguments:
+```sh
+ -device qemu-xhci,id=xhci0 -device usb-host,bus=xhci0.0,vendorid=0x<yourvendorid>,productid=0x<yourproductid>
+```
+Example for my USB bluetooth receiver:
+```
+$ lsusb
+...
+Bus 001 Device 004: ID 0b05:17cb ASUSTek Computer, Inc. Broadcom BCM20702A0 Bluetooth
+...
+```
+My vendorid is `0x0b05` and productid is `0x17cb`, so in QEMU it would be:
+```sh
+ -device qemu-xhci,id=<usb-bus-id> -device usb-host,bus=<usb-bus-id>.0,vendorid=0x0b05,productid=0x17cb
+```
+
+## Set CPU Affinity
+While libvirt makes this more simple, it appears we need a script/function to do it in bare QEMU
+Borrowed from [here](https://null-src.com/posts/qemu-optimization/post.php#taskset)
+> note: uses bash-isms so that's why I put it in a separate file
+```bash
+#!/bin/bash
+THREAD_LIST="0,4,1,5,2,6,3,7"
+NAME="vfio-vm"
+
+sleep 20 &&
+HOST_THREAD=0
+# for each vCPU thread PID
+for PID in $(pstree -pa $(pstree -pa $(pidof qemu-system-x86_64) | grep $NAME | awk -F',' '{print $2}' | awk '{print $1}') | grep CPU | pstree -pa $(pstree -pa $(pidof qemu-system-x86_64) | grep $NAME | cut -d',' -f2 | cut -d' ' -f1) | grep CPU | sort | awk -F',' '{print $2}')
+do
+ let HOST_THREAD+=1
+ # set each vCPU thread PID to next host CPU thread in THREAD_LIST
+ echo "taskset -pc $(echo $THREAD_LIST | cut -d',' -f$HOST_THREAD) $PID" | sh
+done
+```
+
+## Additional Disk
+You can add another disk by simply copying the arguments for adding the rootfs and slightly modifying
+Example for a qcow2 image:
+```
+ -device virtio-scsi-pci,id=<scsi-id> \
+ -device scsi-hd,bus=<scsi-id>.0,drive=<drive-id> \
+ -drive file=<location>,id=<drive-id>,index=0,format=qcow2,media=disk,if=none
+```
+
+## No Drives During Installation
+Make sure virtio driver is loaded:
+- Click Load Driver
+- Choose virtio-cd disc > amd64 > w10 and press enter
+- Load Red Hat Virtio SCSI driver
+
+## Looking Glass Not Starting
+Make sure no virtual display like QXL is loaded too (`-nographic -vga none` in QEMU)
+
+## JACK Support
+To use JACK instead of Scream, you can use these QEMU arguments
+```sh
+-audiodev jack,id=snd0,in.client-name=default,out.client-name=default,in.start-server=off,out.start-server=off,in.exact-name=on,out.exact-name=on,in.connect-ports=system,out.connect-ports=system,in.frequency=48000,out.frequency=48000,timer-period=2048,out.buffer-length=5120 \
+-device ich9-intel-hda \
+-device hda-output,audiodev=snd0 \
+```
+You might need to change the timer-period and buffer-length if experiencing crackling.
+Also you might have to change the controller (ich9-intel-hda) and codec (hda-output) to something else.
+
+To list controller and codecs, run:
+```sh
+qemu-system-x86_64 -device help | grep hda
+```
diff --git a/layouts/_default/single.html b/layouts/_default/single.html
@@ -0,0 +1,11 @@
+{{ partial "head.html" . }}
+
+<h1>
+ {{$.Title}}
+</h1>
+
+<main>
+ {{.Content}}
+</main>
+
+{{ partial "foot.html" }}
diff --git a/layouts/blog/rss.xml b/layouts/blog/rss.xml
@@ -0,0 +1,39 @@
+{{- $pctx := . -}}
+{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
+{{- $pages := slice -}}
+{{- if or $.IsHome $.IsSection -}}
+{{- $pages = $pctx.RegularPages -}}
+{{- else -}}
+{{- $pages = $pctx.Pages -}}
+{{- end -}}
+{{- $limit := .Site.Config.Services.RSS.Limit -}}
+{{- if ge $limit 1 -}}
+{{- $pages = $pages | first $limit -}}
+{{- end -}}
+{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
+ <link>https://open.crates.im</link>
+ <description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
+ <generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
+ <language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
+ <managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
+ <webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
+ <copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
+ <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
+ {{ with .OutputFormats.Get "RSS" }}
+ {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
+ {{ end }}
+ {{ range $pages }}
+ <item>
+ <title>{{ .Title }}</title>
+ <link>{{ .Permalink }}</link>
+ <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
+ {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
+ <guid>{{ .Permalink }}</guid>
+ <description>{{- .Content | html -}}</description>
+ </item>
+ {{ end }}
+ </channel>
+</rss>
diff --git a/layouts/blog/section.html b/layouts/blog/section.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<html lang="en">
+<meta charset="utf-8" />
+<title>{{.Title}}</title>
+{{ $style := resources.Get "main.scss" | css.Sass | resources.Minify | resources.Fingerprint }}
+<link rel="stylesheet" href="{{ $style.RelPermalink }}">
+
+<main>
+ {{.Content}}
+</main>
diff --git a/layouts/blog/single.html b/layouts/blog/single.html
@@ -0,0 +1,15 @@
+{{ partial "head.html" . }}
+<h1>
+ {{$.Title}}
+ <small>
+ <span class="date">{{.Date.Format "January 2, 2006"}}</span>
+ on
+ <span class="site"><a href="{{.Site.BaseURL}}">{{.Site.Title}}</a></span>
+ </small>
+</h1>
+<main>
+ <article>
+ {{.Content}}
+ </article>
+</main>
+{{ partial "foot.html" }}
diff --git a/layouts/index.html b/layouts/index.html
@@ -0,0 +1,15 @@
+{{ partial "head.html" . }}
+
+<main class="index">
+ <section class="article-list">
+ <div>
+ <h1 class="text-center">{{$.Title}}</h1>
+ {{ range (where .Site.RegularPages "Section" "blog") }}
+ <div class="article">
+ <span class="date">{{.Date.Format "2006-01-02"}}
+ <a href="{{.Permalink}}">{{.Title}}</a></span>
+ </div>
+ {{ end }}
+ </div>
+ </section>
+</main>
diff --git a/layouts/partials/foot.html b/layouts/partials/foot.html
@@ -0,0 +1,4 @@
+<footer>
+ The content for the site is under <a href="/cc-by-4.0.txt">CC-BY-4.0</a>.
+ The code is under the <a href="/bsd_license.txt">2-Clause BSD License</a> unless specified otherwise.
+</footer>
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ {{ if $.Params.noindex }}
+ <meta name="robots" content="noindex">
+ {{ end }}
+ <title>{{$.Title}}</title>
+ <link rel="alternate" type="application/rss+xml" title="RSS" href="https://vineetk.net/blog/index.xml">
+ <link rel="icon" type="image/png" href="/AT_terminus.png">
+ {{ $style := resources.Get "main.scss" | css.Sass | resources.Fingerprint }}
+ <link rel="stylesheet" href="{{ $style.RelPermalink }}">
+</head>
diff --git a/static/AT_terminus.png b/static/AT_terminus.png
Binary files differ.
diff --git a/static/bsd_license.txt b/static/bsd_license.txt
@@ -0,0 +1,24 @@
+BSD 2-Clause License
+
+Copyright (c) 2024, Vineet Kumar
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/static/cc-by-4.0.txt b/static/cc-by-4.0.txt
@@ -0,0 +1,395 @@
+Attribution 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+ Considerations for licensors: Our public licenses are
+ intended for use by those authorized to give the public
+ permission to use material in ways otherwise restricted by
+ copyright and certain other rights. Our licenses are
+ irrevocable. Licensors should read and understand the terms
+ and conditions of the license they choose before applying it.
+ Licensors should also secure all rights necessary before
+ applying our licenses so that the public can reuse the
+ material as expected. Licensors should clearly mark any
+ material not subject to the license. This includes other CC-
+ licensed material, or material used under an exception or
+ limitation to copyright. More considerations for licensors:
+ wiki.creativecommons.org/Considerations_for_licensors
+
+ Considerations for the public: By using one of our public
+ licenses, a licensor grants the public permission to use the
+ licensed material under specified terms and conditions. If
+ the licensor's permission is not necessary for any reason--for
+ example, because of any applicable exception or limitation to
+ copyright--then that use is not regulated by the license. Our
+ licenses grant only permissions under copyright and certain
+ other rights that a licensor has authority to grant. Use of
+ the licensed material may still be restricted for other
+ reasons, including because others have copyright or other
+ rights in the material. A licensor may make special requests,
+ such as asking that all changes be marked or described.
+ Although not required by our licenses, you are encouraged to
+ respect those requests where reasonable. More considerations
+ for the public:
+ wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution 4.0 International Public License ("Public License"). To the
+extent this Public License may be interpreted as a contract, You are
+granted the Licensed Rights in consideration of Your acceptance of
+these terms and conditions, and the Licensor grants You such rights in
+consideration of benefits the Licensor receives from making the
+Licensed Material available under these terms and conditions.
+
+
+Section 1 -- Definitions.
+
+ a. Adapted Material means material subject to Copyright and Similar
+ Rights that is derived from or based upon the Licensed Material
+ and in which the Licensed Material is translated, altered,
+ arranged, transformed, or otherwise modified in a manner requiring
+ permission under the Copyright and Similar Rights held by the
+ Licensor. For purposes of this Public License, where the Licensed
+ Material is a musical work, performance, or sound recording,
+ Adapted Material is always produced where the Licensed Material is
+ synched in timed relation with a moving image.
+
+ b. Adapter's License means the license You apply to Your Copyright
+ and Similar Rights in Your contributions to Adapted Material in
+ accordance with the terms and conditions of this Public License.
+
+ c. Copyright and Similar Rights means copyright and/or similar rights
+ closely related to copyright including, without limitation,
+ performance, broadcast, sound recording, and Sui Generis Database
+ Rights, without regard to how the rights are labeled or
+ categorized. For purposes of this Public License, the rights
+ specified in Section 2(b)(1)-(2) are not Copyright and Similar
+ Rights.
+
+ d. Effective Technological Measures means those measures that, in the
+ absence of proper authority, may not be circumvented under laws
+ fulfilling obligations under Article 11 of the WIPO Copyright
+ Treaty adopted on December 20, 1996, and/or similar international
+ agreements.
+
+ e. Exceptions and Limitations means fair use, fair dealing, and/or
+ any other exception or limitation to Copyright and Similar Rights
+ that applies to Your use of the Licensed Material.
+
+ f. Licensed Material means the artistic or literary work, database,
+ or other material to which the Licensor applied this Public
+ License.
+
+ g. Licensed Rights means the rights granted to You subject to the
+ terms and conditions of this Public License, which are limited to
+ all Copyright and Similar Rights that apply to Your use of the
+ Licensed Material and that the Licensor has authority to license.
+
+ h. Licensor means the individual(s) or entity(ies) granting rights
+ under this Public License.
+
+ i. Share means to provide material to the public by any means or
+ process that requires permission under the Licensed Rights, such
+ as reproduction, public display, public performance, distribution,
+ dissemination, communication, or importation, and to make material
+ available to the public including in ways that members of the
+ public may access the material from a place and at a time
+ individually chosen by them.
+
+ j. Sui Generis Database Rights means rights other than copyright
+ resulting from Directive 96/9/EC of the European Parliament and of
+ the Council of 11 March 1996 on the legal protection of databases,
+ as amended and/or succeeded, as well as other essentially
+ equivalent rights anywhere in the world.
+
+ k. You means the individual or entity exercising the Licensed Rights
+ under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+ a. License grant.
+
+ 1. Subject to the terms and conditions of this Public License,
+ the Licensor hereby grants You a worldwide, royalty-free,
+ non-sublicensable, non-exclusive, irrevocable license to
+ exercise the Licensed Rights in the Licensed Material to:
+
+ a. reproduce and Share the Licensed Material, in whole or
+ in part; and
+
+ b. produce, reproduce, and Share Adapted Material.
+
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
+ Exceptions and Limitations apply to Your use, this Public
+ License does not apply, and You do not need to comply with
+ its terms and conditions.
+
+ 3. Term. The term of this Public License is specified in Section
+ 6(a).
+
+ 4. Media and formats; technical modifications allowed. The
+ Licensor authorizes You to exercise the Licensed Rights in
+ all media and formats whether now known or hereafter created,
+ and to make technical modifications necessary to do so. The
+ Licensor waives and/or agrees not to assert any right or
+ authority to forbid You from making technical modifications
+ necessary to exercise the Licensed Rights, including
+ technical modifications necessary to circumvent Effective
+ Technological Measures. For purposes of this Public License,
+ simply making modifications authorized by this Section 2(a)
+ (4) never produces Adapted Material.
+
+ 5. Downstream recipients.
+
+ a. Offer from the Licensor -- Licensed Material. Every
+ recipient of the Licensed Material automatically
+ receives an offer from the Licensor to exercise the
+ Licensed Rights under the terms and conditions of this
+ Public License.
+
+ b. No downstream restrictions. You may not offer or impose
+ any additional or different terms or conditions on, or
+ apply any Effective Technological Measures to, the
+ Licensed Material if doing so restricts exercise of the
+ Licensed Rights by any recipient of the Licensed
+ Material.
+
+ 6. No endorsement. Nothing in this Public License constitutes or
+ may be construed as permission to assert or imply that You
+ are, or that Your use of the Licensed Material is, connected
+ with, or sponsored, endorsed, or granted official status by,
+ the Licensor or others designated to receive attribution as
+ provided in Section 3(a)(1)(A)(i).
+
+ b. Other rights.
+
+ 1. Moral rights, such as the right of integrity, are not
+ licensed under this Public License, nor are publicity,
+ privacy, and/or other similar personality rights; however, to
+ the extent possible, the Licensor waives and/or agrees not to
+ assert any such rights held by the Licensor to the limited
+ extent necessary to allow You to exercise the Licensed
+ Rights, but not otherwise.
+
+ 2. Patent and trademark rights are not licensed under this
+ Public License.
+
+ 3. To the extent possible, the Licensor waives any right to
+ collect royalties from You for the exercise of the Licensed
+ Rights, whether directly or through a collecting society
+ under any voluntary or waivable statutory or compulsory
+ licensing scheme. In all other cases the Licensor expressly
+ reserves any right to collect such royalties.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+ a. Attribution.
+
+ 1. If You Share the Licensed Material (including in modified
+ form), You must:
+
+ a. retain the following if it is supplied by the Licensor
+ with the Licensed Material:
+
+ i. identification of the creator(s) of the Licensed
+ Material and any others designated to receive
+ attribution, in any reasonable manner requested by
+ the Licensor (including by pseudonym if
+ designated);
+
+ ii. a copyright notice;
+
+ iii. a notice that refers to this Public License;
+
+ iv. a notice that refers to the disclaimer of
+ warranties;
+
+ v. a URI or hyperlink to the Licensed Material to the
+ extent reasonably practicable;
+
+ b. indicate if You modified the Licensed Material and
+ retain an indication of any previous modifications; and
+
+ c. indicate the Licensed Material is licensed under this
+ Public License, and include the text of, or the URI or
+ hyperlink to, this Public License.
+
+ 2. You may satisfy the conditions in Section 3(a)(1) in any
+ reasonable manner based on the medium, means, and context in
+ which You Share the Licensed Material. For example, it may be
+ reasonable to satisfy the conditions by providing a URI or
+ hyperlink to a resource that includes the required
+ information.
+
+ 3. If requested by the Licensor, You must remove any of the
+ information required by Section 3(a)(1)(A) to the extent
+ reasonably practicable.
+
+ 4. If You Share Adapted Material You produce, the Adapter's
+ License You apply must not prevent recipients of the Adapted
+ Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+ a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+ to extract, reuse, reproduce, and Share all or a substantial
+ portion of the contents of the database;
+
+ b. if You include all or a substantial portion of the database
+ contents in a database in which You have Sui Generis Database
+ Rights, then the database in which You have Sui Generis Database
+ Rights (but not its individual contents) is Adapted Material; and
+
+ c. You must comply with the conditions in Section 3(a) if You Share
+ all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+ a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+ EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+ AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+ ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+ IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+ WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+ ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+ KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+ ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+ b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+ TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+ NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+ INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+ COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+ USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+ DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+ IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+ c. The disclaimer of warranties and limitation of liability provided
+ above shall be interpreted in a manner that, to the extent
+ possible, most closely approximates an absolute disclaimer and
+ waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+ a. This Public License applies for the term of the Copyright and
+ Similar Rights licensed here. However, if You fail to comply with
+ this Public License, then Your rights under this Public License
+ terminate automatically.
+
+ b. Where Your right to use the Licensed Material has terminated under
+ Section 6(a), it reinstates:
+
+ 1. automatically as of the date the violation is cured, provided
+ it is cured within 30 days of Your discovery of the
+ violation; or
+
+ 2. upon express reinstatement by the Licensor.
+
+ For the avoidance of doubt, this Section 6(b) does not affect any
+ right the Licensor may have to seek remedies for Your violations
+ of this Public License.
+
+ c. For the avoidance of doubt, the Licensor may also offer the
+ Licensed Material under separate terms or conditions or stop
+ distributing the Licensed Material at any time; however, doing so
+ will not terminate this Public License.
+
+ d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+ License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+ a. The Licensor shall not be bound by any additional or different
+ terms or conditions communicated by You unless expressly agreed.
+
+ b. Any arrangements, understandings, or agreements regarding the
+ Licensed Material not stated herein are separate from and
+ independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+ a. For the avoidance of doubt, this Public License does not, and
+ shall not be interpreted to, reduce, limit, restrict, or impose
+ conditions on any use of the Licensed Material that could lawfully
+ be made without permission under this Public License.
+
+ b. To the extent possible, if any provision of this Public License is
+ deemed unenforceable, it shall be automatically reformed to the
+ minimum extent necessary to make it enforceable. If the provision
+ cannot be reformed, it shall be severed from this Public License
+ without affecting the enforceability of the remaining terms and
+ conditions.
+
+ c. No term or condition of this Public License will be waived and no
+ failure to comply consented to unless expressly agreed to by the
+ Licensor.
+
+ d. Nothing in this Public License constitutes or may be interpreted
+ as a limitation upon, or waiver of, any privileges and immunities
+ that apply to the Licensor or You, including from the legal
+ processes of any jurisdiction or authority.
+
+
+=======================================================================
+
+Creative Commons is not a party to its public
+licenses. Notwithstanding, Creative Commons may elect to apply one of
+its public licenses to material it publishes and in those instances
+will be considered the “Licensor.” The text of the Creative Commons
+public licenses is dedicated to the public domain under the CC0 Public
+Domain Dedication. Except for the limited purpose of indicating that
+material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the
+public licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/update.sh b/update.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+hugo
+#rsync --exclude="update.sh" --delete -ash . vineetk.net:/usr/local/www/vineetk_html/
+rsync --exclude="update.sh" --delete -ash public/ 10.0.13.1:/var/www/vineetk_html/