From 0c1a96101cdfc778dbffa7ceffea5765ffd4d1bd Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sat, 12 Nov 2016 22:16:48 +0100 Subject: [PATCH] nwztools: rework dualboot The new code gets closer to an actual bootloader: - it provides a menu with three options: Sony, Rockox, tools with icons (and extracts the Sony logo from the NVP) - the dualboot install script now creates a symlink from /.rockbox to /contents/.rockox which is necessary to run rockbox - more text drawing / framebuffer functions In the long run, we will move this under bootloader/ and rbutil/ and also use firmware/ drawing facilities, at the moment we use OF display program which is slow and creates some flickering. The logo extraction/placement code was tested with resolution 240x320 and I guessed some reasonable values for 240x400, but those will probably need some tweaking. Change-Id: I0319be902d21a7d33c1dee0fffdb4797065dbf8a --- utils/nwztools/plattools/data/Makefile | 8 + ...xygen480-categories-preferences-system.svg | 334 ++++++++++++++++++ utils/nwztools/plattools/data/make_images.sh | 53 +++ .../nwztools/plattools/data/rockbox_icon.bmp | Bin 0 -> 51014 bytes utils/nwztools/plattools/data/tools_icon.bmp | Bin 0 -> 51014 bytes utils/nwztools/plattools/dualboot.c | 235 +++++++++--- utils/nwztools/plattools/nwz_lib.c | 50 ++- utils/nwztools/plattools/nwz_lib.h | 13 + utils/nwztools/scripts/install_dualboot.sh | 49 +-- 9 files changed, 666 insertions(+), 76 deletions(-) create mode 100644 utils/nwztools/plattools/data/Makefile create mode 100644 utils/nwztools/plattools/data/Oxygen480-categories-preferences-system.svg create mode 100755 utils/nwztools/plattools/data/make_images.sh create mode 100644 utils/nwztools/plattools/data/rockbox_icon.bmp create mode 100644 utils/nwztools/plattools/data/tools_icon.bmp diff --git a/utils/nwztools/plattools/data/Makefile b/utils/nwztools/plattools/data/Makefile new file mode 100644 index 0000000000..86f3bb339c --- /dev/null +++ b/utils/nwztools/plattools/data/Makefile @@ -0,0 +1,8 @@ +TOOLS_DIR=../../../../tools/ +all: rockbox_icon.h tools_icon.h + +%.h: %.bmp + $(TOOLS_DIR)/bmp2rb -f 4 $^ > $@ + +clean: + rm -rf *.h diff --git a/utils/nwztools/plattools/data/Oxygen480-categories-preferences-system.svg b/utils/nwztools/plattools/data/Oxygen480-categories-preferences-system.svg new file mode 100644 index 0000000000..0835251992 --- /dev/null +++ b/utils/nwztools/plattools/data/Oxygen480-categories-preferences-system.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/utils/nwztools/plattools/data/make_images.sh b/utils/nwztools/plattools/data/make_images.sh new file mode 100755 index 0000000000..7ac21dc17a --- /dev/null +++ b/utils/nwztools/plattools/data/make_images.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# +# This script contains the code used to produce all the images. +# Because of the variety of tools needed to achieve that, the result is also +# included in the repository but this makes it easier to modify the data +# to add more content +# + +# path to root of repository +ROOT_DIR=../../../../ + +# final resolution +NWZ_WIDTH=130 +NWZ_HEIGHT=130 + +# path to rockbox icon +RB_ICON_PATH=$ROOT_DIR/docs/logo/rockbox-icon.svg +# path to tools icon (currently stolen from KDE Oxygen icon set) +TOOL_ICON_PATH=Oxygen480-categories-preferences-system.svg + +# convert_svg width height input output +function convert_svg +{ + local width="$1" + local height="$2" + local input="$3" + local output="$4" + TMP=tmp.png + # convert from SVG to PNG + inkscape -z -e $TMP -w $width -h $height $input + if [ "$?" != 0 ]; then + echo "SVG -> PNG conversion failed" + exit 1 + fi + # convert from PNG to BMP, force using "version 3" because the OF don't like + # "recent" BMP + convert -channel RGB $TMP -define bmp:format=bmp3 ${output}_icon.bmp + if [ "$?" != 0 ]; then + rm -f $TMP + echo "PNG -> BMP conversion failed" + exit 1 + fi + # remove temporary + rm -f $TMP +} + +# start by creating the bitmap files from rockbox-icon.svg for all resolutions +# we make a detour by svg because inkscape can only export to SVG +# NOTE: we use image magick to convert to bmp but the OF tools don't like BMPv5 +# and contrary to what the documentation says, image magick tends to produce +# those by default unless asked otherwise +convert_svg $NWZ_WIDTH $NWZ_HEIGHT $RB_ICON_PATH rockbox +convert_svg $NWZ_WIDTH $NWZ_HEIGHT $TOOL_ICON_PATH tools diff --git a/utils/nwztools/plattools/data/rockbox_icon.bmp b/utils/nwztools/plattools/data/rockbox_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..69e6792e7b5f914f3203c7336fb6e1784dd9edc6 GIT binary patch literal 51014 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 literal 0 HcmV?d00001 diff --git a/utils/nwztools/plattools/data/tools_icon.bmp b/utils/nwztools/plattools/data/tools_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f9fccf03068a2056a6748eb4d88f73d935b68487 GIT binary patch literal 51014 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 Z$-m9}`*7_K68Ip24-)twf&UK@_&@I!pRND^ literal 0 HcmV?d00001 diff --git a/utils/nwztools/plattools/dualboot.c b/utils/nwztools/plattools/dualboot.c index a5d04fa4ed..c6d07c7508 100644 --- a/utils/nwztools/plattools/dualboot.c +++ b/utils/nwztools/plattools/dualboot.c @@ -24,6 +24,64 @@ #include "nwz_lib.h" #include "nwz_plattools.h" #include +#include + +/* all images must have the following size */ +#define ICON_WIDTH 130 +#define ICON_HEIGHT 130 + +/* images */ +#include "data/rockbox_icon.h" +#if BMPWIDTH_rockbox_icon != ICON_WIDTH || BMPHEIGHT_rockbox_icon != ICON_HEIGHT +#error rockbox_icon has the wrong resolution +#endif +#include "data/tools_icon.h" +#if BMPWIDTH_tools_icon != ICON_WIDTH || BMPHEIGHT_tools_icon != ICON_HEIGHT +#error tools_icon has the wrong resolution +#endif +/* buffer for Sony image, filled from NVP */ +unsigned short sony_icon[ICON_WIDTH * ICON_HEIGHT]; +/* resolution */ +static int width, height, bpp; + +/* return icon y position (x is always centered) */ +int get_icon_y(void) +{ + /* adjust so that this contains the Sony logo and produces a nice logo + * when used with rockbox */ + if(height == 320) + return 70; + else if(height == 320) + return 100; + else + return height / 2 - ICON_HEIGHT + 30; /* guess, probably won't work */ +} + +/* Sony logo extraction */ +bool extract_sony_logo(void) +{ + /* only support bpp of 16 */ + if(bpp != 16) + return false; + /* load the entire image from the nvp */ + int bti_size = nwz_nvp_read(NWZ_NVP_BTI, NULL); + if(bti_size < 0) + return false; + unsigned short *bti = malloc(bti_size); + if(nwz_nvp_read(NWZ_NVP_BTI, bti) != bti_size) + return false; + /* compute the offset in the image of the logo itself */ + int x_off = (width - ICON_WIDTH) / 2; /* logo is centered horizontally */ + int y_off = get_icon_y(); + /* extract part of the image */ + for(int y = 0; y < ICON_HEIGHT; y++) + { + memcpy(sony_icon + ICON_WIDTH * y, + bti + width * (y + y_off) + x_off, ICON_WIDTH * sizeof(unsigned short)); + } + free(bti); + return true; +} /* Important Note: this bootloader is carefully written so that in case of * error, the OF is run. This seems like the safest option since the OF is @@ -36,13 +94,28 @@ enum boot_mode BOOT_OF }; +void draw_icon(int left, int top, const unsigned short *icon, unsigned short *fb_mmap) +{ + for(int y = 0; y < ICON_HEIGHT; y++) + { + memcpy(fb_mmap + width * (y + top) + left, icon + ICON_WIDTH * y, + ICON_WIDTH * sizeof(unsigned short)); + } +} + enum boot_mode get_boot_mode(void) { - /* get time */ - struct timeval deadline; - if(gettimeofday(&deadline, NULL) != 0) + if(bpp != 16) { - nwz_lcdmsg(false, 0, 2, "Cannot get time"); + nwz_lcdmsg(true, 0, 2, "Unsupported bpp"); + sleep(2); + return BOOT_OF; + } + /* open framebuffer */ + int fb_fd = nwz_fb_open(true); + if(fb_fd < 0) + { + nwz_lcdmsg(true, 0, 2, "Cannot open input device"); sleep(2); return BOOT_OF; } @@ -50,70 +123,131 @@ enum boot_mode get_boot_mode(void) int input_fd = nwz_key_open(); if(input_fd < 0) { - nwz_lcdmsg(false, 0, 2, "Cannot open input device"); + nwz_fb_close(fb_fd); + nwz_lcdmsg(true, 0, 2, "Cannot open input device"); + sleep(2); + return BOOT_OF; + } + int fb_size = width * height * bpp / 2; + void *fb_mmap = nwz_fb_mmap(fb_fd, 0, fb_size); + void *fb_mmap_p1 = nwz_fb_mmap(fb_fd, NWZ_FB_LCD_PAGE_OFFSET, fb_size); + if(fb_mmap == NULL || fb_mmap_p1 == NULL) + { + nwz_fb_close(fb_fd); + nwz_key_close(input_fd); + nwz_lcdmsg(true, 0, 2, "Cannot map framebuffer"); sleep(2); return BOOT_OF; } - deadline.tv_sec += 5; /* wait for user action */ enum boot_mode mode = BOOT_OF; + /* NOTE on drawing: since screen is redrawn automatically, and we invoke + * external programs to draw, we can't hope to fit it in the frame time + * and it will flicker. To avoid this, we use the fact that all programs + * only write to page 0. So we setup the lcd to update from page 1. When + * we need to update the screen, we ask it to draw from page 0, then copy + * page 0 to page 1 and then switch back to page 1 */ + memset(fb_mmap_p1, 0xff, fb_size); /* clear page 1 */ + nwz_fb_set_page(fb_fd, 1); + bool redraw = true; while(true) { - /* get time */ - struct timeval cur_time; - if(gettimeofday(&cur_time, NULL) != 0) + if(redraw) { - nwz_lcdmsg(false, 0, 4, "Cannot get time"); - sleep(2); - break; + /* redraw screen on page 0: clear screen */ + memset(fb_mmap, 0, fb_size); + /* display top text */ + nwz_display_text_center(width, 0, true, NWZ_COLOR(255, 201, 0), + NWZ_COLOR(0, 0, 0), 0, "SELECT PLAYER"); + /* display icon */ + const unsigned short *icon = (mode == BOOT_OF) ? sony_icon : + (mode == BOOT_ROCKBOX) ? rockbox_icon : tools_icon; + draw_icon((width - ICON_WIDTH) / 2, get_icon_y(), icon, fb_mmap); + /* display bottom description */ + const char *desc = (mode == BOOT_OF) ? "SONY" : + (mode == BOOT_ROCKBOX) ? "ROCKBOX" : "DEBUG TOOLS"; + nwz_display_text_center(width, get_icon_y() + ICON_HEIGHT + 30, true, + NWZ_COLOR(255, 201, 0), NWZ_COLOR(0, 0, 0), 0, desc); + /* display arrows */ + int arrow_y = get_icon_y() + ICON_HEIGHT / 2 - NWZ_FONT_H(true) / 2; + nwz_display_text(NWZ_FONT_W(true) / 2, arrow_y, true, + NWZ_COLOR(255, 201, 0), NWZ_COLOR(0, 0, 0), 0, "<"); + nwz_display_text(width - 3 * NWZ_FONT_W(true) / 2, arrow_y, true, + NWZ_COLOR(255, 201, 0), NWZ_COLOR(0, 0, 0), 0, ">"); + /* switch to page 1 */ + nwz_fb_set_page(fb_fd, 0); + /* copy page 0 to page 1 */ + memcpy(fb_mmap_p1, fb_mmap, fb_size); + /* switch back to page 1 */ + nwz_fb_set_page(fb_fd, 1); + + redraw = false; } - /* check timeout */ - if(cur_time.tv_sec > deadline.tv_sec) - break; - if(cur_time.tv_sec == deadline.tv_sec && cur_time.tv_usec >= deadline.tv_usec) - break; - /* print message */ - int sec_left = deadline.tv_sec - cur_time.tv_sec; - sec_left += (deadline.tv_usec - cur_time.tv_usec + 999999) / 1000000; /* round up */ - nwz_lcdmsgf(false, 0, 2, "Booting OF in %d seconds ", sec_left); - nwz_lcdmsg(false, 0, 3, "Press BACK to run tools"); - nwz_lcdmsg(false, 0, 3, "Press PLAY to boot RB"); - /* wait for a key (1s) */ - int ret = nwz_key_wait_event(input_fd, 1000000); + + /* wait for a key */ + int ret = nwz_key_wait_event(input_fd, -1); if(ret != 1) continue; struct input_event evt; if(nwz_key_read_event(input_fd, &evt) != 1) continue; + /* only act on release */ if(nwz_key_event_is_press(&evt)) continue; - if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_PLAY) - { - mode = BOOT_ROCKBOX; + int key_code = nwz_key_event_get_keycode(&evt); + /* play -> stop loop and return mode */ + if(key_code == NWZ_KEY_PLAY) break; + /* left/right/up/down: change mode */ + if(key_code == NWZ_KEY_LEFT || key_code == NWZ_KEY_DOWN) + { + if(mode == BOOT_ROCKBOX) + mode = BOOT_OF; + else if(mode == BOOT_OF) + mode = BOOT_TOOLS; + else + mode = BOOT_ROCKBOX; + redraw = true; } - else if(nwz_key_event_get_keycode(&evt) == NWZ_KEY_BACK) + if(key_code == NWZ_KEY_RIGHT || key_code == NWZ_KEY_UP) { - mode = BOOT_TOOLS; - break; + if(mode == BOOT_ROCKBOX) + mode = BOOT_TOOLS; + else if(mode == BOOT_OF) + mode = BOOT_ROCKBOX; + else + mode = BOOT_OF; + redraw = true; } } + /* switch back to page 0 */ + nwz_fb_set_page(fb_fd, 0); nwz_key_close(input_fd); + nwz_fb_close(fb_fd); return mode; } static char *boot_rb_argv[] = { - "lcdmsg", - "-c", - "-l", - "0,3", - "Hello from RB", + "rockbox.sony", NULL }; int NWZ_TOOL_MAIN(all_tools)(int argc, char **argv); +void error_screen(const char *msg) +{ + nwz_lcdmsg(true, 0, 0, msg); + sleep(3); +} + +void create_sony_logo(void) +{ + for(int y = 0; y < ICON_HEIGHT; y++) + for(int x = 0; x < ICON_WIDTH; x++) + sony_icon[y * ICON_WIDTH + x] = 0xf81f; +} + int main(int argc, char **argv) { /* make sure backlight is on and we are running the standard lcd mode */ @@ -125,9 +259,20 @@ int main(int argc, char **argv) bl.level = NWZ_FB_BL_MAX_LEVEL; nwz_fb_set_brightness(fb_fd, &bl); nwz_fb_set_standard_mode(fb_fd); + /* get resolution */ + /* we also need to get the native resolution */ + if(nwz_fb_get_resolution(fb_fd, &width, &height, &bpp) != 0) + { + /* safe one */ + width = 240; + height = 320; + bpp = 16; + } nwz_fb_close(fb_fd); } - nwz_lcdmsg(true, 0, 0, "dualboot"); + /* extract logo */ + if(!extract_sony_logo()) + create_sony_logo(); /* run all tools menu */ enum boot_mode mode = get_boot_mode(); if(mode == BOOT_TOOLS) @@ -137,19 +282,19 @@ int main(int argc, char **argv) } else if(mode == BOOT_ROCKBOX) { - /* boot rockox */ - nwz_lcdmsg(true, 0, 3, "Booting rockbox..."); - /* in the future, we will run rockbox here, for now we just print a - * message */ - execvp("/usr/local/bin/lcdmsg", boot_rb_argv); + /* Rockbox expects /.rockbox to contain themes, rocks, etc, but we + * cannot easily create this symlink because the root filesystem is + * mounted read-only. Although we could remount it read-write temporarily, + * this is neededlessly complicated and we defer this job to the dualboot + * install script */ + execvp("/contents/.rockbox/rockbox.sony", boot_rb_argv); /* fallback to OF in case of failure */ - nwz_lcdmsg(false, 0, 4, "failed."); + error_screen("Cannot boot Rockbox"); sleep(5); } /* boot OF */ - nwz_lcdmsg(true, 0, 3, "Booting OF..."); execvp("/usr/local/bin/SpiderApp.of", argv); - nwz_lcdmsg(false, 0, 4, "failed."); + error_screen("Cannot boot OF"); sleep(5); /* if we reach this point, everything failed, so return an error so that * sysmgrd knows something is wrong */ diff --git a/utils/nwztools/plattools/nwz_lib.c b/utils/nwztools/plattools/nwz_lib.c index 70dc070fc9..a81d352ff0 100644 --- a/utils/nwztools/plattools/nwz_lib.c +++ b/utils/nwztools/plattools/nwz_lib.c @@ -156,6 +156,13 @@ void nwz_display_text(int x, int y, bool big_font, nwz_color_t foreground_col, nwz_run(path_display, args, true); } +void nwz_display_text_center(int width, int y, bool big_font, nwz_color_t fg, + nwz_color_t bg, int alpha, const char *text) +{ + int txt_w = NWZ_FONT_W(big_font) * strlen(text); + nwz_display_text((width - txt_w) / 2, y, big_font, fg, bg, alpha, text); +} + void nwz_display_textf(int x, int y, bool big_font, nwz_color_t foreground_col, nwz_color_t background_col, int alpha, const char *fmt, ...) { @@ -167,6 +174,17 @@ void nwz_display_textf(int x, int y, bool big_font, nwz_color_t foreground_col, nwz_display_text(x, y, big_font, foreground_col, background_col, alpha, buffer); } +void nwz_display_textf_center(int width, int y, bool big_font, nwz_color_t fg, + nwz_color_t bg, int alpha, const char *fmt, ...) +{ + char buffer[1024]; + va_list args; + va_start(args, fmt); + vsprintf(buffer, fmt, args); + va_end(args); + nwz_display_text_center(width, y, big_font, fg, bg, alpha, buffer); +} + void nwz_display_bitmap(int x, int y, const char *file, int left, int top, int width, int height, nwz_color_t key_col, int bmp_alpha) { @@ -319,6 +337,21 @@ int nwz_fb_set_brightness(int fd, struct nwz_fb_brightness *bl) return 1; } +int nwz_fb_set_page(int fd, int page) +{ + /* set page mode to no transparency and no rotation */ + struct nwz_fb_image_info mode_info; + mode_info.tc_enable = 0; + mode_info.t_color = 0; + mode_info.alpha = 0; + mode_info.rot = 0; + mode_info.page = page; + mode_info.update = NWZ_FB_ONLY_2D_MODE; + if(ioctl(fd, NWZ_FB_UPDATE, &mode_info) < 0) + return -2; + return 0; +} + int nwz_fb_set_standard_mode(int fd) { /* disable timer (apparently useless with LCD) */ @@ -327,17 +360,7 @@ int nwz_fb_set_standard_mode(int fd) update_timer.timeout = NWZ_FB_DEFAULT_TIMEOUT; if(ioctl(fd, NWZ_FB_UPDATE_TIMER, &update_timer) < 0) return -1; - /* set page 0 mode to no transparency and no rotation */ - struct nwz_fb_image_info mode_info; - mode_info.tc_enable = 0; - mode_info.t_color = 0; - mode_info.alpha = 0; - mode_info.rot = 0; - mode_info.page = 0; - mode_info.update = NWZ_FB_ONLY_2D_MODE; - if(ioctl(fd, NWZ_FB_UPDATE, &mode_info) < 0) - return -2; - return 0; + return nwz_fb_set_page(fd, 0); } int nwz_fb_get_resolution(int fd, int *x, int *y, int *bpp) @@ -354,6 +377,11 @@ int nwz_fb_get_resolution(int fd, int *x, int *y, int *bpp) return 0; } +void *nwz_fb_mmap(int fd, int offset, int size) +{ + return mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)offset); +} + int nwz_adc_open(void) { return open(NWZ_ADC_DEV, O_RDONLY); diff --git a/utils/nwztools/plattools/nwz_lib.h b/utils/nwztools/plattools/nwz_lib.h index 18d7f9dd07..23bb80986d 100644 --- a/utils/nwztools/plattools/nwz_lib.h +++ b/utils/nwztools/plattools/nwz_lib.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "nwz_keys.h" #include "nwz_fb.h" @@ -72,11 +73,19 @@ typedef int nwz_color_t; #define NWZ_COLOR_GREEN(col) (((col) >> 8) & 0xff) #define NWZ_COLOR_BLUE(col) ((col) & 0xff) #define NWZ_COLOR_NO_KEY (1 << 24) + +#define NWZ_FONT_W(big_font) ((big_font) ? 14 : 8) +#define NWZ_FONT_H(big_font) ((big_font) ? 24 : 14) + void nwz_display_clear(nwz_color_t color); void nwz_display_text(int x, int y, bool big_font, nwz_color_t foreground_col, nwz_color_t background_col, int background_alpha, const char *text); +void nwz_display_text_center(int width, int y, bool big_font, nwz_color_t foreground_col, + nwz_color_t background_col, int background_alpha, const char *text); void nwz_display_textf(int x, int y, bool big_font, nwz_color_t foreground_col, nwz_color_t background_col, int background_alpha, const char *fmt, ...); +void nwz_display_textf_center(int width, int y, bool big_font, nwz_color_t foreground_col, + nwz_color_t background_col, int background_alpha, const char *fmt, ...); void nwz_display_bitmap(int x, int y, const char *file, int left, int top, int width, int height, nwz_color_t key, int bmp_alpha); @@ -113,6 +122,10 @@ int nwz_fb_set_brightness(int fd, struct nwz_fb_brightness *bl); /* setup framebuffer to its standard mode: LCD output, page 0, no transparency * and no rotation, 2D only updates */ int nwz_fb_set_standard_mode(int fd); +/* change framebuffer page and update screen */ +int nwz_fb_set_page(int fd, int page); +/* map framebuffer */ +void *nwz_fb_mmap(int fd, int offset, int size); /* open adc device */ int nwz_adc_open(void); diff --git a/utils/nwztools/scripts/install_dualboot.sh b/utils/nwztools/scripts/install_dualboot.sh index ece5b9e3a3..08c24b7b5f 100644 --- a/utils/nwztools/scripts/install_dualboot.sh +++ b/utils/nwztools/scripts/install_dualboot.sh @@ -10,7 +10,6 @@ nvpflag fup 0xFFFFFFFF # FIXME document this # - # go to /tmp cd /tmp @@ -30,6 +29,9 @@ if [ "$?" != 0 ]; then exit 0 fi +# redirect all output to a log file +exec > "$CONTENTS/install_dualboot_log.txt" 2>&1 + # import constants . /install_script/constant.txt _UPDATE_FN_=`nvpstr ufn` @@ -66,6 +68,7 @@ fi lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,9 "Install rockbox" fwpchk -f /contents/$_UPDATE_FN_.UPG -c -1 $SPIDERAPP_PATH if [ "$?" != 0 ]; then + umount "$ROOTFS_TMP_DIR" lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: no file to extract" sleep 3 exit 0 @@ -74,40 +77,45 @@ fi # make it executable and change user/group chmod 775 $SPIDERAPP_PATH if [ "$?" != 0 ]; then + umount "$ROOTFS_TMP_DIR" lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot make it executable" sleep 3 exit 0 fi chown 500:500 $SPIDERAPP_PATH if [ "$?" != 0 ]; then + umount "$ROOTFS_TMP_DIR" lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot change owner" sleep 3 exit 0 fi -# # change main application -# lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,9 "Modify app list" -# sed -i 's/Rockbox/SpiderApp/' $ROOTFS_TMP_DIR/etc/AppList.conf -# if [ "$?" != 0 ]; then -# lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,14 "ERROR: sed failed" -# sleep 3 -# exit 0 -# fi -# # and fix ownership -# chown 500:500 $ROOTFS_TMP_DIR/etc/AppList.conf -# if [ "$?" != 0 ]; then -# lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,14 "ERROR: cannot change group" -# sleep 3 -# exit 0 -# fi -cat $ROOTFS_TMP_DIR/etc/AppList.conf >$CONTENTS/AppList.conf -ls -l $ROOTFS_TMP_DIR/usr/local/bin/ >$CONTENTS/ls.txt -ls -l $ROOTFS_TMP_DIR/etc/ >$CONTENTS/ls2.txt +# create a symlink from /.rockbox to /contents/.rockbox (see dualboot code +# for why) +lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,10 "Create rockbox symlink" +rm -f "$ROOTFS_TMP_DIR/.rockbox" +ln -s "$CONTENTS/.rockbox" "$ROOTFS_TMP_DIR/.rockbox" +if [ "$?" != 0 ]; then + umount "$ROOTFS_TMP_DIR" + lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot create rockbox symlink" + sleep 3 + exit 0 +fi + +# change user/group +chown -h 500:500 "$ROOTFS_TMP_DIR/.rockbox" +if [ "$?" != 0 ]; then + umount "$ROOTFS_TMP_DIR" + lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: cannot change symlink owner" + sleep 3 + exit 0 +fi # unmount root partition -lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,10 "Unmount root filesystem" +lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,11 "Unmount root filesystem" sync if [ "$?" != 0 ]; then + umount "$ROOTFS_TMP_DIR" lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "ERROR: sync failed" sleep 3 exit 0 @@ -125,5 +133,6 @@ lcdmsg -f /usr/local/bin/font_08x12.bmp -l 0,15 "Rebooting in 3 seconds." sleep 3 sync +echo "Installation successful" # finish exit 0