diff --git a/content/posts/0001-immutable-vars-vs-constants-rs.md b/content/posts/0001-immutable-vars-vs-constants-rs.md new file mode 100644 index 0000000..beaec32 --- /dev/null +++ b/content/posts/0001-immutable-vars-vs-constants-rs.md @@ -0,0 +1,337 @@ ++++ +draft = false +date = 2022-10-06T10:30:00+05:30 +title = "Dfferences between Constants and Variables in Rust" +description = "No really, why do constants exist among \"immutable\" variables?" +slug = "immutable-vars-vs-constants-rs.md" +tags = [ "rust", "educational" ] ++++ + +The reason why the Rust language's developers can advertise features like +_thread safety_ and _memory safety guarantee_ is because of a fundamental +design ideology of immutable variables. Immutable variables are the type of +variables where, once you assign a value, it does not change. + +Rust also has constants. So you might wonder "Why does Rust have Immutable +variables _and_ Constants? Aren't they the same thing?" + +In this blog post, I will explain the basics of variables and constants +in Rust, and how an immutable variable differs from a mutable variable. + +## Immutable variables VS Constants + +If, like me, Rust is not your first programming language, this confusion is +bound to occur sooner rather than later--"Why do either immutable variables +or constants exist in Rust?" + +If you have written a simple program in Rust, you will realize that Rust has +2 types of variables. One is the type which allows changing a value, even +after it is assigned, called _mutable variables_. The second type is the one +in question, immutable variables. Unless explicitly specified, Rust assumes +a variable is immutable. Meaning, once a value is assigned to your variable, +that value will never be allowed to be changed. + +Rust only has one type for constants. The one which makes sense. Immutable by +default. Once a value is assigned, it is not allowed to change. + +## Type inferencing + +When you declare a variable in Rust, you do it using the `let` keyword. This +is different than other low-level languages like C and C++, where you are to +explicitly specify the data-type of a variable using the appropriate keyword +like, `int`, `float`, `char`, etc. + +Using the `let` keyword is necessary, but specifying a variable's data-type +is not necessary. You can either leave it to the Rust compiler (`rustc`) to +take a guess--which hardly misfires--or you can annotate the type yourself. + +This guessing that `rustc` does is called "type inferencing". + +Type inferencing is absent for constants. It is the job of a programmer to +provide a type for a constant that is declared. + +Take a look at the following code: + +Filename: const_example.rs + +```rust +fn main() { + let my_var = -128; + const MY_CONST = -128; +} +``` + +In here, I am declaring an immutable variable (`my_var`) with the value "-128" +and a constant (`MY_CONST`) with the same value of "-128". Another similarity +is that neither of them are type annotated. + +Let's try and compile this. + +```bash +$ rustc const_example.rs +error: missing type for `const` item + --> const_example.rs:3:11 + | +3 | const MY_CONST = -128; + | ^^^^^^^^ help: provide a type for the constant: `MY_CONST: i32` + +error: aborting due to previous error +``` + +Hmm... + +`rustc` is complaining about an error on line 3 (where we declared our +constant). The highlighted part is the name (`MY_CONST`). + +The help states "provide a type for the constant". The help message also +included a "recommended/suggested type" (`i32`) but it was not applied. + +Hence, one of the difference between an immutable variable and a constant in +Rust is that constants **need** type annotation. Type inferencing is **not** +applicable to constants. + +## Scope of declaration + +Another point of difference between an immutable variable and a constant in +Rust is its scope of declaration. + +Constants can be declared globally (before/outside the `main` function). +Variables, immutable or otherwise, cannot be declared globally. + +Let's see this with an example. + +Filename: const_example.rs + +```rust +const MY_CONST:i32 = -128; +let my_var: i32 = -128; + +fn main() { + println!("{my_var} {MY_CONST}"); +} +``` + +As you can see here, I have mostly the same code as above, but I have moved +both, the variable and the constant declaration, in the global scope. + +'tis compile time! + +```bash +$ rustc const_example.rs +error: expected item, found keyword `let` + --> const_example.rs:2:1 + | +2 | let my_var: i32 = -128; + | ^^^ expected item + +error: aborting due to previous error +``` + +An error :( + +The way I wrote the code should give you a hint. We have an error on the +2nd line. Our constant is declared on the 1st line. + +This means, `rustc` did not see any problems with a constant in the global +scope. But it does have a problem with our immutable variable if it is +declared in the global scope. + +## Assignable values + +Another major difference between variables (immutable or otherwise) and +constants in Rust is that a constant **cannot** have a value that can be +calculated **only at run-time**. + +What do I mean by this? + +Take a look at the following code: + +Filename: const_example.rs + +```rust +cat const_example.rs +fn main() { + let pi: f32 = 3.14; + const PI_TIMES_TWO: f32 = pi * 2; +} +``` + +In this code, I am declaring an immutable variable (`pi`) and assigning it the +value of "3.14". Next, I declare a constant, with the same type as `pi`, +and I assign it the value of `pi * 2`. + +Shall we compile? + +```bash +$ rustc const_example.rs +error[E0435]: attempt to use a non-constant value in a constant + --> const_example.rs:3:31 + | +3 | const PI_TIMES_TWO: f32 = pi * 2; + | ------------------ ^^ non-constant value + | | + | help: consider using `let` instead of `const`: `let PI_TIMES_TWO` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0435`. +``` + +As you can see, even though `pi` is an immutable variable, we get this error. +This is because `PI_TIMES_TWO` is dependent on the value stored in `pi` +to determine its own value. This is problematic because the values of +variables are **not** evaluated at compile-time. + +The value assigned to a constant **must not** be calculated/evaluated at +_run-time_. + +## Compile-time vs Run-time + +As I just proved, constants can not be assigned a value that will be +calculated at run-time. That must raise a question if the core reason for the +existence of immutable variables and constants must be related to the +differences in run-time and compile-time. + +While I am **not** someone who has contributed to the design of the Rust +language, I am inclined to assume that this might be the reason. + +You can use the value assigned to a constant during compile-time, to make +decisions _while_ the code is being compiled. This can not be done using +variables, immutable or otherwise. + +Let me demonstrate this using an example. + +Filename: const_example.rs + +```rust +fn main() { + let arr_len_var: usize = 5; + const ARR_LEN_CONST: usize = 5; + + let arr_from_const: [i32; ARR_LEN_CONST]; + let arr_from_var: [i32; arr_len_var]; +} +``` + +In this example, I am doing the following: + + 1. Declare an immutable variable with the value "5". + 2. Declare a constant with the value "5". + 3. Create an empty array, using the value of an immutable variable as the + "array size/length". + 4. Create another empty array, using the value of a constant as the "array + size/length" + +If, the jibberish that I just wrote above is correct, we should expect a +compilation error on the 6th line. + +```bash +$ rustc const_example.rs +error[E0435]: attempt to use a non-constant value in a constant + --> const_example.rs:6:29 + | +2 | let arr_len_var: usize = 5; + | --------------- help: consider using `const` instead of `let`: `const arr_len_var` +... +6 | let arr_from_var: [i32; arr_len_var]; + | ^^^^^^^^^^^ non-constant value + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0435`. +``` + +As expected. + +`rustc` has 2 messages for us. The first message--after looking at the +6th line--is a suggestion for us; to change `arr_len_var` from +a variable to a constant. + +The second message is an error message. It is complaining that the value +which determines the length of an array, is a "non-constant value". + +"But I thought the values of immutable variables could never change?! Does +that not equate to a _non-constant value_?" + +You are correct, but this is something different. You see--this is where I am +applying my knowledge of what I learnt about compiler design from my +college--constants are also _evaluated_ at compile-time. + +This means, the following line - + +```rust + const PI: f32 = 3.14; + println!("{PI}"); +``` + +gets replaced with the following in the first few passes of the Rust compiler. + +```rust + const PI: f32 = 3.14; + println!("3.14"); +``` + +The constant got evaluated (expanded), at compile-time. This will not be be +the case for a variable, immutable or otherwise. + +This is also what happens when we use a constant to determine the length/size +of an array. + +## Shadows + +You might know about shadowing in Rust. It refers to the act of referring +to a different storage/address using the same name. + +Below is an example of shadowing: + +```rust +let five = 5; +let five = 6; +``` + +Here, on the first line, we are declaring an immutable variable `five`. It +assigned the value "5". In the immediate next line, we declare the variable +`five` again. This time, we assign it "6". + +What this does is, when `five` was first declared and assigned the value "5", +it was given a memory address to store that "5" which we assigned to it. +Assume this memory address to be `0x01`. + +Then, when we declared `five` again; this time with a different value, "6"; +a different memory address was given to our variable `five`. This, new memory +address stored the value "6". Assume this memory address to be `0x02`. + +Now, the older memory address (`0x01`) is not overwritten with "6", instead of +"5". It is still kept--maybe because this shadow was a local change and we +will need the previous value again? who knows--intact. But now, when we ask, +"Hey `five`, what is your assigned value?", it will check the memory location +`0x02` and give us a value from there; which is "6". + +This isn't possible for constants. + + - You can not shadow a constant with a constant (of any type). + - You can not shadow a constant with a variable (of any type). + - You can not shadow a variable with a constant (of any type). + +## Minor nit-picks + +A few minor differences between a constant and an immutable variable are as +follows: + + - Variables are immutable by default, but they can also be mutable, if + asked nicely. On the contrary, constants are _always_ immutable. (You cannot + use the keyword `mut` next to the `const` keyword.) + - To declare a constant, we use the `const` keyword, but to declare an + immutable variable, we use the `let` keyword. A variable can be made + immutable if, at the time of declaration, the `mut` keyword is used alongside + the `let` keyword. + +## Conclusion + +The intelligent mind who were designing the Rust language were obviously not +out of their minds when they created variables that default to immutability +when constants would also exist. + +To recap, constants need type annotations, but they can be declared in the +global scope; values assigned to constants cannot be something that is +calculated at run-time and they can not be shadowed. diff --git a/content/posts/0002-convert-mutable-var-to-immutable-rs.md b/content/posts/0002-convert-mutable-var-to-immutable-rs.md new file mode 100644 index 0000000..1b210c6 --- /dev/null +++ b/content/posts/0002-convert-mutable-var-to-immutable-rs.md @@ -0,0 +1,83 @@ ++++ +draft = false +date = 2022-10-09T10:30:00+05:30 +title = "Convert a mutable variable to immutable in Rust" +description = "Fore_shadowing_" +slug = "convert-mutable-var-to-immutable-rs.md" +tags = [ "rust", "educational" ] ++++ + +The immutability of Rust's variables is a curse and a boon. It is a life saver +when you are dealing with multi-threaded code. A curse when you want to modify +the value. + +So what do you do now? You add a `mut` after the `let` and make it mutable. +Some time down the line (haha, get it?), you realize that you need the +immutability. How do you turn a mutable variable into an immutable variable? + +## Shadow it + +Most of the times, the solution you are looking for is to shadow the mutable +variable with the immutable variable. + +Take the following code snippet for example: + +File: test.rs + +```rust +fn main() { + let mut x = 1; + x = x + 1; + println!("{x}"); + let x = x; + x = x + 3; +} +``` + +And, compiling... + +```bash +$ rustc test.rs +error[E0384]: cannot assign twice to immutable variable `x` + --> test.rs:6:5 + | +5 | let x = x; + | - + | | + | first assignment to `x` + | help: consider making this binding mutable: `mut x` +6 | x = x + 3; + | ^^^^^^^^^ cannot assign twice to immutable variable + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0384`. +``` + +(The unused variable warning from `rustc` is snipped.) + +`rustc` is complaining that on line 6, column 5 of "test.rs", it is referring +to `x` as immutable. + +But didn't we declare `x` as `mut` on line 2? Yes, we did. + +Now, check the 5th line. There I assigned `x` to itself, making use +of Rust's _shadowing_ feature. The name `x` is now pointing to a different +storage that is immutable, but has the value of `&mut x` assigned to it. + +{{< notice info >}} +Please note that in the above explanation, I only use "`&mut x`" to demonstrate +that the _value_ of mutable variable `x` gets copied. This does not mean that +the new `x` will point to `&mut x`. +{{< /notice >}} + +## Conclusion + +To turn an existing mutable variable into an immutable variable (that Rust +provides a thread-safe guarantee for), you can shadow the existing mutable +variable with a new immutable variable. + +```rust +let mut foo; // foo is mutable +let foo = foo; // foo shadows [mutable foo] and is now immutable +``` diff --git a/content/posts/0003-visionfive-2-initial-review.md b/content/posts/0003-visionfive-2-initial-review.md new file mode 100644 index 0000000..f7df745 --- /dev/null +++ b/content/posts/0003-visionfive-2-initial-review.md @@ -0,0 +1,322 @@ ++++ +draft = false +date = 2023-02-22T12:36:00+05:30 +title = "Hands on and initial review of the VisionFive 2" +description = "So RISC-V is a thing, huh." +slug = "visionfive-2-initial-review.md" +tags = [ "riscv" ] ++++ + +Since a long time, RISC-V was in my news feed. I have no idea about RISC-V +other than that it is an open source ISA (not implementation). That made me +curious and I wanted to get something RISC-y to understand the hype first-hand. + +In August of 2022, I came across the Kickstarter announcement from StarFive +([here](https://www.kickstarter.com/projects/starfive/visionfive-2)) about the +VisionFive 2. Following hardware features peaked my interest the *most*: + + - Dual Gigabit Ethernet ports (some _Super early bird_ models have 1x 1000M + and 1x 100M ports) + - Presence of QSPI flash for `u-boot` + - The SBC was available with 8 GB of RAM (that is the minimum for me) + +The VisionFive 2 also has one M.2 slot for an NVMe (2280) drive, but it doesn't +interest me as much. Particularly because it only has the bandwidth of **1x +PCIe 2.0** lane. Also because I can not afford a _"good"_ NVMe drive at the +moment. + +I don't want to put in a cheap NVMe drive because the cheap ones usually omit +DRAM. That isn't a problem on a moderately fast computer. But on a computer +whose CPU (SiFive U74) [allegedly] performs similarly to an ARM A55 core, said +latency hit is more noticeable. + +{{< notice info >}} +On the note of NVMe, the one thing missing from the hardware perspective is +the screw to hold the NVMe drive itself. +{{}} + + +# Initial software setup + +_For now, one is expected to form their opinions on hardware performance based +on the [Debian image provided the vendor](https://debian.starfivetech.com/)._ + +**Before you flash the image provided by the vendor, the board firmware +_needs_ to be updated. Please do that first.** + + +## Updating firmware + +The firmware can be easily updated by following these steps: + + 1. Download 3 assets from VisionFive 2's + [latest SDK release](https://github.com/starfive-tech/VisionFive2/releases/latest): + `sdcard.img`, `u-boot-spl.bin.normal.out`, `visionfive2_fw_payload.img` + 2. `sudo dd if=sdcard.img conv=sync status=progress bs=1M of=/dev/` + 3. `mkdir temp-dir` + 4. `sudo mount /dev/4 temp-dir` + 5. `sudo cp u-boot-spl.bin.normal.out visionfive2_fw_payload.img temp-dir/root/` + 6. `sudo umount /dev/4` + 7. Eject the SD Card from your computer, insert it in VisionFive 2 and power + it up. The green LED should start blinking. + 8. Plug the network cable on the Ethernet port that is next to the HDMI port. + 9. `ssh root@` (passwd: `starfive`) + 10. Run the command `cat /proc/mtd` and you should have the following output: + ``` + dev: size erasesize name + mtd0: 00020000 00001000 "spl" + mtd1: 00300000 00001000 "uboot" + mtd2: 00100000 00001000 "data" + ``` + 11. If the partition information is correct, update the `spl` and `uboot` + firmware using the following commands: + ``` + flashcp -v u-boot-spl.bin.normal.out /dev/mtd0 + flashcp -v visionfive2_fw_payload.img /dev/mtd1 + ``` + +Done! Now `systemctl poweroff` and flash the vendor's Debian image to your SD +card and boot it up. + + +## Setup with vendor's image + +Although the SD Card image provided by the vendor worked fine for me, people +have reported two major things missing from their kernel. The modules for +BTRFS are not built and IPv6 isn't supported either. We will compile the +kernel soon, but there are other problems with the image that need to be +tackled first. + + +### Manually expand the root partition + +Unlike most images available for the Raspberry Pi, this image does not +automatically expand the root partition. So first, resize your `/` partition +using `parted`: + +```bash +root@starfive:~# parted /dev/mmcblk1 +GNU Parted 3.5 +Using /dev/mmcblk1 +Welcome to GNU Parted! Type 'help' to view a list of commands. +(parted) resizepart 3 100% +Warning: Partition /dev/mmcblk1p3 is being used. Are you sure you want to +continue? +Yes/No? Y +(parted) q +Information: You may need to update /etc/fstab. +``` + +Resize the filesystem using `resize2fs`: + +```bash +root@starfive:~# resize2fs /dev/mmcblk1p3 +resize2fs 1.46.5 (30-Dec-2021) +Filesystem at /d[ 192.744328] EXT4-fs (mmcblk1p3): resizing filesystem from 1280507 to +31186944 blocks +ev/mmcblk1p3 is mounted on /; on-line resizing required +old_desc_blocks = 1, new_desc_blocks = 15 +[ 196.934822] EXT4-fs (mmcblk1p3): resized filesystem to 31186944 +The filesystem on /dev/mmcblk1p3 is now 31186944 (4k) blocks long. +``` + +Verify the change using the 'df' command. Best reboot now to prevent any +soft-errors. + + +### Update Debian keyring + +To run `apt update` without any errors, the Debian keyring needs to be updated. +This can be easily remedied by manually downloading the `.deb` file for the +Debian keyring package from [here](https://packages.debian.org/sid/all/debian-ports-archive-keyring/download) (don't worry, it is architecture agnostic). + +Choose your nearest mirror and download it. Then, like any other package, do a +`dpkg -i debian-ports-archive-keyring*.deb`. + +Now, you can `apt update` flawlessly :wink: + + +### OPTIONAL: Update APT sources + +**Please note that there is a reason why the APT sources point to a snapshot. +That is because it is a "known good" state of the packages. I am not +accountable if your system breaks. I am not a sysadmin.** + +But this is what I have done to make sure that I stay up-to-date with any +developments in the ecosystem. + +```bash +root@starfive:~# cat < /etc/apt/sources.list +deb http://deb.debian.org/debian-ports sid main +deb http://deb.debian.org/debian-ports unreleased main +deb-src http://deb.debian.org/debian sid main +EOF + +root@starfive:~# apt update +``` + + +### MISC + +Better do some housekeeping now... + +```bash +root@starfive:~# passwd # use a strong password +root@starfive:~# userdel -r user +root@starfive:~# useradd -m -G -s /bin/bash +root@starfive:~# visudo # I enabled 'NOPASSWD' for my user +``` + + +# Software status of the VisionFive 2 + +Other than the minor inconvenience of updating the board firmware, setting +up the vendor's Debian image, everything else seems to mostly work for me. + +As new as this SBC is, there already are 5 total offerings for compatible +images. + + 1. The vendor provided [Debian Sid image](https://debian.starfivetech.com) + 2. An "experimental" [Debian Sid image](https://forum.rvspace.org/t/experimental-debian-sid-image/1517) + 3. An [Arch Linux image](https://forum.rvspace.org/t/arch-linux-image-for-visionfive-2/1459) + 4. [Build your own Debian images](https://forum.rvspace.org/t/build-your-own-debain-images/1881) + 5. A community image of [OpenSUSE Tumbleweed](https://en.opensuse.org/HCL:VisionFive2) + +The OpenSUSE image, at the time of writing this, _seems_ to be using the latest +Linux kernel that is available (6.2-rc8) and adding StarFive's patches that are +for the VisionFive 2. Every other image listed above is using the [StarFive 5.15.0 kernel](https://github.com/starfive-tech/linux/tree/JH7110_VisionFive2_devel). + +I have tested images #1, #2 and #3 and I can confirm that the following things +are working as **_I_** expected: + + - The hardware reset switch works + - The GPIO pins work[^1] (along with UART) + - Both of the Gigabit Ethernet ports on my board work at the max speed[^2] + - All 4 of the front USB 3.0 ports work (didn’t test speed) + - HDMI port works[^3] + +[^1]: I haven't tested _all the pins_. I used pins 4, 6, 8, 10, and 14. These +work without any issue so I assume all 40 pins work as intended. + +[^2]: You can get 948-ish MBit/s of throughput from each port, which lines up +with real world performance of other Gigabit NICs. But, sending traffic in from +one port and receiving it from another port is limited to 500-ish MBit/s of +throughput due to the way the PHYs are wired ("multiplexed"). + +[^3]: I don't have a use for display out (on the VF2). I only plugged it in and +booted the SBC up. For what it is worth, the boot logs show up when connected +to my 2160p monitor. **No further graphics testing was performed**, since that +is not my primary aim with this SBC. + +{{< notice info >}} +No offence, but I won't be trying out the OpenSUSE image anytime soon. I +despise camel case in a _package manager_ of all things. Firefox is called +`MozillaFirefox`. **WHY?!** +{{}} + +I am daily driving cwt's Arch Linux image. The kernel in this image is the +vendor's 5.15.0 Linux kernel. This kernel was compiled to enable the support +for IPv6 and BTRFS. + +The only modification that I had to perform was to add the following line to +the `/etc/pacman.conf` file: + +``` +IgnorePkg = linux-api-headers +``` + +I had to do this because the Linux kernel installed is the vendor's 5.15.0 +kernel and the version of the `linux-api-headers` package is `6.1.9`. + +{{< notice warning >}} +This image has an issue with **_rebooting_**. When you try to reboot, the board +just shuts down. Though, I am looking into fixing this issue. +{{}} + +--- + +People on the RVSpace forum reported that the XU4 fan by Hardkernel fits on +their board ([buy here](https://www.hardkernel.com/shop/cooling-fan-xu4-blue/)). +So I ordered one. **The fan header on the fan and on the board are +incompatible.** So I removed the connector from the fan and soldered the wires +to the jumper wires and inserted it into my GPIO pins. It works now :smile: + +With the fan on, and compiling the StarFive's Linux tree for the VisionFive 2 +using `make all -j4`, I never saw the temps go above 42 C. This is quite an +achievement because I am in India (it's very hot here) and in a room that is +without an AC. + +![btop running on VisionFive 2](/static/images/visionfive_2_review_btop_screenshot.png) + +The compilation of StarFive's VisionFive 2 Linux kernel tree using the +following command completed in 2 hours and 15 minutes. That's _really quick_ +for such a machine! + +```bash +make clean +make mrproper +make starfive_visionfive2_defconfig +ARCH=riscv CFLAGS="-march=rv64imafdc_zicsr_zba_zbb -mcpu=sifive-u74 -mtune=sifive-7-series -O2 -pipe" make all -j4 +``` + +{{< notice warning >}} +You will need to patch the file `arch/riscv/Makefile` to compile the kernel +successfully. Here is the [patch](https://github.com/hexdump0815/linux-starfive-visionfive2-kernel/blob/main/misc.vf2/patches/make-newer-binutils-work.patch). +{{}} + + +# My thoughts so far + +Since the RISC-V ISA is pretty new, there are still some packages that have +not been ported yet. As a Neovim user, the biggest hit I received was when +I noticed that RISC-V support from **upstream** LuaJIT is missing. Though, that +is [being worked on](https://github.com/LuaJIT/LuaJIT/issues/628). + +The Arch Linux maintainer [felixonmars](https://github.com/felixonmars)--who is +also porting a lot of packages to RISC-V--has made the Neovim package depend on +`lua51` instead of `luajit` ([relevant git commit](https://github.com/felixonmars/archriscv-packages/commit/7b7f04a28cbe6a04f663a14c914ba4d63b081ede)). +Neovim wouldn't even install on Debian due to the missing dependency of LuaJIT, +but on Arch Linux, I can at least install and use Neovim, albeit without the +traditional Lua support. + +I have installed the packages that I have listed below. I haven't tested _all_ +of them, but of what I did test, they work as I expect them to do on my +Raspbery Pi or on my x86 computer. + +``` +android-tools arch-install-scripts aria2 bandwhich base base-devel bat btop cargo-audit cargo-auditable cargo-bloat cargo-depgraph cargo-outdated cargo-spellcheck cargo-watch choose chrony cifs-utils dhcpcd dog dua-cli dust exa fd figlet firewalld gcc git git-lfs groff hd-idle hdparm htop iotop iperf iperf3 linux-firmware lsb-release lsof man-db man-pages mkinitcpio mlocate namcap nano neofetch neovim networkmanager nfs-utils nload nvme-cli opendoas openssh parted paru ripgrep rsync rustup skim smartmontools sudo tealdeer tmux tre tree unrar unzip usbutils wget which wireguard-tools wireless-regdb wol xmlto yt-dlp zsh zsh-autosuggestions zsh-completions zsh-syntax-highlighting +``` + +{{< notice note >}} +**My current workflow does not involve making use of the iGPU in any capacity +whatsoever.** Hence I will not make any _personal comments_ on it yet. But, +people have reported some issues with the display output when the SBC is +connected to a 2160p monitor. On the first day, when I couldn't find my UART +cable, I had to rely on the display output of the board. So I connected the +HDMI port to my **2160p** monitor, and, for what it is worth, it at least +showed me the boot logs. Though, I did see a black screen instead of the login +manager. I haven't done any further testing in this area since. +{{< /notice >}} + +--- + +The state of hardware on the SBC seems good enough for my use: as a development +machine and to build software for RISC-V. + +StarFive is [upstreaming](https://rvspace.org/en/project/JH7110_Upstream_Plan) +software components. The only thing StarFive is not upstreaming is the GPU +drivers. That commitment is the responsibility of Imagination, as per their +[post](https://developer.imaginationtech.com/open-source-gpu-driver/). + +As of now, I have no gripes as the vendor is not withholding any patches; of +what is available, works, the vendor is making an effort to upstream as much as +they can. + +To repeat myself for the _nth_ time, of what packages are available, +they work as one might expect from a PC/laptop. Having such a low cost device +with minor issues, like the display output not working as intended at 2160p +resolution, (**in the context of a developer/porting machine**) is a _STEAL_! + +I am very happy with it and I will be using this to learn Linux kernel +development (using :crab:) and help port more ARM64/AMD64 software to it. Let +me know if you want Rocky Linux on this! :wink: diff --git a/static/images/visionfive_2_review_btop_screenshot.png b/static/images/visionfive_2_review_btop_screenshot.png new file mode 100644 index 0000000..2008827 Binary files /dev/null and b/static/images/visionfive_2_review_btop_screenshot.png differ