Yi 4k+ bitrate mod and firmware unpacker.

Great news! I will try this mod, but i do not have fast microSD card. Also interesting hdr function, that available in some resolution (if I understand correctly). In the future, still would like to have the ability to disable noise reduction, which considerably spoils the image quality.
 
forked your repo @irungentoo , added few things to the unpacker (now a little toolkit) such as a table dumper and command dumper (still have to clean the code for it, added a txt with many dumped commands)

repo : https://github.com/wavepacket0/Xiaomi_Yi_4k_Plus

just thinking, maybe it is too complicated, but would be interesting if we can add things to the rtos, such as menu, custom functions etc, then repack the fw and upload it. I've took a look at the updater code, it checks CRC, and it is in the section header. I think while we pack the modded fw, we might update the CRC...or patch the updater.
 
@wpacket nice, I'm happy that I'm not the only one trying to hack the yi4k+.

I'm pretty sure the only thing that needs to be updated if the firmware is modified (but the size of the sections doesn't change) is the crc32 in the section headers (and there might be a crc32 for the whole thing somewhere like for the normal yi4k firmware). The crc32 in the header is the exact crc32 of the sections my dumper dumps stored in little endian so it's easy to recalculate it and update it.
 
See this is the kind of hacking i like, then there is the other kind of hacking i dont like at all to put it nicely.

But this kind of hacking i feel make the world a better place. (y)
 
@wpacket nice, I'm happy that I'm not the only one trying to hack the yi4k+.

I'm pretty sure the only thing that needs to be updated if the firmware is modified (but the size of the sections doesn't change) is the crc32 in the section headers (and there might be a crc32 for the whole thing somewhere like for the normal yi4k firmware). The crc32 in the header is the exact crc32 of the sections my dumper dumps stored in little endian so it's easy to recalculate it and update it.

I'm happy too, we can work together on this :)

managed to get a shell command dump, you can find it in the repo. There you will find all main commands the autoexec.ash script takes, like t, savebin etc.
There's also loadbin :whistle:

t ants save_log on : dumps the RTOS internal log to SD. Add the command to autoexec, then start the camera and power it off. On the next startup it will generate the logs and keep generating even if you remove the autoexec. In order to stop it, use off command, start the camera and power it off. On the next statup it wont generate them

have you already tried binwalk on the out_rtos.bin image ?
 
Last edited:
t ants save_log on :

I just put a file called: save_log_enable.script on the sd card and it makes the camera copy over the logs to the sd card from the b: partition. The rtos bin seems to only contain code.

Right now what I'm doing is trying to figure out how the sensor stuff works to see if it's possible to increase the framerates of the modes on the camera.
 
I just put a file called: save_log_enable.script on the sd card and it makes the camera copy over the logs to the sd card from the b: partition. The rtos bin seems to only contain code.

Right now what I'm doing is trying to figure out how the sensor stuff works to see if it's possible to increase the framerates of the modes on the camera.


Yes tried it too and it's working fine.

Managed to get a more complete commands list dump, including all shell, t, t app, t ants commands
 
Hello! been watching this forum and hoping to see if someone would figure out some 4k+ hacks, you guys have done great work

I am a embedded hardware enthusiast also, and have modified my Yi 4k+ lens with backbone kit. Now I'm keen to give these scripts a go to see what more can be done.

How are you guys reversing this stuff? are you using IDA pro and going through the dissassembled ARMv8 code? Have you tried the JTAG?

About the frame rate stuff, I found a product brief on the super secret Amba and it says it can do H.264 at 4k90, but the IMX377 is maxed out doing 60fps in 8MP 10bit so not sure if much more can be squeezed there. I was wondering if connecting another MIPI dphy 4 lane sensor would work theoretically?

Also apparently there was a beta version of the 4k+ released to developers that had HDMI out instead of the wifi module which is very interesting to me as I now have a sharp varifocal lens, but its a bit hard to focus 4k on the inbuilt LCD. Maybe it would be possible to turn the output back on and with some sort of flat flex adapter output HDMI again?

And one more thing before I finally shutup, how fast can the SD port write data? I have a 100mbps card but can get 135mbps files (guessing the YI its buffering using ram). If it can go much faster I would get one of those extreme pro 275mbps SD cards and use the script to crank it up.

Sorry for the long post and maybe bit over ambitious ideas but I'm keen to learn and yall clearly know your stuff.

Much appreciated guys keep it up
 
https://github.com/irungentoo/Xiaomi_Yi_4k_Camera/tree/master/4k+/increased_framerate

Figured out a way to increase the framerates for the camera modes by overclocking the camera sensor. Only problem is that I can't go very high because it looks like the dsp doesn't encode fast enough so either the ram, dsp or core (probably the dsp) need a clock boost to make things like 1080p @ 180fps or higher and maybe even higher framerates at 4k possible.

Here's a video I took at 1080p 150fps:


About the frame rate stuff, I found a product brief on the super secret Amba and it says it can do H.264 at 4k90

The public one says 4k @ 120fps in h264 and 4k @ 60fps in 10bit hevc. That's likely at a higher clock than what it is on the 4k+ camera though. I think they put the minimum clock that works with all the modes on the camera in order to keep the battery usage low.


And one more thing before I finally shutup, how fast can the SD port write data?

I don't know, when the U3 card I ordered arrives I'll do some actual tests. One guy on reddit said he managed to go up to 165mbs bitrate without errors so it goes at least to that.
 
Here's a video I took at 1080p 150fps:

Wow that's a great find. Datasheet for imx377 says max recommended is 27MHz, but here it is running at 30MHz, wonder how fast it can really go...

I would be tempted to see if soldering on a slightly faster crystal circuit would work. Though I might wait to see if you can find the main PLL setting before I turn my camera into a Yi zeroK potato (y)


Also:
  • I read that Beta developer version of the 4k+ had HDMI instead of wifi,
  • In the test command dump from @wpacket it is referencing HDMI out,
  • And the Amba public data saying it has HDMI out...
I think this MAYBE could be a MIPI CSI-2 HDMI port in the image below:
MCr6XHg.jpg
 
Last edited:
  • Like
Reactions: Mtz
Hello! been watching this forum and hoping to see if someone would figure out some 4k+ hacks, you guys have done great work

I am a embedded hardware enthusiast also, and have modified my Yi 4k+ lens with backbone kit. Now I'm keen to give these scripts a go to see what more can be done.

How are you guys reversing this stuff? are you using IDA pro and going through the dissassembled ARMv8 code? Have you tried the JTAG?

......

And one more thing before I finally shutup, how fast can the SD port write data? I have a 100mbps card but can get 135mbps files (guessing the YI its buffering using ram). If it can go much faster I would get one of those extreme pro 275mbps SD cards and use the script to crank it up.

Much appreciated guys keep it up

Dont know about irungentoo (are you using objdump?, so an offline (not runtime) disassembling approach?)
but I'm using IDA Pro with its ARM decompiler, so I can disassemble and take a look at the C pseudocode.
Been struggling a bit due to the fact Im not that used with ARM opcodes, Im way more experienced into x86/x64 disassembly.

I noticed that IDA cant find the entrypoint of the rtos.bin (it's based on header analysis), so I think I can give binwalk a try, to see if it can extract something. Anyway the rtos.bin is still correctly loaded into ida. Havent tried any JTAG as I dont want to damage my camera :)

Regarding the unpacker, bitrate, and framerate credits to irungentoo!
I just added an eaiser to use way around it with some fixes and dumping tables based on signatures.


https://github.com/irungentoo/Xiaomi_Yi_4k_Camera/tree/master/4k+/increased_framerate

Figured out a way to increase the framerates for the camera modes by overclocking the camera sensor. Only problem is that I can't go very high because it looks like the dsp doesn't encode fast enough so either the ram, dsp or core (probably the dsp) need a clock boost to make things like 1080p @ 180fps or higher and maybe even higher framerates at 4k possible.

The public one says 4k @ 120fps in h264 and 4k @ 60fps in 10bit hevc. That's likely at a higher clock than what it is on the 4k+ camera though. I think they put the minimum clock that works with all the modes on the camera in order to keep the battery usage low.

I don't know, when the U3 card I ordered arrives I'll do some actual tests. One guy on reddit said he managed to go up to 165mbs bitrate without errors so it goes at least to that.

Well done!! :D Sadly cant help you right now as Im busy with university exams


There's also an Amba A2 SDK laying around I found while searching on the net, still havent had the chance to take a look, okay we're on H2, but still can be useful
 
Last edited:
  • Like
Reactions: Mtz
I got 300fps 720p working without doing an overclock, only problem is that it only records for 12 seconds probably because something is too slow so it gets bottle necked (that's my hypothesis right now). Also had to figure out how to set custom exposure values to make it actually work.

https://github.com/irungentoo/Xiaomi_Yi_4k_Camera/tree/master/4k+/increased_framerate


Datasheet for imx377 says max recommended is 27MHz, but here it is running at 30MHz, wonder how fast it can really go...

I got it running at 36MHz when I checked to see if 1080p 180fps could work (the lcd preview was working perfectly) so the sensor can do at least that. The bottleneck is not the sensor right now.

are you using objdump?
I have not done much decompiling, what I have mostly done is found structs with values that looked relevant (the rtos log is very useful) and tried to figure out what they were for.
 
Last edited:
Really good work on the recent findings! Okay I'll take a closer look to the rtos log too ;)

Regarding the recent irungentoo findings about framerate, shutter, I made some nice structs in order to better understand and to be later added in my Fw toolkit.


Framerate mod

Looking at the 1080p address, it seems to be part of a large array of structs, starting at 0x7237C0 (1.3.11), referenced at 0x4936F0 (0r 0x493300 -> 0x7237CC - 0x8)

the struct layout is:
Code:
class CFramerate_video_setting
{
public:
    int32_t sensor_frequency_hz; //0x0000 MHz = Hz / 1000000
    int32_t N0000009C; //0x0004
    int32_t N000000AE; //0x0008 in the right struct,  720 120 to 300 mod : without touching the freq
    int32_t N0000009D; //0x000C
    int32_t N0000009E; //0x0010 in the right stuct, 720 120 to 300 mod : without touching the freq
    int32_t N0000009F; //0x0014
    int32_t N000000A0; //0x0018
    int32_t mfps; //0x001C milli frame per second fps = mfps / 1000
    int32_t N000000A2; //0x0020
    int32_t N000000A3; //0x0024
}; //size 0x28

class CFramerate_video
{
public:
    CFramerate_video_setting framerate_video_array[55]; //0x0000
};

CFramerate_video* pFramerate_array = (CFramerate_video*)0x7237C0;

The 1080p struct is at the 20 position : 0x723AE0 - 0x7237C0 = 0x320 -> / 0x28 (struct size) = 0x14 -> 20 dec. Since there are many other entries in this big array, we could mod other resolutions too.

The third address needed to force 1080p 120fps to 150fps, it is found at the bottom of the (pal? Im not sure about the naming yet, dont have my camera to test right now) videomode table. After this struct, there's another videomode table, which should be the ntsc one.

Code:
class CVideomode_video_setting
{
public:
    char resolution_full_name[24]; //0x0000
    char pad_0018[40]; //0x0018
    char resolution_short_name[16]; //0x0040
    char pad_0050[48]; //0x0050
    char fps_text[8]; //0x0080
    char pad_0088[56]; //0x0088
    int32_t N000000BE; //0x00C0
    int32_t N000000BF; //0x00C4
    int32_t N000000C0; //0x00C8
    int32_t N000000C1; //0x00CC
    char pad_00D0[128]; //0x00D0
}; //Size: 0x0150

class CVideomode_video
{
public:
    CVideomode_video_setting pVideomode_pal_array[93]; //0x0000
    char pad_7A10[2432]; //0x7A10
    int32_t framerate_1080p_120_mfps; //0x8390
    char pad_8394[540]; //0x8394
    CVideomode_video_setting pVideomode_ntsc_array[93]; //0x85B0
};

CVideomode_video* pVidemode= (CVideomode_video*)0xA9E0D0;

here you can see the relevant disassembly, with the struct size too:
Code:
const char *__fastcall sub_86BE8(int a1)
{
  int v1; // r4@1
  const char *v2; // r3@2

  v1 = a1;
  if ( sub_147E00() == 1 )                      // pal or ntsc
    v2 = "3840x2160 25P 16:9";
  else
    v2 = "3840x2160 30P 16:9";
  return &v2[0x150 * v1];
}

As you can see, around "framerate_1080p_120_mfps" there are manu unknowns, so other fps mod addresses could lay there.


Shutter mod

Pretty easy and compact struct, the layout is:
Code:
class CShutter_video_setting
{
public:
    int32_t base_frame_rate; //0x0000
    int32_t frame_rate_div; //0x0004
    char shutter_name[8]; //0x0008
    char pad_0010[120]; //0x0010
    int32_t exposure; //0x0088
    int32_t unknown; //0x008C
}; //Size: 0x0090

class CShutter_video
{
public:
    char pad_0000[8]; //0x0000
    CShutter_video_setting video_shutter_speed[8]; //0x0008
};
CShutter_video* pShutter= (CShutter_video*)0xA59634;

/*
if ( (unsigned __int16)video_shutter_speed_struct != v9 ) //0xA59634
  {
    v10 = 0;
    v11 = 0;
    while ( 1 )
    {
      ++v11;
      v10 += 0x90;
      if ( v11 == v8 )
        return 0;
      if ( *(_WORD *)(v10 + 0xA59634) == v9 )
        goto LABEL_10;
    }
  }
  v11 = 0;
LABEL_10:
  v13 = 0x90 * v11;
*/


Hope everything is clear and if you have any doubts just ask. In the next hours/day I will push an update to the Fw toolkit to support those too. This way if there arent big changes, we can quickly dump tables and addresses on new fws, and who know, maybe generating custom fw on the fly :whistle:
 
milli frame per second
Framerates are stored in the same way in every struct I have seen. There's a base framerate and a divisor right beside it (just like for the shutter mod).

Also, that camera sensor struct contains video mode timings which is what I changed to get 720@300fps. As for how they relate to the framerate taking my 300fps mode as an example: (((24000000 / 312) / 770) * 3) * 1001 = 300000

The third address needed to force 1080p 120fps to 150fps, it is found at the bottom of the (pal?
It's the ntsc table. The pal equivalent to the 120fps mode is the 100fps mode. The ntsc table is the table that starts with the 4k@30 mode and the pal one starts with the 4k@25 mode.
 
  • Like
Reactions: Mtz
The: t drv pll command looked interesting

https://github.com/irungentoo/Xiaomi_Yi_4k_Camera/blob/master/4k+/autoexec.ash_research/drv/pll.log

t drv pll set gclk_idsp seems to do something but I'm pretty sure the clock gets reset back to the default (576000000) as soon as the cam switches modes.

There are a couple of relevant log entries from the rtos log:

[Desire]IDSP freq: 576000000

[Actual]IDSP freq: 576000000

AmbaDSP_ImgSetSystemPerformanceInfo(), (1001, 60000, 2275, 576000000)

This last print gets called at 0x484dd8 (0x464dd8 in the rtos bin file) and I think that the jump right before to 0x24fab0 is theAmbaDSP_ImgSetSystemPerformanceInfo() function.

The value 576000000 seems to be set at 3 different places in the code:
0x12ebd8
0x13fbf0
0x142ddc

However patching the instructions with writel doesn't seem to do anything and the logs keep printing 576000000
 
Hey late reply I've been busy, not that I'm much help anyway haha.

Do you have any way to test if the PLL is raising the master clock? Like maybe make a LED strobe with an Arduino or 555 to test any frame increases? Cause even oscilloscope might not be much help.

Also, even though the pixel clock can be overclocked and it works, could cranking master clocks make the sensor pop? Cause the differential clock from the sensor is already doing a few hundred MHz and the sensor could get hot without some cooling?

I bought a Yi Action cam (the funky lime green 1080p one) and when it arrives I'm gonna try do some hardware stuff on it, and I wont cry for as long as I would breaking a 4k+.
I also bought some camera connectors to put a test rig between the sensor and the main pcb so I can probe around and figure out a bit of this D-PHY MIPI stuff, because the Yi 4k+ almost definately has another connector on the front of the board for another sensor (not HDMI as I said before, its just D-PHY by the looks of it, a differential clock and data lines, an SPI bus and pinout matches the datasheet I found for a IMX377 sensor module evaluation board).

Lattice semiconductors etc make some cool CSI-2 FPGA bridges and I was seeing how feasible it would be intercept image sensor output and eg. split into alternating frames for 4K120 or split image in half for 6k60 using two Yi+ to process the data and recombine in post video software.

The Yi M1 has a IMX269, which is apparently whats in the Panassonic GH5 and its 20MP at ~60fps 10bit and its APS-C format.

Anyway enough crap from me, but one thing I wanted to ask you @irungentoo , is the Linux stuff inside the wifi module, or is it inside the SoC running parallel with the RTOS and the DSP?
 
so I went off topic, condensed:

However patching the instructions with writel doesn't seem to do anything and the logs keep printing 576000000

Maybe they have disabled it in script if its a dangerous condition for the processor or sensor... *hypothesis*
 
Is this possible to port a VR Firmware from xiaomi 4k to 4k+ for SYNC a few cameras together? Either make a script to sync...
I contacted with yitech about that, but they don't seem to plan to release similar firmware for 4K+.
 
Anyway enough crap from me, but one thing I wanted to ask you @irungentoo , is the Linux stuff inside the wifi module, or is it inside the SoC running parallel with the RTOS and the DSP?

Yes, it's on the soc but it only runs on one of the cores of the arm64 cpu and 66MB of ram.

Maybe they have disabled it in script if its a dangerous condition for the processor or sensor... *hypothesis*

I managed to figure out how to actually increase the dsp and core frequencies. There was an unused branch in the code that sets the clocks to what I assume are the default H2 clocks

writel 0x45d6b8 0xe1a00000 #nop
writel 0x45d6c4 0xea000025

Makes it go to that branch and sets the dsp to 696MHz and core to 552MHz which might be the real default values (camera sets them normally to 576MHz dsp and 432MHz core).

And since the branch it goes to has constants they can be changed by patching out the instructions in the branch:

Lowering the dsp to 432MHz

writel 0x45d760 0xE3A01B33
writel 0x45d768 0xE34119BF

or core to 324MHz

writel 0x45d764 0xE3A03CD9
writel 0x45d76c 0xE341334F

Makes the dsp crash (invalid fb_id in vin_util.c) when recording at 4k@60 but it works at 4k@30. Increasing it doesn't do anything to fix the crash with the 1080p@180 res which is a (run out of WARP_MCTF FB at vproc_prep.c) crash. MCTF means motion compensated temporal filter so I'm assuming since it's not a chip is too slow issue that there's something somewhere that's setting the amount of frames in that buffer to a too high amount.

It would be useful if someone could test if lowering the clocks of the dsp/core can save battery life when recording in modes that don't need much processing power.

Is this possible to port a VR Firmware from xiaomi 4k to 4k+ for SYNC a few cameras together

Would have to check if the hardware can support it first but even then I think it would be very difficult. One of my future projects is to try to make my 4k and 4k+ cameras record at the same time to try to film in 3d (once I get something to properly mount them on at the same time) so I'll see what's possible then but I'm probably going to use wifi or bluetooth.

Also, even though the pixel clock can be overclocked and it works, could cranking master clocks make the sensor pop? Cause the differential clock from the sensor is already doing a few hundred MHz and the sensor could get hot without some cooling?

I don't think there's much chance of that happening. If it's like overclocking computer screens it's just going to stop working at some point if you increase the clock too high but it's not going to get damaged or anything.
 
Last edited:
Back
Top