[Re-release] BootCtr - A simple boot manager for 3DS

Discussion in '3DS - Homebrew Development and Emulators' started by m45t3r, Oct 31, 2015.

  1. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    Introduction

    Hi

    For some time now I am developing an alternative to @cpasjuste's CtrBootManager. This is based in the original code from @mashers' HBL-Emergency (that itself is a modified version of @smealum's Homebrew Launcher), props to him. Look in the original topic for history of changes and some early discussion. I created this new topic to better organize OP, since new users would need to hunt this information in the topic itself. Now that I have control of the OP, I can maintain it with up-to-date information.

    BootCtr is a boot manager. What it means is that it allows selecting arbitrary entries from a configuration file. The common user case for this homebrew is as an alternative for boot.3dsx file in HomeMenuHax. Traditionally, you use HomeMenuHax with Homebrew Launcher as your boot.3dsx file (this is what happens if you use Homebrew Launcher starter pack), so when HomeMenuHax boot you get Homebrew Launcher screen.

    However, HomeMenuHax is very convenient since it supports autobooting (officially since version 2.0). What it means is, to load any hack with HomeMenuHax, you can simple turn on your console and wait for the magic to happen, no need to enter in Browser or DS Profile Settings or anything else. So people started to substitute boot.3dsx from Homebrew Launcher with other files, like rxTools.3dsx or Cakes.3dsx, so they would boot directly to they favorite CFW from boot.

    This is very nice, however there is two problems: firstly, the boot rate for direct booting CFWs from boot.3dsx is kind low in some situations (I don't think someone knows what is the problem exactly); secondly, if you want, for example, boot a CFW by default and boot Homebrew Launcher in some situations, you could not. So you either would maintain Homebrew Launcher as your boot.3dsx file, booting CFW from Homebrew Launcher itself, and loosing the convenience of autobooting CFWs, or use some ugly hack to boot both (generally, involving hex editing themehax payload so it would point to other file instead boot.3dsx). This works, however it wouldn't solve the bad boot rate problem.

    BootCtr solve both these problems: it is a boot manager, so it will boot a default entry if you don't press any button. If you put your favorite CFW as default entry, you don't need to do anything to boot it. However, if you want to boot something different, like Homebrew Launcher, you can too. Just add a entry for Homebrew Launcher, set a trigger button (like R), so when you boot your 3DS holding R, for example, it will boot in Homebrew Launcher instead of your CFW. All this configuration can be done editing the included boot_config.ini file.

    To increase CFW boot rate, BootCtr implements a small delay when booting: delaying the boot for a couple of microseconds (1500ms, or 1.5s by default) seems to improve CFW booting a lot.

    TL;DR: BootCtr is a substitute for boot.3dsx, aimed mainly for HomeMenuHax (autoboot) users, that allows multiple boot entries by holding keys, supports both .3dsx and binary payloads, increases boot rate of CFWs, and is customized using the included boot_config.ini file.

    Features
    • Supports both .3dsx files and binary payloads (for example, /rxTools/sys/code.bin, /Cakes.dat, etc.).
    • Supports advanced features in .3dsx files, like network support.
    • Boot delay, to increase the boot rate chance of CFWs like rxTools and CakesFW.
    • Allows up-to 16+1 (16 using keys and 1 default) homebrews in O3DS, up-to 22+1 homebrews in N3DS.
    Installation
    • (Optional, but recommended) Install HomeMenuHax and set up autoboot (not gonna link a tutorial here, since there is tons of them in GBAtemp).
    • Modify, according to your needs, the included boot_config.ini file.
    • Copy both boot.3dsx and boot_config.ini to the root of your SD card.
    Usage
    • Boot up your homebrew hax as usual.
    • If you do nothing, then boot_default.3dsx (or anything that you setup in [DEFAULT] section) will be launched.
    • If you want to load an alternative launcher, hold down a button (configured according your boot_config.ini) to boot it.
    • See example boot_config.ini below for documentation.
    Code:
    ;Comments starts with ";" or "#", so you need to remove it first to the
    ;line actually do something.
    
    ;[DEFAULT] is the option that is used if you don't press anything, or press
    ;a button without configuration.
    ;The options below are the defaults used internally in the application
    ;if you don't override them first (with the exception of "path"). So even
    ;if you don't set those options in a section, the values below are used.
    [DEFAULT]
    path = /boot_default.3dsx
    ;delay = 2000
    ;offset = 0x12000
    ;payload = -1
    ;splash = 1
    ;splash_image =
    
    ;Each key can be defined using a section, like the example below. Section
    ;names must be ALL caps, and between "[]". Valid keys:
    ;  * Common keys: KEY_A, KEY_B, KEY_X, KEY_Y, KEY_L, KEY_R, KEY_SELECT,
    ;  KEY_START.
    ;  * D-PAD: KEY_DUP, KEY_DDOWN, KEY_DLEFT, KEY_DRIGHT.
    ;  * Circle pad: KEY_CPAD_UP, KEY_CPAD_DOWN, KEY_CPAD_LEFT, KEY_CPAD_RIGHT.
    ;  * N3DS-only: KEY_ZL, KEY_ZR, KEY_CSTICK_RIGHT, KEY_CSTICK_LEFT,
    ;  KEY_CSTICK_UP, KEY_CSTICK_DOWN.
    ;You MUST set at least "path" for each section, and it is the ONLY option you
    ;should set in the majority of cases.
    ;You may pass a .3dsx file or a .dat/.bin payload, the file type is detect
    ;automatically based on extension. Double check the path, since it must be
    ;correct (including caps).
    ;[KEY_CPAD_LEFT] ;MUST BE ALL CAPS
    ;path = /And/Respect_Caps_in_Path.3dsx
    
    ;Basic usage examples:
    ;Boot /boot_1.3dsx if R button is pressed.
    [KEY_R]
    path = /boot_1.3dsx
    ;Boot examples for almost every CFW out there.
    ;You can use both .3dsx files or binary (.bin, .dat) payloads
    ;[KEY_A]
    ;path = /rxTools/sys/code.bin
    ;[KEY_B]
    ;path = /Cakes.dat
    ;[KEY_X]
    ;path = /3ds/GW/GW.3dsx
    ;[KEY_Y]
    ;path = /ReiNand.dat
    
    ;An important remark: the majority of CFWs set L button to show menu instead
    ;of autobooting. So it is generally a bad idea to set L button to CFW boot,
    ;or the CFW menu will be shown instead of booting directly to CFW.
    ;[KEY_L]
    ;path = /rxTools/sys/code.bin ;BAD IDEA!!!
    
    ;################################IMPORTANT NOTE################################
    ;From here on, I will start explaining advanced options.
    ;THEY GENERALLY SHOULD NOT BE SET, except if something does not work.
    ;SO UNLESS SOMETHING IS BROKEN, set "path" option (as the examples above), and
    ;nothing else.
    ;If you have any issue, the first thing I will ask you is to remove any extra
    ;option set below. So instead of making me do extra work, just don't set the
    ;options below.
    ;##############################################################################
    
    ;The first advanced option is "delay". Delay is a number of microseconds to
    ;delay the application boot.
    ;Why this is important? It may improve the booting of some homebrews and CFWs.
    ;For example, O3DS autobooting with themehax, using either rxTools or
    ;CakesFW with Brahma2 loaders will have increased boot rate chance with 100
    ;ms of delay. For Homebrew Launcher (and other homebrews) the delay may be
    ;set to 0, unless your homebrew needs network connection during boot (such as
    ;FTBrony 1.x). In this case you may increase the delay (for example to 5000,
    ;or 5 seconds) to makes sure that you have a valid network connection.
    ;By default delay is set to 1500 (1.5s). This is a value that seems to work
    ;well with CFWs, without delaying the boot of homebrews by too much.
    ;[KEY_LEFT]
    ;path = /boot_hbl.3dsx
    ;delay = 0
    ;[KEY_RIGHT]
    ;path = /3ds/ftbrony/ftbrony.3dsx
    ;delay = 5000
    
    ;Instead of loading .3dsx files, you can use ARM9 payloads like rxTools'
    ;code.bin or CakesFW's Cakes.dat. By default it will try to detect if the
    ;file is a payload by checking the extension (.bin or .dat), however you can
    ;force by passing "payload = 1" (passing "payload = 0" forces homebrew mode,
    ;while "payload = -1" forces autodetect, the default).
    ;You may need to change the default payload offset depending of the binary
    ;you're loading. The values are generally in hexadecimal, so append "0x" in
    ;front of the number (however, decimal values are supported too).
    ;The default offset (0x12000) works in RxTools/CakesFW/ReiNand.
    ;Don't worry about setting offset option in .3dsx files, it is ignored.
    ;[KEY_START]
    ;path = /Decrypt9WIP.dat
    ;payload = 1
    ;offset = 0x12000
    
    ;Splash is a screen that shows while BootCtr is loading, showing information
    ;about the current entry in the bottom screen and a nice logo in ASCII art in
    ;top screen, or optionally any image converted in the BGR format.
    ;You can manually enable or disable top and bottom splash screens. Setting
    ;"splash = 0" disables both top and bottom screen. This may avoid garbage
    ;screens while booting in some cases (i.e. Homebrew Launcher). "splash = 1"
    ;enables only top screen, "splash = 2" enables only bottom screen, while
    ;"splash = 3" (default) enables both.
    ;WARNING: this option only controls the display of splash screen, however the
    ;actual duration of splash is controlled (indirectly) by "delay" option. If
    ;you want to increase the duration of splash, for example, set a higher delay.
    ;Setting "delay = 0" does not disable splash either, however it may be too
    ;fast to read the information.
    ;To use an image instead of the default ASCII art, you need to pass a converted
    ;BGR file to the "splash_image" option. Use the site below to convert files:
    ;https://xem.github.io/3DShomebrew/tools/image-to-bin.html
    ;A (ugly) splash screen example can be found in "splash" folder.
    
    ;[GLOBAL] is a special section that may be used to override the application
    ;defaults. For example, if you want to set a global "splash_image" to
    ;"/boot_splash.bin", instead of copying and pasting the same entry in every
    ;section, just set it one time in [GLOBAL].
    ;[GLOBAL] is the only section that you may not set "path" option, however you
    ;can. In this case, you will have a default path in every entry, that isn't
    ;exactly what you would want (unless you want to set booting to the same
    ;homebrew with different configurations).
    ;[GLOBAL]
    ;splash = 1
    ;splash_image = /boot_splash.bin
    
    
    Downloads
     
    Last edited by m45t3r, Jan 29, 2016
    stl25, jon2491, TVL and 30 others like this.


  2. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    @d0k3, I think your function load_arm9_payload() should be something like this: https://gist.github.com/m45t3r/a577fa84adbfda62d9e7

    Instead of passing the exactly payload size, you pass the maximum allowed payload size. So if the payload is less than max_psize, it would only load the calculated psize, otherwise, it would load max_psize. This is similar that I am doing in BootCtr (look here: https://github.com/m45t3r/BootCtr/blob/master/source/loader.c#L20; just FYI, PAYLOAD_SIZE is 0x10000), and works for both rxTools and Cakes (probably for ReiNand too, however I don't have a N3DS to test).

    This may seem silly, however I don't know a better method to do it. Simply assuming psize=ARM9_MAX_PAYLOAD_SIZE seems to break rxTools booting for god knows why (I am sure that the rxTools payload is less than ARM9_MAX_PAYLOAD_SIZE, since using 0x10000 or 0x50000 for payload size seems to work with rxTools). The binary of rxTools is bigger than Cakes (and probably ReiNand too), so it tries to load the whole function, that fails.
     
  3. Xenosaiga

    Xenosaiga That one guy that doesn't give a shit anymore

    Member
    1,478
    838
    Oct 9, 2015
    United States
    The Shadows
    This is a continuation of your work on emergency launcher right? As in a continuation of your last launcher posted on mashers thread?

    If so I'm just gonna keep using this since I already had been.
     
  4. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    Yep, I just changed the name since it was starting to get confusing (mainly for new users, they would look at the OP and not know about the new features).
     
    Xenosaiga likes this.
  5. d0k3

    d0k3 3DS Homebrew Legend

    Member
    2,606
    2,627
    Dec 3, 2004
    Gambia, The
    Alright, thanks! I'll add the change to my BrahmaLoader fork. Also, I'll keep a close eye on this thread. Keep up the good work!

    EDIT: After making the change, it seems pretty strange that this works. psize was always limited by fsize, and additional bytes at the end of the actual payload shouldn't matter. The end result now should be the same as before (max_psize byte are loaded now if the file is bigger the max_psize). Anyways, the fix is in.

    EDIT2: Nevermind. The problem before was that BrahmaLoader actually tried to load more data than there actually was in some cases. Should be fixed now, remember to update your submodule.
     
    Last edited by d0k3, Nov 1, 2015
  6. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    Thanks for the fix, however I am waiting for @mid-kid merge the warnings fixes. After that, I will start using upstream (CakeBrah). Maybe it would be best if you can do a Pull Request for CakeBrah, so this change would be in upstream too.
     
    d0k3 likes this.
  7. zuxicovp

    zuxicovp Advanced Member

    Newcomer
    82
    18
    Jan 25, 2015
    United States
    Doesn't support gatewaylauncher.dat right?
     
  8. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    You really need to ask Gateway for this one.

    Gateway uses their own payload, unless they add a .3dsx loader we (as homebrew creators) can't do much.
     
    Last edited by m45t3r, Nov 2, 2015
  9. mid-kid

    mid-kid GBAtemp spamBOT

    Member
    879
    962
    Aug 2, 2012
    This is how rxTools used to load it's payload when booting via Mset (which was encrypted in the same way as Gateway's): https://github.com/roxas75/rxTools/...909bd1bda5c4ecaf/msethax/loader/source/main.c
    This is done from arm9 (note the copying of the code in lines 27-31), but it should be able to be done from anywhere (it's just xoring). The only thing that will need to be done from arm9 is copying the code and setting the framebuffers right (although this could in theory be done in arm11 kernel), but for this you can either implement it yourself or use CakeHax' chainloader payload.
    The only thing I'm not completely sure is if Gateway's encryption hasn't changed over time. That could be a problem.
    I don't really care if this actually ends up happening, but just saying it isn't impossible (and a lot of the info you need is already out there, except for maybe the encryption method).
     
    Last edited by mid-kid, Nov 2, 2015
  10. temper999

    temper999 GBAtemp Regular

    Member
    288
    54
    Sep 22, 2015
    Gambia, The
  11. DjoeN

    DjoeN Captain Haddock!

    Member
    5,136
    1,478
    Oct 21, 2005
    Belgium
    Somewhere in this potatoland!
    Great to see another choice, Friendly competition is always good, also a screenshot would be nice if possible :)

    Thanks
     
  12. night_hawk

    night_hawk GBAtemp Fan

    Member
    489
    186
    Dec 3, 2014
    Italy
    What screenshot? It has no GUI, direct boot whatever you set in the .ini. No need to select entries by a menu
     
    DjoeN likes this.
  13. DjoeN

    DjoeN Captain Haddock!

    Member
    5,136
    1,478
    Oct 21, 2005
    Belgium
    Somewhere in this potatoland!
    ah, i tought it had some kind of GUI like ctrbootmanager, my mistake.
     
  14. night_hawk

    night_hawk GBAtemp Fan

    Member
    489
    186
    Dec 3, 2014
    Italy
    Nope, i used ctr bootmanager then switched to this one, just edit the ini as you wish, then you can for example just turn on the console to boot cfw, hold a button to boot Homebrew loader, hold another one to load the grid layout Hbl and so
     
  15. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    I can try something, however I don't have a Gateway (making tests more difficult).

    Edit: forget what I said, I only need to launch Launcher.dat right? So I can do without a Gateway card.

    It is slightly faster since it is based in key presses instead of a GUI to select your choice. And, according to @d0k3, it seems to work with homebrews that uses network, while CtrBootManager seems not to work in every case.
     
    Last edited by m45t3r, Nov 2, 2015
  16. d0k3

    d0k3 3DS Homebrew Legend

    Member
    2,606
    2,627
    Dec 3, 2004
    Gambia, The
    Just so that request is in this thread as well :)... I think that a simply menu, similar to CTR Boot Managers menu (that could be accessed by a button the user chooses, f.e.) would be a great addition to this. You could even go further and use that menu to reassign keys (only on startentries the user manually entered before, of course).
     
    klear, Xenosaiga and Shaker78 like this.
  17. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    I initiallly thought that this wasn't a bad idea, however now that I think about it more it seems to be too similar to CtrBootManager.

    Anyway, I did a brainstorm Sunday and have almost everything ready to implement in my head (I just don't know if this is a good idea, really). The only problem is that I did not know a way to allow more than a certain number of entries in the menu (would probably need to scroll when there is more than a certain number of options, however I don't know how to count if I passed this limit already).
     
    peteruk likes this.
  18. d0k3

    d0k3 3DS Homebrew Legend

    Member
    2,606
    2,627
    Dec 3, 2004
    Gambia, The
    I gave BootCTR another try today. Some thoughts:
    • I don't like that the stuff under [DEFAULT] is used for other entries as well. The default entry, for most, will be a CFW payload with an offset and a delay. Because I gave an offset and a delay there, I need to manually specify the offset and delay for each and every other entry (.3DSX file, f.e.), despite most of these being zero. I'd suggest, if specifying default values for offset and delay, these should be given for payload and 3DSX separate.
    • If I start an app like ftBrony (even if I first started HB Launcher and ran it from there), it returns to BootCTR, and in turn boots my default (unless I have lightning fast reflexes, I guess). This is bad in some cases (like with ftBrony & HB Launcher). Is there some way to give the user control over which app it returns to?
    • Despite what I said earlier, wifi doesn't work properly. That's nothing to be surprised of, cause the 3DS wifi needs time to connect. If I fire up ftBrony too quick, it will be the same in HB Grid Launcher, HB Launcher, CTR Boot Manager and BootCTR: It will not work. Wifi does work even when doing this quick if it was setup by another app earlier, but not very reliable. Nothing much that you can do there, cause the whole concept of this is firing up apps as quickly as possible.
    • Might be a problem by design, but there is no reasonable way to load rxTools Devmode or ReiNAND SysNAND mode with BootCTR & themehax. You've got no indicators of when to press which button, and booting these in themehax always requires at least two different buttons held at different times
     
    Last edited by d0k3, Nov 6, 2015
  19. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    • I removed the default loading in another commit (simplified the code quite a bit), however I had the problem that if you pressed a key that was not set, however you had set a default, it would mean that the app would try to load the default from application instead of the default from the user. What it happened (in my case) is that the app would try to load boot_default.3dsx when I pressed R (I sometimes do this to show the RxTools menu), that I don't have (my default entry is /rxTools/sys/code.bin). So yeah, at least some kind of default loading is needed, and I don't want to complicate my code with special cases (so your sugestion is a no-no). I don't really like the current solution, so if there is a nice solution on how I can solve this, I am open to suggestions.
      • Just an observation: offset is default set to 0x12000 (since this is the value used by CakeBrah by default), and is only valid to payloads, so if you're using a .3dsx file there is no offset, ever (does not make sense anyway). And the delay is set to 100 ms, because even if homebrew does not need, it does not increase homebrew boot too much (c'mon, it is just 100 ms, HBL takes ~5 seconds, or 50x the delay time, to boot in my O3DS). For the majority of user cases, you don't need to set anything except for the path (I should probably write this somewhere). The other options are completely optional, and only for advance users.
      • So just to make this clear: unless you are a advanced user or have are a special case (100ms delay is not enough or your payload does not have a offset 0x12000), you don't need to set anything except for path. BootCtr defaults are sane that should work in 95% of cases (and of course this statistic is invented, like 97.5% of all statistics).
      • If you can give me examples of binary payloads that uses 0 for offset I may change the default, however the ones I know (rxTools's code.bin and Cakes' Cakes.dat) both use 0x120000.
    • I don't think so, this is a problem with HBL itself. It tries to load boot.3dsx after any app exits. One way that you may return to HBL instead of BootCtr is to hex edit the themehax payload to load a file that is not boot.3dsx (for example, bctr.3dsx), and re-rename your HBL file to boot.3dsx. So when themehax boots, it will load bctr.3dsx, and after exiting a homebrew it will load boot.3dsx that is HBL itself. I for one just remember that I need to press R (the button I assigned to HBL) when exiting any homebrew.
    • Well, never had this problem since I actually launch FTP-Brony (or any other homebrew that needs network) from HBL itself. Anyway, WiFi does work properly (it is different from early versions of CtrBootManager, that network did not work at all).
    • Well, maybe (I don't find this difficult at all, however I am the homebrew creator), but for me it is very easy to load rxTools Devmode (can't say much for ReiNAND, don't have a N3DS). I just leave my L button not-assigned to anything in BootCtr, so when I need to access rxTools menu I hold L (remember that RxTools is my default entry). If I need to access CakesFW menu (that is my alternate CFW), I hold A (the button assigned to CakesFW) until I see the end of debug screen from menuhax, and after that I wait sometime and press L, so I have access to CakesFW menu. I may put a screen saying "Booting whatever.3dsx..." if this is a big problem, however I will probably only implement this in non-default mode (since I want default to be as fast as possible). The only problem for me is, this screen needs to show for a reasonable amount of time (at least 2 seconds), and will delay anything that isn't a default boot (or I may include a option to turn on/off this screen).
     
    Last edited by m45t3r, Nov 6, 2015
    d0k3 likes this.
  20. m45t3r
    OP

    m45t3r GBAtemp Regular

    Member
    243
    181
    Jul 17, 2007
    Brazil
    Well, did a update to boot_config.ini file (available in OP, not included yet in an actual release) that should clarify some things (like you don't actually need to set offset and delay options unless you really need them). Hope it is less confusing now.

    Just reinterating that the defaults from BootCtr are sane, so you don't need to set anything else except for path in the majority of cases.