[libcamera-devel,RFC] ChromiumOS build instructions for amd64-generic board

Message ID 5279f1e6-262b-5ace-0f4c-bff2cfdccb11@uajain.com
State Not Applicable
Delegated to: Umang Jain
Headers show
Series
  • [libcamera-devel,RFC] ChromiumOS build instructions for amd64-generic board
Related show

Commit Message

Umang Jain Aug. 11, 2020, 8:06 p.m. UTC
Guide format: .markdown
===============================


# Chromium OS build for board amd64-generic

Reference guide: 
https://chromium.googlesource.com/chromiumos/docs/+/master/developer_guide.md

This particular guide is a supplement guide for building chromium OS for 
a `amd64-generic` board. It is recommended to have a read of the 
reference guide above because most of the steps in this guide are 
extracted from there. This guide primarily focuses on few nuances that a 
developer might face while building CrOS for first time for 
amd64-generic board.

### Download the source
Prepare the prerequisites and download the source as per the reference 
guide on the development machine.

### Building CrOS for --board=amd64-generic

#### Creating the chroot:
- Open terminal and  `cd` to the chromium source directory : for e.g. 
`cd ~/src/chromiumos`
- `cros_sdk --nouse-image` (without --nouse-image, running `cros_sdk` 
does nothing for me)

#### Enter the chroot:
- `cros_sdk` - Running `cros_sdk` in ~/src/chromiumos will now help you 
enter the chroot.
While in the chroot you will see a special “(cr)” prompt to remind you 
that you are there for e.g.:
`(cr) ((431cf23...)) uajain@localhost ~/trunk/src/scripts $`

#### Prepare for the build:
- CrOS needs to be built for specific board, in our case, it's 
"amd64-generic". We need to export $BOARD var inside the chroot so that  
it's easier to specify in subsequent build commands.
`(cr) export BOARD=amd64-generic`
**Tip**: If you want $BOARD var being set automatically everytime you 
enter the chroot, it is recommended to set this in `~/.bashrc`
`(cr) echo "export BOARD=amd64-generic" >> ~/.bashrc`

- After this, you need to setup the board by: `(cr) $ setup_board 
--board=$BOARD`

#### Build packages and test image (and go get some coffee!)
- `./build_packages --board=${BOARD} --nowithautotest`
This will start building the packages and will take quite a long time to 
complete.
- After the packages are built (and hopefully you didn't receive any 
errors) - now is the time to build a test image which can be flashed 
onto a flash drive:
` ./build_image --board=${BOARD} --noenable_rootfs_verification 
--adjust_part='STATE:+3G' test`

#### Flash the image and testing
- After `./build_image` is completed, the instruction to flash to a USB 
will be displayed. Generally it will be:
`(cr) ~/trunk/src/scripts$ cros flash usb:// 
../build/images/amd64-generic/latest/` followed by USB selection. The 
drives I used were 16+ GB flash drives.
- Boot a x86_64 device (DUT) from this USB. You might need to play 
around with BIOS and/or disable secure boot for it to work.

#### Enable debug features:
When the system is booted up from USB from the first time, you have an 
option to enable debugging features.
Enable the debugging features. One might see a flash screen "Something 
went wrong" while enabling it, but it doesn't cause any harm and 
probably it has already enabled the debugging features.

#### Updating the kernel:
- Now that your test image works, it's time to know the kernel version 
of the build. Simply enter the console on DUT by pressing [Alt} + [Ctrl] 
+ [F2 or F3 ...]
- After getting to the console, you need to login. I generally use 
default user and password provided by the test build - User: `chronos` 
Password: `test0000`
- [After a successful login] Query $`uname -r` to know the kernel 
version. It is a high possibility that the kernel version is `4.14` has 
been deployed and we need to update it to `>=5.1` in order for libcamera 
integration.  If the version already reported is `>=5.1` you can skip 
this step.
- **Tip**: Recommended reading of `emerge-` and `cros deploy` at this 
point, from the reference guide.
- On your development machine, inside chroot:
`emerge-${BOARD} -C chromeos-kernel-4_14 && emerge-${BOARD}  
chromeos-kernel-5_4`
This will unlink kernel-4_14 and build chromeos-kernel-5_4 in the ebuild.
- Since it's the kernel, CrOS has a special script for it's deployment 
and traditional `cros deploy` for packages is not used here. The concept 
of deployment, more or less is the same as seen from the build user's 
point-of-view.
`./update_kernel.sh --remote <remote_ip> chromeos-kernel-5_4`
- The `./update kernel.sh` will update the kernel and also restart the 
system.
Hopefully, the new kernel has been deployed; to check that refer and 
repeat to the first 3 steps of this section.

After updating the kernel, if you see a black screen with the mouse 
arrow in center, follow on to the next section, otherwise, skip it.

#### Black screen with mouse arrow on kernel update:
This has been found after updating the kernel to `v5.4` on Haswell(or 
older) systems. This particular issue is about X-Tiling on these 
platforms which are causing this graphics issue. We will simply disable 
the X-Tiling for now, to make it work. The changes to be done is a 
platform module named `minigbm`.

- On the development machine,  inside chroot:
$ `(cr) cros_workon-$BOARD start minigbm` (Refer to `cros_workon` 
documentation from reference guide)
- Apply the following patch in `~/trunk/src/platform/minigbm/i915.c` file
```diff
+       //                   &metadata, scanout_and_render);

         metadata.tiling = I915_TILING_Y;
         metadata.priority = 3;
@@ -271,9 +271,9 @@ static int i915_bo_compute_metadata(struct bo *bo, 
uint32_t width, uint32_t heig
                                     uint64_t use_flags, const uint64_t 
*modifiers, uint32_t count)
  {
         static const uint64_t modifier_order[] = {
-               I915_FORMAT_MOD_Y_TILED,
-               I915_FORMAT_MOD_X_TILED,
                 DRM_FORMAT_MOD_LINEAR,
+               I915_FORMAT_MOD_Y_TILED,
+               I915_FORMAT_MOD_X_TILED
         };
         uint64_t modifier;
         struct i915_device *i915 = bo->drv->priv;
@@ -289,6 +289,7 @@ static int i915_bo_compute_metadata(struct bo *bo, 
uint32_t width, uint32_t heig
                 modifier = combo->metadata.modifier;
         }

+       modifier = DRM_FORMAT_MOD_LINEAR;
         /*
          * i915 only supports linear/x-tiled above 4096 wide
          */
```

- Build this `minigbm` patched version and deploy it to the system.
  `(cr) ~/trunk/src/scripts$   emerge-${BOARD} minigbm`
   `(cr) ~/trunk/src/scripts$   cros deploy <remote IP of DUT> minigbm`
- Restart DUT and boot it again from USB. Hopefully you should see a  
functional login screen at this point with an updated kernel (v5.4).

#### Proceed to Libcamera integration as per 
chromiumos-libcamera-integration.txt
In order to test the libcamera integration, you can use the `cam` 
utility tool on the DUT console (console can be obtained by [Alt] + 
[Ctrl] + [F2, F3...]. If the `cam` reports the cameras present on 
system, your libcamera integration has been successful.

Otherwise, if it happens so that no cameras are reported, one needs to 
check for the CONFIG_MEDIA_CONTROLLER kernel config option. To check the 
kernel config, logged in as `chronos` user on DUT console:
$ `sudo modprobe configs `
$ `zcat /proc/config.gz | grep CONFIG_MEDIA_CONTROLLER`
It will probably output  `# CONFIG_MEDIA_CONTROLLER is not set`.
If you are hitting this issue, you need to enable this(and related) 
kernel configuration for libcamera to work.
This can be very tricky to work out in my honest opinion. Refer to the 
following guide in order to playaround with kernel configuration: 
[https://www.chromium.org/chromium-os/how-tos-and-troubleshooting/kernel-configuration](https://www.chromium.org/chromium-os/how-tos-and-troubleshooting/kernel-configuration)
*[This sections needs further expanding ]*

Patch

diff --git a/i915.c b/i915.c
index bccc0b5..821953c 100644
--- a/i915.c
+++ b/i915.c
@@ -102,13 +102,13 @@  static int i915_add_combinations(struct driver *drv)
         render = unset_flags(render, linear_mask);
         scanout_and_render = unset_flags(scanout_and_render, linear_mask);

-       metadata.tiling = I915_TILING_X;
-       metadata.priority = 2;
-       metadata.modifier = I915_FORMAT_MOD_X_TILED;
+       //metadata.tiling = I915_TILING_X;
+       //metadata.priority = 2;
+       //metadata.modifier = I915_FORMAT_MOD_X_TILED;

-       drv_add_combinations(drv, render_formats, 
ARRAY_SIZE(render_formats), &metadata, render);
-       drv_add_combinations(drv, scanout_render_formats, 
ARRAY_SIZE(scanout_render_formats),
-                            &metadata, scanout_and_render);
+       //drv_add_combinations(drv, render_formats, 
ARRAY_SIZE(render_formats), &metadata, render);
+       //drv_add_combinations(drv, scanout_render_formats, 
ARRAY_SIZE(scanout_render_formats),