1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * Operating System Interface 4 * 5 * This provides access to useful OS routines for the sandbox architecture. 6 * They are kept in a separate file so we can include system headers. 7 * 8 * Copyright (c) 2011 The Chromium OS Authors. 9 */ 10 11#ifndef __OS_H__ 12#define __OS_H__ 13 14#include <linux/types.h> 15 16struct rtc_time; 17struct sandbox_state; 18 19/** 20 * os_printf() - print directly to OS console 21 * 22 * @format: format string 23 */ 24int os_printf(const char *format, ...); 25 26/** 27 * Access to the OS read() system call 28 * 29 * @fd: File descriptor as returned by os_open() 30 * @buf: Buffer to place data 31 * @count: Number of bytes to read 32 * Return: number of bytes read, or -1 on error 33 */ 34ssize_t os_read(int fd, void *buf, size_t count); 35 36/** 37 * Access to the OS write() system call 38 * 39 * @fd: File descriptor as returned by os_open() 40 * @buf: Buffer containing data to write 41 * @count: Number of bytes to write 42 * Return: number of bytes written, or -1 on error 43 */ 44ssize_t os_write(int fd, const void *buf, size_t count); 45 46/** 47 * Access to the OS lseek() system call 48 * 49 * @fd: File descriptor as returned by os_open() 50 * @offset: File offset (based on whence) 51 * @whence: Position offset is relative to (see below) 52 * Return: new file offset 53 */ 54off_t os_lseek(int fd, off_t offset, int whence); 55 56/* Defines for "whence" in os_lseek() */ 57#define OS_SEEK_SET 0 58#define OS_SEEK_CUR 1 59#define OS_SEEK_END 2 60 61/** 62 * os_filesize() - Calculate the size of a file 63 * 64 * @fd: File descriptor as returned by os_open() 65 * Return: file size or negative error code 66 */ 67off_t os_filesize(int fd); 68 69/** 70 * Access to the OS open() system call 71 * 72 * @pathname: Pathname of file to open 73 * @flags: Flags, like OS_O_RDONLY, OS_O_RDWR 74 * Return: file descriptor, or -1 on error 75 */ 76int os_open(const char *pathname, int flags); 77 78#define OS_O_RDONLY 0 79#define OS_O_WRONLY 1 80#define OS_O_RDWR 2 81#define OS_O_MASK 3 /* Mask for read/write flags */ 82#define OS_O_CREAT 0100 83#define OS_O_TRUNC 01000 84 85/** 86 * os_close() - access to the OS close() system call 87 * 88 * @fd: File descriptor to close 89 * Return: 0 on success, -1 on error 90 */ 91int os_close(int fd); 92 93/** 94 * os_unlink() - access to the OS unlink() system call 95 * 96 * @pathname: Path of file to delete 97 * Return: 0 for success, other for error 98 */ 99int os_unlink(const char *pathname); 100 101/** os_persistent_fname() - Find the path to a test file 102 * 103 * @buf: Buffer to hold path 104 * @maxsize: Maximum size of buffer 105 * @fname: Leaf filename to find 106 * Returns: 0 on success, -ENOENT if file is not found, -ENOSPC if the buffer is 107 * too small 108 */ 109int os_persistent_file(char *buf, int maxsize, const char *fname); 110 111/** 112 * os_mktemp() - Create a temporary file 113 * @fname: The template to use for the file name. This must end with 6 Xs. It 114 * will be modified to the opened filename on success. 115 * @size: The size of the file 116 * 117 * Create a temporary file using @fname as a template, unlink it, and truncate 118 * it to @size. 119 * 120 * Return: A file descriptor, or negative errno on error 121 */ 122int os_mktemp(char *fname, off_t size); 123 124/** 125 * os_exit() - access to the OS exit() system call 126 * 127 * This exits with the supplied return code, which should be 0 to indicate 128 * success. 129 * 130 * @exit_code: exit code for U-Boot 131 */ 132void os_exit(int exit_code) __attribute__((noreturn)); 133 134/** 135 * os_alarm() - access to the OS alarm() system call 136 * 137 * @seconds: number of seconds before the signal is sent 138 * Returns: number of seconds remaining until any previously scheduled alarm was 139 * due to be delivered; 0 if there was no previously scheduled alarm 140 */ 141unsigned int os_alarm(unsigned int seconds); 142 143/** 144 * os_set_alarm_handler() - set handler for SIGALRM 145 * 146 * @handler: The handler function. Pass NULL for SIG_DFL. 147 */ 148void os_set_alarm_handler(void (*handler)(int)); 149 150/** 151 * os_raise_sigalrm() - do raise(SIGALRM) 152 */ 153void os_raise_sigalrm(void); 154 155/** 156 * os_tty_raw() - put tty into raw mode to mimic serial console better 157 * 158 * @fd: File descriptor of stdin (normally 0) 159 * @allow_sigs: Allow Ctrl-C, Ctrl-Z to generate signals rather than 160 * be handled by U-Boot 161 */ 162void os_tty_raw(int fd, bool allow_sigs); 163 164/** 165 * os_fs_restore() - restore the tty to its original mode 166 * 167 * Call this to restore the original terminal mode, after it has been changed 168 * by os_tty_raw(). This is an internal function. 169 */ 170void os_fd_restore(void); 171 172/** 173 * os_malloc() - aquires some memory from the underlying os. 174 * 175 * @length: Number of bytes to be allocated 176 * Return: Pointer to length bytes or NULL if @length is 0 or on error 177 */ 178void *os_malloc(size_t length); 179 180/** 181 * os_free() - free memory previous allocated with os_malloc() 182 * 183 * This returns the memory to the OS. 184 * 185 * @ptr: Pointer to memory block to free. If this is NULL then this 186 * function does nothing 187 */ 188void os_free(void *ptr); 189 190/** 191 * os_realloc() - reallocate memory 192 * 193 * This follows the semantics of realloc(), so can perform an os_malloc() or 194 * os_free() depending on @ptr and @length. 195 * 196 * @ptr: pointer to previously allocated memory of NULL 197 * @length: number of bytes to allocate 198 * Return: pointer to reallocated memory or NULL if @length is 0 199 */ 200void *os_realloc(void *ptr, size_t length); 201 202/** 203 * os_usleep() - access to the usleep function of the os 204 * 205 * @usec: time to sleep in micro seconds 206 */ 207void os_usleep(unsigned long usec); 208 209/** 210 * Gets a monotonic increasing number of nano seconds from the OS 211 * 212 * Return: a monotonic increasing time scaled in nano seconds 213 */ 214uint64_t os_get_nsec(void); 215 216/** 217 * Parse arguments and update sandbox state. 218 * 219 * @state: sandbox state to update 220 * @argc: argument count 221 * @argv: argument vector 222 * Return: 223 * * 0 if ok, and program should continue 224 * * 1 if ok, but program should stop 225 * * -1 on error: program should terminate 226 */ 227int os_parse_args(struct sandbox_state *state, int argc, char *argv[]); 228 229/* 230 * enum os_dirent_t - type of directory entry 231 * 232 * Types of directory entry that we support. See also os_dirent_typename in 233 * the C file. 234 */ 235enum os_dirent_t { 236 /** 237 * @OS_FILET_REG: regular file 238 */ 239 OS_FILET_REG, 240 /** 241 * @OS_FILET_LNK: symbolic link 242 */ 243 OS_FILET_LNK, 244 /** 245 * @OS_FILET_DIR: directory 246 */ 247 OS_FILET_DIR, 248 /** 249 * @OS_FILET_UNKNOWN: something else 250 */ 251 OS_FILET_UNKNOWN, 252 /** 253 * @OS_FILET_COUNT: number of directory entry types 254 */ 255 OS_FILET_COUNT, 256}; 257 258/** 259 * struct os_dirent_node - directory node 260 * 261 * A directory entry node, containing information about a single dirent 262 * 263 */ 264struct os_dirent_node { 265 /** 266 * @next: pointer to next node, or NULL 267 */ 268 struct os_dirent_node *next; 269 /** 270 * @size: size of file in bytes 271 */ 272 ulong size; 273 /** 274 * @type: type of entry 275 */ 276 enum os_dirent_t type; 277 /** 278 * @name: name of entry 279 */ 280 char name[0]; 281}; 282 283/** 284 * os_dirent_ls() - get a directory listing 285 * 286 * This allocates and returns a linked list containing the directory listing. 287 * 288 * @dirname: directory to examine 289 * @headp: on return pointer to head of linked list, or NULL if none 290 * Return: 0 if ok, -ve on error 291 */ 292int os_dirent_ls(const char *dirname, struct os_dirent_node **headp); 293 294/** 295 * os_dirent_free() - free directory list 296 * 297 * This frees a linked list containing a directory listing. 298 * 299 * @node: pointer to head of linked list 300 */ 301void os_dirent_free(struct os_dirent_node *node); 302 303/** 304 * os_dirent_get_typename() - get the name of a directory entry type 305 * 306 * @type: type to check 307 * Return: 308 * string containing the name of that type, 309 * or "???" if none/invalid 310 */ 311const char *os_dirent_get_typename(enum os_dirent_t type); 312 313/** 314 * os_get_filesize() - get the size of a file 315 * 316 * @fname: filename to check 317 * @size: size of file is returned if no error 318 * Return: 0 on success or -1 if an error ocurred 319 */ 320int os_get_filesize(const char *fname, long long *size); 321 322/** 323 * os_putc() - write a character to the controlling OS terminal 324 * 325 * This bypasses the U-Boot console support and writes directly to the OS 326 * stdout file descriptor. 327 * 328 * @ch: haracter to write 329 */ 330void os_putc(int ch); 331 332/** 333 * os_puts() - write a string to the controlling OS terminal 334 * 335 * This bypasses the U-Boot console support and writes directly to the OS 336 * stdout file descriptor. 337 * 338 * @str: string to write (note that \n is not appended) 339 */ 340void os_puts(const char *str); 341 342/** 343 * os_flush() - flush controlling OS terminal 344 * 345 * This bypasses the U-Boot console support and flushes directly the OS 346 * stdout file descriptor. 347 */ 348void os_flush(void); 349 350/** 351 * os_write_ram_buf() - write the sandbox RAM buffer to a existing file 352 * 353 * @fname: filename to write memory to (simple binary format) 354 * Return: 0 if OK, -ve on error 355 */ 356int os_write_ram_buf(const char *fname); 357 358/** 359 * os_read_ram_buf() - read the sandbox RAM buffer from an existing file 360 * 361 * @fname: filename containing memory (simple binary format) 362 * Return: 0 if OK, -ve on error 363 */ 364int os_read_ram_buf(const char *fname); 365 366/** 367 * os_jump_to_image() - jump to a new executable image 368 * 369 * This uses exec() to run a new executable image, after putting it in a 370 * temporary file. The same arguments and environment are passed to this 371 * new image, with the addition of: 372 * 373 * -j <filename> Specifies the filename the image was written to. The 374 * calling image may want to delete this at some point. 375 * -m <filename> Specifies the file containing the sandbox memory 376 * (ram_buf) from this image, so that the new image can 377 * have access to this. It also means that the original 378 * memory filename passed to U-Boot will be left intact. 379 * 380 * @dest: buffer containing executable image 381 * @size: size of buffer 382 * Return: 0 if OK, -ve on error 383 */ 384int os_jump_to_image(const void *dest, int size); 385 386/** 387 * os_find_u_boot() - determine the path to U-Boot proper 388 * 389 * This function is intended to be called from within sandbox SPL. It uses 390 * a few heuristics to find U-Boot proper. Normally it is either in the same 391 * directory, or the directory above (since u-boot-spl is normally in an 392 * spl/ subdirectory when built). 393 * 394 * @fname: place to put full path to U-Boot 395 * @maxlen: maximum size of @fname 396 * @use_img: select the 'u-boot.img' file instead of the 'u-boot' ELF file 397 * @cur_prefix: prefix of current executable, e.g. "spl" or "tpl" 398 * @next_prefix: prefix of executable to find, e.g. "spl" or "" 399 * Return: 0 if OK, -NOSPC if the filename is too large, -ENOENT if not found 400 */ 401int os_find_u_boot(char *fname, int maxlen, bool use_img, 402 const char *cur_prefix, const char *next_prefix); 403 404/** 405 * os_spl_to_uboot() - Run U-Boot proper 406 * 407 * When called from SPL, this runs U-Boot proper. The filename is obtained by 408 * calling os_find_u_boot(). 409 * 410 * @fname: full pathname to U-Boot executable 411 * Return: 0 if OK, -ve on error 412 */ 413int os_spl_to_uboot(const char *fname); 414 415/** 416 * os_localtime() - read the current system time 417 * 418 * This reads the current Local Time and places it into the provided 419 * structure. 420 * 421 * @rt: place to put system time 422 */ 423void os_localtime(struct rtc_time *rt); 424 425/** 426 * os_abort() - raise SIGABRT to exit sandbox (e.g. to debugger) 427 */ 428void os_abort(void) __attribute__((noreturn)); 429 430/** 431 * os_mprotect_allow() - Remove write-protection on a region of memory 432 * 433 * The start and length will be page-aligned before use. 434 * 435 * @start: Region start 436 * @len: Region length in bytes 437 * Return: 0 if OK, -1 on error from mprotect() 438 */ 439int os_mprotect_allow(void *start, size_t len); 440 441/** 442 * os_write_file() - write a file to the host filesystem 443 * 444 * This can be useful when debugging for writing data out of sandbox for 445 * inspection by external tools. 446 * 447 * @name: File path to write to 448 * @buf: Data to write 449 * @size: Size of data to write 450 * Return: 0 if OK, -ve on error 451 */ 452int os_write_file(const char *name, const void *buf, int size); 453 454/** 455 * os_read_file() - Read a file from the host filesystem 456 * 457 * This can be useful when reading test data into sandbox for use by test 458 * routines. The data is allocated using os_malloc() and should be freed by 459 * the caller. 460 * 461 * @name: File path to read from 462 * @bufp: Returns buffer containing data read 463 * @sizep: Returns size of data 464 * Return: 0 if OK, -ve on error 465 */ 466int os_read_file(const char *name, void **bufp, int *sizep); 467 468/** 469 * os_map_file() - Map a file from the host filesystem into memory 470 * 471 * This can be useful when to provide a backing store for an emulated device 472 * 473 * @pathname: File pathname to map 474 * @os_flags: Flags, like OS_O_RDONLY, OS_O_RDWR 475 * @bufp: Returns buffer containing the file 476 * @sizep: Returns size of data 477 * Return: 0 if OK, -ve on error 478 */ 479int os_map_file(const char *pathname, int os_flags, void **bufp, int *sizep); 480 481/** 482 * os_unmap() - Unmap a file previously mapped 483 * 484 * @buf: Mapped address 485 * @size: Size in bytes 486 * Return: 0 if OK, -ve on error 487 */ 488int os_unmap(void *buf, int size); 489 490/* 491 * os_find_text_base() - Find the text section in this running process 492 * 493 * This tries to find the address of the text section in this running process. 494 * It can be useful to map the address of functions to the address listed in 495 * the u-boot.map file. 496 * 497 * Return: address if found, else NULL 498 */ 499void *os_find_text_base(void); 500 501/** 502 * os_relaunch() - restart the sandbox 503 * 504 * This functions is used to implement the cold reboot of the sand box. 505 * @argv\[0] specifies the binary that is started while the calling process 506 * stops immediately. If the new binary cannot be started, the process is 507 * terminated and 1 is set as shell return code. 508 * 509 * The PID of the process stays the same. All file descriptors that have not 510 * been opened with O_CLOEXEC stay open including stdin, stdout, stderr. 511 * 512 * @argv: NULL terminated list of command line parameters 513 */ 514void os_relaunch(char *argv[]); 515 516/** 517 * os_setup_signal_handlers() - setup signal handlers 518 * 519 * Install signal handlers for SIGBUS and SIGSEGV. 520 * 521 * Return: 0 for success 522 */ 523int os_setup_signal_handlers(void); 524 525/** 526 * os_signal_action() - handle a signal 527 * 528 * @sig: signal 529 * @pc: program counter 530 */ 531void os_signal_action(int sig, unsigned long pc); 532 533/** 534 * os_get_time_offset() - get time offset 535 * 536 * Get the time offset from environment variable UBOOT_SB_TIME_OFFSET. 537 * 538 * Return: offset in seconds 539 */ 540long os_get_time_offset(void); 541 542/** 543 * os_set_time_offset() - set time offset 544 * 545 * Save the time offset in environment variable UBOOT_SB_TIME_OFFSET. 546 * 547 * @offset: offset in seconds 548 */ 549void os_set_time_offset(long offset); 550 551#endif 552