A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 98 lines 2.9 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2010 by Thomas Martitz 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include "config.h" 23#include "system.h" 24#include "kernel.h" 25#include "file.h" 26#include "debug.h" 27#include "load_code.h" 28 29/* load binary blob from disk to memory, returning a handle */ 30void * lc_open(const char *filename, unsigned char *buf, size_t buf_size) 31{ 32 int fd = open(filename, O_RDONLY); 33 ssize_t read_size; 34 struct lc_header hdr; 35 unsigned char *buf_end = buf+buf_size; 36 off_t copy_size; 37 38 if (fd < 0) 39 { 40 DEBUGF("Could not open file"); 41 goto error; 42 } 43 44#if NUM_CORES > 1 45 /* Make sure COP cache is flushed and invalidated before loading */ 46 { 47 int my_core = switch_core(CURRENT_CORE ^ 1); 48 switch_core(my_core); 49 } 50#endif 51 52 /* read the header to obtain the load address */ 53 read_size = read(fd, &hdr, sizeof(hdr)); 54 55 if (read_size < 0) 56 { 57 DEBUGF("Could not read from file"); 58 goto error_fd; 59 } 60 61 /* hdr.end_addr points to the end of the bss section, 62 * but there might be idata/icode behind that so the bytes to copy 63 * can be larger */ 64 copy_size = MAX(filesize(fd), hdr.end_addr - hdr.load_addr); 65 66 if (hdr.load_addr < buf || (hdr.load_addr+copy_size) > buf_end) 67 { 68 DEBUGF("Binary doesn't fit into memory"); 69 goto error_fd; 70 } 71 72 /* go back to beginning to load the whole thing (incl. header) */ 73 if (lseek(fd, 0, SEEK_SET) < 0) 74 { 75 DEBUGF("lseek failed"); 76 goto error_fd; 77 } 78 79 /* the header has the addresses where the code is linked at */ 80 read_size = read(fd, hdr.load_addr, copy_size); 81 close(fd); 82 83 if (read_size < 0) 84 { 85 DEBUGF("Could not read from file"); 86 goto error; 87 } 88 89 /* commit dcache and discard icache */ 90 commit_discard_idcache(); 91 /* return a pointer the header, reused by lc_get_header() */ 92 return hdr.load_addr; 93 94error_fd: 95 close(fd); 96error: 97 return NULL; 98}