L4Re/departure

Annotated tests/dstest_exec.cc

360:92c5f6aa8c36
2022-06-12 Paul Boddie Reintroduced PagerObject code generation required to initiate servers. mmap-region-flags
paul@308 1
/*
paul@308 2
 * Support for executing code in new tasks and threads.
paul@308 3
 *
paul@308 4
 * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
paul@308 5
 *
paul@308 6
 * This program is free software; you can redistribute it and/or
paul@308 7
 * modify it under the terms of the GNU General Public License as
paul@308 8
 * published by the Free Software Foundation; either version 2 of
paul@308 9
 * the License, or (at your option) any later version.
paul@308 10
 *
paul@308 11
 * This program is distributed in the hope that it will be useful,
paul@308 12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@308 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@308 14
 * GNU General Public License for more details.
paul@308 15
 *
paul@308 16
 * You should have received a copy of the GNU General Public License
paul@308 17
 * along with this program; if not, write to the Free Software
paul@308 18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
paul@308 19
 * Boston, MA  02110-1301, USA
paul@308 20
 */
paul@308 21
paul@308 22
#include <l4/re/env.h>
paul@308 23
#include <l4/sys/err.h>
paul@312 24
#include <l4/util/util.h>
paul@308 25
paul@327 26
#include <exec/elf.h>
paul@349 27
#include <exec/memory.h>
paul@355 28
#include <exec/pager.h>
paul@324 29
#include <exec/process.h>
paul@308 30
#include <ipc/server.h>
paul@312 31
paul@308 32
#include <stdio.h>
paul@308 33
paul@308 34
#include <pthread-l4.h>
paul@308 35
#include <pthread.h>
paul@308 36
paul@312 37
#include "pager_object_server.h"
paul@308 38
paul@308 39
paul@308 40
paul@308 41
static ExecPager exec_pager;
paul@308 42
paul@308 43
paul@308 44
paul@308 45
int main(int argc, char *argv[])
paul@308 46
{
paul@308 47
  long err;
paul@308 48
paul@308 49
  if (argc < 2)
paul@308 50
  {
paul@308 51
    printf("Need a program to run.\n");
paul@308 52
    return 1;
paul@308 53
  }
paul@308 54
paul@349 55
  /* Initialise the memory of the new task. */
paul@323 56
paul@349 57
  offset_t initial_stack_size = 16 * L4_PAGESIZE;
paul@349 58
  ExplicitSegment stack(Utcb_area_start - initial_stack_size, initial_stack_size, L4_FPAGE_RW);
paul@349 59
  Payload *payload;
paul@323 60
paul@349 61
  if (exec_get_payload(argv[1], &payload))
paul@323 62
  {
paul@349 63
    printf("Could not initialise program.\n");
paul@325 64
    return 1;
paul@325 65
  }
paul@325 66
paul@349 67
  if (stack.allocate())
paul@316 68
  {
paul@349 69
    printf("Could not allocate stack.\n");
paul@349 70
    return 1;
paul@308 71
  }
paul@308 72
paul@354 73
  /* Initialise pager regions. */
paul@312 74
paul@349 75
  for (unsigned int i = 0; i < payload->segments(); i++)
paul@325 76
  {
paul@349 77
    if (payload->segment(i)->loadable())
paul@349 78
      exec_pager.add(payload->segment(i)->region());
paul@349 79
  }
paul@325 80
paul@349 81
  exec_pager.add(stack.region());
paul@308 82
paul@354 83
  /* Start the pager. */
paul@354 84
paul@354 85
  pthread_t pager_thread;
paul@354 86
  pthread_attr_t attr;
paul@354 87
paul@354 88
  pthread_attr_init(&attr);
paul@354 89
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
paul@354 90
paul@354 91
  ipc_server_config_type config;
paul@354 92
  ipc_server_init_for(&config, PagerObject, &exec_pager);
paul@354 93
paul@308 94
  err = pthread_create(&pager_thread, &attr, ipc_server_start_mainloop, &config);
paul@308 95
paul@308 96
  if (err)
paul@308 97
  {
paul@308 98
    printf("Could not start pager thread.\n");
paul@308 99
    return 1;
paul@308 100
  }
paul@308 101
paul@354 102
  printf("Starting pager thread...\n");
paul@354 103
  err = ipc_server_start_config_thread(&config, pthread_l4_cap(pager_thread));
paul@308 104
paul@308 105
  if (err)
paul@308 106
  {
paul@308 107
    printf("Could not start pager.\n");
paul@308 108
    return 1;
paul@308 109
  }
paul@308 110
paul@319 111
  /* Configure the environment for the task, specifying the pager (and exception
paul@319 112
     handler plus region mapper). */
paul@308 113
paul@321 114
  Process process;
paul@321 115
paul@321 116
  err = process.configure(config.server);
paul@308 117
paul@308 118
  if (err)
paul@308 119
  {
paul@321 120
    printf("Could not configure task.\n");
paul@308 121
    return 1;
paul@308 122
  }
paul@308 123
paul@321 124
  /* Populate a thread stack with argument and environment details. */
paul@321 125
paul@321 126
  Stack st(stack);
paul@321 127
paul@321 128
  /* NOTE: Environment vector is currently not defined. */
paul@321 129
paul@321 130
  char *envp[] = {NULL};
paul@321 131
paul@321 132
  st.populate(argc - 1, argv + 1, envp);
paul@321 133
paul@321 134
  /* Start the new thread in the given stack. */
paul@308 135
paul@308 136
  printf("Run thread...\n");
paul@308 137
paul@349 138
  err = process.thread_start(payload->entry_point(), st);
paul@308 139
paul@308 140
  if (err)
paul@308 141
  {
paul@308 142
    printf("Could not run thread.\n");
paul@308 143
    return 1;
paul@308 144
  }
paul@308 145
paul@308 146
  printf("Finished.\n");
paul@308 147
  while (1);
paul@308 148
paul@308 149
  return 0;
paul@308 150
}
paul@308 151
paul@308 152
/* vim: tabstop=2 expandtab shiftwidth=2
paul@308 153
*/