Lineage Android OS for the Jetson TX2 and TX2 NX

LineageOS is a free, community built, aftermarket firmware distribution of Android, which is designed to increase performance and reliability over stock Android for your device.

LineageOS is based on the Android Open Source Project with extra contributions from many people within the Android community. It can be used without any need to have any Google applications installed. Linked in the instructions is a package that has come from another Android project that restores the Google parts. LineageOS does still include various hardware-specific prebuilts for which source is not available.

All the source code for LineageOS is available in the LineageOS Github repo. And if you would like to contribute to LineageOS, please visit out Gerrit Code Review.

Instructions:
Android TV
Tablet

Notes:

  • This has been tested on the TX2 devkit and with a TX2 NX production module in a p3509 carrier board (the one that comes in the Xavier NX devkit).
  • These builds use the A/B update system, allowing for updates to run in the background while doing other things.
  • The boot stack is mostly from the L4T r32.5.1 release, except for cboot, which is source built with android support enabled and many fixes and modifications for android.
  • As of the time of this posting, Android TV builds are not available yet. They are scheduled to build later this week.

Cool! Thanks for your sharing to community!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

hello @Steel01 I know that its been a few years but I am using this build. Everything works perfectly except display. For some reason the display resolution gets reduced to 720 no matter what I do. I tried changing with adb but no dice. If possible could you tell me where the source code for this lives? I’d be happy to recompile myself but was not sure where to find it. I see props vendor.sys.ui.resolution.x and would appreciate knowing where those are coming from. Thank you for your help and amazing roms <3

Mmm, I don’t know why that would happen. I’ve not worked on the 17.1 releases for some time either. 18.1 is in usable shape and pretty close to where I would be comfortable shipping it, except for one issue with bluetooth on the tx2 nx. If you wish to build 18.1, you can follow the instructions on the Lineage wiki:

https://wiki.lineageos.org/devices/quill/build/variant1

I recently uploaded the t186 flash packages (see link in the wiki install instructions) for 18.1-20, so that part is available without compiling.

A bit more general info for anyone that might be interested. My lineage 18.1 and newer kernel support is based on l4t r34.x/r35.x (r34 for 18.1 and r35 for 19.1/20). Nvidia started removing t186 support from the code base on r34 and further on r35. So far, I’ve been able to revert support back in and make it work, but it has taken some effort. And I think things are in pretty good shape at this point, except for a handful of points.

  1. The bluetooth portion of the rtl8822ce in the p3509 carrier that’s used with the tx2 nx resets constantly. It’s a usb device and logs report that the usb device disconnects and reconnects. But the wifi side on pcie has no trouble. This could potentially be hardware damage on my unit, but I don’t have any other units to verify that.
  2. I have been unable to make auto frame rate matching work properly on 19.1 or 20. This is a general tegra issue and not specific to t186, but it is a reason I still recommend 18.1 at this point. If afr is not a factor, 19.1 is perfectly usable.
  3. BLE on nvidia’s broadcom bluetooth chips is completely broken on 20. Best guess right now is that the firmware needs updated for something, but I’m not entirely certain. The realtek chip paired with the tx2 nx works fine, well… until the device resets, that is. The tx2 module has a bcm4354 chip and is affected by the ble issues. If neither afr nor ble are factors, 20 might be usable. I’ve not been able to do much long term testing since both afr and ble are things I use.

audio is not a problem nor is bluetooth, thank you so much for the pointers, you are a massive asset to the community

Just to verify I have a tx2 nx, is it the same build? Also I see the Extract proprietary blobs part needing a device with this version, is that necessary or is that default instructions for other lineageos builds?

TX2 and TX2 NX are supported in the same build, yes. The build instructions for tegra are a bit different from what the boilerplate wiki text suggests, I really do need to find a way to highlight that. Running extract is as described, except you do not need an existing device, everything is instead downloaded and extracted from nvidia factory images and releases.

Good morning! I got as far as extracting but got an error

~/android/lineage/device/nvidia/quill$ ./extract-files.sh
otatools must be built before running this script!

I cant seem to find where to run the otatools

Commented out that check and script ran to completion but I don’t see the files

Archive: /tmp/tmp.mZMmfiH1m8/downloads/stock-t210.zip
creating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/
extracting: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/android-info.txt
inflating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/blob
inflating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/boot.img
inflating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/mdarcy.dtb.img
inflating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/recovery.img
inflating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/system.img
inflating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/vbmeta.img
inflating: /tmp/tmp.mZMmfiH1m8/extract/stock-t210/nv-recovery-image-shield-atv-8.2.3/vendor.img
/home/mike/android/lineage/device/nvidia/quill/…/tegra-common/extract/…/…/…/…/device/nvidia/tegra-common/extract/extract_utils.sh: line 169: /home/mike/android/lineage/device/nvidia/quill/…/tegra-common/extract/…/…/…/…/out/host/linux-x86/bin/simg2img: No such file or directory

tried commenting out the offending lines, next was failure on 181 for same reason but brotli. Commented that out and got as far as

cp: cannot stat ‘/tmp/tmp.bbZTiWhLkI/extract/stock-t210//vendor/app/AccessoryUiTv/AccessoryUiTv.apk’: No such file or directory

Undo all the changes, then run m otatools. It’s telling you that you need to build the otatools target, so that the tools are available for extract to do its thing.

Hello good sir I tried compiling 19.1 and hit an issue. During compilation I got the following error while running brunch quill


2023-05-25 12:35:15 - ota_from_target_files.py - ERROR   : 
   ERROR:
Traceback (most recent call last):
  File "/home/mike/android/lineage/out/host/linux-x86/bin/ota_from_target_files/ota_from_target_files.py", line 1504, in <module>
  File "/home/mike/android/lineage/out/host/linux-x86/bin/ota_from_target_files/ota_from_target_files.py", line 1478, in main
  File "/home/mike/android/lineage/out/host/linux-x86/bin/ota_from_target_files/ota_from_target_files.py", line 1108, in GenerateAbOtaPac
kage
  File "/home/mike/android/lineage/out/host/linux-x86/bin/ota_from_target_files/ota_utils.py", line 253, in GetPackageMetadata
    boot_variable_values, True)
  File "/home/mike/android/lineage/out/host/linux-x86/bin/ota_from_target_files/ota_utils.py", line 214, in UpdateDeviceState
    UpdatePartitionStates(device_state.partition_state)
  File "/home/mike/android/lineage/out/host/linux-x86/bin/ota_from_target_files/ota_utils.py", line 194, in UpdatePartitionStates
    partition))
  File "/home/mike/android/lineage/out/host/linux-x86/bin/ota_from_target_files/common.py", line 501, in GetPartitionBuildProp
    (prop, partition))
ExternalError: couldn't find ro.product.vendor.device in vendor.build.prop
12:35:16 ninja failed with: exit status 1

#### failed to build some targets (58:05 (mm:ss)) ####


Apologies, I forgot about that. The way I support multiple devices in a single build broke a/b zip generation on 19.1 and 20. And I haven’t come up with a clean fix for that yet. In the meantime, I have a workaround that can now be repopicked from the Lineage gerrit.

https://review.lineageos.org/c/LineageOS/android_build/+/357489

As an fyi, I was able to get the build running on my tx2 nx but got into a bootloop during the launch screen. I don’t have time to continue looking today but will dive more into it tomorrow/next week.

I built quill 19.1 from the Lineage org and it booted to setup wizard for me. Logs would be needed to know why your build isn’t booting.

Hello, not sure what I was doing wrong, I recompiled from source and was able to get up and running.

On to my next problem…when I use hdmi I am able to get my resolution (1920 or 4k) correctly through my gigabyte m32u monitor.

When I instead use displayport I get a strange 720x400 resolution. I tried using adb shell wm size to adjust but it never gets above 2x that resolution.

Not sure if you have used the build with displayport, I’ve tried a few cables and monitors to make sure it is not something on my end.

Here’s what I got from dumpsys display


  DisplayModeDirector
  mSupportedModesByDisplay:
    0 -> [{id=1, width=1280, height=720, fps=60.000004, alternativeRefreshRates=[]}]
    2 -> [{id=2, width=720, height=400, fps=70.0, alternativeRefreshRates=[]}, {id=3, width=1280, height=720, fps=60.000004, alternativeRefreshRates=[50.0, 59.94006, 120.00001]}, {id=4, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[50.0, 59.94006, 120.00001]}, {id=5, width=1920, height=1080, fps=120.00001, alternativeRefreshRates=[50.0, 59.94006, 60.000004]}, {id=6, width=720, height=480, fps=60.000004, alternativeRefreshRates=[]}, {id=7, width=1280, height=720, fps=50.0, alternativeRefreshRates=[59.94006, 60.000004, 120.00001]}, {id=8, width=1920, height=1080, fps=50.0, alternativeRefreshRates=[59.94006, 60.000004, 120.00001]}, {id=9, width=3840, height=2160, fps=24.000002, alternativeRefreshRates=[23.976025, 25.0, 29.97003, 30.000002]}, {id=10, width=3840, height=2160, fps=25.0, alternativeRefreshRates=[23.976025, 24.000002, 29.97003, 30.000002]}, {id=11, width=3840, height=2160, fps=30.000002, alternativeRefreshRates=[23.976025, 24.000002, 25.0, 29.97003]}, {id=12, width=1280, height=720, fps=120.00001, alternativeRefreshRates=[50.0, 59.94006, 60.000004]}, {id=13, width=1280, height=720, fps=59.94006, alternativeRefreshRates=[50.0, 60.000004, 120.00001]}, {id=14, width=1920, height=1080, fps=59.94006, alternativeRefreshRates=[50.0, 60.000004, 120.00001]}, {id=15, width=3840, height=2160, fps=23.976025, alternativeRefreshRates=[24.000002, 25.0, 29.97003, 30.000002]}, {id=16, width=3840, height=2160, fps=29.97003, alternativeRefreshRates=[23.976025, 24.000002, 25.0, 30.000002]}]
  mDefaultModeByDisplay:
    0 -> {id=1, width=1280, height=720, fps=60.000004, alternativeRefreshRates=[]}
    2 -> {id=2, width=720, height=400, fps=70.0, alternativeRefreshRates=[]}
  mVotesByDisplay:
    -1:
      PRIORITY_USER_SETTING_MIN_REFRESH_RATE -> Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=Infinity, disableRefreshRateSwitching=false, baseModeRefreshRate=0.0}
      PRIORITY_DEFAULT_REFRESH_RATE -> Vote{width=-1, height=-1, minRefreshRate=0.0, maxRefreshRate=60.0, disableRefreshRateSwitching=false, baseModeRefreshRate=0.0}
  mModeSwitchingType: SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS
  mAlwaysRespectAppRequest: false
  SettingsObserver
    mDefaultRefreshRate: 60.0
    mDefaultPeakRefreshRate: 0.0
  AppRequestObserver
    mAppRequestedModeByDisplay:
    mAppPreferredRefreshRateRangeByDisplay:
  BrightnessObserver
    mAmbientLux: -1.0
    mBrightness: 102
    mDefaultDisplayState: 2
    mLowPowerModeEnabled: false
    mRefreshRateChangeable: false
    mShouldObserveDisplayLowChange: false
    mShouldObserveAmbientLowChange: false
    mRefreshRateInLowZone: 0
    mShouldObserveDisplayHighChange: false
    mShouldObserveAmbientHighChange: false
    mRefreshRateInHighZone: 0
    mLastSensorData: 0.0
    mTimestamp: 1970-01-01 00:00:00.000
  UdfpsObserver
    mLocalHbmEnabled:
    mGlobalHbmEnabled:
   HbmObserver
     mHbmMode: {}
     mHbmActive: {}
     mRefreshRateInHbmSunlight: 0
     mRefreshRateInHbmHdr: 0
  SkinThermalStatusObserver:
    mStatus: -1
  SensorObserver
    mIsProxActive=false
    mDozeStateByDisplay:
      0 -> false
      2 -> false

It’s probably because the dummy hdmi display is primary. If I understand correctly, that dummy display exists to help hotplug work on android, for the shield type devices, which only have hdmi. Because android gets really unhappy if there’s no display at all.

So to do display port testing, I have to completely disable hdmi display controller. I made a dtbo that can be flashed via fastboot that does this. Or the node could be disabled directly in the kernel device tree if hdmi would never be used. Try this and see if hwcomposer detects a more sane resolution.

fastboot flash dtbo t186-disable-hdmi.dtbo

t186-disable-hdmi.dtbo (338 Bytes)
t186-disable-hdmi.dts (280 Bytes)

Undoing that is more complicated than it should be. fastboot erase is broken and I haven’t figured out why yet. But a 8 byte file of zeroes can clear the header, so the bootloader ignores the partition. Like:

dd if=/dev/zero bs=1 count=8 of=zeros.bin
fastboot flash dtbo zeros.bin

I’m not familiar with fastboot, do I need to enter recovery or do something else before running it? Thank you for the help