<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://freemyipod.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=LemonJesus</id>
	<title>freemyipod - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://freemyipod.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=LemonJesus"/>
	<link rel="alternate" type="text/html" href="https://freemyipod.org/wiki/Special:Contributions/LemonJesus"/>
	<updated>2026-04-26T13:08:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://freemyipod.org/index.php?title=RetailOS&amp;diff=22076</id>
		<title>RetailOS</title>
		<link rel="alternate" type="text/html" href="https://freemyipod.org/index.php?title=RetailOS&amp;diff=22076"/>
		<updated>2024-05-09T19:44:04Z</updated>

		<summary type="html">&lt;p&gt;LemonJesus: add a RTXC 3.2 training manual I found on archive.org&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The stock operating system running on non-iOS iPods. It runs everything from device drivers to the clickwheel user interface.&lt;br /&gt;
&lt;br /&gt;
== Naming ==&lt;br /&gt;
&lt;br /&gt;
The only &#039;official&#039; name seems to be &#039;retailOS&#039;, found in the [[Nano 3G]] WTF. It is also referred to as &#039;osos&#039; per the file name in the resource partition of the firmware bundle.&lt;br /&gt;
&lt;br /&gt;
== Architecture ==&lt;br /&gt;
&lt;br /&gt;
retailOS is a small, embedded, single-user, single-binary, real time operating system. With time it acquire more and more complex functionality, like PowerVR drivers and being able to load external applications (&#039;eApps&#039;) which are used for games.&lt;br /&gt;
&lt;br /&gt;
The core of the system is based on RTXC 3.2, with the end-user interface based on intellectual property from a company called Pixo. &amp;lt;ref&amp;gt;https://web.archive.org/web/20230224105131/https://twitter.com/johnwhitley/status/1451952369248264201&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
&lt;br /&gt;
As evidenced by the success of the [[Notes vulnerability]], at least up to Nano 4G there was no kind of security hardening, and in fact all processes, including games, seem to be running in ARM system mode. This should make exploitation of newer retailOS bugs trivial.&lt;br /&gt;
&lt;br /&gt;
=== Boot chain ===&lt;br /&gt;
&lt;br /&gt;
retailOS is loaded by the second-stage bootloader (stored on NOR/NAND depending on the device generation), from NAND into DRAM.&lt;br /&gt;
&lt;br /&gt;
While other stages of the boot chain (eg. the bootloader, WTF mode in newer devices, the diagnostics tool) are based around EFI firmware volumes and an EFI runtime, retailOS is a single binary blob without any built-in modularity.&lt;br /&gt;
&lt;br /&gt;
=== eApp Signing ===&lt;br /&gt;
&lt;br /&gt;
Not yet documented fully. Each game seems to ship with a Manifest.plist.p7p which is a PKCS#7 signature for the main Manifest.plist.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
We have found some &#039;secret&#039; options that can be set by creating specially named files. See [[RetailOS_Options|Options]].&lt;br /&gt;
&lt;br /&gt;
== Analysis / Memory Layout ==&lt;br /&gt;
&lt;br /&gt;
Loading RetailOS correctly into a decompiler/disassembler is tricky, as the contents of the IMG1 image are a binary blob which self-relocates to the correct places in memory.&lt;br /&gt;
&lt;br /&gt;
These are the memory segments within RetailOS that we know of (at least on Nano 5G):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Marker !! Location in memory !! Description&lt;br /&gt;
|-&lt;br /&gt;
| sram.text || n/a || SRAM 0x22000000 || SRAM-resident code, most of RTXC lives here.&lt;br /&gt;
|-&lt;br /&gt;
| sram.bss || n/a || SRAM 0x22030000 || SRAM-resident zero data.&lt;br /&gt;
|-&lt;br /&gt;
| sram.data || n/a || SRAM 0x22030000 + sram_bss_size || SRAM-resident data.&lt;br /&gt;
|-&lt;br /&gt;
| dram.textdata || hibe || DRAM 0x08000000 || Combined .text and .data which lives in DRAM. Bulk of code lives here.&lt;br /&gt;
|-&lt;br /&gt;
| dram.frameworks || miscTBD || DRAM 0x08000000 + dram_textdata_size || &#039;Framework&#039; system of some kind, interfaces used by eApps.&lt;br /&gt;
|-&lt;br /&gt;
| dram.bss || n/a || DRAM 0x08000000 + dram_textdata_size + dram_frameworks_size || DRAM-resident zero data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And here&#039;s how the segments are built up within the RetailOS binary blob:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! Size&lt;br /&gt;
|-&lt;br /&gt;
| Start || sram.text || sram_text_size&lt;br /&gt;
|-&lt;br /&gt;
| || sram.bss || sram_bss_size&lt;br /&gt;
|-&lt;br /&gt;
| || sram.data || sram_data_size&lt;br /&gt;
|-&lt;br /&gt;
| || dram.text || dram_text_size&lt;br /&gt;
|-&lt;br /&gt;
| End || dram.frameworks || dram_frameworks_size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(yes, the firmware blob ships a sram.bss physically in the file)&lt;br /&gt;
&lt;br /&gt;
So the goal to be able to load the binary is to figure out the segment sizes and then load them into a decompiler/disassembler. &lt;br /&gt;
&lt;br /&gt;
Here, we&#039;ll show how to figure out the segment sizes for N5G. First, load the RetailOS body (without the header!) at 0x22000000 in a decompiler. We load it there (intead of into DRAM as it is done on the device) as the stub relocates to this address first by performing the SRAM .text/.data copies very early in the process, and the code is position independent for only a short time.&lt;br /&gt;
&lt;br /&gt;
Then, look at the start function (follow the reset vector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void start(void) { // 0x2200505c&lt;br /&gt;
    offs = relocation_offset();&lt;br /&gt;
    /* ... peeks/pokes to bus matrix periph at 0x3ff00000 ... */&lt;br /&gt;
    if (offs != 0) {&lt;br /&gt;
        relocate(offs);&lt;br /&gt;
    }&lt;br /&gt;
    (*0x22000000) = 0xea000007;&lt;br /&gt;
    zero_bss();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
relocation_offset will return 0 if the stub is already at 0x22000000, so will return 0 for the way we&#039;ve loaded it. On a real device, this will be 0x22000000 - 0x08000000 ==&lt;br /&gt;
0x1a000000, as the real device loads RetailOS into DRAM first. Thus, relocate() will be called:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void relocate(int offs) { // 0x22005ec8&lt;br /&gt;
  int iVar1 = -offs;&lt;br /&gt;
  void *blob_start = iVar1 + 0x22000000;&lt;br /&gt;
  memmove(0x22000000, blob_start, 0xe27c); // copy sram.text&lt;br /&gt;
  memzero(0x22000000 + 0xe27c, 0xbc4); // zero out sram.bss within blob&lt;br /&gt;
  memmove(0x22030000, 0x22000000 + 0xe27c + iVar1, 0x20000); // copy sram.bss + sram.data&lt;br /&gt;
  jump_offset(offs);&lt;br /&gt;
  memmove(0x08000000, 0x22000000 + 0xe27c + 0x20000 + iVar1, 0x6c3768); // copy dram.textdata&lt;br /&gt;
  memmove(0x08000000 + 0x6c3768, iVar1 + 0x22000000 + 0xe27c + 0x20000 + 0x6c3768), 0xc40); // copy dram.frameworks&lt;br /&gt;
  start();&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above listing shows reconstituted address calculations - in a plain decompilation, all the additions will of course be simplified to a single constant. But you should be able to figure out the following:&lt;br /&gt;
&lt;br /&gt;
# sram_text_size is 0xe27c&lt;br /&gt;
# sram_bss_size is 0xbc4&lt;br /&gt;
# sram_bss_size + sram_data_size is 0x20000&lt;br /&gt;
# dram_textdata_size is 0x6c3768&lt;br /&gt;
# dram_frameworks_size is 0xc40&lt;br /&gt;
&lt;br /&gt;
Then, in zero_bss we can find the size of dram.bss:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void zero_bss(void) { // 0x22005fec&lt;br /&gt;
    memzero(0x2200e27c, 0xbc4); // zero out sram.bss&lt;br /&gt;
    // inlined memzero:&lt;br /&gt;
    void *start = 0x08000000 + 0x6c3768 + 0xc40;&lt;br /&gt;
    int size = 0x790a84;&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From which we can figure out that the dram.bss segment size is 0x790a84.&lt;br /&gt;
&lt;br /&gt;
Thus we can load the file like so (combining sram.bss and sram.data) into a &#039;clean&#039; decompiler/disassembler session:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Address !! File Offset&lt;br /&gt;
|-&lt;br /&gt;
| sram.text || 0x22000000 || 0x00000000&lt;br /&gt;
|-&lt;br /&gt;
| sram.bssdata || 0x22030000 || 0x0000e27c&lt;br /&gt;
|-&lt;br /&gt;
| dram.textdata || 0x08000000 || 0x0002e27c (0xe27c + 0x20000)&lt;br /&gt;
|-&lt;br /&gt;
| dram.frameworks || 0x086c3768 || 0x006f19e4 (0xe27c + 0x20000 + 0x6c3768)&lt;br /&gt;
|-&lt;br /&gt;
| dram.bss || 0x086c43a || n/a (0x790a84 zeroes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Writing an automated converter into ELF from arbitrary RetailOS blobs is an exercise left to the reader.&lt;br /&gt;
&lt;br /&gt;
== RTXC == &lt;br /&gt;
&lt;br /&gt;
=== Documentation ===&lt;br /&gt;
&lt;br /&gt;
This seems to be the best public document available about RTXC 3.2: [https://web.archive.org/web/20230218212424/https://datasheet.datasheetarchive.com/originals/library/Datasheets-AS2/DSAAXSA0003458.pdf DSAAXSA0003458.pdf]. It contains example code for most services, but unfortunately is still missing any structure definitions.&lt;br /&gt;
&lt;br /&gt;
There&#039;s also some training slides available: [https://ia801800.us.archive.org/26/items/manualzilla-id-5752851/5752851.pdf 5752851.pdf]. These introduce the general architecture and concept of RTXC 3.2. &lt;br /&gt;
&lt;br /&gt;
=== Services / Syscalls ===&lt;br /&gt;
&lt;br /&gt;
While RTXC documentation speaks mostly of &#039;kernel services&#039; (which are defined as C function signatures/symbols), we like to talk about &#039;syscalls&#039; and &#039;syscall numbers&#039; when reverse engineering retailOS. All service functions go through a central dispatch function and that&#039;s the easiest point to start reverse engineering the kernel service interface.&lt;br /&gt;
&lt;br /&gt;
The dispatcher receives a saved caller state which contains a pointer to a serialized syscall request in its saved R0. The syscall request is a trivial structure containing a syscall number and arguments. The dispatcher is executed with interrupts enabled (and thus is non-preemptable) and performs actual work on kernel structures. There is no privilege-granting &#039;gate&#039; mechanism, all caller code is just as privileged as the kernel code.&lt;br /&gt;
&lt;br /&gt;
Service functions in turn prepare the syscall request structure (including syscall number), and then call an intermediary state saving function which then calls the dispatcher after disabling interrupts. Some syscall numbers are used by multiple service functions, with some extra arguments in the request being used to decide on the behaviour of the service call (eg. blocking/nonblocking).&lt;br /&gt;
&lt;br /&gt;
The following table comes from cross-referencing retailOS, publicly available RTXC PDFs and publicly availble RTXC binaries with debug symbols.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Number !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_pend(SEMA sema)&amp;lt;/code&amp;gt; || 0x03 || Semaphore DONE -&amp;gt; PENDING.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTXCMSG *KS_receive(MBOX mailbox, TASK  task)&amp;lt;/code&amp;gt; || 0x05 || Receive from mailbox.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_enqueue[w](QUEUE queue, void *entry)&amp;lt;/code&amp;gt; || 0x0c || Push into FIFO (and block if full with &#039;w&#039; variant).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_dequeue[w](QUEUE queue, void *dest)&amp;lt;/code&amp;gt; || 0x0d || Pop from FIFO (and block if empty with &#039;w&#039; variant).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_lock(RESOURCE resource)&amp;lt;/code&amp;gt; || 0x0e || Lock a resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_lockt(RESOURCE resource, TICKS timoeut)&amp;lt;/code&amp;gt; || 0x0e || Lock a resource with timeout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_unlock(RESOURCE resource)&amp;lt;/code&amp;gt; || 0x0f || Unlock an owned resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CLKBLK *KS_alloc_timer(void)&amp;lt;/code&amp;gt; || 0x10 || Allocate next free timer from pool.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CLKBLK *KS_start_timer(CLKBLK *timer, TICKS initial_period, TICKS cycle_time, SEMA sema)&amp;lt;/code&amp;gt; || 0x12 || Start timer.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_stop_timer(CLKBLK *timer)&amp;lt;/code&amp;gt; || 0x13 || Stop timer.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_delay(TASK task, TICKS period)&amp;lt;/code&amp;gt; || 0x14 || Block specified task for a period of time.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_execute(TASK task)&amp;lt;/code&amp;gt; || 0x15 || Start a task from its beginning address.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_deftask(TASK task, PRIORITY priority, char *stack, size_t stacksize, void (*entry)(void))&amp;lt;/code&amp;gt; || 0x16 || Define the attributes of an inactive task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TASK KS_alloc_task(void)&amp;lt;/code&amp;gt; || 0x17 || Allocate the next available Task Control Block from the pool of free TCBs. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_terminate(TASK task)&amp;lt;/code&amp;gt; || 0x18 || Stop a task by setting it to INACTIVE.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_suspend(TASK task)&amp;lt;/code&amp;gt; || 0x19 || Suspend a task until resumed or re-executed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_defpriority(TASK task, PRIORITY priority)&amp;lt;/code&amp;gt; || 0x1b || Define or set priority of task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_yield(void)&amp;lt;/code&amp;gt; || 0x1c || Voluntary release of control to any other task of the same priority.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SEMA KS_waitm(SEMA *semalist)&amp;lt;/code&amp;gt; || 0x22 || Wait on multiple semaphores.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;time_t KS_inqtime(void)&amp;lt;/code&amp;gt; || 0x24 || Get current time-of-day.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_deftime(time_t time)&amp;lt;/code&amp;gt; || 0x25 || Set current time-of-day.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TASK KS_inqres(RESOURCE resource)&amp;lt;/code&amp;gt; || 0x26 || Get owner of resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_defres(RESOURCE resource, RESATTR condition)&amp;lt;/code&amp;gt; || 0x27 || Define priority inversion on resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void *KS_inqtask_arg(TASK task)&amp;lt;/code&amp;gt; || 0x28 || Get environment arguments of task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_deftask_arg(TASK task, void *arg)&amp;lt;/code&amp;gt; || 0x29 || Set environment arguments for task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_defqueue(QUEUE queue, size_t width, int depth, void *body, int currsize)&amp;lt;/code&amp;gt; || 0x2e || Define queue.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;int KS_user(int (*func) (void *), void *arg)&amp;lt;/code&amp;gt; || 0x30 || Execute function as if it were kernel service.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The RTXC memory allocation facilities (&amp;lt;code&amp;gt;KS_alloc/free/create_part/alloc_part/defpart/free_part&amp;lt;/code&amp;gt;) are &#039;&#039;not&#039;&#039; used by retailOS and not built into the service dispatcher, at least on [[Nano 5G]].&lt;br /&gt;
&lt;br /&gt;
=== Semaphores ===&lt;br /&gt;
&lt;br /&gt;
The following semaphores are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || &amp;lt;code&amp;gt;S_FW_PWR_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || &amp;lt;code&amp;gt;S_BAT_PWR_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || &amp;lt;code&amp;gt;S_USB_PWR_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || &amp;lt;code&amp;gt;S_CNA_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x05 || &amp;lt;code&amp;gt;S_WHEEL_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || &amp;lt;code&amp;gt;S_DISKMGRQ&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x07 || &amp;lt;code&amp;gt;S_TOPPLUG_SWITCH&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || &amp;lt;code&amp;gt;S_RTCTIMERMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x09 || &amp;lt;code&amp;gt;S_ALARM_01&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0a || &amp;lt;code&amp;gt;S_ALARM_02&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0b || &amp;lt;code&amp;gt;S_ALARM_03&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0c || &amp;lt;code&amp;gt;S_WATCHDOG&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0d || &amp;lt;code&amp;gt;S_CPUMGRQ&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0e || &amp;lt;code&amp;gt;S_PCFPOWERMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0f || &amp;lt;code&amp;gt;S_POWER_STATE_AC&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || &amp;lt;code&amp;gt;S_CGR_STATE_TMR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x11 || &amp;lt;code&amp;gt;S_DEEPSLEEP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || &amp;lt;code&amp;gt;S_ALARM_DONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x13 || &amp;lt;code&amp;gt;S_PIEZOMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x14 || &amp;lt;code&amp;gt;S_PIEZOMGRSNDR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x15 || &amp;lt;code&amp;gt;S_PIEZODONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x16 || &amp;lt;code&amp;gt;S_ACCPOWER&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x17 || &amp;lt;code&amp;gt;S_ACC_REINIT&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x18 || &amp;lt;code&amp;gt;S_TOPPLUGSENSER&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x19 || &amp;lt;code&amp;gt;S_TOPPLUGCHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1a || &amp;lt;code&amp;gt;S_BTMCONNECT&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1b || &amp;lt;code&amp;gt;S_BTMPLUGCHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1c || &amp;lt;code&amp;gt;S_BTMREVERIFY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1d || &amp;lt;code&amp;gt;S_BTMREVERTIMED&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1e || &amp;lt;code&amp;gt;S_BTMVERCOMP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1f || &amp;lt;code&amp;gt;S_TOPACCPKTRCVD&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x20 || &amp;lt;code&amp;gt;S_BTMACCPKTRCVD&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x21 || &amp;lt;code&amp;gt;S_SERIALIDRCVD&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x22 || &amp;lt;code&amp;gt;S_UARTATXEMPTY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x23 || &amp;lt;code&amp;gt;S_UARTBTXEMPTY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x24 || &amp;lt;code&amp;gt;S_HDDSCANCOMP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x25 || &amp;lt;code&amp;gt;S_BL_ON&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x26 || &amp;lt;code&amp;gt;S_BL_OFF&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x27 || &amp;lt;code&amp;gt;S_BL_RAMPDOWN&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x28 || &amp;lt;code&amp;gt;S_BL_RAMPUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x29 || &amp;lt;code&amp;gt;S_BL_TIMESUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2a || &amp;lt;code&amp;gt;S_BATT_TIMESUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2b || &amp;lt;code&amp;gt;S_BATT_AC_PWR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2c || &amp;lt;code&amp;gt;S_BATT_TMR_RST&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2d || &amp;lt;code&amp;gt;S_GRAPHMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2e || &amp;lt;code&amp;gt;S_VBL&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2f || &amp;lt;code&amp;gt;S_DTVRECOVERY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x30 || &amp;lt;code&amp;gt;S_CM_HEADPHONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x31 || &amp;lt;code&amp;gt;S_CM_EXTPOWER&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x32 || &amp;lt;code&amp;gt;S_CM_ACCATTACHED&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x33 || &amp;lt;code&amp;gt;S_CM_DAC_SETUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x34 || &amp;lt;code&amp;gt;S_ATAWRKLPRDY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x35 || &amp;lt;code&amp;gt;S_RTXCBUG&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x36 || &amp;lt;code&amp;gt;S_BLOCKDEVICE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x37 || &amp;lt;code&amp;gt;S_BLOCKDEVICEQ&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x38 || &amp;lt;code&amp;gt;S_DISPLAY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x39 || &amp;lt;code&amp;gt;S_ARB_READY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x3a || &amp;lt;code&amp;gt;S_I2C_DONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x3b || &amp;lt;code&amp;gt;S_VSYNC&amp;lt;/code&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are three more semaphores (0x3c, 0x3d, 0x3e) that have no name defined and are likely unused. Anything 0x3f and up is a &#039;Dynamic&#039; semaphore defined at runtime (which we haven&#039;t reversed yet).&lt;br /&gt;
&lt;br /&gt;
=== Queues ===&lt;br /&gt;
&lt;br /&gt;
The following queues are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || PIXORESQ ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || PIXOSEMAQ ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || POSIXRESQ ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || POSIXSEMAQ ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mailboxes ===&lt;br /&gt;
&lt;br /&gt;
The following mailboxes are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || M_DISKMGR ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || M_PIEZOMGR ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || M_GRAPHMGR ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || M_BLOCKDEVICE ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x05 || M_DISPLAY ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
&lt;br /&gt;
The following lockable resources are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || GPIO_REG_WRITE ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || GPIO_INT_INIT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || RTC_TIME_ADJUST ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || RTC_ALARM_ADJUST ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x05 || I2C_MASTER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || USB_GRANT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x07 || USB_RESP_INIT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || USB_RESPONDER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x09 || DISKPWRMGRSEND ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0a || PIEZOMGRSEND ||&lt;br /&gt;
|- &lt;br /&gt;
| 0x0b || SERIALVERIFIER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0c || RESISTORVERIFIER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0d || FW_IRAM ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0e || ACCPOWER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0f || UARTA ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || UARGB ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x11 || PMU_LOCK ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || ADC_LOCK ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x13 || DTV_ENC_INIT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x14 || BACKLIGHT ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://web.archive.org/web/19990220054659/http://www.rtxc.com/Products/RTXC/Services.htm RTXC Kernel Services (1999)]&lt;br /&gt;
* [https://archive.org/details/manualzilla-id-5752851 RTXC 3.2 Training Manual]&lt;/div&gt;</summary>
		<author><name>LemonJesus</name></author>
	</entry>
	<entry>
		<id>https://freemyipod.org/index.php?title=RetailOS&amp;diff=22075</id>
		<title>RetailOS</title>
		<link rel="alternate" type="text/html" href="https://freemyipod.org/index.php?title=RetailOS&amp;diff=22075"/>
		<updated>2024-05-09T19:31:34Z</updated>

		<summary type="html">&lt;p&gt;LemonJesus: Un-dead the Twitter link talking about Pixo.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The stock operating system running on non-iOS iPods. It runs everything from device drivers to the clickwheel user interface.&lt;br /&gt;
&lt;br /&gt;
== Naming ==&lt;br /&gt;
&lt;br /&gt;
The only &#039;official&#039; name seems to be &#039;retailOS&#039;, found in the [[Nano 3G]] WTF. It is also referred to as &#039;osos&#039; per the file name in the resource partition of the firmware bundle.&lt;br /&gt;
&lt;br /&gt;
== Architecture ==&lt;br /&gt;
&lt;br /&gt;
retailOS is a small, embedded, single-user, single-binary, real time operating system. With time it acquire more and more complex functionality, like PowerVR drivers and being able to load external applications (&#039;eApps&#039;) which are used for games.&lt;br /&gt;
&lt;br /&gt;
The core of the system is based on RTXC 3.2, with the end-user interface based on intellectual property from a company called Pixo. &amp;lt;ref&amp;gt;https://web.archive.org/web/20230224105131/https://twitter.com/johnwhitley/status/1451952369248264201&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
&lt;br /&gt;
As evidenced by the success of the [[Notes vulnerability]], at least up to Nano 4G there was no kind of security hardening, and in fact all processes, including games, seem to be running in ARM system mode. This should make exploitation of newer retailOS bugs trivial.&lt;br /&gt;
&lt;br /&gt;
=== Boot chain ===&lt;br /&gt;
&lt;br /&gt;
retailOS is loaded by the second-stage bootloader (stored on NOR/NAND depending on the device generation), from NAND into DRAM.&lt;br /&gt;
&lt;br /&gt;
While other stages of the boot chain (eg. the bootloader, WTF mode in newer devices, the diagnostics tool) are based around EFI firmware volumes and an EFI runtime, retailOS is a single binary blob without any built-in modularity.&lt;br /&gt;
&lt;br /&gt;
=== eApp Signing ===&lt;br /&gt;
&lt;br /&gt;
Not yet documented fully. Each game seems to ship with a Manifest.plist.p7p which is a PKCS#7 signature for the main Manifest.plist.&lt;br /&gt;
&lt;br /&gt;
== Options ==&lt;br /&gt;
&lt;br /&gt;
We have found some &#039;secret&#039; options that can be set by creating specially named files. See [[RetailOS_Options|Options]].&lt;br /&gt;
&lt;br /&gt;
== Analysis / Memory Layout ==&lt;br /&gt;
&lt;br /&gt;
Loading RetailOS correctly into a decompiler/disassembler is tricky, as the contents of the IMG1 image are a binary blob which self-relocates to the correct places in memory.&lt;br /&gt;
&lt;br /&gt;
These are the memory segments within RetailOS that we know of (at least on Nano 5G):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Marker !! Location in memory !! Description&lt;br /&gt;
|-&lt;br /&gt;
| sram.text || n/a || SRAM 0x22000000 || SRAM-resident code, most of RTXC lives here.&lt;br /&gt;
|-&lt;br /&gt;
| sram.bss || n/a || SRAM 0x22030000 || SRAM-resident zero data.&lt;br /&gt;
|-&lt;br /&gt;
| sram.data || n/a || SRAM 0x22030000 + sram_bss_size || SRAM-resident data.&lt;br /&gt;
|-&lt;br /&gt;
| dram.textdata || hibe || DRAM 0x08000000 || Combined .text and .data which lives in DRAM. Bulk of code lives here.&lt;br /&gt;
|-&lt;br /&gt;
| dram.frameworks || miscTBD || DRAM 0x08000000 + dram_textdata_size || &#039;Framework&#039; system of some kind, interfaces used by eApps.&lt;br /&gt;
|-&lt;br /&gt;
| dram.bss || n/a || DRAM 0x08000000 + dram_textdata_size + dram_frameworks_size || DRAM-resident zero data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And here&#039;s how the segments are built up within the RetailOS binary blob:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! Size&lt;br /&gt;
|-&lt;br /&gt;
| Start || sram.text || sram_text_size&lt;br /&gt;
|-&lt;br /&gt;
| || sram.bss || sram_bss_size&lt;br /&gt;
|-&lt;br /&gt;
| || sram.data || sram_data_size&lt;br /&gt;
|-&lt;br /&gt;
| || dram.text || dram_text_size&lt;br /&gt;
|-&lt;br /&gt;
| End || dram.frameworks || dram_frameworks_size&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(yes, the firmware blob ships a sram.bss physically in the file)&lt;br /&gt;
&lt;br /&gt;
So the goal to be able to load the binary is to figure out the segment sizes and then load them into a decompiler/disassembler. &lt;br /&gt;
&lt;br /&gt;
Here, we&#039;ll show how to figure out the segment sizes for N5G. First, load the RetailOS body (without the header!) at 0x22000000 in a decompiler. We load it there (intead of into DRAM as it is done on the device) as the stub relocates to this address first by performing the SRAM .text/.data copies very early in the process, and the code is position independent for only a short time.&lt;br /&gt;
&lt;br /&gt;
Then, look at the start function (follow the reset vector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void start(void) { // 0x2200505c&lt;br /&gt;
    offs = relocation_offset();&lt;br /&gt;
    /* ... peeks/pokes to bus matrix periph at 0x3ff00000 ... */&lt;br /&gt;
    if (offs != 0) {&lt;br /&gt;
        relocate(offs);&lt;br /&gt;
    }&lt;br /&gt;
    (*0x22000000) = 0xea000007;&lt;br /&gt;
    zero_bss();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
relocation_offset will return 0 if the stub is already at 0x22000000, so will return 0 for the way we&#039;ve loaded it. On a real device, this will be 0x22000000 - 0x08000000 ==&lt;br /&gt;
0x1a000000, as the real device loads RetailOS into DRAM first. Thus, relocate() will be called:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void relocate(int offs) { // 0x22005ec8&lt;br /&gt;
  int iVar1 = -offs;&lt;br /&gt;
  void *blob_start = iVar1 + 0x22000000;&lt;br /&gt;
  memmove(0x22000000, blob_start, 0xe27c); // copy sram.text&lt;br /&gt;
  memzero(0x22000000 + 0xe27c, 0xbc4); // zero out sram.bss within blob&lt;br /&gt;
  memmove(0x22030000, 0x22000000 + 0xe27c + iVar1, 0x20000); // copy sram.bss + sram.data&lt;br /&gt;
  jump_offset(offs);&lt;br /&gt;
  memmove(0x08000000, 0x22000000 + 0xe27c + 0x20000 + iVar1, 0x6c3768); // copy dram.textdata&lt;br /&gt;
  memmove(0x08000000 + 0x6c3768, iVar1 + 0x22000000 + 0xe27c + 0x20000 + 0x6c3768), 0xc40); // copy dram.frameworks&lt;br /&gt;
  start();&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above listing shows reconstituted address calculations - in a plain decompilation, all the additions will of course be simplified to a single constant. But you should be able to figure out the following:&lt;br /&gt;
&lt;br /&gt;
# sram_text_size is 0xe27c&lt;br /&gt;
# sram_bss_size is 0xbc4&lt;br /&gt;
# sram_bss_size + sram_data_size is 0x20000&lt;br /&gt;
# dram_textdata_size is 0x6c3768&lt;br /&gt;
# dram_frameworks_size is 0xc40&lt;br /&gt;
&lt;br /&gt;
Then, in zero_bss we can find the size of dram.bss:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
void zero_bss(void) { // 0x22005fec&lt;br /&gt;
    memzero(0x2200e27c, 0xbc4); // zero out sram.bss&lt;br /&gt;
    // inlined memzero:&lt;br /&gt;
    void *start = 0x08000000 + 0x6c3768 + 0xc40;&lt;br /&gt;
    int size = 0x790a84;&lt;br /&gt;
    // ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From which we can figure out that the dram.bss segment size is 0x790a84.&lt;br /&gt;
&lt;br /&gt;
Thus we can load the file like so (combining sram.bss and sram.data) into a &#039;clean&#039; decompiler/disassembler session:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Address !! File Offset&lt;br /&gt;
|-&lt;br /&gt;
| sram.text || 0x22000000 || 0x00000000&lt;br /&gt;
|-&lt;br /&gt;
| sram.bssdata || 0x22030000 || 0x0000e27c&lt;br /&gt;
|-&lt;br /&gt;
| dram.textdata || 0x08000000 || 0x0002e27c (0xe27c + 0x20000)&lt;br /&gt;
|-&lt;br /&gt;
| dram.frameworks || 0x086c3768 || 0x006f19e4 (0xe27c + 0x20000 + 0x6c3768)&lt;br /&gt;
|-&lt;br /&gt;
| dram.bss || 0x086c43a || n/a (0x790a84 zeroes)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Writing an automated converter into ELF from arbitrary RetailOS blobs is an exercise left to the reader.&lt;br /&gt;
&lt;br /&gt;
== RTXC == &lt;br /&gt;
&lt;br /&gt;
=== Documentation ===&lt;br /&gt;
&lt;br /&gt;
This seems to be the best public document available about RTXC 3.2: [https://web.archive.org/web/20230218212424/https://datasheet.datasheetarchive.com/originals/library/Datasheets-AS2/DSAAXSA0003458.pdf DSAAXSA0003458.pdf]. It contains example code for most services, but unfortunately is still missing any structure definitions.&lt;br /&gt;
&lt;br /&gt;
There&#039;s also some training slides available: [https://ia801800.us.archive.org/26/items/manualzilla-id-5752851/5752851.pdf 5752851.pdf]. These introduce the general architecture and concept of RTXC 3.2. &lt;br /&gt;
&lt;br /&gt;
=== Services / Syscalls ===&lt;br /&gt;
&lt;br /&gt;
While RTXC documentation speaks mostly of &#039;kernel services&#039; (which are defined as C function signatures/symbols), we like to talk about &#039;syscalls&#039; and &#039;syscall numbers&#039; when reverse engineering retailOS. All service functions go through a central dispatch function and that&#039;s the easiest point to start reverse engineering the kernel service interface.&lt;br /&gt;
&lt;br /&gt;
The dispatcher receives a saved caller state which contains a pointer to a serialized syscall request in its saved R0. The syscall request is a trivial structure containing a syscall number and arguments. The dispatcher is executed with interrupts enabled (and thus is non-preemptable) and performs actual work on kernel structures. There is no privilege-granting &#039;gate&#039; mechanism, all caller code is just as privileged as the kernel code.&lt;br /&gt;
&lt;br /&gt;
Service functions in turn prepare the syscall request structure (including syscall number), and then call an intermediary state saving function which then calls the dispatcher after disabling interrupts. Some syscall numbers are used by multiple service functions, with some extra arguments in the request being used to decide on the behaviour of the service call (eg. blocking/nonblocking).&lt;br /&gt;
&lt;br /&gt;
The following table comes from cross-referencing retailOS, publicly available RTXC PDFs and publicly availble RTXC binaries with debug symbols.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Number !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_pend(SEMA sema)&amp;lt;/code&amp;gt; || 0x03 || Semaphore DONE -&amp;gt; PENDING.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;RTXCMSG *KS_receive(MBOX mailbox, TASK  task)&amp;lt;/code&amp;gt; || 0x05 || Receive from mailbox.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_enqueue[w](QUEUE queue, void *entry)&amp;lt;/code&amp;gt; || 0x0c || Push into FIFO (and block if full with &#039;w&#039; variant).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_dequeue[w](QUEUE queue, void *dest)&amp;lt;/code&amp;gt; || 0x0d || Pop from FIFO (and block if empty with &#039;w&#039; variant).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_lock(RESOURCE resource)&amp;lt;/code&amp;gt; || 0x0e || Lock a resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_lockt(RESOURCE resource, TICKS timoeut)&amp;lt;/code&amp;gt; || 0x0e || Lock a resource with timeout.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_unlock(RESOURCE resource)&amp;lt;/code&amp;gt; || 0x0f || Unlock an owned resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CLKBLK *KS_alloc_timer(void)&amp;lt;/code&amp;gt; || 0x10 || Allocate next free timer from pool.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CLKBLK *KS_start_timer(CLKBLK *timer, TICKS initial_period, TICKS cycle_time, SEMA sema)&amp;lt;/code&amp;gt; || 0x12 || Start timer.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_stop_timer(CLKBLK *timer)&amp;lt;/code&amp;gt; || 0x13 || Stop timer.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_delay(TASK task, TICKS period)&amp;lt;/code&amp;gt; || 0x14 || Block specified task for a period of time.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_execute(TASK task)&amp;lt;/code&amp;gt; || 0x15 || Start a task from its beginning address.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_deftask(TASK task, PRIORITY priority, char *stack, size_t stacksize, void (*entry)(void))&amp;lt;/code&amp;gt; || 0x16 || Define the attributes of an inactive task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TASK KS_alloc_task(void)&amp;lt;/code&amp;gt; || 0x17 || Allocate the next available Task Control Block from the pool of free TCBs. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_terminate(TASK task)&amp;lt;/code&amp;gt; || 0x18 || Stop a task by setting it to INACTIVE.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_suspend(TASK task)&amp;lt;/code&amp;gt; || 0x19 || Suspend a task until resumed or re-executed.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_defpriority(TASK task, PRIORITY priority)&amp;lt;/code&amp;gt; || 0x1b || Define or set priority of task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_yield(void)&amp;lt;/code&amp;gt; || 0x1c || Voluntary release of control to any other task of the same priority.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SEMA KS_waitm(SEMA *semalist)&amp;lt;/code&amp;gt; || 0x22 || Wait on multiple semaphores.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;time_t KS_inqtime(void)&amp;lt;/code&amp;gt; || 0x24 || Get current time-of-day.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_deftime(time_t time)&amp;lt;/code&amp;gt; || 0x25 || Set current time-of-day.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TASK KS_inqres(RESOURCE resource)&amp;lt;/code&amp;gt; || 0x26 || Get owner of resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_defres(RESOURCE resource, RESATTR condition)&amp;lt;/code&amp;gt; || 0x27 || Define priority inversion on resource.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void *KS_inqtask_arg(TASK task)&amp;lt;/code&amp;gt; || 0x28 || Get environment arguments of task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;void KS_deftask_arg(TASK task, void *arg)&amp;lt;/code&amp;gt; || 0x29 || Set environment arguments for task.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;KSRC KS_defqueue(QUEUE queue, size_t width, int depth, void *body, int currsize)&amp;lt;/code&amp;gt; || 0x2e || Define queue.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;int KS_user(int (*func) (void *), void *arg)&amp;lt;/code&amp;gt; || 0x30 || Execute function as if it were kernel service.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The RTXC memory allocation facilities (&amp;lt;code&amp;gt;KS_alloc/free/create_part/alloc_part/defpart/free_part&amp;lt;/code&amp;gt;) are &#039;&#039;not&#039;&#039; used by retailOS and not built into the service dispatcher, at least on [[Nano 5G]].&lt;br /&gt;
&lt;br /&gt;
=== Semaphores ===&lt;br /&gt;
&lt;br /&gt;
The following semaphores are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || &amp;lt;code&amp;gt;S_FW_PWR_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || &amp;lt;code&amp;gt;S_BAT_PWR_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || &amp;lt;code&amp;gt;S_USB_PWR_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || &amp;lt;code&amp;gt;S_CNA_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x05 || &amp;lt;code&amp;gt;S_WHEEL_CHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || &amp;lt;code&amp;gt;S_DISKMGRQ&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x07 || &amp;lt;code&amp;gt;S_TOPPLUG_SWITCH&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || &amp;lt;code&amp;gt;S_RTCTIMERMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x09 || &amp;lt;code&amp;gt;S_ALARM_01&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0a || &amp;lt;code&amp;gt;S_ALARM_02&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0b || &amp;lt;code&amp;gt;S_ALARM_03&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0c || &amp;lt;code&amp;gt;S_WATCHDOG&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0d || &amp;lt;code&amp;gt;S_CPUMGRQ&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0e || &amp;lt;code&amp;gt;S_PCFPOWERMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x0f || &amp;lt;code&amp;gt;S_POWER_STATE_AC&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || &amp;lt;code&amp;gt;S_CGR_STATE_TMR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x11 || &amp;lt;code&amp;gt;S_DEEPSLEEP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || &amp;lt;code&amp;gt;S_ALARM_DONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x13 || &amp;lt;code&amp;gt;S_PIEZOMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x14 || &amp;lt;code&amp;gt;S_PIEZOMGRSNDR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x15 || &amp;lt;code&amp;gt;S_PIEZODONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x16 || &amp;lt;code&amp;gt;S_ACCPOWER&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x17 || &amp;lt;code&amp;gt;S_ACC_REINIT&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x18 || &amp;lt;code&amp;gt;S_TOPPLUGSENSER&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x19 || &amp;lt;code&amp;gt;S_TOPPLUGCHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1a || &amp;lt;code&amp;gt;S_BTMCONNECT&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1b || &amp;lt;code&amp;gt;S_BTMPLUGCHANGE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1c || &amp;lt;code&amp;gt;S_BTMREVERIFY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1d || &amp;lt;code&amp;gt;S_BTMREVERTIMED&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1e || &amp;lt;code&amp;gt;S_BTMVERCOMP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x1f || &amp;lt;code&amp;gt;S_TOPACCPKTRCVD&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x20 || &amp;lt;code&amp;gt;S_BTMACCPKTRCVD&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x21 || &amp;lt;code&amp;gt;S_SERIALIDRCVD&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x22 || &amp;lt;code&amp;gt;S_UARTATXEMPTY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x23 || &amp;lt;code&amp;gt;S_UARTBTXEMPTY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x24 || &amp;lt;code&amp;gt;S_HDDSCANCOMP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x25 || &amp;lt;code&amp;gt;S_BL_ON&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x26 || &amp;lt;code&amp;gt;S_BL_OFF&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x27 || &amp;lt;code&amp;gt;S_BL_RAMPDOWN&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x28 || &amp;lt;code&amp;gt;S_BL_RAMPUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x29 || &amp;lt;code&amp;gt;S_BL_TIMESUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2a || &amp;lt;code&amp;gt;S_BATT_TIMESUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2b || &amp;lt;code&amp;gt;S_BATT_AC_PWR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2c || &amp;lt;code&amp;gt;S_BATT_TMR_RST&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2d || &amp;lt;code&amp;gt;S_GRAPHMGR&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2e || &amp;lt;code&amp;gt;S_VBL&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x2f || &amp;lt;code&amp;gt;S_DTVRECOVERY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x30 || &amp;lt;code&amp;gt;S_CM_HEADPHONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x31 || &amp;lt;code&amp;gt;S_CM_EXTPOWER&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x32 || &amp;lt;code&amp;gt;S_CM_ACCATTACHED&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x33 || &amp;lt;code&amp;gt;S_CM_DAC_SETUP&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x34 || &amp;lt;code&amp;gt;S_ATAWRKLPRDY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x35 || &amp;lt;code&amp;gt;S_RTXCBUG&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x36 || &amp;lt;code&amp;gt;S_BLOCKDEVICE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x37 || &amp;lt;code&amp;gt;S_BLOCKDEVICEQ&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x38 || &amp;lt;code&amp;gt;S_DISPLAY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x39 || &amp;lt;code&amp;gt;S_ARB_READY&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x3a || &amp;lt;code&amp;gt;S_I2C_DONE&amp;lt;/code&amp;gt; || &lt;br /&gt;
|-&lt;br /&gt;
| 0x3b || &amp;lt;code&amp;gt;S_VSYNC&amp;lt;/code&amp;gt; || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are three more semaphores (0x3c, 0x3d, 0x3e) that have no name defined and are likely unused. Anything 0x3f and up is a &#039;Dynamic&#039; semaphore defined at runtime (which we haven&#039;t reversed yet).&lt;br /&gt;
&lt;br /&gt;
=== Queues ===&lt;br /&gt;
&lt;br /&gt;
The following queues are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || PIXORESQ ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || PIXOSEMAQ ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || POSIXRESQ ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || POSIXSEMAQ ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mailboxes ===&lt;br /&gt;
&lt;br /&gt;
The following mailboxes are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || M_DISKMGR ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || M_PIEZOMGR ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || M_GRAPHMGR ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || M_BLOCKDEVICE ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x05 || M_DISPLAY ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Resources ===&lt;br /&gt;
&lt;br /&gt;
The following lockable resources are defined in the [[Nano 3G]] retailOS:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Number !! Name !! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || GPIO_REG_WRITE ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || GPIO_INT_INIT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 || RTC_TIME_ADJUST ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x04 || RTC_ALARM_ADJUST ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x05 || I2C_MASTER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x06 || USB_GRANT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x07 || USB_RESP_INIT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x08 || USB_RESPONDER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x09 || DISKPWRMGRSEND ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0a || PIEZOMGRSEND ||&lt;br /&gt;
|- &lt;br /&gt;
| 0x0b || SERIALVERIFIER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0c || RESISTORVERIFIER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0d || FW_IRAM ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0e || ACCPOWER ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x0f || UARTA ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x10 || UARGB ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x11 || PMU_LOCK ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 || ADC_LOCK ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x13 || DTV_ENC_INIT ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x14 || BACKLIGHT ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://web.archive.org/web/19990220054659/http://www.rtxc.com/Products/RTXC/Services.htm RTXC Kernel Services (1999)]&lt;/div&gt;</summary>
		<author><name>LemonJesus</name></author>
	</entry>
	<entry>
		<id>https://freemyipod.org/index.php?title=Disk_Mode&amp;diff=22071</id>
		<title>Disk Mode</title>
		<link rel="alternate" type="text/html" href="https://freemyipod.org/index.php?title=Disk_Mode&amp;diff=22071"/>
		<updated>2024-01-11T06:26:31Z</updated>

		<summary type="html">&lt;p&gt;LemonJesus: created a Disk Mode page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Disk Mode is a binary that serves two purposes: first, it exposes a USB Mass Storage and SCSI device to provide access to the iPod&#039;s filesystem. Second, it facilitates the recovery functionality of the iPod. On the Nano 3G, it is stored on NOR Flash.&lt;br /&gt;
&lt;br /&gt;
This page currently focuses on the Nano 3G&#039;s Disk Mode unless otherwise noted.&lt;br /&gt;
&lt;br /&gt;
== Memory Layout ==&lt;br /&gt;
The memory layout of Disk Mode is far simpler than that of Retail OS. See [[RetailOS#Analysis_.2F_Memory_Layout|analysis of Retail OS&#039;s memory layout]] for more details about how this relocation process works. There are only two sections that get relocated:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Memory Address !! File Offset&lt;br /&gt;
|-&lt;br /&gt;
| sram.text || 0x22000000 || 0x00000000&lt;br /&gt;
|-&lt;br /&gt;
| dram.textdata || 0x08000000 || 0x000051f4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Known RTXC Tasks ==&lt;br /&gt;
There are several tasks in Disk Mode that RTXC manages. These are inferred by the presence of string names for these tasks:&lt;br /&gt;
* HostOSTask&lt;br /&gt;
* USBDeviceTask&lt;br /&gt;
* ATAWorkLoopTask&lt;br /&gt;
* ATAWorkLoopIRQTask&lt;br /&gt;
* CNATask&lt;/div&gt;</summary>
		<author><name>LemonJesus</name></author>
	</entry>
	<entry>
		<id>https://freemyipod.org/index.php?title=Nano_3G&amp;diff=22066</id>
		<title>Nano 3G</title>
		<link rel="alternate" type="text/html" href="https://freemyipod.org/index.php?title=Nano_3G&amp;diff=22066"/>
		<updated>2023-11-19T19:19:12Z</updated>

		<summary type="html">&lt;p&gt;LemonJesus: porting over my hardware notes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:nano_3g_frt_a.png|500px]]&lt;br /&gt;
[[Image:nano_3g_bck_a.png|500px]]&lt;br /&gt;
==Components==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Label !! Component !! Part !! Markings !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| CPU&lt;br /&gt;
| Samsung S5L8702&lt;br /&gt;
| 337S3473 8702, NONBWOEC, 0731 ARM&lt;br /&gt;
| ARM926EJ-S processor. The package itself is Apple-branded and marked 337S3473 8702.&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| SDRAM&lt;br /&gt;
| [http://www.samsung.com/global/system/business/semiconductor/product/2007/11/13/236652ds_k4x56163pi.pdf K4X56163PI] or Qimonda HYE18M169CX75&lt;br /&gt;
| 0728, C, HYE18M256, 169CX75, W3338092&lt;br /&gt;
| SDRAM - Mobile DDR, 256Mb, 1.8V. WORK ON THIS: Like the flash chip, the memory also varies. The most popular chip seems to be the [http://www.samsung.com/global/system/business/semiconductor/product/2007/11/13/236652ds_k4x56163pi.pdf K4X56163PI]. Another similar one that is sometimes used is the Qimonda HYE18M169CX75&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Utility Flash&lt;br /&gt;
| [http://www.sst.com/products/?inode=41340 SST25VF080B]&lt;br /&gt;
| V80B, 729379&lt;br /&gt;
| Flash - NOR, 8Mb, Serial SPI&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| NAND Flash&lt;br /&gt;
| Varies&lt;br /&gt;
| Samsung 728, K9HCG08U5M, PCB0, FCF285X1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Audio codec&lt;br /&gt;
| WM1870&lt;br /&gt;
| APPLE, 338S0462, 76BZKTM&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Power manager&lt;br /&gt;
| D1671B&lt;br /&gt;
| 338S0408, 07258HAH&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== SPI NOR Test Pads ==&lt;br /&gt;
&lt;br /&gt;
Test pads are available on the back of the board to access SCK, MISO and CS between the SoC and the NOR utility flash. MOSI is also present, but is buried in an internal layer (second from back) which can be  accessed by carefully scraping off the top FR4 using a sharp tool, or by using a tiny carbide bit on a milling machine.&lt;br /&gt;
&lt;br /&gt;
[[Image:N3g-spi-nor.png|500px]]&lt;br /&gt;
[[Image:N3g-spi-nor-zoom.png|500px]]&lt;br /&gt;
&lt;br /&gt;
== Hardware Notes ==&lt;br /&gt;
=== CPU ===&lt;br /&gt;
The Apple S5L8702 is an ARM926EJ-S processor designed by Samsung. It is estimated to run at 100MHz (I read this somewhere but I don&#039;t remember where). The basics of the chip are similar to the S5L8700x for which there is [[S5L8700 datasheet|a leaked datasheet]]. For some peripherals, merely a base address has changed. For others, full subsystems have been updated and refined. &lt;br /&gt;
&lt;br /&gt;
=== GPU ===&lt;br /&gt;
Very little is known about the GPU core other than the fact that it almost certainly exists. It&#039;s likely a single PowerVR GPU core that can maybe can decode H.264 content up to 480p (or perhaps there&#039;s another peripheral responsible for this?). It&#039;s also possible that the GPU is responsible for rendering games, since it appears the games use some form of OpenGL ES. CoverFlow also probably leverages the GPU.&lt;br /&gt;
&lt;br /&gt;
=== I2C ===&lt;br /&gt;
The S5L8702 has several I2C busses (two, probably?), but possibly only one is used (bus #0). On this bus, there are currently two known slaves:&lt;br /&gt;
* The PMU at address 0x73&lt;br /&gt;
* The DAC at address 0x1A&lt;br /&gt;
The bus runs at 1.8V with a clock of 333.33KHz.&lt;br /&gt;
&lt;br /&gt;
Other notes about the I2C peripheral from Rockbox:&lt;br /&gt;
* s5l8702 I2C controller is similar to s5l8700, known differences are:&lt;br /&gt;
** IICCON[5] is not used in s5l8702.&lt;br /&gt;
** IICCON[13:8] are used to enable interrupts.&lt;br /&gt;
** IICSTA2[13:8] are used to read the status and write-clear interrupts.&lt;br /&gt;
* Known interrupts:&lt;br /&gt;
** [13] STOP on bus (TBC)&lt;br /&gt;
** [12] START on bus (TBC)&lt;br /&gt;
** [8] byte transmitted or received in Master mode (not tested in Slave)&lt;br /&gt;
** IICCON[4] does not clear interrupts, it is enabled when a byte is transmited or received, in Master mode the tx/rx of the next byte starts when it is written as &amp;quot;1&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Digital Audio Subsystem (I2S) ===&lt;br /&gt;
The iPod n3g uses a Wolfson DAC (WM1870) to convert digital audio to analog audio. The S5L8702 sends digital audio in the form of I2S data at 44.1kHz with 16-bit resolution. Even if there is no audio playing, at some point during boot up, the I2S peripheral is turned on, meaning the Bit Clock and Word Select are always on. During the 1kHz tone test in the diagnostic menu, the I2S mode is different, possibly a half-data mode since the test tone is one channel.&lt;br /&gt;
The S5L8702 seems to support 3 I2S interfaces, but only one is used for audio playback. It&#039;s possible another one is used for microphone recording (when an Apple headset with a microphone is plugged in, you can record voice memos) but this is unconfirmed.&lt;br /&gt;
&lt;br /&gt;
The S5L8702 sends data to the DAC at full volume no matter what. Volume is configured via I2C bus #0. As far as I can tell, two commands are issued to change the volume:&lt;br /&gt;
 Address 0x1A, Data 0x04 &amp;lt;volume&amp;gt;&lt;br /&gt;
 Address 0x1A, Data 0x07 &amp;lt;volume&amp;gt;&lt;br /&gt;
Where &amp;lt;volume&amp;gt; is a number between 0xB7 for quietest to 0xF5 for loudest. It&#039;s also possible that a special value of 0x80 is for full mute, but this is unconfirmed. It&#039;s also unclear what the 0x04 and 0x07 mean, perhaps it&#039;s capable of changing the volume of both channels independently?&lt;br /&gt;
&lt;br /&gt;
Both the I2C and I2S busses run at 1.8V.&lt;br /&gt;
&lt;br /&gt;
=== NAND ===&lt;br /&gt;
NAND hardware is an enigma. There has been a rather substantial effort on this subsystem alone. Most of that is documented [https://github.com/lemonjesus/S5L8702-FMISS-Tools here].&lt;br /&gt;
&lt;br /&gt;
==Helpful pages==&lt;br /&gt;
Chip analyses:&lt;br /&gt;
*http://www2.electronicproducts.com/Applie_iPod_Nano_(4GB)_3rd_Generation-whatsinside-16.aspx#&lt;br /&gt;
Teardowns:&lt;br /&gt;
*http://content.techrepublic.com.com/2346-13636_11-170826-1.html&lt;br /&gt;
*http://www.ifixit.com/Guide/First-Look/iPod-Nano-3rd-Generation/594/1&lt;br /&gt;
*http://insidetronics.blogspot.com/2007/09/teardown-ipod-nano-3g.html&lt;br /&gt;
*[http://www.combert-elec.com/www/bookpic/200810916515460624.jpg Image of 3G Nano board]&lt;/div&gt;</summary>
		<author><name>LemonJesus</name></author>
	</entry>
</feed>