1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Operating System Interface 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This provides access to useful OS routines for the sandbox architecture. 5*4882a593Smuzhiyun * They are kept in a separate file so we can include system headers. 6*4882a593Smuzhiyun * 7*4882a593Smuzhiyun * Copyright (c) 2011 The Chromium OS Authors. 8*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 9*4882a593Smuzhiyun */ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #ifndef __OS_H__ 12*4882a593Smuzhiyun #define __OS_H__ 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include <linux/types.h> 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun struct rtc_time; 17*4882a593Smuzhiyun struct sandbox_state; 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun /** 20*4882a593Smuzhiyun * Access to the OS read() system call 21*4882a593Smuzhiyun * 22*4882a593Smuzhiyun * \param fd File descriptor as returned by os_open() 23*4882a593Smuzhiyun * \param buf Buffer to place data 24*4882a593Smuzhiyun * \param count Number of bytes to read 25*4882a593Smuzhiyun * \return number of bytes read, or -1 on error 26*4882a593Smuzhiyun */ 27*4882a593Smuzhiyun ssize_t os_read(int fd, void *buf, size_t count); 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /** 30*4882a593Smuzhiyun * Access to the OS read() system call with non-blocking access 31*4882a593Smuzhiyun * 32*4882a593Smuzhiyun * \param fd File descriptor as returned by os_open() 33*4882a593Smuzhiyun * \param buf Buffer to place data 34*4882a593Smuzhiyun * \param count Number of bytes to read 35*4882a593Smuzhiyun * \return number of bytes read, or -1 on error 36*4882a593Smuzhiyun */ 37*4882a593Smuzhiyun ssize_t os_read_no_block(int fd, void *buf, size_t count); 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /** 40*4882a593Smuzhiyun * Access to the OS write() system call 41*4882a593Smuzhiyun * 42*4882a593Smuzhiyun * \param fd File descriptor as returned by os_open() 43*4882a593Smuzhiyun * \param buf Buffer containing data to write 44*4882a593Smuzhiyun * \param count Number of bytes to write 45*4882a593Smuzhiyun * \return number of bytes written, or -1 on error 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun ssize_t os_write(int fd, const void *buf, size_t count); 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun /** 50*4882a593Smuzhiyun * Access to the OS lseek() system call 51*4882a593Smuzhiyun * 52*4882a593Smuzhiyun * \param fd File descriptor as returned by os_open() 53*4882a593Smuzhiyun * \param offset File offset (based on whence) 54*4882a593Smuzhiyun * \param whence Position offset is relative to (see below) 55*4882a593Smuzhiyun * \return new file offset 56*4882a593Smuzhiyun */ 57*4882a593Smuzhiyun off_t os_lseek(int fd, off_t offset, int whence); 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun /* Defines for "whence" in os_lseek() */ 60*4882a593Smuzhiyun #define OS_SEEK_SET 0 61*4882a593Smuzhiyun #define OS_SEEK_CUR 1 62*4882a593Smuzhiyun #define OS_SEEK_END 2 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /** 65*4882a593Smuzhiyun * Access to the OS open() system call 66*4882a593Smuzhiyun * 67*4882a593Smuzhiyun * \param pathname Pathname of file to open 68*4882a593Smuzhiyun * \param flags Flags, like OS_O_RDONLY, OS_O_RDWR 69*4882a593Smuzhiyun * \return file descriptor, or -1 on error 70*4882a593Smuzhiyun */ 71*4882a593Smuzhiyun int os_open(const char *pathname, int flags); 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun #define OS_O_RDONLY 0 74*4882a593Smuzhiyun #define OS_O_WRONLY 1 75*4882a593Smuzhiyun #define OS_O_RDWR 2 76*4882a593Smuzhiyun #define OS_O_MASK 3 /* Mask for read/write flags */ 77*4882a593Smuzhiyun #define OS_O_CREAT 0100 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun /** 80*4882a593Smuzhiyun * Access to the OS close() system call 81*4882a593Smuzhiyun * 82*4882a593Smuzhiyun * \param fd File descriptor to close 83*4882a593Smuzhiyun * \return 0 on success, -1 on error 84*4882a593Smuzhiyun */ 85*4882a593Smuzhiyun int os_close(int fd); 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun /** 88*4882a593Smuzhiyun * Access to the OS unlink() system call 89*4882a593Smuzhiyun * 90*4882a593Smuzhiyun * \param pathname Path of file to delete 91*4882a593Smuzhiyun * \return 0 for success, other for error 92*4882a593Smuzhiyun */ 93*4882a593Smuzhiyun int os_unlink(const char *pathname); 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun /** 96*4882a593Smuzhiyun * Access to the OS exit() system call 97*4882a593Smuzhiyun * 98*4882a593Smuzhiyun * This exits with the supplied return code, which should be 0 to indicate 99*4882a593Smuzhiyun * success. 100*4882a593Smuzhiyun * 101*4882a593Smuzhiyun * @param exit_code exit code for U-Boot 102*4882a593Smuzhiyun */ 103*4882a593Smuzhiyun void os_exit(int exit_code) __attribute__((noreturn)); 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun /** 106*4882a593Smuzhiyun * Put tty into raw mode to mimic serial console better 107*4882a593Smuzhiyun * 108*4882a593Smuzhiyun * @param fd File descriptor of stdin (normally 0) 109*4882a593Smuzhiyun * @param allow_sigs Allow Ctrl-C, Ctrl-Z to generate signals rather than 110*4882a593Smuzhiyun * be handled by U-Boot 111*4882a593Smuzhiyun */ 112*4882a593Smuzhiyun void os_tty_raw(int fd, bool allow_sigs); 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun /** 115*4882a593Smuzhiyun * Restore the tty to its original mode 116*4882a593Smuzhiyun * 117*4882a593Smuzhiyun * Call this to restore the original terminal mode, after it has been changed 118*4882a593Smuzhiyun * by os_tty_raw(). This is an internal function. 119*4882a593Smuzhiyun */ 120*4882a593Smuzhiyun void os_fd_restore(void); 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun /** 123*4882a593Smuzhiyun * Acquires some memory from the underlying os. 124*4882a593Smuzhiyun * 125*4882a593Smuzhiyun * \param length Number of bytes to be allocated 126*4882a593Smuzhiyun * \return Pointer to length bytes or NULL on error 127*4882a593Smuzhiyun */ 128*4882a593Smuzhiyun void *os_malloc(size_t length); 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun /** 131*4882a593Smuzhiyun * Free memory previous allocated with os_malloc()/os_realloc() 132*4882a593Smuzhiyun * 133*4882a593Smuzhiyun * This returns the memory to the OS. 134*4882a593Smuzhiyun * 135*4882a593Smuzhiyun * \param ptr Pointer to memory block to free 136*4882a593Smuzhiyun */ 137*4882a593Smuzhiyun void os_free(void *ptr); 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun /** 140*4882a593Smuzhiyun * Reallocate previously-allocated memory to increase/decrease space 141*4882a593Smuzhiyun * 142*4882a593Smuzhiyun * This works in a similar way to the C library realloc() function. If 143*4882a593Smuzhiyun * length is 0, then ptr is freed. Otherwise the space used by ptr is 144*4882a593Smuzhiyun * expanded or reduced depending on whether length is larger or smaller 145*4882a593Smuzhiyun * than before. 146*4882a593Smuzhiyun * 147*4882a593Smuzhiyun * If ptr is NULL, then this is similar to calling os_malloc(). 148*4882a593Smuzhiyun * 149*4882a593Smuzhiyun * This function may need to move the memory block to make room for any 150*4882a593Smuzhiyun * extra space, in which case the new pointer is returned. 151*4882a593Smuzhiyun * 152*4882a593Smuzhiyun * \param ptr Pointer to memory block to reallocate 153*4882a593Smuzhiyun * \param length New length for memory block 154*4882a593Smuzhiyun * \return pointer to new memory block, or NULL on failure or if length 155*4882a593Smuzhiyun * is 0. 156*4882a593Smuzhiyun */ 157*4882a593Smuzhiyun void *os_realloc(void *ptr, size_t length); 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun /** 160*4882a593Smuzhiyun * Access to the usleep function of the os 161*4882a593Smuzhiyun * 162*4882a593Smuzhiyun * \param usec Time to sleep in micro seconds 163*4882a593Smuzhiyun */ 164*4882a593Smuzhiyun void os_usleep(unsigned long usec); 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun /** 167*4882a593Smuzhiyun * Gets a monotonic increasing number of nano seconds from the OS 168*4882a593Smuzhiyun * 169*4882a593Smuzhiyun * \return A monotonic increasing time scaled in nano seconds 170*4882a593Smuzhiyun */ 171*4882a593Smuzhiyun uint64_t os_get_nsec(void); 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun /** 174*4882a593Smuzhiyun * Parse arguments and update sandbox state. 175*4882a593Smuzhiyun * 176*4882a593Smuzhiyun * @param state Sandbox state to update 177*4882a593Smuzhiyun * @param argc Argument count 178*4882a593Smuzhiyun * @param argv Argument vector 179*4882a593Smuzhiyun * @return 0 if ok, and program should continue; 180*4882a593Smuzhiyun * 1 if ok, but program should stop; 181*4882a593Smuzhiyun * -1 on error: program should terminate. 182*4882a593Smuzhiyun */ 183*4882a593Smuzhiyun int os_parse_args(struct sandbox_state *state, int argc, char *argv[]); 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun /* 186*4882a593Smuzhiyun * Types of directory entry that we support. See also os_dirent_typename in 187*4882a593Smuzhiyun * the C file. 188*4882a593Smuzhiyun */ 189*4882a593Smuzhiyun enum os_dirent_t { 190*4882a593Smuzhiyun OS_FILET_REG, /* Regular file */ 191*4882a593Smuzhiyun OS_FILET_LNK, /* Symbolic link */ 192*4882a593Smuzhiyun OS_FILET_DIR, /* Directory */ 193*4882a593Smuzhiyun OS_FILET_UNKNOWN, /* Something else */ 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun OS_FILET_COUNT, 196*4882a593Smuzhiyun }; 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun /** A directory entry node, containing information about a single dirent */ 199*4882a593Smuzhiyun struct os_dirent_node { 200*4882a593Smuzhiyun struct os_dirent_node *next; /* Pointer to next node, or NULL */ 201*4882a593Smuzhiyun ulong size; /* Size of file in bytes */ 202*4882a593Smuzhiyun enum os_dirent_t type; /* Type of entry */ 203*4882a593Smuzhiyun char name[0]; /* Name of entry */ 204*4882a593Smuzhiyun }; 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun /** 207*4882a593Smuzhiyun * Get a directionry listing 208*4882a593Smuzhiyun * 209*4882a593Smuzhiyun * This allocates and returns a linked list containing the directory listing. 210*4882a593Smuzhiyun * 211*4882a593Smuzhiyun * @param dirname Directory to examine 212*4882a593Smuzhiyun * @param headp Returns pointer to head of linked list, or NULL if none 213*4882a593Smuzhiyun * @return 0 if ok, -ve on error 214*4882a593Smuzhiyun */ 215*4882a593Smuzhiyun int os_dirent_ls(const char *dirname, struct os_dirent_node **headp); 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun /** 218*4882a593Smuzhiyun * Free directory list 219*4882a593Smuzhiyun * 220*4882a593Smuzhiyun * This frees a linked list containing a directory listing. 221*4882a593Smuzhiyun * 222*4882a593Smuzhiyun * @param node Pointer to head of linked list 223*4882a593Smuzhiyun */ 224*4882a593Smuzhiyun void os_dirent_free(struct os_dirent_node *node); 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun /** 227*4882a593Smuzhiyun * Get the name of a directory entry type 228*4882a593Smuzhiyun * 229*4882a593Smuzhiyun * @param type Type to check 230*4882a593Smuzhiyun * @return string containing the name of that type, or "???" if none/invalid 231*4882a593Smuzhiyun */ 232*4882a593Smuzhiyun const char *os_dirent_get_typename(enum os_dirent_t type); 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun /** 235*4882a593Smuzhiyun * Get the size of a file 236*4882a593Smuzhiyun * 237*4882a593Smuzhiyun * @param fname Filename to check 238*4882a593Smuzhiyun * @param size size of file is returned if no error 239*4882a593Smuzhiyun * @return 0 on success or -1 if an error ocurred 240*4882a593Smuzhiyun */ 241*4882a593Smuzhiyun int os_get_filesize(const char *fname, loff_t *size); 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /** 244*4882a593Smuzhiyun * Write the sandbox RAM buffer to a existing file 245*4882a593Smuzhiyun * 246*4882a593Smuzhiyun * @param fname Filename to write memory to (simple binary format) 247*4882a593Smuzhiyun * @return 0 if OK, -ve on error 248*4882a593Smuzhiyun */ 249*4882a593Smuzhiyun int os_write_ram_buf(const char *fname); 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun /** 252*4882a593Smuzhiyun * Read the sandbox RAM buffer from an existing file 253*4882a593Smuzhiyun * 254*4882a593Smuzhiyun * @param fname Filename containing memory (simple binary format) 255*4882a593Smuzhiyun * @return 0 if OK, -ve on error 256*4882a593Smuzhiyun */ 257*4882a593Smuzhiyun int os_read_ram_buf(const char *fname); 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun /** 260*4882a593Smuzhiyun * Jump to a new executable image 261*4882a593Smuzhiyun * 262*4882a593Smuzhiyun * This uses exec() to run a new executable image, after putting it in a 263*4882a593Smuzhiyun * temporary file. The same arguments and environment are passed to this 264*4882a593Smuzhiyun * new image, with the addition of: 265*4882a593Smuzhiyun * 266*4882a593Smuzhiyun * -j <filename> Specifies the filename the image was written to. The 267*4882a593Smuzhiyun * calling image may want to delete this at some point. 268*4882a593Smuzhiyun * -m <filename> Specifies the file containing the sandbox memory 269*4882a593Smuzhiyun * (ram_buf) from this image, so that the new image can 270*4882a593Smuzhiyun * have access to this. It also means that the original 271*4882a593Smuzhiyun * memory filename passed to U-Boot will be left intact. 272*4882a593Smuzhiyun * 273*4882a593Smuzhiyun * @param dest Buffer containing executable image 274*4882a593Smuzhiyun * @param size Size of buffer 275*4882a593Smuzhiyun */ 276*4882a593Smuzhiyun int os_jump_to_image(const void *dest, int size); 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun /** 279*4882a593Smuzhiyun * os_find_u_boot() - Determine the path to U-Boot proper 280*4882a593Smuzhiyun * 281*4882a593Smuzhiyun * This function is intended to be called from within sandbox SPL. It uses 282*4882a593Smuzhiyun * a few heuristics to find U-Boot proper. Normally it is either in the same 283*4882a593Smuzhiyun * directory, or the directory above (since u-boot-spl is normally in an 284*4882a593Smuzhiyun * spl/ subdirectory when built). 285*4882a593Smuzhiyun * 286*4882a593Smuzhiyun * @fname: Place to put full path to U-Boot 287*4882a593Smuzhiyun * @maxlen: Maximum size of @fname 288*4882a593Smuzhiyun * @return 0 if OK, -NOSPC if the filename is too large, -ENOENT if not found 289*4882a593Smuzhiyun */ 290*4882a593Smuzhiyun int os_find_u_boot(char *fname, int maxlen); 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun /** 293*4882a593Smuzhiyun * os_spl_to_uboot() - Run U-Boot proper 294*4882a593Smuzhiyun * 295*4882a593Smuzhiyun * When called from SPL, this runs U-Boot proper. The filename is obtained by 296*4882a593Smuzhiyun * calling os_find_u_boot(). 297*4882a593Smuzhiyun * 298*4882a593Smuzhiyun * @fname: Full pathname to U-Boot executable 299*4882a593Smuzhiyun * @return 0 if OK, -ve on error 300*4882a593Smuzhiyun */ 301*4882a593Smuzhiyun int os_spl_to_uboot(const char *fname); 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun /** 304*4882a593Smuzhiyun * Read the current system time 305*4882a593Smuzhiyun * 306*4882a593Smuzhiyun * This reads the current Local Time and places it into the provided 307*4882a593Smuzhiyun * structure. 308*4882a593Smuzhiyun * 309*4882a593Smuzhiyun * @param rt Place to put system time 310*4882a593Smuzhiyun */ 311*4882a593Smuzhiyun void os_localtime(struct rtc_time *rt); 312*4882a593Smuzhiyun 313*4882a593Smuzhiyun #endif 314