====== Samsung Chromebook Plus XE513C24 ====== {{ :chromebookplus.jpg?400 |}} === Developer Mode === * Turn off the laptop. * To invoke Recovery mode, you hold down the ESC and Refresh keys and poke the Power button. * At the Recovery screen press Ctrl-D (there's no prompt - you have to know to do it). * Confirm switching to developer mode by pressing enter, and the laptop will reboot and reset the system. This takes about 10-15 minutes. Note: After enabling developer mode, you will need to press Ctrl-D each time you boot, or wait 30 seconds to continue booting. === Enable booting from external storage === * After booting into developer mode, hold Ctrl and Alt and poke the T key. This will open up the crosh shell. * Type shell to get into a bash shell. * Type sudo -i to become root. (sudo su doesn't seem to be available and this is functionally the same) * Then type this to enable USB booting: crossystem dev_boot_usb=1 dev_boot_signed_only=0 * Reboot the system to allow the change to take effect. === First Attempt Gentoo SD Image === Note: I'm doing the build from my Orange Pi 800 with the same RK3399 so no cross compile environment is required. == Preparing SD Card == Install the required tools onto the build system: emerge --ask dev-embedded/u-boot-tools sys-apps/dtc sys-block/parted sys-boot/vboot-utils Partion the sd card. root #parted /dev/sdc mklabel gpt root #parted -a optimal /dev/sdc unit mib mkpart Kernel 1 65 root #parted -a optimal /dev/sdc unit mib mkpart Root 65 100% Depthcharge requires some specific parameters to be set. These signal the bootloader the presence of a valid kernel partition: root #cgpt add -i 1 -t kernel -S 1 -T 5 -P 15 /dev/sdc Create a filesystem on the root partition and mount it: root #mkfs.ext4 /dev/sdc2 root #mount /dev/sdc2 /mnt/sdcard Grabbed latest arm64 stage3 and extracted to /mnt/sdcard: [[https://distfiles.gentoo.org/releases/arm64/autobuilds/20240128T234815Z/stage3-arm64-openrc-20240128T234815Z.tar.xz]] Also grabbed the latest portage snapshot as it doesn't appear its in the stage 3 and extracted to /var/db/repos/gentoo: [[https://distfiles.gentoo.org/snapshots/portage-latest.tar.bz2]] I copied my make.conf from my Orange Pi 800 as they both have the same rk3399 SOC. # These settings were set by the catalyst build script that automatically # built this stage. # Please consult /usr/share/portage/config/make.conf.example for a more # detailed example. COMMON_FLAGS="-march=armv8-a+crc+crypto -mtune=cortex-a72.cortex-a53 -mfix-cortex-a53-835769 -mfix-cortex-a53-843419" CFLAGS="${COMMON_FLAGS}" CXXFLAGS="${COMMON_FLAGS}" FCFLAGS="${COMMON_FLAGS}" FFLAGS="${COMMON_FLAGS}" # WARNING: Changing your CHOST is not something that should be done lightly. # Please consult https://wiki.gentoo.org/wiki/Changing_the_CHOST_variable before changing. CHOST="aarch64-unknown-linux-gnu" # NOTE: This stage was built with the bindist Use flag enabled # This sets the language of build output to English. # Please keep this setting intact when reporting bugs. LC_MESSAGES=C.utf8 USE="-X gpm alsa -udev pulseaudio" ACCEPT_LICENSE="-* @FREE @BINARY-REDISTRIBUTABLE" LLVM_TARGETS="AArch64" VIDEO_CARDS="panfrost" == Getting ready to Chroot == Copy over resolv.conf: cp --dereference /etc/resolv.conf /mnt/sdcard/etc/ Setup binds: root #mount --types proc /proc /mnt/sdcard/proc root #mount --rbind /sys /mnt/sdcard/sys root #mount --make-rslave /mnt/sdcard/sys root #mount --rbind /dev /mnt/sdcard/dev root #mount --make-rslave /mnt/sdcard/dev root #mount --bind /run /mnt/sdcard/run root #mount --make-slave /mnt/sdcard/run Chroot in: root #chroot /mnt/sdcard /bin/bash root #source /etc/profile root #export PS1="(chroot) ${PS1}" == Get sources and configure kernel == emerge --ask gentoo-sources I stole the config from [[https://git.alpinelinux.org/aports/plain/testing/linux-gru/config]] I edited the config text and added the gentoo specific options required: < # Linux/arm64 6.6.2 Kernel Configuration --- > # Linux/arm64 6.6.13-gentoo Kernel Configuration 5c5 < CONFIG_CC_VERSION_TEXT="gcc (Alpine 13.2.1_git20231014) 13.2.1 20231014" --- > CONFIG_CC_VERSION_TEXT="gcc (Gentoo 13.2.1_p20240113-r1 p12) 13.2.1 20240113" 7294a7295,7312 > > # > # Gentoo Linux > # > CONFIG_GENTOO_LINUX=y > CONFIG_GENTOO_LINUX_UDEV=y > CONFIG_GENTOO_LINUX_PORTAGE=y > > # > # Support for init systems, system and service managers > # > CONFIG_GENTOO_LINUX_INIT_SCRIPT=y > # CONFIG_GENTOO_LINUX_INIT_SYSTEMD is not set > # end of Support for init systems, system and service managers > > # CONFIG_GENTOO_KERNEL_SELF_PROTECTION is not set > CONFIG_GENTOO_PRINT_FIRMWARE_INFO=y > # end of Gentoo Linux I manually applied both patch files found here: [[https://git.alpinelinux.org/aports/tree/testing/linux-gru/]] Compiling the kernel: make make dtbs Set the root password with passwd. Set the timezone: root #echo "America/Detroit" > /etc/timezone root #emerge --config sys-libs/timezone-data Setup locale: vim /etc/locale.gen locale-gen eselect locale list eselect locale set Install some system tools and firmware (required for wireless): emerge --ask linux-firmware wpa_supplicant dhcpcd syslog-ng cronie chrony e2fsprogs rc-update add dhcpcd default rc-update add syslog-ng default rc-update add cronie default rc-update add sshd default rc-update add chronyd default Configure hostname: echo "hostname" > /etc/hostname vim /etc/hosts 127.0.0.1 hostname.localdomain.lan hostname localhost ::1 hostname.localdomain.lan hostname localhost Set clock="local" if your hardware clock is localtime Setup a normal user: useradd -m -G users,wheel,audio -s /bin/bash johndoe passwd johndoe Exit the chroot. Create a swapfile (ensure you've exited the chroot): fallocate -l 4G /mnt/sdcard/swapfile mkswap /mnt/sdcard/swapfile Use blkid to get UUID of the sdcard root partition. Configure fstab: vim /mnt/sdcard/etc/fstab UUID="c47efd86-d6df-4c76-a4e9-2e8207d28710" / ext4 defaults 0 1 /swapfile swap swap defaults 0 0 Create /mnt/sdcard/usr/src/linux/gentoo.its: /dts-v1/; / { description = "Chrome OS kernel image with one or more FDT blobs"; images { kernel-1{ description = "kernel"; data = /incbin/("arch/arm64/boot/Image"); type = "kernel_noload"; arch = "arm64"; os = "linux"; compression = "none"; load = <0>; entry = <0>; }; fdt-1{ description = "rk3399-gru-kevin.dtb"; data = /incbin/("arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dtb"); type = "flat_dt"; arch = "arm64"; compression = "none"; hash-1{ algo = "sha1"; }; }; }; configurations { default = "conf-1"; conf-1{ kernel = "kernel-1"; fdt = "fdt-1"; }; }; }; Package and sign the image and write it to boot partition: lucy /mnt/sdcard/usr/src/linux # mkimage -f gentoo.its gentoo.itb FIT description: Chrome OS kernel image with one or more FDT blobs Created: Fri Feb 2 08:46:34 2024 Image 0 (kernel-1) Description: kernel Created: Fri Feb 2 08:46:34 2024 Type: Kernel Image (no loading done) Compression: uncompressed Data Size: 17617408 Bytes = 17204.50 KiB = 16.80 MiB Image 1 (fdt-1) Description: rk3399-gru-kevin.dtb Created: Fri Feb 2 08:46:34 2024 Type: Flat Device Tree Compression: uncompressed Data Size: 69134 Bytes = 67.51 KiB = 0.07 MiB Architecture: AArch64 Hash algo: sha1 Hash value: 35021c41658ce3f8b86f5fcfe7ca1b0a4fd3ccd2 Default Configuration: 'conf-1' Configuration 0 (conf-1) Description: unavailable Kernel: kernel-1 FDT: fdt-1 lucy /mnt/sdcard/usr/src/linux # vim kernel.flags lucy /mnt/sdcard/usr/src/linux # cat kernel.flags console=tty1 root=/dev/mmcblk1p2 rootfstype=ext4 rootwait rw lucy /mnt/sdcard/usr/src/linux # sync lucy /mnt/sdcard/usr/src/linux # futility --debug vbutil_kernel --arch arm --version 1 --keyblock /usr/share/vboot/devkeys/kernel.keyblock --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk --bootloader kernel.flags --config kernel.flags --vmlinuz gentoo.itb --pack vmlinuz.signed DEBUG: run_command: "vbutil_kernel" ... DEBUG: run_command: argv[0] = "vbutil_kernel" DEBUG: run_command: argv[1] = "--arch" DEBUG: run_command: argv[2] = "arm" DEBUG: run_command: argv[3] = "--version" DEBUG: run_command: argv[4] = "1" DEBUG: run_command: argv[5] = "--keyblock" DEBUG: run_command: argv[6] = "/usr/share/vboot/devkeys/kernel.keyblock" DEBUG: run_command: argv[7] = "--signprivate" DEBUG: run_command: argv[8] = "/usr/share/vboot/devkeys/kernel_data_key.vbprivk" DEBUG: run_command: argv[9] = "--bootloader" DEBUG: run_command: argv[10] = "kernel.flags" DEBUG: run_command: argv[11] = "--config" DEBUG: run_command: argv[12] = "kernel.flags" DEBUG: run_command: argv[13] = "--vmlinuz" DEBUG: run_command: argv[14] = "gentoo.itb" DEBUG: run_command: argv[15] = "--pack" DEBUG: run_command: argv[16] = "vmlinuz.signed" DEBUG: do_vbutil_kernel: Reading kernel.flags DEBUG: ReadConfigFile: config file size=0x38 DEBUG: do_vbutil_kernel: Reading kernel.flags DEBUG: do_vbutil_kernel: bootloader file size=0x38 DEBUG: do_vbutil_kernel: Reading gentoo.itb DEBUG: do_vbutil_kernel: vmlinuz file size=0x10de6a9 DEBUG: CreateKernelBlob: g_kernel_blob_size 0x10e2000 DEBUG: CreateKernelBlob: g_kernel_size 0x10de6a9 ofs 0x0 DEBUG: CreateKernelBlob: g_config_size 0x1000 ofs 0x10df000 DEBUG: CreateKernelBlob: g_param_size 0x1000 ofs 0x10e0000 DEBUG: CreateKernelBlob: g_bootloader_size 0x1000 ofs 0x10e1000 DEBUG: CreateKernelBlob: g_ondisk_bootloader_addr 0x11e1000 DEBUG: CreateKernelBlob: end of kern_blob at kern_blob+0x10e2000 DEBUG: PickApartVmlinuz: kernel32_start=0x0 DEBUG: PickApartVmlinuz: kernel32_size=0x10de6a9 DEBUG: do_vbutil_kernel: kblob_size = 0x10e2000 DEBUG: do_vbutil_kernel: vblock_size = 0x10000 DEBUG: WriteSomeParts: writing vmlinuz.signed with 0x10000, 0x10e2000 lucy /mnt/sdcard/usr/src/linux # dd if=vmlinuz.signed of=/dev/sdc1 34704+0 records in 34704+0 records out 17768448 bytes (18 MB, 17 MiB) copied, 3.95567 s, 4.5 MB/s Umount everything you can eject the sd card and install it in the chromebook. Use Ctrl+U to boot from external media. After reboot I noticed it was trying to spawn a serial session so I commented out f0 at the bottom of /etc/inittab. I also forgot to build the kernel modules... cd /usr/src/linux make modules_install reboot Then I had wlp1s0 to configure the normal way. === Tweaks === I didn't want my screen to go black in X with a timeout. I have my custom UI but also fluxbox installed. To disable the screen shutting off edit /etc/X11/xorg.conf: Section "ServerFlags" Option "BlankTime" "0" EndSection I kept bumping the power button and shutting of the machine due to a default settings in elogind. I edited /etc/elogind/logind.conf: [Login] HandlePowerKey=ignore === Conky === -- Conky, a system monitor https://github.com/brndnmtthws/conky -- -- This configuration file is Lua code. You can write code in here, and it will -- execute when Conky loads. You can use it to generate your own advanced -- configurations. -- -- Try this (remove the `--`): -- -- print("Loading Conky config") -- -- For more on Lua, see: -- https://www.lua.org/pil/contents.html conky.config = { alignment = "top_left", use_xft = true, font = 'GE Inspira:size=16', xftalpha = 0.8, text_buffer_size = 2048, max_text_width = 0, override_utf8_locale = true, uppercase = false, no_buffers = true, short_units = true, format_human_readable = true, update_interval = 1, total_run_times = 0, own_window = true, own_window_transparent = false, own_window_type = 'desktop', own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager', own_window_argb_visual = true, own_window_argb_value = 128, background = true, use_spacer = 'none', double_buffer = true, minimum_width = 215, minimum_height = 215, draw_shades = false, default_shade_color = '#000000', draw_outline = false, default_outline_color = '#000000', default_color = 'FFFFFF', color0 = 'FFFFFF', color1 = 'FFA300', draw_borders = false, stippled_borders = 0, border_inner_margin = 10, border_outer_margin = 0, border_width = 1, draw_graph_borders = false,--no gap_x = 50, gap_y = 50, imlib_cache_size = 0, } conky.text = [[ ${color grey}Info:$color ${scroll 32 Conky $conky_version - $sysname $nodename $kernel $machine} $hr ${color grey}Uptime:$color $uptime ${color grey}Frequency (in MHz):$color $freq ${color grey}Frequency (in GHz):$color $freq_g ${color grey}RAM Usage:$color $mem/$memmax - $memperc% ${membar 4} ${color grey}Swap Usage:$color $swap/$swapmax - $swapperc% ${swapbar 4} ${color grey}CPU Usage:$color $cpu% ${cpubar 4} ${color grey}Processes:$color $processes ${color grey}Running:$color $running_processes $hr ${color grey}File systems: / $color${fs_used /}/${fs_size /} ${fs_bar 6 /} ${color grey}Networking: Up:$color ${upspeed wlp1s0} ${color grey} - Down:$color ${downspeed wlp1s0} ${color grey}Battery:${color} ${battery_percent sbs-9-000b} ${alignr}${battery_bar 8, 250 sbs-9-000b} $hr ${color grey}Name PID CPU% MEM% ${color lightgrey} ${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1} ${color lightgrey} ${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2} ${color lightgrey} ${top name 3} ${top pid 3} ${top cpu 3} ${top mem 3} ${color lightgrey} ${top name 4} ${top pid 4} ${top cpu 4} ${top mem 4} # #REFRESH LOCATION & WEATHER INFO CACHE ${execi 600 curl -so ~/.cache/WeatherData 'https://api.openweathermap.org/data/2.5/onecall?units=imperial&lat=46.4855&lon=-88.8940&exclude=minutely,hourly&APPID=a6f8bedf50667be2d3764422a37077d2'} # #REFRESH ICON CACHE ${execi 600 sleep 2 && jq -r '.current.weather[0].icon' ~/.cache/WeatherData | xargs printf "http://openweathermap.org/img/wn/%s@2x.png" | xargs curl -so ~/.cache/WeatherNow.png}\ ${execi 600 sleep 2 && jq -r '.daily[0].weather[0].icon' ~/.cache/WeatherData | xargs printf "http://openweathermap.org/img/wn/%s@2x.png" | xargs curl -so ~/.cache/Weather0.png}\ ${execi 600 sleep 2 && jq -r '.daily[1].weather[0].icon' ~/.cache/WeatherData | xargs printf "http://openweathermap.org/img/wn/%s@2x.png" | xargs curl -so ~/.cache/Weather1.png}\ ${execi 600 sleep 2 && jq -r '.daily[2].weather[0].icon' ~/.cache/WeatherData | xargs printf "http://openweathermap.org/img/wn/%s@2x.png" | xargs curl -so ~/.cache/Weather2.png}\ ${execi 600 sleep 2 && jq -r '.daily[3].weather[0].icon' ~/.cache/WeatherData | xargs printf "http://openweathermap.org/img/wn/%s@2x.png" | xargs curl -so ~/.cache/Weather3.png}\ ${execi 600 sleep 2 && jq -r '.daily[4].weather[0].icon' ~/.cache/WeatherData | xargs printf "http://openweathermap.org/img/wn/%s@2x.png" | xargs curl -so ~/.cache/Weather4.png} # #WEATHER NOW ${voffset -40}${color1}Kenton, MI ${color0}${execi 1 jq -r '.current.temp' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}° ${image ~/.cache/WeatherNow.png -s 70x70 -p 160,570} #WEATHER TODAY ${color1}Today${goto 100}${color0}${execi 1 jq -r '.daily[0].temp.min' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°/ ${execi 1 jq -r '.daily[0].temp.max' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°${image ~/.cache/Weather0.png -s 30x30 -p 180, 635} # #WEATHER +1 DAY ${color1}${execi 1 jq -r '.daily[1].dt' ~/.cache/WeatherData |awk ' {print "@" $1}' |xargs date +%a --date}${goto 100}${color0}${execi 1 jq -r '.daily[1].temp.min' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°/ ${execi 1 jq -r '.daily[1].temp.max' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°${image ~/.cache/Weather1.png -s 30x30 -p 180,658} # #WEATHER +2 DAYS ${color1}${execi 1 jq -r '.daily[2].dt' ~/.cache/WeatherData |awk ' {print "@" $1}' |xargs date +%a --date}${goto 100}${color0}${execi 1 jq -r '.daily[2].temp.min' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°/ ${execi 1 jq -r '.daily[2].temp.max' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°${image ~/.cache/Weather2.png -s 30x30 -p 180,685} # #WEATHER +3 DAYS ${color1}${execi 1 jq -r '.daily[3].dt' ~/.cache/WeatherData |awk ' {print "@" $1}' |xargs date +%a --date}${goto 100}${color0}${execi 1 jq -r '.daily[3].temp.min' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°/ ${execi 1 jq -r '.daily[3].temp.max' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°${image ~/.cache/Weather3.png -s 30x30 -p 180,710} # #WEATHER +4 DAYS ${color1}${execi 1 jq -r '.daily[4].dt' ~/.cache/WeatherData |awk ' {print "@" $1}' |xargs date +%a --date}${goto 100}${color0}${execi 1 jq -r '.daily[4].temp.min' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°/ ${execi 1 jq -r '.daily[4].temp.max' ~/.cache/WeatherData |awk '{print int($1+0.5)}'}°${image ~/.cache/Weather3.png -s 30x30 -p 180,735} ]] {{ :conky.png?400 |}} === Docker === When attempted to emerge docker I got errors about circular deps with dev-lang/go. I also needed to recompile binutils with gold use flag. sys-devel/binutils gold Then I emerged dev-lang/go by itself. emerge --ask devlang/go Finally I emerged docker. emerge --ask app-containers/docker After that I found I couldn't start a container. I was missing some required kernel CONFIG options. * I ran this [[https://github.com/moby/moby/blob/master/contrib/check-config.sh|script]] to figure out what needed to be changed. * Then compile the kernel and modules as normal. * Follow the steps above to recreate the image for p1. * dd the image, ensure to take in account that the device is now probably /dev/mmcblk1 === Refrences === * [[https://archlinuxarm.org/platforms/armv8/rockchip/samsung-chromebook-plus]] * [[https://wiki.gentoo.org/wiki/Samsung_Chromebook_Plus]] * [[https://wiki.gentoo.org/wiki/Creating_bootable_media_for_depthcharge_based_devices]] * [[https://git.alpinelinux.org/aports/tree/testing/linux-gru/]] * [[https://sites.google.com/a/chromium.org/dev/chromium-os/how-tos-and-troubleshooting/mainline-kernel-on-kevin-chromebook-plus]] * [[https://github.com/hexdump0815/imagebuilder/blob/main/systems/chromebook_gru/readme.md]]