Rockbox Development > Starting Development and Compiling
Beginning steps in kernel disassembly and analysis
amachronic:
--- Quote from: dconrad on June 19, 2021, 08:34:40 AM ---it didn't seem to rigorously follow the struct pattern of pointer to string, pointer to data, size
--- End quote ---
It does :) you just made some of those "pointer to data" an int. And ghidra obscured the beginning of the array with "false" references.
Recommend you create a struct -- select the data members of one struct instance in the main window, press shift+[ -- clear the types from the entire range (select it & press C) and assign the whole thing to an array of structs. (You may have to clear spurious types added by ghidra near the end of the array since it won't let you cause an overlap with other typed data.)
I found it's good to create structs aggressively even if creating them by hand is a bit slow... it pays off later. And ghidra also lets you use bitfields in structs, which is sometimes necessary. (bitfield type is named like uint:N). Should you need to amend the struct due to wrong members, wrong alignment, etc, you can quickly edit it and any place the struct is used will automatically update to the new definition. Very handy.
dconrad:
--- Quote from: amachronic on June 19, 2021, 08:03:13 AM ---Go look at one of the other LCD drivers to get an idea of what you're looking for, mainly you want to figure out bpp, smart_config.bus_width, smart_config.write_gram_command, and smart_config.data_table. There are also the LCD ops for powering on the panel (GPIOs, levels, timings, etc. needed to power it up.)
--- End quote ---
Some progress on the LCD structs, though I'm having trouble figuring out jzfb_platform_data - nothing in it seems to line up quite right, even if I get creative with padding in between stuff. fb_videomode seemed to go together pretty smoothly though. This is pointed to from the pdata position.
--- Code: --- jzfb_platform_data XREF[1]: 805728e8(*)
80514788 01 00 00 00 uint 1h
8051478c 14 48 51 80 addr fb_videomode =
80514790 00 ?? 00h
80514791 00 ?? 00h
80514792 00 ?? 00h
80514793 00 ?? 00h
80514794 0d ?? 0Dh
80514795 00 ?? 00h
80514796 00 ?? 00h
80514797 80 ?? 80h
80514798 18 ?? 18h
80514799 00 ?? 00h
8051479a 00 ?? 00h
8051479b 00 ?? 00h
8051479c 1f ?? 1Fh
8051479d 00 ?? 00h
8051479e 00 ?? 00h
8051479f 00 ?? 00h
805147a0 1f ?? 1Fh
805147a1 00 ?? 00h
805147a2 00 ?? 00h
805147a3 00 ?? 00h
805147a4 00 ?? 00h
805147a5 00 ?? 00h
805147a6 00 ?? 00h
805147a7 00 ?? 00h
805147a8 00 ?? 00h
805147a9 00 ?? 00h
805147aa 00 ?? 00h
805147ab 00 ?? 00h
805147ac 11 ?? 11h
805147ad 00 ?? 00h
805147ae 00 ?? 00h
805147af 00 ?? 00h
805147b0 01 ?? 01h
805147b1 00 ?? 00h
805147b2 00 ?? 00h
805147b3 00 ?? 00h
805147b4 4c 48 51 80 addr fb_videomode.flag = null
805147b8 08 ?? 08h
805147b9 00 ?? 00h
805147ba 00 ?? 00h
805147bb 00 ?? 00h
805147bc 00 ?? 00h
805147bd 00 ?? 00h
805147be 00 ?? 00h
805147bf 00 ?? 00h
805147c0 38 ?? 38h 8
805147c1 00 ?? 00h
805147c2 00 ?? 00h
805147c3 00 ?? 00h
805147c4 7c 48 51 80 addr LAB_8051487c
805147c8 00 ?? 00h
805147c9 00 ?? 00h
805147ca 00 ?? 00h
805147cb 00 ?? 00h
805147cc 00 ?? 00h
805147cd 00 ?? 00h
805147ce 00 ?? 00h
805147cf 00 ?? 00h
805147d0 00 ?? 00h
805147d1 00 ?? 00h
805147d2 00 ?? 00h
805147d3 00 ?? 00h
805147d4 00 ?? 00h
805147d5 00 ?? 00h
805147d6 00 ?? 00h
805147d7 00 ?? 00h
805147d8 00 ?? 00h
805147d9 00 ?? 00h
805147da 00 ?? 00h
805147db 00 ?? 00h
805147dc 00 ?? 00h
805147dd 00 ?? 00h
805147de 00 ?? 00h
805147df 00 ?? 00h
805147e0 00 ?? 00h
805147e1 00 ?? 00h
805147e2 00 ?? 00h
805147e3 00 ?? 00h
805147e4 00 ?? 00h
805147e5 00 ?? 00h
805147e6 00 ?? 00h
805147e7 00 ?? 00h
805147e8 00 ?? 00h
805147e9 00 ?? 00h
805147ea 00 ?? 00h
805147eb 00 ?? 00h
805147ec 00 ?? 00h
805147ed 00 ?? 00h
805147ee 00 ?? 00h
805147ef 00 ?? 00h
805147f0 a8 94 01 80 addr LAB_800194a8
805147f4 d4 93 01 80 addr FUN_800193d4
805147f8 00 ?? 00h
805147f9 00 ?? 00h
805147fa 00 ?? 00h
805147fb 00 ?? 00h
805147fc 00 ?? 00h
805147fd 00 ?? 00h
805147fe 00 ?? 00h
805147ff 00 ?? 00h
80514800 00 ?? 00h
80514801 00 ?? 00h
80514802 00 ?? 00h
80514803 00 ?? 00h
80514804 00 ?? 00h
80514805 00 ?? 00h
80514806 00 ?? 00h
80514807 00 ?? 00h
80514808 00 ?? 00h
80514809 00 ?? 00h
8051480a 00 ?? 00h
8051480b 00 ?? 00h
8051480c 00 ?? 00h
8051480d 00 ?? 00h
8051480e 00 ?? 00h
8051480f 00 ?? 00h
80514810 00 ?? 00h
80514811 00 ?? 00h
80514812 00 ?? 00h
80514813 00 ?? 00h
fb_videomode.flag XREF[1,1]: 8051478c(*), 805147b4(*)
fb_videomode
80514814 e0 8d 4b fb_video
80 50 00
00 00 40
80514814 e0 8d 4b 80 addr s_320x240_804b8de0 name = "320x240" XREF[1]: 8051478c(*)
80514818 50 00 00 00 uint 50h refresh
8051481c 40 01 00 00 uint 140h xres
80514820 f0 00 00 00 uint F0h yres
80514824 50 c3 00 00 uint C350h init_pixclock
80514828 00 00 00 00 uint 0h pixclock
8051482c 00 00 00 00 uint 0h left_margin
80514830 00 00 00 00 uint 0h right_margin
80514834 00 00 00 00 uint 0h upper_margin
80514838 00 00 00 00 uint 0h lower_margin
8051483c 00 00 00 00 uint 0h hsync_len
80514840 03 00 00 00 uint 3h vsync_len
80514844 00 00 00 00 uint 0h sync
80514848 00 00 00 00 uint 0h vmode
8051484c 2c 2c 2c 2c uint 2C2C2C2Ch flag XREF[1]: 805147b4(*)
--- End code ---
I had some progress on jzmmc_platform_data, too, but again I can't quite get stuff to line up correctly. I think the mmc_recovery_info struct is located directly below it, but it doesn't seem to fit before the pointer to s_bt_power_804b761c.
--- Code: --- jzmmc_platform_data_80511180 XREF[1]: 8057287c(*)
80511180 02 00 00 jzmmc_pl
00 00 00
30 00 07
80511180 02 00 ushort 2h removal XREF[1]: 8057287c(*)
80511182 00 00 ushort 0h sdio_clk
80511184 00 00 30 00 uint 300000h ocr_avail
80511188 07 00 00 00 uint 7h capacity
8051118c 00 00 00 00 uint 0h pm_flags
80511190 00 6c dc 02 uint 2DC6C00h max_freq
80511194 00 00 00 00 int 0h UNDEFINED
80511198 b0 11 51 80 00 addr PTR_805111b0 *recovery_info = NaP
00 00 00
805111a0 00 00 00 00 00 addr 00000000 *gpio
00 00 00
805111a8 00 00 00 00 uint 0h pio_mode
805111ac 00 00 00 00 int 0h (*private_in
PTR_805111b0 XREF[1]: 80511198(*)
805111b0 ff ff ff addr * NaP
ff 2b 00
00 00
partition_num
805111b8 2a 00 01 00 uint 1002Ah
permission
805111bc ff ff ff ff uint FFFFFFFFh
protect_boundary XREF[1]: 80572884(*)
805111c0 1c 76 4b 80 uint * s_bt_power_804b761c = "bt_power"
805111c4 ff ff ff ff int FFFFFFFFh
805111c8 00 ?? 00h
805111c9 00 ?? 00h
--- End code ---
I'm going to just keep inspecting different stuff, there's a lot to go through!
dconrad:
I have a suspicion that the jzfb_platform_data struct is actually the one outlined in arch/mips/xburst/soc-x1000/include/mach/jzfb.h, could this be true?
dconrad:
I'm going out on a limb here, but I found 2 LCD jzfb_platform_data structs that seem to match up somewhat with the data I have, though I can't get the struct to line up right (it uses bitfields...), so I'm probably in error here...
lcd-bmtf200_2.c and lcd-ili9342_320240.c:
--- Code: ---struct jzfb_platform_data jzfb_pdata = {
.num_modes = 1,
.modes = &jzfb0_videomode,
.lcd_type = LCD_TYPE_SLCD,
.bpp = 24,
.width = 31,
.height = 31,
.pinmd = 0,
.smart_config.rsply_cmd_high = 0,
.smart_config.csply_active_high = 0,
.smart_config.newcfg_fmt_conv = 1,
.smart_config.write_gram_cmd = cmd_buf,
.smart_config.clkply_active_rising = 1,
.smart_config.length_cmd = ARRAY_SIZE(cmd_buf),
.smart_config.bus_width = 8,
.smart_config.length_data_table = ARRAY_SIZE(ili9342_data_table),
.smart_config.data_table = ili9342_data_table,
.dither_enable = 0,
};
--- End code ---
and my data struct - which is all messed up, but the first few items seem to make sense:
--- Code: --- jzfb_platform_data XREF[1]: 805728e8(*)
80514788 01 00 00 jzfb_pla
00 14 48
51 80 00
80514788 01 00 00 00 long 1h num_modes XREF[1]: 805728e8(*)
8051478c 14 48 51 80 addr fb_videomode *modes =
80514790 00 00 00 00 addr 00000000 *dsi_data
80514794 0d 00 00 80 uint 8000000Dh lcd_type
80514798 18 00 00 00 uint 18h bpp
8051479c 1f 00 00 00 uint 1Fh width
805147a0 1f 00 00 00 uint 1Fh height
805147a4 00 uint:1 0h pinmd:1
805147a4 00 uint:1 0h pixclk_falli
805147a4 00 uint:1 0h data_enable_
805147a5 00 00 00 00 00 smart_co field_0x1d
00 00 11 00 00
00 01 00 00 00
805147a5 00 00 00 00 uint 0h smart_type
805147a9 00 uint:1 0h clkply_activ
805147a9 00 uint:1 0h rsply_cmd_hi
805147a9 00 uint:1 0h csply_active
805147a9 00 uint:1 0h newcfg_6800_
805147a9 00 uint:1 0h newcfg_fmt_c
805147a9 00 uint:1 0h datatx_type_
805147a9 00 uint:1 0h newcfg_cmd_9
805147aa 00 00 11 00 ulong 110000h length_cmd
805147ae 00 00 01 00 addr 00010000 write_gram_cmd
805147b2 00 00 4c 48 ulong 484C0000h bus_width
805147b6 51 80 08 00 uint 88051h data_times
805147ba 00 00 00 00 ulong 0h length_data_
805147be 00 00 38 00 addr 00380000 *data_table
805147c2 00 00 7c 48 addr 487c0000 (*init)
805147c6 51 80 00 00 addr 00008051 (*gpio_for_s
805147ca 00 00 00 00 int 0h te_gpio
805147ce 00 00 00 00 int 0h te_irq_level
805147d2 00 uint:1 0h dither_enabl
805147d3 00 00 00 00 00 dither dither
00 00 00 00 00
00 00
805147d3 00 00 00 00 uint 0h dither_red
805147d7 00 00 00 00 uint 0h dither_green
805147db 00 00 00 00 uint 0h dither_blue
805147df 00 ?? 00h
805147e0 00 ?? 00h
805147e1 00 ?? 00h
805147e2 00 ?? 00h
805147e3 00 ?? 00h
--- End code ---
I dunno, I've been playing with it for an hour or 2 and I can't seem to get anything past "height" to make any sense.
amachronic:
0x2c2c2c2c is most definitely the value pointed to by smart_config.write_gram_cmd. 0x2c is the standard write_memory_start command of MIPI DCS, used to initiate writing data to the LCD controller's framebuffer RAM. It's not fb_videomode.flag.
In the M3K kernel sources the init_pixclock member is dropped vs. the YuanhuanLiang repo. That's probably why your fb_videomode struct is too big. Maybe you should check the M3K sources for other structs that seem "wrong", it's possible that the Eros Q is using sources similar to the M3K's. (A reminder that your source won't necessarily line up with the binary!)
So with this in mind, jzfb stuff looks lined up right to me:
--- Code: ---805147ac = bitfield
clkply_active_rising=1
newcfg_fmt_conv=1
others=0
(this is standard fare, nothing exotic)
805147b8 = smart_config.bus_width
805147c0 = smart_config.length_data_table
805147c4 = smart_config.data_table
--- End code ---
Also a look at this
--- Code: --- 805147a4 00 uint:1 0h pinmd:1
805147a4 00 uint:1 0h pixclk_falli
805147a4 00 uint:1 0h data_enable_
805147a5 00 00 00 00 00 smart_co field_0x1d
--- End code ---
That start address 805147a5 is almost certainly wrong. The alignment of the struct is at least 4 bytes and struct alignment = maximum alignment of any member. Plus, the first member must be aligned wrong because enums seem to be ints under the ABI used (an implementation detail which I haven't bothered to verify but seems to be true).
Weirdly, Ghidra doesn't align structs by default -- in the lower right corner of the struct editor is an unobtrusive "Align" checkbox. Checking that will make Ghidra insert the correct padding to follow C alignment rules (afaict). It seems Ghidra defaults to "packed" alignment by default... it confused me for a couple hours too. :o
In this particular case I think I can say with certainty the alignment is wrong -- but in general, you would need to check the generated code to see if the compiler emitted code to access aligned addresses or unaligned addresses. The lw/sw instructions to load/store a word require 4 byte aligned addresses, whereas to access an improperly aligned word, the compiler would need to generate different instructions -- in the case of MIPS the instructions used would depend on the ISA version targeted, IIRC the older versions don't have any unaligned load/store instructions.
--- Quote from: dconrad on June 19, 2021, 10:38:06 PM ---I have a suspicion that the jzfb_platform_data struct is actually the one outlined in arch/mips/xburst/soc-x1000/include/mach/jzfb.h, could this be true?
--- End quote ---
That's my assumption. Sure, it's defined in other parts of the xburst tree for other SoCs, but this is an X1000 kernel... where else would it be defined?
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version