|
|
Thread Tools | Search this Thread |
10-05-2017, 01:28 AM | #1 |
Wizard
Posts: 3,821
Karma: 19162882
Join Date: Nov 2012
Location: Te Riu-a-Māui
Device: Kobo Glo
|
Questions on how to create/update Metazoa patches, ARM assembler, objdump, etc.
In this thread I will try to pass on what I have learned about making patches for the Kobo e-ink ereaders. I have been meaning to do this for a while now, but I never know where to start, so if you have a specific question just ask and I'll try to answer here.
I am not an expert on any of this, so don't assume the way I do something is the only way or the best way. I have a bit of background programming in C and x86 assembly language for Linux, but I didn't know anything about ARM CPUs or modifying programs without access to source code until I started patching my Glo. I've just learned the bits I needed as I went along, there are big gaps in my knowledge. I use the following programs in Debian 8 Linux, there are alternatives for other systems but I haven't used them, so any explanation I give will be based on these: * Disassembler: objdump (binutils-multiarch package) -- I use version 2.25, some older versions didn't show function names in disassembly. * Hex editor: emacs [M-x hexl-open-file] (emacs24 package) * Patcher: patch32lsb (included in tools/ directory of patch archives) * A hexdecimal calculator can be handy, I have an old HP 42s. I'll keep an index of topics in this first post and update it as different topics come up: Post #2 Address vs. file offset Post #3 Finding function addresses Post #4 Patching compressed CSS strings Post #8 Function call arguments Last edited by GeoffR; 10-06-2017 at 04:10 AM. Reason: objdump version 2.25 |
10-05-2017, 01:31 AM | #2 |
Wizard
Posts: 3,821
Karma: 19162882
Join Date: Nov 2012
Location: Te Riu-a-Māui
Device: Kobo Glo
|
Address vs. file offset
In patch comments and the patch32lsb code I have used the term address as if it was the same thing as file offset, but that is not always true. For dynamic libraries such as libnickel.so.1.0.0 and librmsdk.so.1.0.0 they are the same, but for executables such as nickel and sickel they are different.
objdump works mainly with addresses, but the patch32lsb tool only deals with file offsets, so for some nickel and sickel patches it may be necessary to convert addresses to file offsets. If you use the -F switch with objdump it will show the file offsets along with the addresses. For example the objdump command: Code:
$ objdump -dCF sickel | grep SickelService::Ping | grep ":$" Code:
0000b2bc <SickelService::Ping()> (File Offset: 0x32bc): Code:
000133d0 <SickelService::Ping()> (File Offset: 0x33d0): Last edited by GeoffR; 10-05-2017 at 08:21 AM. Reason: spelling |
Advert | |
|
10-05-2017, 02:09 AM | #3 |
Wizard
Posts: 3,821
Karma: 19162882
Join Date: Nov 2012
Location: Te Riu-a-Māui
Device: Kobo Glo
|
Finding function addresses
External functions are called indirectly via a jump table. Slots in the jump table are filled in by the linker when the program is loaded.
To find the C++ function ValueDisplaySlider::setStep Code:
objdump -dC libnickel.so.1.0.0 | grep ValueDisplaySlider::setStep | grep ":$" Code:
004d9d14 <ValueDisplaySlider::setStep(int)@plt>: 008214f0 <ValueDisplaySlider::setStep(int)>: To find where the function is called: Code:
objdump -dC libnickel.so.1.0.0 | grep ValueDisplaySlider::setStep | grep @plt Code:
004d9d14 <ValueDisplaySlider::setStep(int)@plt>: 741dce: f597 efa2 blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt> 7420ee: f597 ee12 blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt> 7c692a: f513 e9f4 blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt> 7c69c2: f513 e9a8 blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt> 7c6a58: f513 e95c blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt> 7c6af0: f513 e910 blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt> (The function could be called from other places too, via a pointer variable. I don't know of any easy way to find such calls.) Last edited by GeoffR; 10-05-2017 at 02:23 AM. Reason: indirect calls via a pointer variable |
10-05-2017, 07:43 AM | #4 |
I need a chapter break
Posts: 4,042
Karma: 56058267
Join Date: Mar 2015
Location: Israel
Device: Kobo Glo
|
Create patches form CSS string.
This is a easy way to make patches from CSS string.
From firmware 4.x a lot of code moved from libnickel.so.1.0.0 to nickel have been compressed to CSS string. Tools: CSS styles modifications inside nickel (Python 2 needed). By pipcat makepatch program preferable makepatch-0.02.zip file, By GeoffR Instructions:
To make a patch from the same nickel file repeat steps 5-10. Last edited by oren64; 03-20-2018 at 07:08 AM. |
10-05-2017, 07:43 AM | #5 |
Wizard
Posts: 2,783
Karma: 6990707
Join Date: May 2016
Location: Ontario, Canada
Device: Kobo Mini, Aura Edition 2 v1, Clara HD
|
Thanks so much! This is quite useful.
|
Advert | |
|
10-05-2017, 08:33 AM | #6 |
Grand Sorcerer
Posts: 6,308
Karma: 12116851
Join Date: Jun 2009
Location: Madrid, Spain
Device: Kobo Clara/Aura One/Forma,XiaoMI 5, iPad, Huawei MediaPad, YotaPhone 2
|
Thank you very much both of you!
|
10-05-2017, 09:11 AM | #7 |
Grand Sorcerer
Posts: 6,308
Karma: 12116851
Join Date: Jun 2009
Location: Madrid, Spain
Device: Kobo Clara/Aura One/Forma,XiaoMI 5, iPad, Huawei MediaPad, YotaPhone 2
|
Now, go looking for the other css
|
10-06-2017, 02:37 AM | #8 |
Wizard
Posts: 3,821
Karma: 19162882
Join Date: Nov 2012
Location: Te Riu-a-Māui
Device: Kobo Glo
|
Function call arguments
(Note that objdump refers to the 16 core registers as r0 - r9, sl, fp, ip, sp, lr, pc. Other tools might name them differently.)
The first 4 (non-float) arguments to a C/C++ function are passed in registers r0, r1, r2, r3, with any additional arguments passed on the stack. On return the result (if any) is in r0 - r3, and any of the registers r0 - r3 not used for the result contain junk. The contents of r4 - r9, sl, fp are preserved by the called function. A standard C function takes a fixed number of arguments and returns a single result. In the C source, calling a function with 2 small integer arguments returning a small integer result could look something like: Code:
result = fun(100, 23) Code:
movs r0, #100 movs r1, #23 blx fun@plt ; now r0 contains result, r1 - r3 are junk Code:
result = obj.fun(100, 23) Code:
ldr r0, [sp, #40] ; obj movs r1, #100 movs r2, #23 blx Class::fun(int,int)@plt ; now r0 contains result, r1 - r3 are junk Code:
<Patch>
patch_name = `Brightness fine control`
patch_enable = `yes`
#
## Sun symbols change the frontlight brightness in 2% instead of 1% steps.
#
# ValueDisplaySlider::setStep(1) --> ValueDisplaySlider::setStep(2)
replace_int = 741DCA, 1, 2
</Patch>
Code:
objdump -dC libnickel.so.1.0.0 --start-address=0x741dc6 | less Code:
741dc6: f8d4 308c ldr.w r3, [r4, #140] ; 0x8c
741dca: 2101 movs r1, #1
741dcc: 6a58 ldr r0, [r3, #36] ; 0x24
741dce: f597 efa2 blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt>
Code:
741dc6: f8d4 308c ldr.w r3, [r4, #140] ; 0x8c
741dca: 2102 movs r1, #2
741dcc: 6a58 ldr r0, [r3, #36] ; 0x24
741dce: f597 efa2 blx 4d9d14 <ValueDisplaySlider::setStep(int)@plt>
|
10-06-2017, 04:24 PM | #9 | |
Grand Sorcerer
Posts: 6,308
Karma: 12116851
Join Date: Jun 2009
Location: Madrid, Spain
Device: Kobo Clara/Aura One/Forma,XiaoMI 5, iPad, Huawei MediaPad, YotaPhone 2
|
Quote:
How do you adapt the absolut addresses to relative ones? Pdta: Forget it, I found the option -b Last edited by Terisa de morgan; 10-06-2017 at 04:26 PM. Reason: I found the answer |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Index to the Metazoa firmware patches | GeoffR | Kobo Developer's Corner | 284 | 01-11-2023 05:16 PM |
KindleTool: Create/Unpack Kindle update files | NiLuJe | Kindle Developer's Corner | 189 | 12-21-2021 09:41 PM |
Paperwhite 5.4.2 update questions | joangolfing | Amazon Kindle | 11 | 11-25-2013 11:28 AM |
Feature request: Update Patches | kiwimonk | Calibre | 1 | 01-05-2011 01:09 PM |
An update and a few questions... | kressg23 | HanLin eBook | 9 | 03-10-2009 09:05 PM |