Skip to content

Commit

Permalink
o Some code cleanup, but mostly implementing a working /dev/rtc, for …
Browse files Browse the repository at this point in the history
…RTC_RD_TIME anyway.
  • Loading branch information
Mike Miller committed Nov 24, 2023
1 parent 73395b6 commit 15d6f4e
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 73 deletions.
15 changes: 8 additions & 7 deletions app/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import "SceneDelegate.h"
#import "PasteboardDevice.h"
#import "LocationDevice.h"
#import "RTCDevice.h"
#import "NSObject+SaneKVO.h"
#import "Roots.h"
#import "TerminalViewController.h"
Expand Down Expand Up @@ -57,9 +58,7 @@ static void ios_handle_exit(struct task *task, int code) {
pid_t pid = task->pid;
// if(pids_lock.pid == pid)
// unlock(&pids_lock);
// while((critical_region_count(task)) || (locks_held_count(task))) { // Wait for now, task is in one or more critical sections, and/or has locks
// nanosleep(&lock_pause, NULL);
// }

unlock(&pids_lock);
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:ProcessExitedNotification
Expand Down Expand Up @@ -103,7 +102,6 @@ @implementation AppDelegate

- (intptr_t)boot {
#if !ISH_LINUX

NSURL *root = [Roots.instance rootUrl:Roots.instance.defaultRoot];

intptr_t err = mount_root(&fakefs, [root URLByAppendingPathComponent:@"data"].fileSystemRepresentation);
Expand Down Expand Up @@ -165,16 +163,19 @@ - (intptr_t)boot {

// Register clipboard device driver and create device node for it
err = dyn_dev_register(&clipboard_dev, DEV_CHAR, DYN_DEV_MAJOR, DEV_CLIPBOARD_MINOR);
if (err != 0) {
if (err != 0)
return err;
}
generic_mknodat(AT_PWD, "/dev/clipboard", S_IFCHR|0666, dev_make(DYN_DEV_MAJOR, DEV_CLIPBOARD_MINOR));

err = dyn_dev_register(&location_dev, DEV_CHAR, DYN_DEV_MAJOR, DEV_LOCATION_MINOR);
if (err != 0)
return err;
generic_mknodat(AT_PWD, "/dev/location", S_IFCHR|0666, dev_make(DYN_DEV_MAJOR, DEV_LOCATION_MINOR));
// The following does nothing for now. Placeholder

// Create an emulated Real Time Clock
err = dyn_dev_register(&rtc_dev, DEV_CHAR, DEV_RTC_MAJOR, DEV_RTC_MINOR);
if (err != 0)
return err;
generic_mknodat(AT_PWD, "/dev/rtc0", S_IFCHR|0666, dev_make(DEV_RTC_MAJOR, DEV_RTC_MINOR));
generic_symlinkat("/dev/rtc0", AT_PWD, "/dev/rtc");

Expand Down
14 changes: 14 additions & 0 deletions app/RTCDevice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// RTCDevice.h
// iSH-AOK
//
// Created by Michael Miller on 11/22/23.
//
#include"fs/tty.h"

extern struct dev_ops rtc_dev;
extern int rtc_close(struct fd *fd);
extern ssize_t rtc_read(struct fd *fd, void *buf, size_t bufsize);
extern int rtc_ioctl(struct fd *fd, int cmd, void *arg);
extern int rtc_poll(struct fd *fd);
extern int rtc_open(int major, int minor, struct fd *fd);
123 changes: 123 additions & 0 deletions app/RTCDevice.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#include <Foundation/Foundation.h>
#include "fs/poll.h"
#include "fs/dyndev.h"
#include "kernel/errno.h"
#include "debug.h"
#include "fs/devices.h"

// Real Time Clock file descriptor structure
typedef struct fd rtc_fd;

// Function to get the current time
typedef struct rtc_time {
int tm_sec; // seconds
int tm_min; // minutes
int tm_hour; // hours
int tm_mday; // day of the month
int tm_mon; // month
int tm_year; // year
} rtc_time;

static rtc_time *get_current_time(rtc_fd *fd, size_t *len) {
// Obtain the current date
NSDate *currentDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];

// Define the desired date components
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond)
fromDate:currentDate];

// Allocate and populate the rtc_time structure
rtc_time *timeStruct = malloc(sizeof(rtc_time));
if (!timeStruct) {
// Handle memory allocation failure
*len = 0;
return NULL;
}

// Populate the structure
// Note: tm_mon is 0-based (0 for January) and tm_year is years since 1900
timeStruct->tm_sec = (int)[components second];
timeStruct->tm_min = (int)[components minute];
timeStruct->tm_hour = (int)[components hour];
timeStruct->tm_mday = (int)[components day];
timeStruct->tm_mon = (int)[components month] - 1; // Adjust for tm_mon
timeStruct->tm_year = (int)[components year] - 1900; // Adjust for tm_year

// Update the size
*len = sizeof(rtc_time);

return timeStruct;
}


// Read current time into buffer
static ssize_t rtc_read(rtc_fd *fd, void *buf, size_t bufsize) {
@autoreleasepool {
size_t length = 0;
rtc_time *data = get_current_time(fd, &length);

if (bufsize < length) {
return _EINVAL; // Buffer size is too small
}

memcpy(buf, data, length);
return length; // Return the number of bytes copied
}
}

// Polling is not needed for RTC, return 0
static int rtc_poll(rtc_fd *fd) {
return 0;
}

// Function to open the RTC device
static int rtc_open(int major, int minor, rtc_fd *fd) {
return 0;
}

// Function to close the RTC device
static int rtc_close(rtc_fd *fd) {
return 0;
}

#define RTC_RD_TIME 0x80247009 // Example definition, adjust as necessary

static ssize_t rtc_ioctl_size(int cmd) {
switch (cmd) {
case RTC_RD_TIME:
return sizeof(rtc_time);
}
return -1;
}

// Function to handle ioctl operations
static int rtc_ioctl(struct fd *fd, int cmd, void *arg) {
@autoreleasepool {
switch (cmd) {
case RTC_RD_TIME: { // On a real Linux, there are a number of other possible ioctl()'s. We don't really need them
size_t length = 0;
rtc_time *data = get_current_time(fd, &length);

if (arg == NULL) {
return _EFAULT; // Null pointer argument
}

*(rtc_time *) arg = *data; // This is the magic that gets the value back to the "kernel"

return 0; // Success
}
default:
return _EFAULT; // Oops
}
}
}

struct dev_ops rtc_dev = {
.open = rtc_open,
.fd.read = rtc_read,
.fd.poll = rtc_poll,
.fd.close = rtc_close,
.fd.ioctl = rtc_ioctl,
.fd.ioctl_size = rtc_ioctl_size,
};
3 changes: 2 additions & 1 deletion fs/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "fs/tty.h"
#include "fs/dyndev.h"
#include "fs/devices.h"
#include "app/RTCDevice.h"

struct dev_ops *block_devs[256] = {
// no block devices yet
Expand All @@ -15,7 +16,7 @@ struct dev_ops *char_devs[256] = {
[TTY_ALTERNATE_MAJOR] = &tty_dev,
[TTY_PSEUDO_MASTER_MAJOR] = &tty_dev,
[TTY_PSEUDO_SLAVE_MAJOR] = &tty_dev,
// [DEV_RTC_MAJOR] = &rtc_dev_char,
[DEV_RTC_MAJOR] = &rtc_dev,
[DYN_DEV_MAJOR] = &dyn_dev_char,
};

Expand Down
6 changes: 0 additions & 6 deletions fs/dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,6 @@ static inline dev_t_ dev_fake_from_real(dev_t dev) {
#define DEV_BLOCK 0
#define DEV_CHAR 1

struct dev_rtc {
int (*open)(int major, int minor, struct fd *fd);
int (*close)(int major, int minor, struct fd *fd);
ssize_t (*read)(void *buf, size_t count);
};

struct dev_ops {
int (*open)(int major, int minor, struct fd *fd);
struct fd_ops fd;
Expand Down
3 changes: 2 additions & 1 deletion fs/devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@

// --- dynamic devices ---
#define DYN_DEV_MAJOR 240

// /dev/rtc
#define DEV_RTC_MAJOR 252
#define DEV_RTC_MINOR 0
#define DEV_RTC_MINOR 2


// /dev/clipboard
Expand Down
66 changes: 14 additions & 52 deletions fs/dyndev.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int dyn_dev_register(struct dev_ops *ops, int type, int major, int minor) {
if (minor < 0 || minor > MAX_MINOR) {
return _EINVAL;
}
if (major != DYN_DEV_MAJOR) {
if ((major != DYN_DEV_MAJOR) && (major != DEV_RTC_MAJOR)) {
return _EINVAL;
}
if (ops == NULL) {
Expand All @@ -52,68 +52,30 @@ int dyn_dev_register(struct dev_ops *ops, int type, int major, int minor) {

static int dyn_open(int type, int major, int minor, struct fd *fd) {
assert((type == DEV_CHAR) || (type == DEV_BLOCK));
assert(major == DYN_DEV_MAJOR || major == DEV_RTC_MAJOR); // mkemkemke
assert(major == DYN_DEV_MAJOR);
// it's safe to access devs without locking (read-only)

if(major == DEV_RTC_MAJOR) {
//return rtc_dev_char(major, minor, fd);
} else {
struct dev_ops *ops = dyn_info_char.devs[minor];
if (ops == NULL) {
return _ENXIO;
}
fd->ops = &ops->fd;

// Succeed if there's no open provided by ops
if (!ops->open)
return 0;
return ops->open(major, minor, fd);
struct dev_ops *ops;

ops = dyn_info_char.devs[minor];
if (ops == NULL) {
return _ENXIO;
}

return 0;
fd->ops = &ops->fd;

// Succeed if there's no open provided by ops
if (!ops->open)
return 0;

return ops->open(major, minor, fd);
}

static int dyn_open_char(int major, int minor, struct fd *fd) {
return dyn_open(DEV_CHAR, major, minor, fd);
}

struct rtc_time {
int tm_sec; /* seconds */
int tm_min; /* minutes */
int tm_hour; /* hours */
int tm_mday; /* day of the month */
int tm_mon; /* month */
int tm_year; /* year */
};

int rtc_dev(void *buf, size_t count) {
if (count < sizeof(struct rtc_time)) {
errno = EFAULT;
return -1;
}

time_t now;
struct tm *tm_now;
struct rtc_time emulatedRTC;

time(&now);
tm_now = localtime(&now);

emulatedRTC.tm_sec = tm_now->tm_sec;
emulatedRTC.tm_min = tm_now->tm_min;
emulatedRTC.tm_hour = tm_now->tm_hour;
emulatedRTC.tm_mday = tm_now->tm_mday;
emulatedRTC.tm_mon = tm_now->tm_mon;
emulatedRTC.tm_year = tm_now->tm_year + 1900;

memcpy(buf, &emulatedRTC, sizeof(emulatedRTC));
return sizeof(emulatedRTC);
}

struct dev_ops dyn_dev_char = {
.open = dyn_open_char,
};

struct dev_ops rtc_dev_char = {
.open = dyn_open_char,
};
3 changes: 0 additions & 3 deletions fs/dyndev.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
// dev_ops handing char device with DYN_DEV_MAJOR major number
extern struct dev_ops dyn_dev_char;

// Implement fake rtc -mke
extern struct dev_ops rtc_dev_char;

// Registeres new block/character device with provided major and
// minor numbers, handled by provided ops
//
Expand Down
4 changes: 2 additions & 2 deletions fs/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ int tty_open(struct tty *tty, struct fd *fd) {
return 0;
}

static intptr_t tty_device_open(int major, int minor, struct fd *fd) {
static int tty_device_open(int major, int minor, struct fd *fd) {
struct tty *tty;
if (major == TTY_ALTERNATE_MAJOR) {
if (minor == DEV_TTY_MINOR) {
Expand Down Expand Up @@ -189,7 +189,7 @@ static intptr_t tty_device_open(int major, int minor, struct fd *fd) {
assert(driver != NULL);
tty = tty_get(driver, major, minor);
if (IS_ERR(tty))
return PTR_ERR(tty);
return (int)PTR_ERR(tty);
}

if (tty->driver->ops->open) {
Expand Down
Loading

0 comments on commit 15d6f4e

Please sign in to comment.