From c09567541b8f5ca7a56592b465fe03e7c9f6781a Mon Sep 17 00:00:00 2001 From: bzt Date: Tue, 27 Mar 2018 15:54:18 +0200 Subject: [PATCH] Fixed Issue #11 --- 14_raspbootin64/OLVASSEL.md | 16 ++++++++++------ 14_raspbootin64/README.md | 19 +++++++++++-------- 14_raspbootin64/kernel8.img | Bin 912 -> 952 bytes 14_raspbootin64/main.c | 11 +++++++++-- 14_raspbootin64/start.S | 8 ++++++++ 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/14_raspbootin64/OLVASSEL.md b/14_raspbootin64/OLVASSEL.md index 78c63fd4..090c7d2c 100644 --- a/14_raspbootin64/OLVASSEL.md +++ b/14_raspbootin64/OLVASSEL.md @@ -9,25 +9,28 @@ A betöltőprogram egyik felét adja csak, a kernel fogadót, ami az RPi-n fut. megtalálható az eredeti forrásban [raspbootcom](https://github.com/mrvn/raspbootin/blob/master/raspbootcom/raspbootcom.cc) néven. Ha Windowsos gépekről is szeretnél kernelt küldeni, akkor javaslom inkább a John Cronin féle átiratot, a [raspbootin-server](https://github.com/jncronin/rpi-boot/blob/master/raspbootin-server.c)-t, ami natív Win32 API-t használ. +Ezen kvül, @milanvidakovic volt olyan jó fej, hogy megosztotta az általa írt [Java-s verziót](https://github.com/bztsrc/raspi3-tutorial/files/1850345/Raspbootin64Client.zip). Hogy az új kernelt ugyanoda tölthessük be, el kell mozdítanunk a kódunkat az útból. Ezt chain loading-nak hívják, amikor az első kód ugyanarra a címre tölti be a második kódot, ezért az utóbbi azt hiszi, a firmware töltötte be. Hogy ezt megvalósítsuk, egy alacsonyabb címre linkeljük a kódot, és mivel a GPU ettől függetlenül a 0x80000-ra tölt be, -nekünk kell a módosított címre másolnunk magunkat. Fontos, hogy ezalatt csak relatív címzést használhatunk. Amikor -végeztünk, a 0x80000-as címen lévő memóriának használaton kívülinek kell lennie. Ezt a következő paranccsal ellenőrizheted: +nekünk kell a módosított címre másolnunk magunkat. Amikor végeztünk, a 0x80000-as címen lévő memóriának használaton +kívülinek kell lennie. Ezt a következő paranccsal ellenőrizheted: ```sh $ aarch64-elf-readelf -s kernel8.elf | grep __bss_end - 21: 000000000007ffc0 0 NOTYPE GLOBAL DEFAULT 4 __bss_end + 27: 000000000007ffe0 0 NOTYPE GLOBAL DEFAULT 4 __bss_end ``` Ajánlott a kódunkat minimalizálni, mivel úgyis figyelmen kívül hagyja az újonnan betöltendő kód. Ezért kivettem az -`uart_puts()` eljárást, így a teljes méret 1024 bájt alá csökkent. +`uart_puts()` és még néhány eljárást, így sikerült a teljes méretet 1024 bájt alá csökkenteni. Start ----- -Hozzáadtam egy ciklust, ami átmásolja a kódunkat arra a címre, ahová vártuk, hogy betöltődjön. +Először is elmentjük a regiszter paramétereket. Hozzáadtam egy ciklust, ami átmásolja a kódunkat arra a címre, ahová +vártuk, hogy betöltődjön. Végül meghívjuk a relokált C kódot. Mivel a gcc RIP-relatív ugrást generál, nekünk kell a +relokálást hozzáadni a címhez. Linker ------ @@ -38,4 +41,5 @@ méretét is, amit másolnunk kell. Main ---- -Kiírjuk, hogy 'RBIN64', majd beolvassuk az új kernelt a soros vonalról, és átadjuk rá a vezérlést. +Kiírjuk, hogy 'RBIN64', majd beolvassuk az új kernelt a soros vonalról, pontosan oda, ahová a start.elf is töltötte volna. +Majd visszaállítjuk a regiszterparamétereket és átadjuk a vezérlést az új kernelre abszolút címzést használva. diff --git a/14_raspbootin64/README.md b/14_raspbootin64/README.md index 3dc427d0..d23bd25c 100644 --- a/14_raspbootin64/README.md +++ b/14_raspbootin64/README.md @@ -9,26 +9,28 @@ I only provide one part of the loader, the kernel receiver, which runs on the RP part, the sender, which runs on your PC see the original [raspbootcom](https://github.com/mrvn/raspbootin/blob/master/raspbootcom/raspbootcom.cc) utility. If you want to send kernels from a Windows machine, I suggest to take a look at John Cronin's rewrite, [raspbootin-server](https://github.com/jncronin/rpi-boot/blob/master/raspbootin-server.c) which can be compiled for the Win32 API. +Even more, @milanvidakovic was kind to share a [Java version](https://github.com/bztsrc/raspi3-tutorial/files/1850345/Raspbootin64Client.zip) with you. In order to load the new kernel to the same address, we have to move ourself out of the way. It's called chain loading: one code loads the next code to the same position in memory, therefore the latter thinks it was loaded by the firmware. To implement that we use a different linking address this time, and since GPU loads us to 0x80000 -regardless, we have to copy our code to that link address. What's important, that we can only use relative addresses -while doing so. When we're done, the memory at 0x80000 must be free to use. You can checked that with: +regardless, we have to copy our code to that link address. When we're done, the memory at 0x80000 must be free to use. +You can check that with: ```sh $ aarch64-elf-readelf -s kernel8.elf | grep __bss_end - 21: 000000000007ffc0 0 NOTYPE GLOBAL DEFAULT 4 __bss_end + 27: 000000000007ffe0 0 NOTYPE GLOBAL DEFAULT 4 __bss_end ``` -We also should minimize the size of the -loader, since it will be regarded by the newly loaded code anyway. By removing `uart_puts()` I've managed to shrink the -size below 1024 bytes. +We also should minimize the size of the loader, since it will be regarded by the newly loaded code anyway. +By removing `uart_puts()` and other functions, I've managed to shrink the loader's size below 1024 bytes. Start ----- -Added a loop to relocate our code to the address it should have been loaded to. +We have to save the arguments in registers passed by the firmware. Added a loop to relocate our code to the +address it should have been loaded to. And last, since gcc generates RIP-relative jumps, we must adjust the +branch instruction to jump to the relocated C code. Linker ------ @@ -39,4 +41,5 @@ know how many bytes we have to copy. Main ---- -We print 'RBIN64', receive the new kernel over serial, and jump to it. +We print 'RBIN64', receive the new kernel over serial and save it at the memory address where the start.elf would +have been loaded it. When finished, we restore the arguments and jump to the new kernel using an absolute address. diff --git a/14_raspbootin64/kernel8.img b/14_raspbootin64/kernel8.img index d60f7938ea083c5df3162ab069f4498291345bdc..50d3215b166685e8beaab8a29d0bd53e1e7c8638 100755 GIT binary patch delta 151 zcmbQhzJp!h6*I%C*UXHo-Y_$*ddtkbYC?o$4FdxM3lK9faDYjMKkQ)oz{Els#xoQ9 zycjz+-u%v}@qn3Y)k9|PRgai?Ry}6sT_wl3;L-u+_-mho9asLXKC}YF25Fr9fJu|_ n%w#TRcZDz7$LqNacaah0O8*I;Ala delta 92 zcmdnNK7oCrK!ju&0|NsK5Hm1vfJufw>|lDr#6}s$9TVqyF*a>{`JGXKfq_ZnbFkye pztx9U9AJ*WHkpH2lX1snBW8CXS;Z{JJmEk4