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