samdrv.ko reverse engineering

Here is information about customize your B series firmware..:!:This forum is NOT FOR USER questions or problems but DEVELOPER.

User avatar
erdem_ua
SamyGO Admin
Posts: 3126
Joined: Thu Oct 01, 2009 6:02 am
Location: Istanbul, Turkey
Contact:

Re: samdrv.ko reverse engineering

Post by erdem_ua »

This will be good but requires good linux kernel knowledge... If you start, I guess people will follow. :)
smartsmurf
Official SamyGO Developer
Posts: 111
Joined: Thu Jun 24, 2010 8:26 am
Location: Frankfurt, Germany

Re: samdrv.ko reverse engineering

Post by smartsmurf »

At first stage I would deeply investigate into the debug interface of samdrv.ko. Please find attached some examples.
At second stage one can patch samdrv.ko in memory using a self-written kernel module (i tried that - it works!).

Best regards,
SM
You do not have the required permissions to view the files attached to this post.
smartsmurf
Official SamyGO Developer
Posts: 111
Joined: Thu Jun 24, 2010 8:26 am
Location: Frankfurt, Germany

Re: samdrv.ko reverse engineering

Post by smartsmurf »

Guessed? No, I started here inside the init_module function:

Code: Select all

...
.text.devDbg_ModuleInit:0003B98C 24 20 9F E5                 LDR     R2, =devDbgFops
.text.devDbg_ModuleInit:0003B990 24 00 9F E5                 LDR     R0, =aDbg       ; "dbg"
.text.devDbg_ModuleInit:0003B994 4C B2 01 EB                 BL      OsaModule_RegisterDev
...
Then I came across the file operations (defined in fs.h)

Code: Select all

.data.devDbgFops:00101AAC 00 00 00 00+devDbgFops      DCD 0, 0, 0, 0, 0, 0, 0, 0
.data.devDbgFops:00101AAC 00 00 00 00+                                        ; DATA XREF: devDbg_ModuleInit+10o
.data.devDbgFops:00101AAC 00 00 00 00+                                        ; .text.devDbg_ModuleInit:off_3B9B8o
.data.devDbgFops:00101ACC 00 BB 03 00                 DCD devDbg_Ioctl
.data.devDbgFops:00101AD0 00 00 00 00+                DCD 0, 0, 0
.data.devDbgFops:00101ADC 64 BA 03 00                 DCD devDbg_Open
.data.devDbgFops:00101AE0 00 00 00 00                 DCD 0
.data.devDbgFops:00101AE4 C8 B9 03 00                 DCD devDbg_Release
.data.devDbgFops:00101AE8 00 00 00 00+                DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
.data.devDbgFops:00101AE8 00 00 00 00+; .data.devDbgFops ends
So the dbg-device supports open(), ioctl() and close().

Finally I analyzed the devDbg_Ioctl function:

Code: Select all

.text.devDbg_Ioctl:0003BB00 0D C0 A0 E1                 MOV     R12, SP
.text.devDbg_Ioctl:0003BB04 30 D8 2D E9                 STMFD   SP!, {R4,R5,R11,R12,LR,PC}
.text.devDbg_Ioctl:0003BB08 04 B0 4C E2                 SUB     R11, R12, #4
.text.devDbg_Ioctl:0003BB0C 10 D0 4D E2                 SUB     SP, SP, #0x10
.text.devDbg_Ioctl:0003BB10 01 04 A0 E3                 MOV     R0, #0x1000000
.text.devDbg_Ioctl:0003BB14 02 40 A0 E1                 MOV     R4, R2
.text.devDbg_Ioctl:0003BB18 03 50 A0 E1                 MOV     R5, R3
.text.devDbg_Ioctl:0003BB1C B1 FA FF EB                 BL      CheckPrintLevel
.text.devDbg_Ioctl:0003BB20 00 00 50 E3                 CMP     R0, #0
.text.devDbg_Ioctl:0003BB24 27 00 00 1A                 BNE     loc_3BBC8
.text.devDbg_Ioctl:0003BB28
.text.devDbg_Ioctl:0003BB28             loc_3BB28                               ; CODE XREF: devDbg_Ioctl+F4j
.text.devDbg_Ioctl:0003BB28                                                     ; devDbg_Ioctl+118j
.text.devDbg_Ioctl:0003BB28 01 30 44 E2                 SUB     R3, R4, #1
.text.devDbg_Ioctl:0003BB2C 23 00 53 E3                 CMP     R3, #35         ; switch 36 cases
.text.devDbg_Ioctl:0003BB30 03 F1 9F 97                 LDRLS   PC, [PC,R3,LSL#2] ; switch jump
.text.devDbg_Ioctl:0003BB34 44 00 00 EA                 B       IOCTL_UNKNOWN   ; default
.text.devDbg_Ioctl:0003BB34                                                     ; jumptable 0003BB30 cases 25-30
.text.devDbg_Ioctl:0003BB34             ; ---------------------------------------------------------------------------
.text.devDbg_Ioctl:0003BB38 1C BC 03 00+                DCD IO_SAM_DEBUG_READ   ; jump table for switch statement
.text.devDbg_Ioctl:0003BB38 A4 C0 03 00+                DCD IO_SAM_DEBUG_WRITE
.text.devDbg_Ioctl:0003BB38 CC BF 03 00+                DCD IO_SAM_GET_PRINT_LEVEL
.text.devDbg_Ioctl:0003BB38 64 C0 03 00+                DCD IO_SAM_SET_PRINT_LEVEL
.text.devDbg_Ioctl:0003BB38 6C BE 03 00+                DCD IO_SAM_GET_PRINT_MODULE
.text.devDbg_Ioctl:0003BB38 84 C0 03 00+                DCD IO_SAM_SET_PRINT_MODULE
.text.devDbg_Ioctl:0003BB38 2C BF 03 00+                DCD IO_SAM_PRINT_INIT
.text.devDbg_Ioctl:0003BB38 0C C0 03 00+                DCD IO_SAM_DISABLE_PRINT_LEVEL
.text.devDbg_Ioctl:0003BB38 B8 BD 03 00+                DCD IO_SAM_DISABLE_PRINT_MODULE
.text.devDbg_Ioctl:0003BB38 9C BF 03 00+                DCD IO_PRINT_S
.text.devDbg_Ioctl:0003BB38 7C BF 03 00+                DCD IO_SAM_CHECK_PRINT_ISR
.text.devDbg_Ioctl:0003BB38 2C C0 03 00+                DCD IO_SAM_UART_SENDSTRING
.text.devDbg_Ioctl:0003BB38 F8 BD 03 00+                DCD IO_SAM_UART_GETSTRING
.text.devDbg_Ioctl:0003BB38 E8 BE 03 00+                DCD IO_SAM_MODE_FLAG
.text.devDbg_Ioctl:0003BB38 C8 BE 03 00+                DCD IO_SAM_MODE_CHANGE
.text.devDbg_Ioctl:0003BB38 EC BF 03 00+                DCD TSD_DEBUG
.text.devDbg_Ioctl:0003BB38 34 BD 03 00+                DCD VD_DEBUG
.text.devDbg_Ioctl:0003BB38 AC BF 03 00+                DCD PVR_DEBUG
.text.devDbg_Ioctl:0003BB38 8C BE 03 00+                DCD AE_DEBUG
.text.devDbg_Ioctl:0003BB38 48 BF 03 00+                DCD AIO_DEBUG
.text.devDbg_Ioctl:0003BB38 D8 BD 03 00+                DCD IO_SAM_GET_MODULE_DATE
.text.devDbg_Ioctl:0003BB38 4C BE 03 00+                DCD IO_SAM_GET_MODULE_TIME
.text.devDbg_Ioctl:0003BB38 30 BE 03 00+                DCD IO_SAM_PRINT_IRQCOUNT
.text.devDbg_Ioctl:0003BB38 0C BF 03 00+                DCD IO_SAM_CHECKIRQFREQ
.text.devDbg_Ioctl:0003BB38 78 BD 03 00+                DCD IO_SAM_DEBUG_READ_MEM
.text.devDbg_Ioctl:0003BB38 4C BC 03 00+                DCD IOCTL_UNKNOWN
.text.devDbg_Ioctl:0003BB38 4C BC 03 00+                DCD IOCTL_UNKNOWN
.text.devDbg_Ioctl:0003BB38 4C BC 03 00+                DCD IOCTL_UNKNOWN
.text.devDbg_Ioctl:0003BB38 4C BC 03 00+                DCD IOCTL_UNKNOWN
.text.devDbg_Ioctl:0003BB38 4C BC 03 00+                DCD IOCTL_UNKNOWN
.text.devDbg_Ioctl:0003BB38 4C BC 03 00+                DCD IOCTL_UNKNOWN
.text.devDbg_Ioctl:0003BB38 0C BD 03 00+                DCD IO_SAM_DEBUG_WRITE_MEM
.text.devDbg_Ioctl:0003BB38 9C BC 03 00+                DCD AD_DEBUG
.text.devDbg_Ioctl:0003BB38 D8 BC 03 00+                DCD IO_SAM_GET_AE_DEC_ERR_CNT
.text.devDbg_Ioctl:0003BB38 80 BC 03 00+                DCD IO_SAM_CROAD_START
.text.devDbg_Ioctl:0003BB38 64 BC 03 00                 DCD IO_SAM_CROAD_STOP
Further questions? 8-)
smartsmurf
Official SamyGO Developer
Posts: 111
Joined: Thu Jun 24, 2010 8:26 am
Location: Frankfurt, Germany

Re: samdrv.ko reverse engineering

Post by smartsmurf »

The thread is quite calm so far. Maybe the topic is not so interesting for the members here...? :?

When looking into samdrv.ko one can find some ?-codes for attached microprocessors. So the audio decoding (AD) part is handled by so-called "Aida". You can find some Aida codes here:

Code: Select all

.data.AidaUcodeAC3MP:00101C7C             ; ===========================================================================
.data.AidaUcodeAC3MP:00101C7C
.data.AidaUcodeAC3MP:00101C7C             ; [00046360 BYTES: COLLAPSED SEGMENT .data.AidaUcodeAC3MP. PRESS KEYPAD "+" TO EXPAND]
.data.AidaUcodeWMA:00147FDC             ; ===========================================================================
.data.AidaUcodeWMA:00147FDC
.data.AidaUcodeWMA:00147FDC             ; [0005CA10 BYTES: COLLAPSED SEGMENT .data.AidaUcodeWMA. PRESS KEYPAD "+" TO EXPAND]
.data.AidaUcodePCM:001A49EC             ; ===========================================================================
.data.AidaUcodePCM:001A49EC
.data.AidaUcodePCM:001A49EC             ; [00038990 BYTES: COLLAPSED SEGMENT .data.AidaUcodePCM. PRESS KEYPAD "+" TO EXPAND]
.data.AidaUcodeAAC:001DD37C             ; ===========================================================================
.data.AidaUcodeAAC:001DD37C
.data.AidaUcodeAAC:001DD37C             ; [00066060 BYTES: COLLAPSED SEGMENT .data.AidaUcodeAAC. PRESS KEYPAD "+" TO EXPAND]
.data.AidaUcodeEC3:002433DC             ; ===========================================================================
.data.AidaUcodeEC3:002433DC
.data.AidaUcodeEC3:002433DC             ; [00059FD0 BYTES: COLLAPSED SEGMENT .data.AidaUcodeEC3. PRESS KEYPAD "+" TO EXPAND]
When looking at the code density and guessing, it obviously is a 16-Bit machine. After changing its byte order, the ucodes can be disassembled using CalmRISC16 disassembler. Nice findings you will see. :D

Another ucode is called TSD_UCODE (which stands for transport stream decryption/demux?):

Code: Select all

.rodata.TSD_UCODE_DM:000F7BEC             ; ===========================================================================
.rodata.TSD_UCODE_DM:000F7BEC
.rodata.TSD_UCODE_DM:000F7BEC             ; [0000022C BYTES: COLLAPSED SEGMENT .rodata.TSD_UCODE_DM. PRESS KEYPAD "+" TO EXPAND]
.rodata.TSD_UCODE:000F7E18             ; ===========================================================================
.rodata.TSD_UCODE:000F7E18
.rodata.TSD_UCODE:000F7E18             ; [00003000 BYTES: COLLAPSED SEGMENT .rodata.TSD_UCODE. PRESS KEYPAD "+" TO EXPAND]
.rodata.TSD_UCODE_DM1:000FAE18             ; ===========================================================================
.rodata.TSD_UCODE_DM1:000FAE18
.rodata.TSD_UCODE_DM1:000FAE18             ; [0000022C BYTES: COLLAPSED SEGMENT .rodata.TSD_UCODE_DM1. PRESS KEYPAD "+" TO EXPAND]
.rodata.TSD_UCODE1:000FB044             ; ===========================================================================
.rodata.TSD_UCODE1:000FB044
.rodata.TSD_UCODE1:000FB044             ; [00003000 BYTES: COLLAPSED SEGMENT .rodata.TSD_UCODE1. PRESS KEYPAD "+" TO EXPAND]
The TSD_UCODE looks like a 32 Bit machine, but the type is yet unknown to me. According to the symbols in samdrv.ko it is declared as ARM7TDMI, but ARM code looks different. Any hint is appreciated.
User avatar
erdem_ua
SamyGO Admin
Posts: 3126
Joined: Thu Oct 01, 2009 6:02 am
Location: Istanbul, Turkey
Contact:

Re: samdrv.ko reverse engineering

Post by erdem_ua »

I don't know or understand from kernel codes. But as I guess that codes initializes audio chip, changes its modes etc... Since audio chip have it's own micro architecture, I don't wait it's initialization codes in arm architecture... Kernel just put this bytes to audio chip. That is all.
sbav1
Official SamyGO Developer
Posts: 374
Joined: Fri Jan 15, 2010 10:20 am

Re: samdrv.ko reverse engineering

Post by sbav1 »

smartsmurf wrote:The thread is quite calm so far. Maybe the topic is not so interesting for the members here...? :?

On the contrary, this is very interesting stuff; just keep up the good work :)

Interesting thing is, some audio formats (E-AC3/DD+, HE-AAC, MP2/MP3) seem to be soft-decoded (on "main" ARMv6 core) in samdrv.ko, not on the Aida engine. I wonder wich microcode is used for "regular" AC3: AidaUcodeAC3MP? AidaUcodeEC3? Or maybe "AidaUcodeEC3" microcode is being used by AC3 encoder incorporated in samdrv.ko?
When looking at the code density and guessing, it obviously is a 16-Bit machine. After changing its byte order, the ucodes can be disassembled using CalmRISC16 disassembler. Nice findings you will see. :D
Any chances PCM microcode can be modified to allow bit-perfect 44.1/48kHz 16bit playback over SPDIF?
The TSD_UCODE looks like a 32 Bit machine, but the type is yet unknown to me. According to the symbols in samdrv.ko it is declared as ARM7TDMI, but ARM code looks different. Any hint is appreciated.
According to well known Chelsea/SDP83 specs, TSD is utilizing "Embedded OpenRISC (32-bit, program memory size: 12KB, Data memory size: 3KB)".
smartsmurf
Official SamyGO Developer
Posts: 111
Joined: Thu Jun 24, 2010 8:26 am
Location: Frankfurt, Germany

Re: samdrv.ko reverse engineering

Post by smartsmurf »

sbav1 wrote: Or maybe "AidaUcodeEC3" microcode is being used by AC3 encoder incorporated in samdrv.ko?
Yes, it looks like it is done this way.
sbav1 wrote: Any chances PCM microcode can be modified to allow bit-perfect 44.1/48kHz 16bit playback over SPDIF?
This would be a long way since not all peripherals are open source, but should be possible.
sbav1 wrote: According to well known Chelsea/SDP83 specs, TSD is utilizing "Embedded OpenRISC (32-bit, program memory size: 12KB, Data memory size: 3KB)".
"well known" - I have not seen it until now. Where can I find the spec?

Best regards.
sbav1
Official SamyGO Developer
Posts: 374
Joined: Fri Jan 15, 2010 10:20 am

Re: samdrv.ko reverse engineering

Post by sbav1 »

smartsmurf wrote:
sbav1 wrote: According to well known Chelsea/SDP83 specs, TSD is utilizing "Embedded OpenRISC (32-bit, program memory size: 12KB, Data memory size: 3KB)".
"well known" - I have not seen it until now. Where can I find the spec?
Check out this thread: http://forum.samygo.tv/viewtopic.php?f=3&t=76
I belive original source was (probably): http://forum.ixbt.com/topic.cgi?id=62:15456:1947

Post Reply

Return to “[B] Firmware”